Path: utzoo!utgpu!water!watmath!clyde!burl!codas!killer!richardh From: richardh@killer.UUCP (Richard Hargrove) Newsgroups: comp.sys.ibm.pc Subject: Re: Turbo C 1.5 setbuf(stderr misunderstanding Summary: this is not a bug Message-ID: <3433@killer.UUCP> Date: 20 Feb 88 20:15:25 GMT References: <8015@elsie.UUCP> Organization: The Unix(R) Connection, Dallas, Texas Lines: 65 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 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 --------------------------------------------