Date: Fri, 12 Apr 1996 09:58:50 -0600 From: Nate Williams <nate@sri.MT.net> To: torek@bsdi.com, hackers@FreeBSD.org Cc: koshy@india.hp.com Subject: STDIO bug and/or misfeature? Message-ID: <199604121558.JAA07307@rocky.sri.MT.net>
next in thread | raw e-mail | index | archive | help
Hi Chris, I'm experiencing what I consider to be a bug in FreeBSD's stdio library. I sent the following post to a mailing list describing the bug, and one of the responses is appended below. If you have any comments on the behavior and the response I'd love to hear them. I diffed our code against the 4.4Lite-2 stdio code, and other than quite a few changes to vfprintf we've made and a fix you posted to fseek.c, our code is pretty much the same as in Lite2. ------------------------------------------------------------ From: Nate Williams <nate@sri.MT.net> Subject: Critical stdio bug? Date: Thu, 11 Apr 1996 23:30:23 -0600 Status: OR OK, this is a *really* simply example, and it works as expected under OSF1, SCO, SunOS, and Solaris. (Not necessary the greatest list of OS's, but I had them available). However, on FreeBSD the EOF doesn't get flushed out when it's read. #include <stdio.h> int main() { char string_space[20]; do { printf("Enter a string. (EOF to exit): "); } while (scanf("%s", string_space) != EOF); printf("\n"); do { printf("Search string? (EOF to exit): "); } while (scanf("%s", string_space) != EOF); printf("\n"); return 1; } What I think should happen (and what happens on the other OS's) is that you input strings until the first EOF marker is input, and then you can input some more. The program is a silly example I'm doing to shove some data into a database and then search it later, but it doesn't work due to what I think are bugs in FreeBSD's stdio library. In FreeBSD, the EOF marker is read and appears to be left in the buffer which causes the second scanf function to read an immediate EOF and bail out of the 2nd loop. Is there something I'm missing here, or some non-obvious syscall() I need to do first? I'm running various incarnations of 2.1R and -stable here which all exhibit this behavior. Nate ------------------------------------------------------------ From: A JOSEPH KOSHY <koshy@india.hp.com> Subject: Re: Critical stdio bug? Date: Fri, 12 Apr 1996 14:07:10 +0530 Status: OR >>>>> "nw" == "Nate Williams" >>>>> nw> OS's, but I had them available). However, on FreeBSD the EOF doesn't nw> get flushed out when it's read. The program works correctly on some HPUX machine I could lay my hands on too. The behaviour seems to be coming from: "lib/libc/stdio/refill.c";__srefill(fp) /* SysV does not make this test; take it out for compatibility */ if (fp->_flags & __SEOF) return (EOF); The problem seems to be here (further down in the function) : fp->_r = (*fp->_read)(fp->_cookie, (char *)fp->_p, fp->_bf._size); fp->_flags &= ~__SMOD; /* buffer contents are again pristine */ if (fp->_r <= 0) { if (fp->_r == 0) fp->_flags |= __SEOF; else { fp->_r = 0; fp->_flags |= __SERR; } return (EOF); } The manual page says: The system guarantees to read the number of bytes requested if the descriptor references a normal file that has that many bytes left before the end-of-file, but in no other case. [...] If successful, the number of bytes actually read is returned. Upon read- ing end-of-file, zero is returned. Otherwise, a -1 is returned and the Thus getting a return count of 0, does not always imply end-of-file forever on the file descriptor. So isn't the check at the beginning of the function incorrect? Koshy
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199604121558.JAA07307>