]> git.saurik.com Git - apple/libc.git/blame - stdio/FreeBSD/fread.c.patch
Libc-763.13.tar.gz
[apple/libc.git] / stdio / FreeBSD / fread.c.patch
CommitLineData
1f2f436a
A
1--- fread.c.bsdnew 2009-11-11 13:33:09.000000000 -0800
2+++ fread.c 2009-11-11 14:14:22.000000000 -0800
3@@ -63,7 +63,7 @@ __fread(void * __restrict buf, size_t si
34e8f829
A
4 {
5 size_t resid;
6 char *p;
7- int r;
8+ int r, ret;
9 size_t total;
10
11 /*
1f2f436a 12@@ -76,19 +76,66 @@ __fread(void * __restrict buf, size_t si
34e8f829
A
13 fp->_r = 0;
14 total = resid;
15 p = buf;
16+ /* first deal with anything left in buffer, plus any ungetc buffers */
17 while (resid > (r = fp->_r)) {
18 (void)memcpy((void *)p, (void *)fp->_p, (size_t)r);
19 fp->_p += r;
20 /* fp->_r = 0 ... done in __srefill */
21 p += r;
22 resid -= r;
23- if (__srefill(fp)) {
24+ if ((ret = __srefill0(fp)) > 0)
25+ break;
26+ else if (ret) {
27 /* no more input: return partial result */
34e8f829
A
28 return ((total - resid) / size);
29 }
30 }
31- (void)memcpy((void *)p, (void *)fp->_p, resid);
32- fp->_r -= resid;
33- fp->_p += resid;
34+ /*
35+ * 5980080: don't use optimization if __SMBF not set (meaning setvbuf
36+ * was called, and the buffer belongs to the user).
37+ * 6180417: but for unbuffered (__SMBF is not set), so specifically
38+ * test for it.
39+ */
40+ if ((fp->_flags & (__SMBF | __SNBF)) && resid > fp->_bf._size) {
41+ struct __sbuf save;
42+ size_t n;
43+
44+ save = fp->_bf;
45+ fp->_bf._base = p;
46+ fp->_bf._size = resid;
47+ while (fp->_bf._size > 0) {
48+ if ((ret = __srefill1(fp)) != 0) {
49+ /* no more input: return partial result */
50+ resid = fp->_bf._size;
51+ fp->_bf = save;
52+ fp->_p = fp->_bf._base;
53+ /* fp->_r = 0; already set in __srefill1 */
34e8f829
A
54+ return ((total - resid) / size);
55+ }
56+ fp->_bf._base += fp->_r;
57+ fp->_bf._size -= fp->_r;
58+ }
59+ fp->_bf = save;
60+ n = fp->_bf._size * ((resid - 1) / fp->_bf._size);
61+ r = resid - n;
62+ (void)memcpy((void *)fp->_bf._base, (void *)(p + n), (size_t)r);
63+ fp->_p = fp->_bf._base + r;
64+ fp->_r = 0;
65+ } else {
66+ while (resid > (r = fp->_r)) {
67+ (void)memcpy((void *)p, (void *)fp->_p, (size_t)r);
68+ fp->_p += r;
69+ /* fp->_r = 0 ... done in __srefill */
70+ p += r;
71+ resid -= r;
72+ if (__srefill1(fp)) {
73+ /* no more input: return partial result */
34e8f829
A
74+ return ((total - resid) / size);
75+ }
76+ }
77+ (void)memcpy((void *)p, (void *)fp->_p, resid);
78+ fp->_r -= resid;
79+ fp->_p += resid;
80+ }
34e8f829
A
81 return (count);
82 }