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