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); }