kern/65402: patch: fflush() should not return error on readonly files

Radim Kolar hsn at netmag.cz
Sat Apr 10 10:20:20 PDT 2004


>Number:         65402
>Category:       kern
>Synopsis:       patch: fflush() should not return error on readonly files
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Apr 10 10:20:19 PDT 2004
>Closed-Date:
>Last-Modified:
>Originator:     Radim Kolar
>Release:        FreeBSD 5.2.1-RELEASE-p3 i386
>Organization:
Sanatana Dharma
>Environment:
System: FreeBSD asura.bsd 5.2.1-RELEASE-p3 FreeBSD 5.2.1-RELEASE-p3 #6: Mon Apr 5 17:41:24 CEST 2004 root at asura.bsd:/usr/src/sys/i386/compile/UP i386
>Description:
When fflush() function is called on file which is opened for read-only,
the call fails with bad file descriptor error. This behaviour is different 
from fsync() kernel function which correctly do not return any error.

I have checked different operation systems (linux, cygwin, msvc++, hpux) and
everywhere fflush() on r/o files works correctly. I have found this problem
while trying to port some application to freebsd, fixing the application is
difficult, since it uses the same set classes for read and write access to
datafiles.
There is no reason for returning error to user. If there are no data to write,
simply do nothing. This patch do not breaks any existing application.

>How-To-Repeat:
#include <stdio.h>
int main (int argc,const char *argv[])
{
        FILE *f;
	    char buf[2222];
	    f=fopen("/etc/passwd","r");
	    fread(buf, 10, 1, f);
	    printf("ff rc %d\n",fflush(f)); /* check errno here */
	    fclose(f);
}
>Fix:
--- /usr/src/lib/libc/stdio/fflush.c	Fri Mar 22 22:53:04 2002
+++ fflush.c	Sat Apr 10 17:22:01 2004
@@ -62,8 +62,7 @@
 		return (_fwalk(sflush_locked));
 	FLOCKFILE(fp);
 	if ((fp->_flags & (__SWR | __SRW)) == 0) {
-		errno = EBADF;
-		retval = EOF;
+		return (0);
 	} else
 		retval = __sflush(fp);
 	FUNLOCKFILE(fp);
@@ -82,8 +81,7 @@
 	if (fp == NULL)
 		return (_fwalk(sflush_locked));
 	if ((fp->_flags & (__SWR | __SRW)) == 0) {
-		errno = EBADF;
-		retval = EOF;
+		return (0);
 	} else
 		retval = __sflush(fp);
 	return (retval);

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


More information about the freebsd-bugs mailing list