ср, 12 дек. 2018 г. в 10:59, Sebastien Marie <[email protected]>: > > On Tue, Dec 11, 2018 at 03:08:38PM -0700, Todd C. Miller wrote: > > On Tue, 11 Dec 2018 20:35:05 +0100, Sebastien Marie wrote: > > > > > According to stdio.h, 6 = __SNBF | __SRD, so "unbuffered" and "OK to > > > read". > > > > > > the feof() call returns false, the python code interpretes it as an error. > > > > > > When looking at fread(3) code in libc, I found that we doesn't set > > > __SEOF when the FILE is unbuffered. > > > > Yes, that is a bug. The code should probably be calling __srefill(), > > though we'd need to set _bf._base and _bf._size appropriately so > > it doesn't use _nbuf. Some care is required... > > > > - todd > > It seems it is the rediscover of a previously signaled bug by zhuk@ . > see https://marc.info/?l=openbsd-tech&m=152554758706248&w=2 > > I found it after setting up a patch, and it is mostly the same than the > proposed one by zhuk@, so I take his diff (exactly, only the chunk that > correct the bug. his diff also corrects something else, but I prefer to > take care to only one thing a time). > > The approch is to directly set __SEOF or __SERR. It is more simple than > trying to reuse __srefill(). > > 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 12 Dec 2018 07:52:02 -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); > } > > I tested it with mercurial, and it corrects the problem. > > Thanks.
I've been running libc with this patch for months, and got not problems yet, FWIW. The four lines you're adding are similar to other stdio code, e.g., see vfprintf.c. The hunk you omitted probably not needed in my case (buffered stdio over IPv4 TCP socket), but it seemed to be logical one (EAGAIN received shouldn't invalidate stream offset, it's still well-known), and also seem to be more non-seekable-file-descriptor-friendly. And, again, I've been running both hunks all that time. I'm glad this issue finally got discussed - thanks, I always suck at attracting attention. :)
