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>