[net.unix] stdout buffering question

gsc@druxr.UUCP (CageG) (04/12/85)

 I am trying to exec a child with its standard in, out and error
directed to pipes. I have managed to accomplish this in two different
ways, closing the std stuff, duping to the pipes and by execing the shell
with appropriate arguments. The snag I have run into is that it appears
that when a process is execed the operating system does you a favor and
make stdout buffered. The result is that nothing is written into the pipe
for stdout until the child flushes stdout or the child exits. If in the child
the buffer size is set to 0 using setbuf then every thing works fine. However
one constraint for what I am trying to do is that no changes (like adding the
setbuf call) can be made to the child process. Calling setbuf after I fork
but before the exec doesn't seem to work. The decision to have buffered output
seems to be done at exec time. Does anyone have any idea how to exec a process
and have it maintain the same buffering characteristics as the parent or how
to exec a process and disable the assignment of buffering to stdout outside
the child process? I am out of ideas and am just about to abandon this
redirection problem. Any thoughts or ideas would be greatly appreciated.

				Thanks
				Gary Cage
				druxr!gsc
				(303) 538-4947

gamma@rtp47.UUCP (Michael Meissner) (04/17/85)

> 
>  I am trying to exec a child with its standard in, out and error
> directed to pipes. I have managed to accomplish this in two different
> ways, closing the std stuff, duping to the pipes and by execing the shell
> with appropriate arguments. The snag I have run into is that it appears
> that when a process is execed the operating system does you a favor and
> make stdout buffered.	...

First, the decision on whether to buffer is not done at exec time, but rather
in the standard I/O library when you first write to the file.  Different
systems make different decisions on when to buffer.  Typically, if the
output is a console, it is either unbuffered (BSD?), or line buffered (system
V).  Pipes are typically fully buffered for performance reasons.  The only
three ways I can see of fixing your problem, is to:

    1)	Create a pseudo terminal that is opened for write in exec'ing the
	child, and for read in the parent.

    2)	Hack on the standard I/O library to unbuffer pipes, and expect a
	possible performance hit on pipes in general.  Or, use the hacked
	library only in the program you use.  Alternatively, hack isatty
	to always return 1 (this can be done with a reasonable patch prog.)

    3)	Try to get the program to use fflush at appropriate times.

	Michael Meissner
	Data General Corporation
	...!mcnc!rti-sel!rtp47!meissner

john@x.UUCP (John Woods) (04/17/85)

>with appropriate arguments. The snag I have run into is that it appears
>that when a process is execed the operating system does you a favor and
>make stdout buffered. The result is that nothing is written into the pipe
>for stdout until the child flushes stdout or the child exits. If in the child
>the buffer size is set to 0 using setbuf then every thing works fine. However
>one constraint for what I am trying to do is that no changes (like adding the
>setbuf call) can be made to the child process. Calling setbuf after I fork
>but before the exec doesn't seem to work. The decision to have buffered
>output seems to be done at exec time.

I'm sure this will get beaten to death, but here goes:

The operating system has not soiled its hands with this buffering decision.
The standard IO library did.  Normally, all standard IO streams are buffered
save those going to terminals.  When you did the exec, you loaded a whole
new program that got to discover for itself that it's output stream was not
connected to a terminal, and therefore to save you some processor time, it
elected to buffer standard output.  Alas, in the case of pipes, this behavior
is sometimes not what one wants (sometimes it is).

What you must do is add setbuf to the child process.  Since you can't do
this, you may be stuck (you probably don't want to adb the binary to add
the unbuffered flag to the stdout structure, either...).

Hope this helps.

-- 
John Woods, Charles River Data Systems, Framingham MA, (617) 626-1101
...!decvax!frog!john, ...!mit-eddie!jfw, jfw%mit-ccc@MIT-XX.ARPA

You can't spell "vile" without "vi".