[net.unix] Buffering problems in pipes

kvancamp@ardc.arpa (LCWSL) (12/18/85)

	I'm sending one more message to the net regarding the use of 
buffering when teeing to a file and stdout.  This is in response to one 
person who asked me to summarize my findings, a couple of others who wrote 
me and shared my misconceptions of the problem, and a few other people who 
sent me programs that I couldn't respond directly to (my mailer didn't 
understand their address on the net).  I apologize to this last group for 
not sending replies directly; it wasn't for lack of trying.  
	My problem was with a program whose output I wished to echo to a 
file at the same time I viewed it on the screen.  Because of the interactive 
nature of the program, it was imperative that buffering be inhibited so I 
could see the questions before having to respond to them.  My findings are 
as follows: 

1.) Three people sent me their versions of tee that inhibited buffering. The
main idea was to make a call to setbuf(stdout, (char *) 0);
The problem here is that tee wasn't the culprit in the buffering. It was the
pipe from my original program, which wrote to stdout. Whenever Unix sees a
pipe, it automatically buffers output. I tried all 3 versions of tee, and
none could inhibit this. To quote one of the respondees:
>This whole saga is so sad when you think about one of the fundamental
>UNIX philosophies:  files are all just streams of characters and you
>can replace files with pipes with devices and it all works the same.
>As long as programs don't try to find out where they are going or coming
>from (unlike stdio & BSD ls, vi) this works great.  When it is violated,
>it causes major problems!

2.) The script command is what I really wanted, but didn't have on my 
Masscomp.  One person was nice enough to send me a program he wrote that was 
similar to script; it compiled on my Masscomp with no alterations (praise be 
for portable programming!).  It's really quite a nifty program.  Just start 
it up and it creates a new shell, piping ALL output thereafter to both a 
file and stdout, until it is killed.  Unfortunately (as the author pointed 
out), the program uses pipes to do what it does, instead of script's method 
of using pseudo ttys (pty's); hence the same old problem.  Output is 
buffered because the system sees a pipe.  Nonetheless, this is a very useful 
program when buffering is not a problem -- I'll definitely keep this one 
around.  Some day when I have the time I'd like to modify this program to use 
pty's (which my Masscomp has) -- to make it a true script command.  

3.) The only solution for now is to modify my original program to add the 
setbuf call.  This is okay because all of my interactive programs were 
written here and I have the sources.  As someone pointed out, if the program 
generates a lot of output, fflush is better to use than setbuf so that 
things aren't slowed down too much by the inhibited buffering.  I've done 
this already and it works fine.  

	Thanks again to all those who responded! (Any additional comments
should be sent directly to me, as I am not on the net. --
<kvancamp@pica-lca.arpa>)

gwyn@BRL.ARPA (VLD/VMB) (12/18/85)

I think it would be a nice idea if the STDIO package
would treat pipes much like terminals by default; i.e.,
not try to fill the whole BUFSIZ buffer but just use
whatever data the read() returns.  (I don't think
anything useful can be done about output to a pipe,
since allowing single-character write() would be too
inefficient for general use.)

Would this cause problems for anyone?  If not, let's
do it..