1 #include "stdio_impl.h"
2 #include <string.h>
3 #ifndef __LITEOS__
4 #include "param_check.h"
5 #endif
6 
7 #define MIN(a,b) ((a)<(b) ? (a) : (b))
8 
__fill_buffer(FILE *f)9 int __fill_buffer(FILE *f)
10 {
11 	int r = __toread(f);
12 	if (r != 0) {
13 		return r;
14 	}
15 
16 	int k = f->readx(f, f->buf, f->buf_size);
17 	if (k <= 0) {
18 		f->flags |= (k == 0) ? F_EOF : F_ERR;
19 		f->rpos = f->rend;
20 		return k;
21 	}
22 
23 	f->rpos = f->buf;
24 	f->rend = f->rpos + k;
25 
26 	return 0;
27 }
28 
fread(void *restrict destv, size_t size, size_t nmemb, FILE *restrict f)29 size_t fread(void *restrict destv, size_t size, size_t nmemb, FILE *restrict f)
30 {
31 #ifndef __LITEOS__
32 	PARAM_CHECK(f);
33 #endif
34 	unsigned char *dest = destv;
35 	size_t len = size * nmemb, l = len, k;
36 	if (!size) {
37 		nmemb = 0;
38 	}
39 
40 	FLOCK(f);
41 
42 	/* allocate file buffer if needed */
43 	if (__falloc_buf(f) < 0) {
44 		f->flags |= F_ERR;
45 		goto exit;
46 	}
47 
48 	f->mode |= f->mode-1;
49 
50 	while (l > 0) {
51 		if (f->rpos != f->rend) {
52 			/* First exhaust the buffer. */
53 			k = MIN(f->rend - f->rpos, l);
54 			memcpy(dest, f->rpos, k);
55 			f->rpos += k;
56 			dest += k;
57 			l -= k;
58 		}
59 		/* done */
60 		if (l == 0) {
61 			goto exit;
62 		}
63 		/* if user buffer is longer than file buffer,
64 		 * maybe buffer size is 0, non-buffer mode,
65 		 * read directly */
66 		if (l > f->buf_size) {
67 			break;
68 		}
69 
70 		if (__fill_buffer(f)) {
71 			goto exit;
72 		}
73 	}
74 
75 	/* Read the remainder directly */
76 	for (; l; l-=k, dest+=k) {
77 		k = f->readx(f, dest, l);
78 		if (!k) {
79 			break;
80 		}
81 	}
82 
83 exit:
84 	FUNLOCK(f);
85 	return (len - l) / size;
86 }
87 
88 weak_alias(fread, fread_unlocked);
89