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