This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Reading a write-only file doesn't set error condition (was Re: Cygwin fread on Write-Only File Descriptor returns undefined state)


Jeff Johnston wrote:
Corinna Vinschen wrote:

Thanks for the testcase.  This looks like a small flaw in newlib.
I redirected to the newlib list.



I debugged your testcase and the problem appears to be in __srefill(),
defined in newlib/libc/stdio/refill.c:

  /* if not already reading, have to be reading and writing */
  if ((fp->_flags & __SRD) == 0)
    {
      if ((fp->_flags & __SRW) == 0)
        return EOF;

So, what happens is that EOF is returned if the file is not readable.
Errno isn't set and the error condition on the file pointer isn't set
either.

Testing the same situation on Linux, errno is set to EBADF and the
error indicator is set on the file pointer, while the EOF condition
stays clear.

So, I'd like to propose the below patch.  I assume a similar patch
should be ok for __sfvwrite, too, isn't it?  There's a call to
cantwrite() which only returns EOF but which probably should also
set the error condition and errno.


This opens a can of worms. You can't just use _REENT to set errno. One has to provide _r versions of the read/write functions. I have just made a patch and am verifying it builds for x86-linux. I will post the patch when I am ready to check it in.


-- Jeff J.


I have checked in the patch. The testcase runs successfully and I am able to build/run x86-linux successfully. Let me know if it causes any problems for Cygwin.


-- Jeff J.

2006-06-14 Jeff Johnston <jjohnstn@redhat.com>

* libc/include/stdio.h: Add new reentrant I/O prototypes for
read/write functions. Change getc/putc macros to have reentrant underlying
macros/functions. This includes __sgetc_raw_r, __sgetc_r, and __sputc_r.
* libc/stdio/fgetc.c: Fix and/or add reentrant version to call
new reentrant I/O functions/macros for reading/writing.
* libc/stdio/fgets.c: Ditto.
* libc/stdio/fputc.c: Ditto.
* libc/stdio/fputs.c: Ditto.
* libc/stdio/fread.c: Ditto.
* libc/stdio/fseek.c: Ditto.
* libc/stdio64/fseeko64.c: Ditto.
* libc/stdio/fwrite.c: Ditto.
* libc/stdio/getc.c: Ditto.
* libc/stdio/getc_u.c: Ditto.
* libc/stdio/getchar.c: Ditto.
* libc/stdio/getchar_u.c: Ditto.
* libc/stdio/putc.c: Ditto.
* libc/stdio/putc_u.c: Ditto.
* libc/stdio/putchar.c: Ditto.
* libc/stdio/puts.c: Ditto.
* libc/stdio/vfprintf.c: Ditto.
* libc/stdio/vfscanf.c: Ditto.
* libc/stdio/fvwrite.c: Change __sfvwrite into reentrant __sfvwrite_r.
Change all previous callers of __sfvwrite. Set errno to EBADF and
set error flag on if attempt is made to write to file that does not
allow writing.
* libc/stdio/fvwrite.h: Fix new reentrant prototypes.
* libc/stdio/local.h: Ditto.
* libc/stdio/refill.c: Turn __srefill into reentrant __srefill_r.
Set errno to EBADF and the error flag on if attempt is made to
read unreadable file. Change all previous callers of __srefill.
* libc/stdio/rget.c
* libc/stdio/wbuf.c: Turn __swbuf into reentrant __swbuf_r. Change
all previous callers of __swbuf.
* libc/sys/linux/machine/i386/huge_val.h: Ifdef out file contents since
huge value macros are already defined correctly for i386 by <math.h>.






Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]