Date: Fri, 12 Sep 2008 15:06:24 -0700 (PDT) From: "Ronald F.Guilmette" <rfg@tristatelogic.com> To: FreeBSD-gnats-submit@FreeBSD.org Cc: rfg@tristatelogic.com Subject: bin/127335: fwrite fails to generate error when applied to a read-only file Message-ID: <20080912220624.0DE14BDC5A@segfault.tristatelogic.com> Resent-Message-ID: <200809122210.m8CMA4iR014504@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 127335 >Category: bin >Synopsis: fwrite fails to generate error when applied to a read-only file >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Fri Sep 12 22:10:04 UTC 2008 >Closed-Date: >Last-Modified: >Originator: Ronald F. Guilmette >Release: FreeBSD 7.0-RELEASE i386 >Organization: Infinite Monkeys & Co. LLC >Environment: System: FreeBSD segfault.tristatelogic.com 7.0-RELEASE FreeBSD 7.0-RELEASE #0: Tue Aug 5 02:38:40 PDT 2008 root@segfault.monkeys.com:/usr/src/sys/i386/compile/rfg20080805 i386 >Description: It the fwrite() stdio library function is called and passed a file which has been opened read-only, then a return value of zero will be generated, but the error flag for the file will NOT be properly set. This affects subsequent calls to ferror(file) where `file' was the read-only file upon which an incorrect attempt was made to write. The failure of fwrite() to properly set the error flag for the file causes fwrite() to arguably violate its own documentation. The relevant quote from the man page is as follows: The function fwrite() returns a value less than nmemb only if a write error has occurred. Zero is returned, and a write error _does_ occur when fwrite is asked to write to a read-only file, but subsequent calls to ferror() do not properly reflect that fact. >How-To-Repeat: Consider the two trivial programs below which test the effects of passing the Wrong Type of file to fread() and fwrite() respectively. The first one correctly prints "Error reading from stdout", but the second one prints "This shouldn't happen!" because of the failure to properly set the file's error flag when fwrite() is called on a read-only file. Prog #1: ===================================================================== #include <stdio.h> int main (void) { char buf[1024]; fread (buf, 1, 12, stdout); if (ferror (stdout)) printf ("Error reading from stdout\n"); else if (feof (stdout)) printf ("EOF detected while reading from stdout\n"); else printf ("This shouldn't happen!\n"); return 0; } ===================================================================== Prog #2: ===================================================================== #include <stdio.h> int main (void) { fwrite ("Hello world!", 1, 12, stdin); if (ferror (stdin)) printf ("Error writing to stdin\n"); else if (feof (stdin)) printf ("EOF detected while writing to stdin\n"); else printf ("This shouldn't happen!\n"); return 0; } ===================================================================== >Fix: I don't know for sure how to fix this, but I do know it ought to be pretty trivial to do. I looked at the relevant stdio library code for awhile, but some of these macros are just too too ugly to even make sense of. I suspect that the problem is either in the definition of the macro "prepwrite(fp)" in /usr/src/lib/libc/stdio/local.h or else it is in the function called __swsetup(fp). The comment just before the definition of the prepwrite() macro sez: /* * Prepare the given FILE for writing, and return 0 iff it * can be written now. Otherwise, return EOF and set errno. */ Well, apparently, it doesn't actually set errno when it should, let alone the file's error flag. >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20080912220624.0DE14BDC5A>