On Thu, Dec 13, 2018 at 11:01:10AM -0700, Todd C. Miller wrote:
> Here's a diff that fakes up a FILE like we do in other parts of
> stdio for unbuffered I/O. This lets us call __srefill() normally.
> If __srefill() returns an error, copy the flags back to the real
> FILE *.
Your patch fixes the mercurial crashes. Many thanks.
>
> - todd
>
> Index: lib/libc/stdio/fread.c
> ===================================================================
> RCS file: /cvs/src/lib/libc/stdio/fread.c,v
> retrieving revision 1.15
> diff -u -p -u -r1.15 fread.c
> --- lib/libc/stdio/fread.c 21 Sep 2016 04:38:56 -0000 1.15
> +++ lib/libc/stdio/fread.c 13 Dec 2018 17:24:34 -0000
> @@ -69,18 +69,39 @@ fread(void *buf, size_t size, size_t cou
> 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) {
> - /*
> - * We know if we're unbuffered that our buffer is empty, so
> - * we can just read directly. This is much faster than the
> - * loop below which will perform a series of one byte reads.
> - */
> - while (resid > 0 && (r = (*fp->_read)(fp->_cookie, p, resid)) >
> 0) {
> - p += r;
> - resid -= r;
> + FILE fake;
> + struct __sfileext fakeext;
> +
> + _FILEEXT_SETUP(&fake, &fakeext);
> + /* copy the important variables */
> + fake._flags = fp->_flags;
> + fake._file = fp->_file;
> + fake._cookie = fp->_cookie;
> + fake._read = fp->_read;
> +
> + /* set up the buffer */
> + fake._bf._base = buf;
> + fake._bf._size = total;
> + fake._lbfsize = 0; /* not line buffered */
> +
> + while (resid > 0) {
> + if (__srefill(&fake)) {
> + /* no more input: return partial result */
> + count = (total - resid) / size;
> + fp->_flags |= (fake._flags & (__SERR|__SEOF));
> + break;
> + }
> + fake._p += fake._r;
> + resid -= fake._r;
> }
> FUNLOCKFILE(fp);
> - return ((total - resid) / size);
> + return (count);
> }
>
> while (resid > (r = fp->_r)) {
>
--
Juan Francisco Cantero Hurtado http://juanfra.info