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.
-- 
Sebastien Marie

Reply via email to