fix fputc and friends on read-only streams

Jeff Johnston jjohnstn@redhat.com
Tue Jun 14 02:40:00 GMT 2011


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 */



More information about the Newlib mailing list