Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 28 Jul 1999 17:38:59 +0200 (CEST)
From:      tobez@plab.ku.dk
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   bin/12852: Non-standard behavior of fread(3)
Message-ID:  <199907281538.RAA68304@lion.plab.ku.dk>

next in thread | raw e-mail | index | archive | help

>Number:         12852
>Category:       bin
>Synopsis:       Non-standard behavior of fread(3)
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jul 28 08:50:01 PDT 1999
>Closed-Date:
>Last-Modified:
>Originator:     Anton Berezin <tobez@plab.ku.dk>
>Release:        FreeBSD 4.0-CURRENT i386
>Organization:
The Protein Laboratory, University of Copenhagen
>Environment:

This is so on 2.2.8, 3.0, 3.1, 3.2 and 4.0, at least. :-)

>Description:

The following little program:

	 #include <stdio.h>
	 #include <errno.h>
	 int               
	 main(int argc, char **argv)
	 {
	    char buf;
	    int r = fread(&buf,1,1,stdout);
	    printf("%d ferror=%d feof=%d errno=%d\n",
		   r, ferror(stdout), feof(stdout), errno);
	    return 0;
	 }            

produces this output:

	0 ferror=0 feof=0 errno=9

I am not exactly sure that this is a bug, strictly speaking.  However,
there are certain indications that this behavior is non-standard.  Let
me explain this a bit.  The issue was raised when perl5 developers have
added a specific test in the most recent developer's version of perl
(5.005_58, to be precise).  It quickly turned out that libc on different
platforms produce very different results.  To my knowledge, several
versions of Linux's glibc, as well as NetBSD libc and OSF1 4.0 libc do
the same thing as we do.  It was reported on p5p mailing list that many
other systems behave differently.  For example, the program above, being
run on HP-UX B.10.20, produce

	0 ferror=32 feof=0 errno=9

Gurusamy Sarathy communicated this with glibc developers, and they
decided to change the behavior of glibc in future versions.  The reason
was (I quote only relevant part of the message Sarathy forwarded to
p5p):

--- quote start ---
   Message-Id: <u8r9m23tin.fsf@arthur.rhein-neckar.de>
   Date:    21 Jul 1999 17:35:44 +0200                
   From:    Andreas Jaeger <aj@arthur.rhein-neckar.de>
   To:      libc-alpha Mailinglist <libc-alpha@sourceware.cygnus.com>,                     
	    gsar@activestate.com                                                           
   Subject: Re: [Gurusamy Sarathy <gsar@activestate.com>] ferror() after fread() on a FILE* 
	***opened for write                                                                 

   [snipped by tobez]

   The ISO C9x draft I've got here, mentions as return value for fread:

	 [#3] The fread  function  returns  the  number  of  elements
	  successfully  read,  which  may be less than nmemb if a read
	  error or end-of-file is encountered.  If size  or  nmemb  is
	  zero,  fread  returns zero and the contents of the array and
	  the state of the stream remain unchanged.

   fread returned 0 which is less than 1 - therefore either a read error
   or end-of-file is encountered.  But feof and ferror tell me that
   neither is encountered.

   [snipped by tobez]
--- quote end ---

This interpretation is also consistent with FreeBSD's man 3 fread:

   If an error occurs, or the end-of-file is reached, the return value
   is a short object count (or zero).

So I think that it might be a good idea to change the behavior of our
libc, too.

In the Fix section I provide a patch which changes the behavior of
fread() to set __SERR together with setting EBADF.

>How-To-Repeat:

Compile and run the program from the Description section.

>Fix:
	
--- /usr/src/lib/libc/stdio/refill.c.orig	Wed Jul 28 17:30:44 1999
+++ /usr/src/lib/libc/stdio/refill.c	Wed Jul 28 17:31:40 1999
@@ -82,6 +82,7 @@
 	if ((fp->_flags & __SRD) == 0) {
 		if ((fp->_flags & __SRW) == 0) {
 			errno = EBADF;
+			fp->_flags |= __SERR;
 			return (EOF);
 		}
 		/* switch to reading */




>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199907281538.RAA68304>