2018-05-05 22:12 GMT+03:00 Vadim Zhukov <persg...@gmail.com>:
> Hi all!
>
> Recently I was working on a program that uses stdio functions heavily.
> While hunting for a bug, I've temporarily disabled buffering (via
> setvbuf(f, NULL, _IONBF, 0)) and realized that program behavior was
> changed heavily. The cause was that fread() stopped setting error flag
> after hitting EAGAIN. It looks like its code is missing setting
> EOF/error flags totally in case of unbuffered read, and first patch
> (below) fixes this.
>
> I'm not sure if "r" variable value should be propagated to fp->_r, or
> not. I've assumed that since things work without it now, this doesn't
> need a change. And headache stops me from further investigation for now,
> sorry.
>
> I understand that use stdio functions without buffering is somewhat
> exotic, and that's for sure is the reason noone found this bug yet. But
> this is still a bad thing, IMHO.
>
> While looking through the libc code I've also found that __sread() drops
> __SOFF flag unconditionally for all read errors. IMHO, the EAGAIN case
> shouldn't be affected here, since, obviously current offset doesn't
> change and is still well-known.
>
> So... any comments, or ever okays? :)

Doing "cvs diff" before mailing the patch works better than doing after.
Sorry.

--
WBR,
  Vadim Zhukov


Index: stdio/fread.c
===================================================================
RCS file: /cvs/src/lib/libc/stdio/fread.c,v
retrieving revision 1.15
diff -u -p -r1.15 fread.c
--- stdio/fread.c       21 Sep 2016 04:38:56 -0000      1.15
+++ stdio/fread.c       5 May 2018 19:14:27 -0000
@@ -79,6 +79,10 @@ fread(void *buf, size_t size, size_t cou
                        p += r;
                        resid -= r;
                }
+                if (r == 0)
+                        fp->_flags |= __SEOF;
+                else if (r < 0)
+                        fp->_flags |= __SERR;
                FUNLOCKFILE(fp);
                return ((total - resid) / size);
        }
Index: stdio/stdio.c
===================================================================
RCS file: /cvs/src/lib/libc/stdio/stdio.c,v
retrieving revision 1.10
diff -u -p -r1.10 stdio.c
--- stdio/stdio.c       21 Sep 2016 04:38:56 -0000      1.10
+++ stdio/stdio.c       5 May 2018 19:14:27 -0000
@@ -32,6 +32,7 @@
  */
 
 #include <stdio.h>
+#include <errno.h>
 #include <unistd.h>
 #include "local.h"
 
@@ -49,7 +50,7 @@ __sread(void *cookie, char *buf, int n)
        /* if the read succeeded, update the current offset */
        if (ret >= 0)
                fp->_offset += ret;
-       else
+       else if (errno != EAGAIN)
                fp->_flags &= ~__SOFF;  /* paranoia */
        return (ret);
 }

Reply via email to