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: fix fputc and friends on read-only streams


I'm fine with the change, but you should probably remove the redundant errno and error flag setting in wbuf.c and fvwrite.c.

In addition, it would be nice to document in the local.h comment that cantwrite macro will set errno and error flag. This will prevent future code from setting errno and the error flag themselves or thinking it is just a test.

Thanks,

-- Jeff J.

On 06/07/2011 01:57 PM, Eric Blake wrote:
POSIX requires that ferror() and errno reflect any failed attempt to
write to a read-only stream, but newlib wasn't reliably doing this:

#include<stdio.h>
#include<errno.h>
int main()
{
   FILE *f = fopen ("f", "w");
   if (!f)
     return 1;
   if (freopen ("f", "r", f) != f)
     return 2;
   if (setvbuf (f, NULL, _IONBF, BUFSIZ))
     return 3;
   if (ferror (f))
     return 4;
   errno = -1;
   if (fprintf (f, "hi") != EOF)
     return 5;
   if (errno<= 0)
     return 6;
   if (!ferror (f))
     return 7;
   if (fclose (f))
     return 8;
   if (remove (f))
     return 9;
   return 0;
}

This was mistakenly existing with status 6; comment that line out and it
exited with status 7.  This fix mirrors the refill.c setting of errors
on attempts to read a write-only stream.

---
  newlib/ChangeLog           |    4 ++++
  newlib/libc/stdio/wsetup.c |    6 +++++-
  2 files changed, 9 insertions(+), 1 deletions(-)

2011-06-07 Eric Blake<eblake@redhat.com>

* libc/stdio/wsetup.c (__swsetup_r): Set errno on failure.

diff --git a/newlib/libc/stdio/wsetup.c b/newlib/libc/stdio/wsetup.c
index dcbda0a..6513e00 100644
--- a/newlib/libc/stdio/wsetup.c
+++ b/newlib/libc/stdio/wsetup.c
@@ -44,7 +44,11 @@ _DEFUN(__swsetup_r, (ptr, fp),
    if ((fp->_flags&  __SWR) == 0)
      {
        if ((fp->_flags&  __SRW) == 0)
-	return EOF;
+        {
+          ptr->_errno = EBADF;
+          fp->_flags |= __SERR;
+          return EOF;
+        }
        if (fp->_flags&  __SRD)
  	{
  	  /* clobber any ungetc data */


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