Skip site navigation (1)Skip section navigation (2)
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>