|
1 /* SETVBUF.C |
|
2 * |
|
3 * Portions Copyright (c) 1990-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 * All rights reserved. |
|
5 */ |
|
6 |
|
7 /* |
|
8 * Copyright (c) 1990 The Regents of the University of California. |
|
9 * All rights reserved. |
|
10 * |
|
11 * Redistribution and use in source and binary forms are permitted |
|
12 * provided that the above copyright notice and this paragraph are |
|
13 * duplicated in all such forms and that any documentation, |
|
14 * advertising materials, and other materials related to such |
|
15 * distribution and use acknowledge that the software was developed |
|
16 * by the University of California, Berkeley. The name of the |
|
17 * University may not be used to endorse or promote products derived |
|
18 * from this software without specific prior written permission. |
|
19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR |
|
20 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED |
|
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
|
22 */ |
|
23 |
|
24 /* |
|
25 FUNCTION |
|
26 <<setvbuf>>---specify file or stream buffering |
|
27 |
|
28 INDEX |
|
29 setvbuf |
|
30 |
|
31 ANSI_SYNOPSIS |
|
32 #include <stdio.h> |
|
33 int setvbuf(FILE *<[fp]>, char *<[buf]>, |
|
34 int <[mode]>, size_t <[size]>); |
|
35 |
|
36 TRAD_SYNOPSIS |
|
37 #include <stdio.h> |
|
38 int setvbuf(<[fp]>, <[buf]>, <[mode]>, <[size]>) |
|
39 FILE *<[fp]>; |
|
40 char *<[buf]>; |
|
41 int <[mode]>; |
|
42 size_t <[size]>; |
|
43 |
|
44 DESCRIPTION |
|
45 Use <<setvbuf>> to specify what kind of buffering you want for the |
|
46 file or stream identified by <[fp]>, by using one of the following |
|
47 values (from <<stdio.h>>) as the <[mode]> argument: |
|
48 |
|
49 o+ |
|
50 o _IONBF |
|
51 Do not use a buffer: send output directly to the host system for the |
|
52 file or stream identified by <[fp]>. |
|
53 |
|
54 o _IOFBF |
|
55 Use full output buffering: output will be passed on to the host system |
|
56 only when the buffer is full, or when an input operation intervenes. |
|
57 |
|
58 o _IOLBF |
|
59 Use line buffering: pass on output to the host system at every |
|
60 newline, as well as when the buffer is full, or when an input |
|
61 operation intervenes. |
|
62 o- |
|
63 |
|
64 Use the <[size]> argument to specify how large a buffer you wish. You |
|
65 can supply the buffer itself, if you wish, by passing a pointer to a |
|
66 suitable area of memory as <[buf]>. Otherwise, you may pass <<NULL>> |
|
67 as the <[buf]> argument, and <<setvbuf>> will allocate the buffer. |
|
68 |
|
69 WARNINGS |
|
70 You may only use <<setvbuf>> before performing any file operation other |
|
71 than opening the file. |
|
72 |
|
73 If you supply a non-null <[buf]>, you must ensure that the associated |
|
74 storage continues to be available until you close the stream |
|
75 identified by <[fp]>. |
|
76 |
|
77 RETURNS |
|
78 A <<0>> result indicates success, <<EOF>> failure (invalid <[mode]> or |
|
79 <[size]> can cause failure). |
|
80 |
|
81 PORTABILITY |
|
82 Both ANSI C and the System V Interface Definition (Issue 2) require |
|
83 <<setvbuf>>. However, they differ on the meaning of a <<NULL>> buffer |
|
84 pointer: the SVID issue 2 specification says that a <<NULL>> buffer |
|
85 pointer requests unbuffered output. For maximum portability, avoid |
|
86 <<NULL>> buffer pointers. |
|
87 |
|
88 Both specifications describe the result on failure only as a |
|
89 nonzero value. |
|
90 |
|
91 Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, |
|
92 <<lseek>>, <<read>>, <<sbrk>>, <<write>>. |
|
93 */ |
|
94 |
|
95 #include <stdio_r.h> |
|
96 #include <stdlib_r.h> |
|
97 #include "LOCAL.H" |
|
98 |
|
99 /** |
|
100 Change stream buffering. |
|
101 Changes the buffer to be used for I/O operations with the specified stream. |
|
102 Size and mode for the buffer can be specified. |
|
103 This function should be called once the file associated with the stream |
|
104 has been opened but before any input or output operation has been done. |
|
105 The size of the buffer is specified by the size parameter, |
|
106 and can be any value between 2 and 32767 in bytes, |
|
107 this value may be rounded down by some system due to specific alignment. |
|
108 buffer can be NULL. |
|
109 @return If the buffer is correctly assigned to the file a 0 value is returned. |
|
110 On error, a non-zero value is returned. This can be because an invalid type or size has been specified or because an error allocating memory (if NULL buffer was specified). |
|
111 @param fp pointer to an open file. |
|
112 @param buf User allocated buffer. Must have at least a size of size bytes. |
|
113 @param mode Specifies a mode for file buffering |
|
114 @param Buffer size in bytes, must be more than 0 and less than 32768, this value may be rounded down by some systems due to specific alignment, in which case the minimum value should be 2. |
|
115 */ |
|
116 EXPORT_C int |
|
117 setvbuf (FILE * fp, char *buf, int mode, size_t size) |
|
118 { |
|
119 int ret = 0; |
|
120 CHECK_INIT (fp); |
|
121 |
|
122 /* |
|
123 * Verify arguments. The `int' limit on `size' is due to this |
|
124 * particular implementation. |
|
125 */ |
|
126 |
|
127 if ((mode != _IOFBF && mode != _IOLBF && mode != _IONBF) || (int) size < 0) |
|
128 return (EOF); |
|
129 |
|
130 /* |
|
131 * Write current buffer, if any; drop read count, if any. |
|
132 * Make sure putc() will not think fp is line buffered. |
|
133 * Free old buffer if it was from malloc(). Clear line and |
|
134 * non buffer flags, and clear malloc flag. |
|
135 */ |
|
136 |
|
137 (void) fflush (fp); |
|
138 fp->_r = 0; |
|
139 fp->_lbfsize = 0; |
|
140 if (fp->_flags & __SMBF) |
|
141 _free_r (fp->_data, (void *) fp->_bf._base); |
|
142 fp->_flags &= ~(__SLBF | __SNBF | __SMBF); |
|
143 |
|
144 if (mode == _IONBF) |
|
145 goto nbf; |
|
146 |
|
147 /* |
|
148 * Allocate buffer if needed. */ |
|
149 if (buf == NULL) |
|
150 { |
|
151 if ((buf = (char *)malloc (size)) == NULL) |
|
152 { |
|
153 ret = EOF; |
|
154 /* Try another size... */ |
|
155 buf = (char *)malloc (BUFSIZ); |
|
156 } |
|
157 if (buf == NULL) |
|
158 { |
|
159 /* Can't allocate it, let's try another approach */ |
|
160 nbf: |
|
161 fp->_flags |= __SNBF; |
|
162 fp->_w = 0; |
|
163 fp->_bf._base = fp->_p = fp->_nbuf; |
|
164 fp->_bf._size = 1; |
|
165 return (ret); |
|
166 } |
|
167 fp->_flags |= __SMBF; |
|
168 } |
|
169 /* |
|
170 * Now put back whichever flag is needed, and fix _lbfsize |
|
171 * if line buffered. Ensure output flush on exit if the |
|
172 * stream will be buffered at all. |
|
173 * Force the buffer to be flushed and hence malloced on first use |
|
174 */ |
|
175 |
|
176 switch (mode) |
|
177 { |
|
178 case _IOLBF: |
|
179 fp->_flags |= __SLBF; |
|
180 fp->_lbfsize = -(int)size; |
|
181 /* FALLTHROUGH */ |
|
182 |
|
183 case _IOFBF: |
|
184 /* no flag */ |
|
185 fp->_data->__cleanup = _cleanup_r; |
|
186 fp->_bf._base = fp->_p = (unsigned char *) buf; |
|
187 fp->_bf._size = size; |
|
188 break; |
|
189 } |
|
190 |
|
191 /* |
|
192 * Patch up write count if necessary. |
|
193 */ |
|
194 |
|
195 if (fp->_flags & __SWR) |
|
196 fp->_w = fp->_flags & (__SLBF | __SNBF) ? 0 : size; |
|
197 |
|
198 return 0; |
|
199 } |