On Fri, 14 Dec 2018 10:49:23 -0700, "Todd C. Miller" wrote:

> After thinking about this a bit more I believe it best to just use
> the existing FILE * and swap in the buffer temporarily.  There's
> no need to store the value of the old buffer; since we are unbuffered
> it can only point to _nbuf.

The last diff had a bug.  It turns out that __srefill() assumes it
has the entire buffer to use so we need to reset the buffer each
time we call it.

This fixes the problem naddy@ saw with a few of the ports in python
code.

 - todd

Index: lib/libc/stdio/fread.c
===================================================================
RCS file: /cvs/src/lib/libc/stdio/fread.c,v
retrieving revision 1.18
diff -u -p -u -r1.18 fread.c
--- lib/libc/stdio/fread.c      16 Dec 2018 03:40:40 -0000      1.18
+++ lib/libc/stdio/fread.c      16 Dec 2018 04:12:32 -0000
@@ -68,6 +68,36 @@ fread(void *buf, size_t size, size_t cou
                fp->_r = 0;
        total = resid;
        p = buf;
+
+       /*
+        * If we're unbuffered we know that the buffer in fp is empty so
+        * we can read directly into buf.  This is much faster than a
+        * series of one byte reads into fp->_nbuf.
+        */
+       if ((fp->_flags & __SNBF) != 0 && buf != NULL) {
+               while (resid > 0) {
+                       /* set up the buffer */
+                       fp->_bf._base = fp->_p = p;
+                       fp->_bf._size = resid;
+
+                       if (__srefill(fp)) {
+                               /* no more input: return partial result */
+                               count = (total - resid) / size;
+                               break;
+                       }
+                       p += fp->_r;
+                       resid -= fp->_r;
+               }
+
+               /* restore the old buffer (see __smakebuf) */
+               fp->_bf._base = fp->_p = fp->_nbuf;
+               fp->_bf._size = 1;
+               fp->_r = 0;
+
+               FUNLOCKFILE(fp);
+               return (count);
+       }
+
        while (resid > (r = fp->_r)) {
                (void)memcpy(p, fp->_p, r);
                fp->_p += r;

Reply via email to