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;