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? :)

--
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:02:04 -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:02:04 -0000
@@ -49,7 +49,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