>>the reason for this being the fact that streams (like stdout) are user data
>>structures, which are not retained across exec(). Open files however, which
>>are kernel data structures, are kept open across fork() and exec().
>At first glance, one tends to think of this as a minor flaw in the
>construction of Unix. "Hmmm... if the parent program opens a
>pipe/socket/&c for the child, but I still want the child program to
>work interactively, I have to explicitly setbuf() within the code of
>the child program." At first, this appears to run contrary to the
>purpose of the tiny stub of child process code between the fork() and
>the exec(), since the setbuf() code must be placed within the source
>of the child program.
>But then, one realizes that - if a program is to be able to run
>interactively - it SHOULD explicitly set stdout to be unbuffered or
>line buffered (as appropriate, and assuming that stdout is the
>preferred channel of interactive output).
Actually the flaw is that pipes present a different interface than
ptys and real ttys, yet the unix programming paradigm is to treat
everything the same. Season that with a stdio library that tries
to guess whether or not it can get away with more efficient block
buffering based on which interface it detects and you get connections
that sometimes do what you want and sometimes not. But, note that
stdio is the real culprit. If a program does it's own buffering
with write()'s whenever needed, you don't have a problem. The simple
solution is to just call fflush() at any point in every program where
it might be useful to be sure something is printed. You need this
anyway if you ever issue prompts that don't include a newline. Or,
if you want to allow the more efficient block buffering in non-interactive
mode, be sure to include a command line option so you can override
stdio's guess.
Les Mikesell