]>
Commit | Line | Data |
---|---|---|
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 | } |