Rev 4921 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4349 | Serge | 1 | /* |
2 | * Copyright (c) 1990 The Regents of the University of California. |
||
3 | * All rights reserved. |
||
4 | * |
||
5 | * Redistribution and use in source and binary forms are permitted |
||
6 | * provided that the above copyright notice and this paragraph are |
||
7 | * duplicated in all such forms and that any documentation, |
||
8 | * advertising materials, and other materials related to such |
||
9 | * distribution and use acknowledge that the software was developed |
||
10 | * by the University of California, Berkeley. The name of the |
||
11 | * University may not be used to endorse or promote products derived |
||
12 | * from this software without specific prior written permission. |
||
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR |
||
14 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED |
||
15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
||
16 | */ |
||
17 | |||
18 | /* |
||
19 | FUNCTION |
||
20 | < |
||
21 | |||
22 | INDEX |
||
23 | setvbuf |
||
24 | |||
25 | ANSI_SYNOPSIS |
||
26 | #include |
||
27 | int setvbuf(FILE *<[fp]>, char *<[buf]>, |
||
28 | int <[mode]>, size_t <[size]>); |
||
29 | |||
30 | TRAD_SYNOPSIS |
||
31 | #include |
||
32 | int setvbuf(<[fp]>, <[buf]>, <[mode]>, <[size]>) |
||
33 | FILE *<[fp]>; |
||
34 | char *<[buf]>; |
||
35 | int <[mode]>; |
||
36 | size_t <[size]>; |
||
37 | |||
38 | DESCRIPTION |
||
39 | Use < |
||
40 | file or stream identified by <[fp]>, by using one of the following |
||
41 | values (from < |
||
42 | |||
43 | o+ |
||
44 | o _IONBF |
||
45 | Do not use a buffer: send output directly to the host system for the |
||
46 | file or stream identified by <[fp]>. |
||
47 | |||
48 | o _IOFBF |
||
49 | Use full output buffering: output will be passed on to the host system |
||
50 | only when the buffer is full, or when an input operation intervenes. |
||
51 | |||
52 | o _IOLBF |
||
53 | Use line buffering: pass on output to the host system at every |
||
54 | newline, as well as when the buffer is full, or when an input |
||
55 | operation intervenes. |
||
56 | o- |
||
57 | |||
58 | Use the <[size]> argument to specify how large a buffer you wish. You |
||
59 | can supply the buffer itself, if you wish, by passing a pointer to a |
||
60 | suitable area of memory as <[buf]>. Otherwise, you may pass < |
||
61 | as the <[buf]> argument, and < |
||
62 | |||
63 | WARNINGS |
||
64 | You may only use < |
||
65 | than opening the file. |
||
66 | |||
67 | If you supply a non-null <[buf]>, you must ensure that the associated |
||
68 | storage continues to be available until you close the stream |
||
69 | identified by <[fp]>. |
||
70 | |||
71 | RETURNS |
||
72 | A <<0>> result indicates success, < |
||
73 | <[size]> can cause failure). |
||
74 | |||
75 | PORTABILITY |
||
76 | Both ANSI C and the System V Interface Definition (Issue 2) require |
||
77 | < |
||
78 | pointer: the SVID issue 2 specification says that a < |
||
79 | pointer requests unbuffered output. For maximum portability, avoid |
||
80 | < |
||
81 | |||
82 | Both specifications describe the result on failure only as a |
||
83 | nonzero value. |
||
84 | |||
85 | Supporting OS subroutines required: < |
||
86 | < |
||
87 | */ |
||
88 | |||
89 | #include <_ansi.h> |
||
90 | #include |
||
91 | #include |
||
92 | #include "local.h" |
||
93 | |||
94 | /* |
||
95 | * Set one of the three kinds of buffering, optionally including a buffer. |
||
96 | */ |
||
97 | |||
98 | int |
||
99 | _DEFUN(setvbuf, (fp, buf, mode, size), |
||
100 | register FILE * fp _AND |
||
101 | char *buf _AND |
||
102 | register int mode _AND |
||
103 | register size_t size) |
||
104 | { |
||
105 | int ret = 0; |
||
4921 | Serge | 106 | struct _reent *reent = _REENT; |
6536 | serge | 107 | size_t iosize; |
108 | int ttyflag; |
||
4349 | Serge | 109 | |
4921 | Serge | 110 | CHECK_INIT (reent, fp); |
4349 | Serge | 111 | |
112 | /* |
||
113 | * Verify arguments. The `int' limit on `size' is due to this |
||
6536 | serge | 114 | * particular implementation. Note, buf and size are ignored |
115 | * when setting _IONBF. |
||
4349 | Serge | 116 | */ |
6536 | serge | 117 | if (mode != _IONBF) |
118 | if ((mode != _IOFBF && mode != _IOLBF) || (int)(_POINTER_INT) size < 0) |
||
4349 | Serge | 119 | return (EOF); |
120 | |||
6536 | serge | 121 | |
4349 | Serge | 122 | /* |
123 | * Write current buffer, if any; drop read count, if any. |
||
124 | * Make sure putc() will not think fp is line buffered. |
||
125 | * Free old buffer if it was from malloc(). Clear line and |
||
126 | * non buffer flags, and clear malloc flag. |
||
127 | */ |
||
6536 | serge | 128 | _newlib_flockfile_start (fp); |
4921 | Serge | 129 | _fflush_r (reent, fp); |
6536 | serge | 130 | if (HASUB(fp)) |
131 | FREEUB(reent, fp); |
||
132 | fp->_r = fp->_lbfsize = 0; |
||
4349 | Serge | 133 | if (fp->_flags & __SMBF) |
4921 | Serge | 134 | _free_r (reent, (_PTR) fp->_bf._base); |
6536 | serge | 135 | fp->_flags &= ~(__SLBF | __SNBF | __SMBF | __SOPT | __SNPT | __SEOF); |
4349 | Serge | 136 | |
137 | if (mode == _IONBF) |
||
138 | goto nbf; |
||
139 | |||
140 | /* |
||
6536 | serge | 141 | * Find optimal I/O size for seek optimization. This also returns |
142 | * a `tty flag' to suggest that we check isatty(fd), but we do not |
||
143 | * care since our caller told us how to buffer. |
||
144 | */ |
||
145 | fp->_flags |= __swhatbuf_r (reent, fp, &iosize, &ttyflag); |
||
146 | if (size == 0) |
||
147 | { |
||
148 | buf = NULL; |
||
149 | size = iosize; |
||
150 | } |
||
151 | |||
152 | /* Allocate buffer if needed. */ |
||
4349 | Serge | 153 | if (buf == NULL) |
154 | { |
||
155 | if ((buf = malloc (size)) == NULL) |
||
156 | { |
||
6536 | serge | 157 | /* |
158 | * Unable to honor user's request. We will return |
||
159 | * failure, but try again with file system size. |
||
160 | */ |
||
4349 | Serge | 161 | ret = EOF; |
6536 | serge | 162 | if (size != iosize) |
163 | { |
||
164 | size = iosize; |
||
165 | buf = malloc (size); |
||
166 | } |
||
4349 | Serge | 167 | } |
168 | if (buf == NULL) |
||
169 | { |
||
6536 | serge | 170 | /* No luck; switch to unbuffered I/O. */ |
4349 | Serge | 171 | nbf: |
172 | fp->_flags |= __SNBF; |
||
173 | fp->_w = 0; |
||
174 | fp->_bf._base = fp->_p = fp->_nbuf; |
||
175 | fp->_bf._size = 1; |
||
4921 | Serge | 176 | _newlib_flockfile_exit (fp); |
4349 | Serge | 177 | return (ret); |
178 | } |
||
179 | fp->_flags |= __SMBF; |
||
180 | } |
||
6536 | serge | 181 | |
4349 | Serge | 182 | /* |
6536 | serge | 183 | * We're committed to buffering from here, so make sure we've |
184 | * registered to flush buffers on exit. |
||
4349 | Serge | 185 | */ |
6536 | serge | 186 | if (!reent->__sdidinit) |
187 | __sinit(reent); |
||
4349 | Serge | 188 | |
6536 | serge | 189 | #ifdef _FSEEK_OPTIMIZATION |
190 | /* |
||
191 | * Kill any seek optimization if the buffer is not the |
||
192 | * right size. |
||
193 | * |
||
194 | * SHOULD WE ALLOW MULTIPLES HERE (i.e., ok iff (size % iosize) == 0)? |
||
195 | */ |
||
196 | if (size != iosize) |
||
197 | fp->_flags |= __SNPT; |
||
198 | #endif |
||
199 | |||
200 | /* |
||
201 | * Fix up the FILE fields, and set __cleanup for output flush on |
||
202 | * exit (since we are buffered in some way). |
||
203 | */ |
||
204 | if (mode == _IOLBF) |
||
4349 | Serge | 205 | fp->_flags |= __SLBF; |
206 | fp->_bf._base = fp->_p = (unsigned char *) buf; |
||
207 | fp->_bf._size = size; |
||
6536 | serge | 208 | /* fp->_lbfsize is still 0 */ |
209 | if (fp->_flags & __SWR) |
||
210 | { |
||
4349 | Serge | 211 | /* |
6536 | serge | 212 | * Begin or continue writing: see __swsetup(). Note |
213 | * that __SNBF is impossible (it was handled earlier). |
||
4349 | Serge | 214 | */ |
6536 | serge | 215 | if (fp->_flags & __SLBF) |
216 | { |
||
217 | fp->_w = 0; |
||
218 | fp->_lbfsize = -fp->_bf._size; |
||
219 | } |
||
220 | else |
||
221 | fp->_w = size; |
||
222 | } |
||
223 | else |
||
224 | { |
||
225 | /* begin/continue reading, or stay in intermediate state */ |
||
226 | fp->_w = 0; |
||
227 | } |
||
4349 | Serge | 228 | |
4921 | Serge | 229 | _newlib_flockfile_end (fp); |
4349 | Serge | 230 | return 0; |
231 | }> |