Rev 1906 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1906 | Rev 3065 | ||
---|---|---|---|
1 | /* |
1 | /* |
2 | * Copyright (c) 1990, 2007 The Regents of the University of California. |
2 | * Copyright (c) 1990, 2007 The Regents of the University of California. |
3 | * All rights reserved. |
3 | * All rights reserved. |
4 | * |
4 | * |
5 | * Redistribution and use in source and binary forms are permitted |
5 | * Redistribution and use in source and binary forms are permitted |
6 | * provided that the above copyright notice and this paragraph are |
6 | * provided that the above copyright notice and this paragraph are |
7 | * duplicated in all such forms and that any documentation, |
7 | * duplicated in all such forms and that any documentation, |
8 | * advertising materials, and other materials related to such |
8 | * advertising materials, and other materials related to such |
9 | * distribution and use acknowledge that the software was developed |
9 | * distribution and use acknowledge that the software was developed |
10 | * by the University of California, Berkeley. The name of the |
10 | * by the University of California, Berkeley. The name of the |
11 | * University may not be used to endorse or promote products derived |
11 | * University may not be used to endorse or promote products derived |
12 | * from this software without specific prior written permission. |
12 | * from this software without specific prior written permission. |
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR |
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR |
14 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED |
14 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED |
15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
16 | */ |
16 | */ |
17 | 17 | ||
18 | /* |
18 | /* |
19 | FUNCTION |
19 | FUNCTION |
20 | < |
20 | < |
21 | 21 | ||
22 | INDEX |
22 | INDEX |
23 | fread |
23 | fread |
24 | INDEX |
24 | INDEX |
25 | _fread_r |
25 | _fread_r |
26 | 26 | ||
27 | ANSI_SYNOPSIS |
27 | ANSI_SYNOPSIS |
28 | #include |
28 | #include |
29 | size_t fread(void *<[buf]>, size_t <[size]>, size_t <[count]>, |
29 | size_t fread(void *<[buf]>, size_t <[size]>, size_t <[count]>, |
30 | FILE *<[fp]>); |
30 | FILE *<[fp]>); |
31 | 31 | ||
32 | #include |
32 | #include |
33 | size_t _fread_r(struct _reent *<[ptr]>, void *<[buf]>, |
33 | size_t _fread_r(struct _reent *<[ptr]>, void *<[buf]>, |
34 | size_t <[size]>, size_t <[count]>, FILE *<[fp]>); |
34 | size_t <[size]>, size_t <[count]>, FILE *<[fp]>); |
35 | 35 | ||
36 | TRAD_SYNOPSIS |
36 | TRAD_SYNOPSIS |
37 | #include |
37 | #include |
38 | size_t fread(<[buf]>, <[size]>, <[count]>, <[fp]>) |
38 | size_t fread(<[buf]>, <[size]>, <[count]>, <[fp]>) |
39 | char *<[buf]>; |
39 | char *<[buf]>; |
40 | size_t <[size]>; |
40 | size_t <[size]>; |
41 | size_t <[count]>; |
41 | size_t <[count]>; |
42 | FILE *<[fp]>; |
42 | FILE *<[fp]>; |
43 | 43 | ||
44 | #include |
44 | #include |
45 | size_t _fread_r(<[ptr]>, <[buf]>, <[size]>, <[count]>, <[fp]>) |
45 | size_t _fread_r(<[ptr]>, <[buf]>, <[size]>, <[count]>, <[fp]>) |
46 | struct _reent *<[ptr]>; |
46 | struct _reent *<[ptr]>; |
47 | char *<[buf]>; |
47 | char *<[buf]>; |
48 | size_t <[size]>; |
48 | size_t <[size]>; |
49 | size_t <[count]>; |
49 | size_t <[count]>; |
50 | FILE *<[fp]>; |
50 | FILE *<[fp]>; |
51 | 51 | ||
52 | DESCRIPTION |
52 | DESCRIPTION |
53 | < |
53 | < |
54 | <[fp]>, <[count]> elements (each of size <[size]>) into memory, |
54 | <[fp]>, <[count]> elements (each of size <[size]>) into memory, |
55 | starting at <[buf]>. < |
55 | starting at <[buf]>. < |
56 | <[count]> if an error, or end of file, intervenes. |
56 | <[count]> if an error, or end of file, intervenes. |
57 | 57 | ||
58 | < |
58 | < |
59 | <[fp]> by the number of @emph{characters} actually read. |
59 | <[fp]> by the number of @emph{characters} actually read. |
60 | 60 | ||
61 | <<_fread_r>> is simply the reentrant version of < |
61 | <<_fread_r>> is simply the reentrant version of < |
62 | takes an additional reentrant structure pointer argument: <[ptr]>. |
62 | takes an additional reentrant structure pointer argument: <[ptr]>. |
63 | 63 | ||
64 | RETURNS |
64 | RETURNS |
65 | The result of < |
65 | The result of < |
66 | reading. |
66 | reading. |
67 | 67 | ||
68 | PORTABILITY |
68 | PORTABILITY |
69 | ANSI C requires < |
69 | ANSI C requires < |
70 | 70 | ||
71 | Supporting OS subroutines required: < |
71 | Supporting OS subroutines required: < |
72 | < |
72 | < |
73 | */ |
73 | */ |
74 | 74 | ||
75 | #include <_ansi.h> |
75 | #include <_ansi.h> |
76 | #include |
76 | #include |
77 | #include |
77 | #include |
78 | #include |
78 | #include |
79 | #include "local.h" |
79 | #include "local.h" |
80 | 80 | ||
81 | #ifdef __SCLE |
81 | #ifdef __SCLE |
82 | static size_t |
82 | static size_t |
83 | _DEFUN(crlf_r, (ptr, fp, buf, count, eof), |
83 | _DEFUN(crlf_r, (ptr, fp, buf, count, eof), |
84 | struct _reent * ptr _AND |
84 | struct _reent * ptr _AND |
85 | FILE * fp _AND |
85 | FILE * fp _AND |
86 | char * buf _AND |
86 | char * buf _AND |
87 | size_t count _AND |
87 | size_t count _AND |
88 | int eof) |
88 | int eof) |
89 | { |
89 | { |
90 | int r; |
90 | int r; |
91 | char *s, *d, *e; |
91 | char *s, *d, *e; |
92 | 92 | ||
93 | if (count == 0) |
93 | if (count == 0) |
94 | return 0; |
94 | return 0; |
95 | 95 | ||
96 | e = buf + count; |
96 | e = buf + count; |
97 | for (s=d=buf; s |
97 | for (s=d=buf; s |
98 | { |
98 | { |
99 | if (*s == '\r' && s[1] == '\n') |
99 | if (*s == '\r' && s[1] == '\n') |
100 | s++; |
100 | s++; |
101 | *d++ = *s; |
101 | *d++ = *s; |
102 | } |
102 | } |
103 | if (s < e) |
103 | if (s < e) |
104 | { |
104 | { |
105 | if (*s == '\r') |
105 | if (*s == '\r') |
106 | { |
106 | { |
107 | int c = __sgetc_raw_r (ptr, fp); |
107 | int c = __sgetc_raw_r (ptr, fp); |
108 | if (c == '\n') |
108 | if (c == '\n') |
109 | *s = '\n'; |
109 | *s = '\n'; |
110 | else |
110 | else |
111 | ungetc (c, fp); |
111 | ungetc (c, fp); |
112 | } |
112 | } |
113 | *d++ = *s++; |
113 | *d++ = *s++; |
114 | } |
114 | } |
115 | 115 | ||
116 | 116 | ||
117 | while (d < e) |
117 | while (d < e) |
118 | { |
118 | { |
119 | r = _getc_r (ptr, fp); |
119 | r = _getc_r (ptr, fp); |
120 | if (r == EOF) |
120 | if (r == EOF) |
121 | return count - (e-d); |
121 | return count - (e-d); |
122 | *d++ = r; |
122 | *d++ = r; |
123 | } |
123 | } |
124 | 124 | ||
125 | return count; |
125 | return count; |
126 | 126 | ||
127 | } |
127 | } |
128 | 128 | ||
129 | #endif |
129 | #endif |
130 | 130 | ||
131 | size_t |
131 | size_t |
132 | _DEFUN(_fread_r, (ptr, buf, size, count, fp), |
132 | _DEFUN(_fread_r, (ptr, buf, size, count, fp), |
133 | struct _reent * ptr _AND |
133 | struct _reent * ptr _AND |
134 | _PTR buf _AND |
134 | _PTR buf _AND |
135 | size_t size _AND |
135 | size_t size _AND |
136 | size_t count _AND |
136 | size_t count _AND |
137 | FILE * fp) |
137 | FILE * fp) |
138 | { |
138 | { |
139 | register size_t resid; |
139 | register size_t resid; |
140 | register char *p; |
140 | register char *p; |
141 | register int r; |
141 | register int r; |
142 | size_t total; |
142 | size_t total; |
143 | 143 | ||
144 | if ((resid = count * size) == 0) |
144 | if ((resid = count * size) == 0) |
145 | return 0; |
145 | return 0; |
146 | 146 | ||
147 | CHECK_INIT(ptr, fp); |
147 | CHECK_INIT(ptr, fp); |
148 | - | ||
149 | __sfp_lock_acquire (); |
148 | |
150 | _flockfile (fp); |
149 | _flockfile (fp); |
151 | ORIENT (fp, -1); |
150 | ORIENT (fp, -1); |
152 | if (fp->_r < 0) |
151 | if (fp->_r < 0) |
153 | fp->_r = 0; |
152 | fp->_r = 0; |
154 | total = resid; |
153 | total = resid; |
155 | p = buf; |
154 | p = buf; |
156 | 155 | ||
157 | #if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) |
156 | #if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) |
158 | 157 | ||
159 | /* Optimize unbuffered I/O. */ |
158 | /* Optimize unbuffered I/O. */ |
160 | if (fp->_flags & __SNBF) |
159 | if (fp->_flags & __SNBF) |
161 | { |
160 | { |
162 | /* First copy any available characters from ungetc buffer. */ |
161 | /* First copy any available characters from ungetc buffer. */ |
163 | int copy_size = resid > fp->_r ? fp->_r : resid; |
162 | int copy_size = resid > fp->_r ? fp->_r : resid; |
164 | _CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, (size_t) copy_size); |
163 | _CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, (size_t) copy_size); |
165 | fp->_p += copy_size; |
164 | fp->_p += copy_size; |
166 | fp->_r -= copy_size; |
165 | fp->_r -= copy_size; |
167 | p += copy_size; |
166 | p += copy_size; |
168 | resid -= copy_size; |
167 | resid -= copy_size; |
169 | 168 | ||
170 | /* If still more data needed, free any allocated ungetc buffer. */ |
169 | /* If still more data needed, free any allocated ungetc buffer. */ |
171 | if (HASUB (fp) && resid > 0) |
170 | if (HASUB (fp) && resid > 0) |
172 | FREEUB (ptr, fp); |
171 | FREEUB (ptr, fp); |
173 | 172 | ||
174 | /* Finally read directly into user's buffer if needed. */ |
173 | /* Finally read directly into user's buffer if needed. */ |
175 | while (resid > 0) |
174 | while (resid > 0) |
176 | { |
175 | { |
177 | int rc = 0; |
176 | int rc = 0; |
178 | /* save fp buffering state */ |
177 | /* save fp buffering state */ |
179 | void *old_base = fp->_bf._base; |
178 | void *old_base = fp->_bf._base; |
180 | void * old_p = fp->_p; |
179 | void * old_p = fp->_p; |
181 | int old_size = fp->_bf._size; |
180 | int old_size = fp->_bf._size; |
182 | /* allow __refill to use user's buffer */ |
181 | /* allow __refill to use user's buffer */ |
183 | fp->_bf._base = (unsigned char *) p; |
182 | fp->_bf._base = (unsigned char *) p; |
184 | fp->_bf._size = resid; |
183 | fp->_bf._size = resid; |
185 | fp->_p = (unsigned char *) p; |
184 | fp->_p = (unsigned char *) p; |
186 | rc = __srefill_r (ptr, fp); |
185 | rc = __srefill_r (ptr, fp); |
187 | /* restore fp buffering back to original state */ |
186 | /* restore fp buffering back to original state */ |
188 | fp->_bf._base = old_base; |
187 | fp->_bf._base = old_base; |
189 | fp->_bf._size = old_size; |
188 | fp->_bf._size = old_size; |
190 | fp->_p = old_p; |
189 | fp->_p = old_p; |
191 | resid -= fp->_r; |
190 | resid -= fp->_r; |
192 | p += fp->_r; |
191 | p += fp->_r; |
193 | fp->_r = 0; |
192 | fp->_r = 0; |
194 | if (rc) |
193 | if (rc) |
195 | { |
194 | { |
196 | #ifdef __SCLE |
195 | #ifdef __SCLE |
197 | if (fp->_flags & __SCLE) |
196 | if (fp->_flags & __SCLE) |
198 | { |
197 | { |
199 | _funlockfile (fp); |
198 | _funlockfile (fp); |
200 | __sfp_lock_release (); |
- | |
201 | return crlf_r (ptr, fp, buf, total-resid, 1) / size; |
199 | return crlf_r (ptr, fp, buf, total-resid, 1) / size; |
202 | } |
200 | } |
203 | #endif |
201 | #endif |
204 | _funlockfile (fp); |
202 | _funlockfile (fp); |
205 | __sfp_lock_release (); |
- | |
206 | return (total - resid) / size; |
203 | return (total - resid) / size; |
207 | } |
204 | } |
208 | } |
205 | } |
209 | } |
206 | } |
210 | else |
207 | else |
211 | #endif /* !PREFER_SIZE_OVER_SPEED && !__OPTIMIZE_SIZE__ */ |
208 | #endif /* !PREFER_SIZE_OVER_SPEED && !__OPTIMIZE_SIZE__ */ |
212 | { |
209 | { |
213 | while (resid > (r = fp->_r)) |
210 | while (resid > (r = fp->_r)) |
214 | { |
211 | { |
215 | _CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, (size_t) r); |
212 | _CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, (size_t) r); |
216 | fp->_p += r; |
213 | fp->_p += r; |
217 | /* fp->_r = 0 ... done in __srefill */ |
214 | /* fp->_r = 0 ... done in __srefill */ |
218 | p += r; |
215 | p += r; |
219 | resid -= r; |
216 | resid -= r; |
220 | if (__srefill_r (ptr, fp)) |
217 | if (__srefill_r (ptr, fp)) |
221 | { |
218 | { |
222 | /* no more input: return partial result */ |
219 | /* no more input: return partial result */ |
223 | #ifdef __SCLE |
220 | #ifdef __SCLE |
224 | if (fp->_flags & __SCLE) |
221 | if (fp->_flags & __SCLE) |
225 | { |
222 | { |
226 | _funlockfile (fp); |
223 | _funlockfile (fp); |
227 | __sfp_lock_release (); |
- | |
228 | return crlf_r (ptr, fp, buf, total-resid, 1) / size; |
224 | return crlf_r (ptr, fp, buf, total-resid, 1) / size; |
229 | } |
225 | } |
230 | #endif |
226 | #endif |
231 | _funlockfile (fp); |
227 | _funlockfile (fp); |
232 | __sfp_lock_release (); |
- | |
233 | return (total - resid) / size; |
228 | return (total - resid) / size; |
234 | } |
229 | } |
235 | } |
230 | } |
236 | _CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, resid); |
231 | _CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, resid); |
237 | fp->_r -= resid; |
232 | fp->_r -= resid; |
238 | fp->_p += resid; |
233 | fp->_p += resid; |
239 | } |
234 | } |
240 | 235 | ||
241 | /* Perform any CR/LF clean-up if necessary. */ |
236 | /* Perform any CR/LF clean-up if necessary. */ |
242 | #ifdef __SCLE |
237 | #ifdef __SCLE |
243 | if (fp->_flags & __SCLE) |
238 | if (fp->_flags & __SCLE) |
244 | { |
239 | { |
245 | _funlockfile (fp); |
240 | _funlockfile (fp); |
246 | __sfp_lock_release (); |
- | |
247 | return crlf_r(ptr, fp, buf, total, 0) / size; |
241 | return crlf_r(ptr, fp, buf, total, 0) / size; |
248 | } |
242 | } |
249 | #endif |
243 | #endif |
250 | _funlockfile (fp); |
244 | _funlockfile (fp); |
251 | __sfp_lock_release (); |
- | |
252 | return count; |
245 | return count; |
253 | } |
246 | } |
254 | 247 | ||
255 | #ifndef _REENT_ONLY |
248 | #ifndef _REENT_ONLY |
256 | size_t |
249 | size_t |
257 | _DEFUN(fread, (buf, size, count, fp), |
250 | _DEFUN(fread, (buf, size, count, fp), |
258 | _PTR buf _AND |
251 | _PTR buf _AND |
259 | size_t size _AND |
252 | size_t size _AND |
260 | size_t count _AND |
253 | size_t count _AND |
261 | FILE * fp) |
254 | FILE * fp) |
262 | { |
255 | { |
263 | return _fread_r (_REENT, buf, size, count, fp); |
256 | return _fread_r (_REENT, buf, size, count, fp); |
264 | } |
257 | } |
265 | #endif>>> |
258 | #endif>>> |