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.
10 #if (_IOFBF != 0) || (_IOLBF != 1) || (_IONBF != 2)
11 #error Assumption violated -- values of _IOFBF, _IOLBF, _IONBF
13 #if (__FLAG_FBF != 0) || (__FLAG_NBF != (2*__FLAG_LBF))
14 #error Assumption violated for buffering mode flags
17 int setvbuf(register FILE * __restrict stream
, register char * __restrict buf
,
18 int mode
, size_t size
)
20 #ifdef __STDIO_BUFFERS
24 __STDIO_AUTO_THREADLOCK_VAR
;
26 __STDIO_AUTO_THREADLOCK(stream
);
27 __STDIO_STREAM_VALIDATE(stream
);
29 if (((unsigned int) mode
) > 2) {
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. */
38 #ifdef __STDIO_FLEXIBLE_SETVBUF
39 /* If we aren't currently reading (including ungots) or writing,
40 * then allow the request to proceed. */
42 if (stream
->__modeflags
& (__MASK_READING
|__FLAG_WRITING
)) {
46 /* The following test isn't quite as strict as C99, as it will
47 * not detect file positioning operations. */
49 if (stream
->__modeflags
& (__MASK_READING
|__FLAG_WRITING
50 |__FLAG_NARROW
|__FLAG_WIDE
51 |__FLAG_ERROR
|__FLAG_EOF
)
57 stream
->__modeflags
&= ~(__MASK_BUFMODE
); /* Clear current mode */
58 stream
->__modeflags
|= mode
* __FLAG_LBF
; /* and set new one. */
60 if ((mode
== _IONBF
) || !size
) {
64 if ((__STDIO_STREAM_BUFFER_SIZE(stream
) == size
) /* Same size or */
65 || !(buf
= malloc(size
)) /* malloc failed, so don't change. */
69 alloc_flag
= __FLAG_FREEBUF
;
72 if (stream
->__modeflags
& __FLAG_FREEBUF
) {
73 stream
->__modeflags
&= ~(__FLAG_FREEBUF
);
74 free(stream
->__bufstart
);
77 stream
->__modeflags
|= alloc_flag
;
78 stream
->__bufstart
= (unsigned char *) buf
;
79 stream
->__bufend
= (unsigned char *) buf
+ size
;
80 __STDIO_STREAM_INIT_BUFREAD_BUFPOS(stream
);
81 __STDIO_STREAM_DISABLE_GETC(stream
);
82 __STDIO_STREAM_DISABLE_PUTC(stream
);
88 __STDIO_STREAM_VALIDATE(stream
);
89 __STDIO_AUTO_THREADUNLOCK(stream
);
93 #else /* __STDIO_BUFFERS */
99 if (((unsigned int) mode
) > 2) {
107 libc_hidden_def(setvbuf
)