]> Git Repo - uclibc-ng.git/blame - libc/stdio/setvbuf.c
make sure TARGET_ARCH is set ... thought i committed this already?
[uclibc-ng.git] / libc / stdio / setvbuf.c
CommitLineData
082e680b
MNI
1/* Copyright (C) 2004 Manuel Novoa III <[email protected]>
2 *
3 * GNU Library General Public License (LGPL) version 2 or later.
4 *
5 * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
6 */
7
8#include "_stdio.h"
9
10#if (_IOFBF != 0) || (_IOLBF != 1) || (_IONBF != 2)
11#error Assumption violated -- values of _IOFBF, _IOLBF, _IONBF
12#endif
13#if (__FLAG_FBF != 0) || (__FLAG_NBF != (2*__FLAG_LBF))
14#error Assumption violated for buffering mode flags
15#endif
16
17int setvbuf(register FILE * __restrict stream, register char * __restrict buf,
18 int mode, size_t size)
19{
20#ifdef __STDIO_BUFFERS
21
22 int retval = EOF;
23 int alloc_flag = 0;
24 __STDIO_AUTO_THREADLOCK_VAR;
25
26 __STDIO_AUTO_THREADLOCK(stream);
27 __STDIO_STREAM_VALIDATE(stream);
28
29 if (((unsigned int) mode) > 2) {
30 __set_errno(EINVAL);
31 goto ERROR;
32 }
33
34 /* C99 states that setvbuf may only be used between a successful
35 * open of the stream and before any other operation other than
36 * an unsuccessful call to setvbuf. */
37
38#ifdef __STDIO_FLEXIBLE_SETVBUF
39 /* If we aren't currently reading (including ungots) or writing,
40 * then allow the request to proceed. */
41
42 if (stream->__modeflags & (__MASK_READING|__FLAG_WRITING)) {
43 goto ERROR;
44 }
45#else
46 /* The following test isn't quite as strict as C99, as it will
47 * not detect file positioning operations. */
48
49 if (stream->__modeflags & (__MASK_READING|__FLAG_WRITING
50 |__FLAG_NARROW|__FLAG_WIDE
51 |__FLAG_ERROR|__FLAG_EOF)
52 ) {
53 goto ERROR;
54 }
55#endif
56
57 stream->__modeflags &= ~(__MASK_BUFMODE); /* Clear current mode */
58 stream->__modeflags |= mode * __FLAG_LBF; /* and set new one. */
59
60 if ((mode == _IONBF) || !size) {
61 size = 0;
62 buf = NULL;
63 } else if (!buf) {
64 if ((__STDIO_STREAM_BUFFER_SIZE(stream) == size) /* Same size or */
65 || !(buf = malloc(size)) /* malloc failed, so don't change. */
66 ) {
67 goto DONE;
68 }
69 alloc_flag = __FLAG_FREEBUF;
70 }
71
72 if (stream->__modeflags & __FLAG_FREEBUF) {
73 stream->__modeflags &= ~(__FLAG_FREEBUF);
74 free(stream->__bufstart);
75 }
76
77 stream->__modeflags |= alloc_flag;
78 stream->__bufstart = buf;
79 stream->__bufend = buf + size;
80 __STDIO_STREAM_INIT_BUFREAD_BUFPOS(stream);
81 __STDIO_STREAM_DISABLE_GETC(stream);
82 __STDIO_STREAM_DISABLE_PUTC(stream);
83
84 DONE:
85 retval = 0;
86
87 ERROR:
88 __STDIO_STREAM_VALIDATE(stream);
89 __STDIO_AUTO_THREADUNLOCK(stream);
90
91 return retval;
92
93#else /* __STDIO_BUFFERS */
94
95 if (mode == _IONBF) {
96 return 0;
97 }
98
99 if (((unsigned int) mode) > 2) {
100 __set_errno(EINVAL);
101 }
102
103 return EOF;
104
105#endif
106}
This page took 0.066143 seconds and 4 git commands to generate.