Rev 4874 | Go to most recent revision | 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; |
4349 | Serge | 107 | |
4921 | Serge | 108 | CHECK_INIT (reent, fp); |
4349 | Serge | 109 | |
4921 | Serge | 110 | _newlib_flockfile_start (fp); |
4349 | Serge | 111 | |
112 | /* |
||
113 | * Verify arguments. The `int' limit on `size' is due to this |
||
114 | * particular implementation. |
||
115 | */ |
||
116 | |||
117 | if ((mode != _IOFBF && mode != _IOLBF && mode != _IONBF) || (int)(_POINTER_INT) size < 0) |
||
118 | { |
||
4921 | Serge | 119 | _newlib_flockfile_exit (fp); |
4349 | Serge | 120 | return (EOF); |
121 | } |
||
122 | |||
123 | /* |
||
124 | * Write current buffer, if any; drop read count, if any. |
||
125 | * Make sure putc() will not think fp is line buffered. |
||
126 | * Free old buffer if it was from malloc(). Clear line and |
||
127 | * non buffer flags, and clear malloc flag. |
||
128 | */ |
||
129 | |||
4921 | Serge | 130 | _fflush_r (reent, fp); |
4349 | Serge | 131 | fp->_r = 0; |
132 | fp->_lbfsize = 0; |
||
133 | if (fp->_flags & __SMBF) |
||
4921 | Serge | 134 | _free_r (reent, (_PTR) fp->_bf._base); |
4349 | Serge | 135 | fp->_flags &= ~(__SLBF | __SNBF | __SMBF); |
136 | |||
137 | if (mode == _IONBF) |
||
138 | goto nbf; |
||
139 | |||
140 | /* |
||
141 | * Allocate buffer if needed. */ |
||
142 | if (buf == NULL) |
||
143 | { |
||
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) |
||
148 | { |
||
149 | ret = EOF; |
||
150 | /* Try another size... */ |
||
151 | buf = malloc (BUFSIZ); |
||
152 | size = BUFSIZ; |
||
153 | } |
||
154 | if (buf == NULL) |
||
155 | { |
||
156 | /* Can't allocate it, let's try another approach */ |
||
157 | nbf: |
||
158 | fp->_flags |= __SNBF; |
||
159 | fp->_w = 0; |
||
160 | fp->_bf._base = fp->_p = fp->_nbuf; |
||
161 | fp->_bf._size = 1; |
||
4921 | Serge | 162 | _newlib_flockfile_exit (fp); |
4349 | Serge | 163 | return (ret); |
164 | } |
||
165 | fp->_flags |= __SMBF; |
||
166 | } |
||
167 | /* |
||
168 | * Now put back whichever flag is needed, and fix _lbfsize |
||
169 | * if line buffered. Ensure output flush on exit if the |
||
170 | * stream will be buffered at all. |
||
171 | * If buf is NULL then make _lbfsize 0 to force the buffer |
||
172 | * to be flushed and hence malloced on first use |
||
173 | */ |
||
174 | |||
175 | switch (mode) |
||
176 | { |
||
177 | case _IOLBF: |
||
178 | fp->_flags |= __SLBF; |
||
179 | fp->_lbfsize = buf ? -size : 0; |
||
180 | /* FALLTHROUGH */ |
||
181 | |||
182 | case _IOFBF: |
||
183 | /* no flag */ |
||
4921 | Serge | 184 | reent->__cleanup = _cleanup_r; |
4349 | Serge | 185 | fp->_bf._base = fp->_p = (unsigned char *) buf; |
186 | fp->_bf._size = size; |
||
187 | break; |
||
188 | } |
||
189 | |||
190 | /* |
||
191 | * Patch up write count if necessary. |
||
192 | */ |
||
193 | |||
194 | if (fp->_flags & __SWR) |
||
195 | fp->_w = fp->_flags & (__SLBF | __SNBF) ? 0 : size; |
||
196 | |||
4921 | Serge | 197 | _newlib_flockfile_end (fp); |
4349 | Serge | 198 | return 0; |
199 | }> |