ado@elsie.UUCP (Arthur David Olson) (02/17/88)
Repeat-By:
Compiling and running this source
#include "stdio.h"
main()
{
static char buf[BUFSIZ];
setbuf(stderr, buf);
(void) fprintf(stderr, "byebye\n");
return 0;
}
and noting the lack of output.
Setvbuf messes up as well.
All goes well if you subsitute "stdout" for "stderr" above.
A workaround is an early "atexit" call specifying a function
that does a fflush(stderr).
Fixes, anyone?
--
ado@vax2.nlm.nih.gov ADO, VAX, and NIH are Ampex and DEC trademarks
richardh@killer.UUCP (Richard Hargrove) (02/21/88)
In article <8015@elsie.UUCP>, ado@elsie.UUCP (Arthur David Olson) writes: > [ code example purporting to demonstrate how calling setbuf() does not > cause stderr to actually become buffered ] > > Setvbuf messes up as well. Not if invoked correctly. See below. > > All goes well if you subsitute "stdout" for "stderr" above. > > A workaround is an early "atexit" call specifying a function > that does a fflush(stderr). > > Fixes, anyone? No fix is required because nothing is broken. Your code example makes the assumption that buffering means line-buffering. This is true for stdout, which, even though not initially buffered, has the line-buffering flag (_F_LBUF - see stdio.h) set. Therefore when you associate a buffer with it via a call to setbuf(), it is line-buffered and will flush the buffer everytime a newline is output. This is NOT the case with stderr. Since the line-buffering flag is not set, the call to setbuf() causes it to go from being unbuffered to full-buffered. Full-buffering means that the buffer contents are output only when the buffer has been filled, which your example fails to do. Until the buffer is filled, only an explicit call to fflush() will cause the contents of the buffer to be output. To accomplish your goal use: if (setvbuf (stderr, buf, _IOLBF, BUFSIZ) != 0) { /* handle setvbuf() failure */ } This establishes line-buffering as the buffering discipline (you can verify that _F_LBUF is set). While I'll admit that the Turbo C documentation does not spell out all of the above, it seems to be based on the assumption that if you are playing around with the file buffering, the concepts discussed are already at least partially understood. To test the above, compile and execute: #include <stdio.h> main(void) { static char mybuf[BUFSIZ]; if (setvbuf (stderr, mybuf, _IOLBF, BUFSIZ) == 0) { fputs ("Does it work yet?\n", stderr); } else { fputs ("setvbuf() error\n", stdout); } return 0; } I tested all of the above using Turbo C 1.5; I did not verify its accuracy for version 1.0. richard hargrove ...!{ihnp4 | codas | cbosgd}!killer!richardh --------------------------------------------
ado@elsie.UUCP (Arthur David Olson) (02/23/88)
In an earlier article I wrote of a "Turbo C 1.5 setbuf(stderr bug": < Repeat-By: < Compiling and running this source < #include "stdio.h" < main() < { < static char buf[BUFSIZ]; < setbuf(stderr, buf); < (void) fprintf(stderr, "byebye\n"); < return 0; < } < and noting the lack of output. In article <3433@killer.UUCP>, richardh@killer.UUCP (Richard Hargrove) writes: < In article <8015@elsie.UUCP>, ado@elsie.UUCP (Arthur David Olson) writes: < < [ code example purporting to demonstrate how calling setbuf() does not < < cause stderr to actually become buffered ] < < . . .with stderr [s]ince the line-buffering flag is not set, the call to < setbuf() causes it to go from being unbuffered to full-buffered. < Full-buffering means that the buffer contents are output only when the < buffer has been filled, which your example fails to do. Until the buffer < is filled, only an explicit call to fflush() will cause the contents of the < buffer to be output. . . Regardless of buffering, the contents of the buffer should be output when the program exits. And yet no output appears when I compile and run the source in my original article. That's the bug--not whether the setbuf call causes "stderr to actually become buffered." -- ado@vax2.nlm.nih.gov ADO, VAX, and NIH are Ampex and DEC trademarks