cniggeler
cniggeler

Reputation: 113

Perl system() requires stdout flush

I have a problem similar to bash script flush but would appreciate confirmation and clarification:

I have a console-based, interactive perl script that writes to stdout. Along the way, it uses system() to call a C program, and its output (also to stdout) is massaged by the script and output to the user.

On Windows there have been no issues. But on Linux, in one very specific and very repeatable instance, only the trailing part of the program's message arrives to the script. Found that by adding fflushes in the C program, the issue goes away.

EDIT: Further testing reveals that a single fflush just before returning has cleared up the issue, at least for this specific instance. So this point of this post is now where the community thinks the issue is occurring, so I can avoid it in other situations in the future...

Is it the interplay between the script and the C program, both of which use stdout? Or is it that system() in perl creates a sub-shell to execute the program, and maybe the issue arises there?

If the former: is fflush the best option? Just one call seems quite reasonable in terms of overhead.

If the latter, could stdbuf somehow be used to alter the stdout behavior of the sub-shell running the program, especially if it's a program that can't be rewritten?

Thanks!

Upvotes: 2

Views: 378

Answers (1)

cniggeler
cniggeler

Reputation: 113

I've tested, and found the issue can be resolved with either of these approaches:

  1. Add fflush at the end of the C program.
  2. Run the C program without fflush using (in perl) `stdbuf -oL myprog` (I had incorrectly referenced system() before, sorry).

Some commenters refer to the fact that C should flush the buffer on exit, but CERT vulnerability FI023.C is specifically about unflushed data in stdout using C. When capturing stdout using perl tickmarks, I'm left wondering if that's a sort of redirection where this situation can occur.

Upvotes: 3

Related Questions