stdio buffering considered harmful

trt at rti-sel.UUCP trt at rti-sel.UUCP
Sat Aug 6 01:38:56 AEST 1983


The stdout buffering discussion has occurred at least twice before on Usenet.
Some blame stdio for being insufficiently clever,
some blame programmers for not defending against stdio's cleverness,
I blame Dennis Ritchie for not taking the buffering problem seriously.
(He once said he never wanted people to use the 'setbuf' hack,
that buffering in stdio should be transparent.  Alas, it is not.)

HOW TO LIVE WITH STDIO BUFFERING
Programming 'correctly' in the presence of stdio buffering
is a bit hard to define, but you probably need to put an fflush(stdout)
before each of the following system calls:
	read, pause (also 'sleep'), fork, exec[lv], kill, wait, ioctl ('stty')
Oddly, exit(II) is OK since it "knows" about stdio.  Oh yes, do not use lseek.
If you are debugging, put an fflush in just before it core dumps.
Oh, and do an fflush before a long running computation.
Do you need to fflush before a 'system'?  It gets awful, doesn't it.

I have found that portability and efficiency are well served
by turning on stdio buffering at the very beginning of main():
	setbuf(stdout, BUFFERED_STDIO);
That means I have to put fflush()es all over the place
so the program works, but that is OK because if I do not
the program will not work in the presence of clever stdio systems, anyway.

For portability, the following are handy (but not perfect):
	#ifndef	BUFFERED_STDIO
	#define	BUFFERED_STDIO	(char *)malloc((unsigned)BUFSIZ)
	#endif
	#ifndef	UNBUFFERED_STDIO
	#define	UNBUFFERED_STDIO (char *)NULL
	#endif
Tom Truscott
P.S.  I have an old article on what is wrong with stdio buffering
and how it was fixed at Duke.  Anyone want it re-submitted?



More information about the Comp.unix.wizards mailing list