netinet/in.h: add IPPROTO_MH
[uclibc-ng.git] / libc / stdio / fread.c
blob5f4ec6f38c2167f07dec2e35b942a1f1b3ad8058
1 /* Copyright (C) 2004 Manuel Novoa III <mjn3@codepoet.org>
3 * GNU Library General Public License (LGPL) version 2 or later.
5 * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
6 */
8 #include "_stdio.h"
11 #ifdef __DO_UNLOCKED
14 size_t fread_unlocked(void * __restrict ptr, size_t size, size_t nmemb,
15 FILE * __restrict stream)
17 __STDIO_STREAM_VALIDATE(stream);
18 assert(stream->__filedes >= -2);
20 /* Note: If nmbem * size > SIZE_MAX then there is an application
21 * bug since no array can be larger than SIZE_MAX in size. */
23 if ((__STDIO_STREAM_IS_NARROW_READING(stream)
24 || !__STDIO_STREAM_TRANS_TO_READ(stream, __FLAG_NARROW))
25 && size && nmemb
26 ) {
28 if (nmemb <= (SIZE_MAX / size)) {
29 unsigned char *buffer = (unsigned char *) ptr;
30 size_t todo, bytes, avail;
32 todo = bytes = size * nmemb;
34 /* Check for ungots... */
35 while (stream->__modeflags & __FLAG_UNGOT) {
36 *buffer++ = stream->__ungot[(stream->__modeflags--) & 1];
37 stream->__ungot[1] = 0;
38 if (!--todo) {
39 goto DONE;
43 #ifdef __STDIO_BUFFERS
44 /* Next check for available buffered... */
45 if ((avail = stream->__bufread - stream->__bufpos) > 0) {
46 if (avail > todo) {
47 avail = todo;
49 memcpy(buffer, stream->__bufpos, avail);
50 buffer += avail;
51 stream->__bufpos += avail;
52 if (!(todo -= avail)) {
53 goto DONE;
57 /* We need to read from the host environment, so we must
58 * flush all line buffered streams if the stream is not
59 * fully buffered. */
60 if (!__STDIO_STREAM_IS_FBF(stream)) {
61 __STDIO_FLUSH_LBF_STREAMS;
63 #endif
65 while ((avail = __stdio_READ(stream, buffer, todo)) > 0) {
66 buffer += avail;
67 if (!(todo -= avail)) {
68 break;
72 DONE:
73 __STDIO_STREAM_VALIDATE(stream);
74 return (bytes - todo) / size;
77 __STDIO_STREAM_SET_ERROR(stream);
78 __set_errno(EINVAL);
81 __STDIO_STREAM_VALIDATE(stream);
82 return 0;
84 libc_hidden_def(fread_unlocked)
86 #ifndef __UCLIBC_HAS_THREADS__
87 strong_alias(fread_unlocked,fread)
88 libc_hidden_def(fread)
89 #endif
91 #elif defined __UCLIBC_HAS_THREADS__
93 size_t fread(void * __restrict ptr, size_t size, size_t nmemb,
94 register FILE * __restrict stream)
96 size_t retval;
97 __STDIO_AUTO_THREADLOCK_VAR;
99 __STDIO_AUTO_THREADLOCK(stream);
101 retval = fread_unlocked(ptr, size, nmemb, stream);
103 __STDIO_AUTO_THREADUNLOCK(stream);
105 return retval;
107 libc_hidden_def(fread)
109 #endif