Pipes - child buffers its output

Leo de Wit leo at ehviea.ine.philips.nl
Fri May 4 06:45:36 AEST 1990


In article <745 at mwtech.UUCP> martin at mwtech.UUCP (Martin Weitzel) writes:
|In article <1364 at ns-mx.uiowa.edu> rpruess at umaxc.weeg.uiowa.edu (Rex Pruess) writes:
|:From a C program, I'd like to be to control an interactive program like
|:'ftp' or 'adb'. It should work as follows:
|:
|: 	write some commands to stdin of 'ftp'
|:	read stdout of 'ftp'
|:	interpret the results
|:	write more commands (depending on the results) to stdin of `ftp'
|:	:
|:
|:I've been successful in setting up the two pipes, but the child (e.g.,
|:ftp) buffers all of its output until it exits.  I need the child's output
|:returned on a line by line basis.  What's the trick to accomplish this?
|
|I have bad news:
|There seems to be no such trick for the "pure mortal user" - the user
|without the source. To the benefit of thousands of lazy programmers who
|could or should not be obliged to use explicit "setbuf()" or "fflush()"
|the decission about buffering an I/O-stream is made automatically in the
|library routines.

Actually, it can be done, and it is rather easy too. Provided that your
system supports them, just open a pseudo tty, connect stdin and stdout
of the interactive program to the slave device (by fork, redirections
and exec), and your own application to the master device. Write your
commands to the output side of the master device, they will appear at
the input side of the slave device for the interactive program as its
standard input; read the results from the input side of the master
device, which reflects the output side of the slave device (the
standard output of the interactive program). Since the interactive
program is connected to a tty, buffering will be as you expect.

This method is also exploited by programs like rlogin and script; I
assume in a System V environment similar solutions are possible.

|
|Unfortunately the one who had to decide about the "automatism" could
|not imagine such an advanced scheme as you describe above and hence
|decided that only I/O-streams connected to devices work unbuffered,
|while pipes and files are buffered.
|

Indeed. Perhaps a new fcntl() could solve this: to indicate what kind
of buffering is wanted (e.g. blocked, line-buffered or unbuffered).
The library functions then could make decisions based on the current
flags for that file descriptor; no need for a kludgy 'check for tty'
(though I could imagine some people would object to have low level I/O
routines store/retrieve information about high level I/O ones (stdio
buffering)).  Also no need to provide 'unbuffered' flags to commands
(e.g. cat).  This mechanism would have to get some support by the
shell, e.g. |+ for a pipe, requesting line buffered I/O, or >: for
output, requesting unbuffered I/O.

Just speculating...

    Leo.



More information about the Comp.unix.questions mailing list