les@chinet.chi.il.us (Leslie Mikesell) (07/06/90)
Does the putc macro have any strange side effects (such as flushing an unfilled buffer) under SysV when setbuf is used? I'm seeing occasional lines in a logfile that should be: line1 line2 become: line1line2 blank_line The relevant code is: (from smail 3.1, incidentally...) static char logbuf[BUFSIZ]; /* stdio buffer to avoid mallocs */ fd = open(log_fn, O_CREAT|O_APPEND|O_WRONLY, log_mode); logfile = fdopen(fd, "a"); (void) setbuf(logfile, logbuf); /* associate stream and buffer */ ... (void)vfprintf(logfile, fmt, ap); putc('\n', logfile); /* log messages don't come with \n */ (void)fflush(logfile); Apparently the putc is performing a flush *before* adding the \n, so that a concurrent process can write it's entry first. Is this a bug or are you not supposed to mix different forms of buffered output? Les Mikesell les@chinet.chi.il.us
gwyn@smoke.BRL.MIL (Doug Gwyn) (07/08/90)
In article <1990Jul5.220009.3724@chinet.chi.il.us> les@chinet.chi.il.us (Leslie Mikesell) writes: >(void)vfprintf(logfile, fmt, ap); >putc('\n', logfile); /* log messages don't come with \n */ >(void)fflush(logfile); >Apparently the putc is performing a flush *before* adding the \n, so >that a concurrent process can write it's entry first. Is this a >bug or are you not supposed to mix different forms of buffered output? All stdio I/O operations are defined in terms of getc() and putc(), so clearly "mixing forms" of output is not an issue. However, there is no particular guarantee that an output operation will not cause an actual write() at some point, even if you have setbuf()ed and have not yet invoked fflush(). Certainly when the buffer is full it will be automatically flushed. While I'm not sure why your implementation of vfprintf() (or less likely, putc()) would flush the buffer where you say it did, there is no rule that prohibits it from doing so. The C standard does not require that no extra buffer flushing occur, although it does suggest that it is not intended.
les@chinet.chi.il.us (Leslie Mikesell) (07/14/90)
In article <13315@smoke.BRL.MIL> gwyn@smoke.BRL.MIL (Doug Gwyn) writes: >>(void)vfprintf(logfile, fmt, ap); >>putc('\n', logfile); /* log messages don't come with \n */ >>(void)fflush(logfile); >>Apparently the putc is performing a flush *before* adding the \n, so >>that a concurrent process can write it's entry first. Is this a >>bug or are you not supposed to mix different forms of buffered output? >All stdio I/O operations are defined in terms of getc() and putc(), >so clearly "mixing forms" of output is not an issue. However, there >is no particular guarantee that an output operation will not cause >an actual write() at some point, even if you have setbuf()ed and have >not yet invoked fflush(). Certainly when the buffer is full it will >be automatically flushed. While I'm not sure why your implementation >of vfprintf() (or less likely, putc()) would flush the buffer where >you say it did, there is no rule that prohibits it from doing so. >The C standard does not require that no extra buffer flushing occur, >although it does suggest that it is not intended. OK, if it's not a bug it's at least "interesting behaviour" that the timing of the write() depends on whether or not setbuf() has been called. Under SysVr3.2 (3B2 & 386), if setbuf() is called, the putc('\n',...) above causes a write() of the previous buffered contents (even though the buffer is not full). Without setbuf(), it doesn't. This may only occur the first time putc() is called. Les Mikesell les@chinet.chi.il.us