]>
Commit | Line | Data |
---|---|---|
493e0eb3 | 1 | .\" Copyright 2005, 2012, 2016 Michael Kerrisk <mtk.manpages@gmail.com> |
2297bf0e | 2 | .\" |
38f20bb9 | 3 | .\" %%%LICENSE_START(GPL_NOVERSION_ONELINE) |
89c9a314 | 4 | .\" Distributed under the GPL. |
38f20bb9 | 5 | .\" %%%LICENSE_END |
0389adc9 | 6 | .\" |
9ba01802 | 7 | .TH FMEMOPEN 3 2019-03-06 "GNU" "Linux Programmer's Manual" |
86cfe9cb | 8 | .SH NAME |
09ffd9ca | 9 | fmemopen \- open memory as stream |
86cfe9cb | 10 | .SH SYNOPSIS |
99111b75 | 11 | .nf |
86cfe9cb | 12 | .B #include <stdio.h> |
dbfe9c70 | 13 | .PP |
99111b75 | 14 | .BI "FILE *fmemopen(void *"buf ", size_t "size ", const char *" mode ");" |
31337f93 | 15 | .fi |
68e4db0a | 16 | .PP |
31337f93 MK |
17 | .in -4n |
18 | Feature Test Macro Requirements for glibc (see | |
19 | .BR feature_test_macros (7)): | |
20 | .in | |
68e4db0a | 21 | .PP |
09ffd9ca | 22 | .BR fmemopen (): |
ea91c3fd MK |
23 | .PD 0 |
24 | .ad l | |
25 | .RS 4 | |
26 | .TP 4 | |
27 | Since glibc 2.10: | |
b0da7b8b | 28 | _POSIX_C_SOURCE\ >=\ 200809L |
ea91c3fd | 29 | .TP |
31337f93 MK |
30 | Before glibc 2.10: |
31 | _GNU_SOURCE | |
ea91c3fd MK |
32 | .RE |
33 | .ad | |
34 | .PD | |
86cfe9cb MK |
35 | .SH DESCRIPTION |
36 | The | |
37 | .BR fmemopen () | |
38 | function opens a stream that permits the access specified by | |
39 | .IR mode . | |
c13182ef | 40 | The stream allows I/O to be performed on the string or memory buffer |
89c9a314 | 41 | pointed to by |
c13182ef | 42 | .IR buf . |
847e0d88 | 43 | .PP |
58c55bb8 | 44 | The |
86cfe9cb | 45 | .I mode |
58c55bb8 MK |
46 | argument specifies the semantics of I/O on the stream, |
47 | and is one of the following: | |
48 | .TP 8 | |
49 | .I r | |
50 | The stream is opened for reading. | |
51 | .TP | |
52 | .I w | |
53 | The stream is opened for writing. | |
54 | .TP | |
55 | .I a | |
56 | Append; open the stream for writing, | |
ddef8b95 | 57 | with the initial buffer position set to the first null byte. |
58c55bb8 MK |
58 | .TP |
59 | .I r+ | |
60 | Open the stream for reading and writing. | |
61 | .TP | |
62 | .I w+ | |
63 | Open the stream for reading and writing. | |
64 | The buffer contents are truncated | |
d1a71985 | 65 | (i.e., \(aq\e0\(aq is placed in the first byte of the buffer). |
58c55bb8 MK |
66 | .TP |
67 | .I a+ | |
68 | Append; open the stream for reading and writing, | |
ddef8b95 | 69 | with the initial buffer position set to the first null byte. |
58c55bb8 | 70 | .PP |
c7de29d4 MK |
71 | The stream maintains the notion of a current position, |
72 | the location where the next I/O operation will be performed. | |
73 | The current position is implicitly updated by I/O operations. | |
74 | It can be explicitly updated using | |
75 | .BR fseek (3), | |
76 | and determined using | |
77 | .BR ftell (3). | |
58c55bb8 MK |
78 | In all modes other than append, |
79 | the initial position is set to the start of the buffer. | |
c7de29d4 MK |
80 | In append mode, if no null byte is found within the buffer, |
81 | then the initial position is | |
82 | .IR size+1 . | |
58c55bb8 | 83 | .PP |
9c8b5ebf MK |
84 | If |
85 | .I buf | |
86 | is specified as NULL, then | |
87 | .BR fmemopen () | |
88 | allocates a buffer of | |
89 | .I size | |
90 | bytes. | |
91 | This is useful for an application that wants to write data to | |
92 | a temporary buffer and then read it back again. | |
93 | The initial position is set to the start of the buffer. | |
94 | The buffer is automatically freed when the stream is closed. | |
95 | Note that the caller has no way to obtain a pointer to the | |
96 | temporary buffer allocated by this call (but see | |
09ffd9ca | 97 | .BR open_memstream (3)). |
9c8b5ebf MK |
98 | .PP |
99 | If | |
100 | .I buf | |
101 | is not NULL, then it should point to a buffer of at least | |
102 | .I len | |
103 | bytes allocated by the caller. | |
104 | .PP | |
c13182ef | 105 | When a stream that has been opened for writing is flushed |
89c9a314 MK |
106 | .RB ( fflush (3)) |
107 | or closed | |
108 | .RB ( fclose (3)), | |
109 | a null byte is written at the end of the buffer if there is space. | |
c13182ef | 110 | The caller should ensure that an extra byte is available in the |
89c9a314 MK |
111 | buffer |
112 | (and that | |
0daa9e92 | 113 | .I size |
89c9a314 | 114 | counts that byte) |
c13182ef | 115 | to allow for this. |
847e0d88 | 116 | .PP |
f29c8cd8 | 117 | In a stream opened for reading, |
d1a71985 | 118 | null bytes (\(aq\e0\(aq) in the buffer do not cause read |
f29c8cd8 MK |
119 | operations to return an end-of-file indication. |
120 | A read from the buffer will indicate end-of-file | |
ddef8b95 | 121 | only when the current buffer position advances |
f29c8cd8 MK |
122 | .I size |
123 | bytes past the start of the buffer. | |
847e0d88 | 124 | .PP |
d779692d MK |
125 | Write operations take place either at the current position |
126 | (for modes other than append), or at the current size of the stream | |
127 | (for append modes). | |
847e0d88 | 128 | .PP |
86cfe9cb MK |
129 | Attempts to write more than |
130 | .I size | |
131 | bytes to the buffer result in an error. | |
d779692d MK |
132 | By default, such errors will be visible |
133 | (by the absence of data) only when the | |
c75ec721 | 134 | .I stdio |
d779692d | 135 | buffer is flushed. |
f5184951 MK |
136 | Disabling buffering with the following call |
137 | may be useful to detect errors at the time of an output operation: | |
847e0d88 | 138 | .PP |
93bb19b1 | 139 | setbuf(stream, NULL); |
47297adb | 140 | .SH RETURN VALUE |
09ffd9ca MK |
141 | Upon successful completion, |
142 | .BR fmemopen () | |
143 | returns a | |
097585ed | 144 | .I FILE |
c13182ef | 145 | pointer. |
28d03ce9 | 146 | Otherwise, NULL is returned and |
c13182ef | 147 | .I errno |
86cfe9cb | 148 | is set to indicate the error. |
45906a48 MK |
149 | .SH VERSIONS |
150 | .BR fmemopen () | |
09ffd9ca | 151 | was already available in glibc 1.0.x. |
c49cfc4f MS |
152 | .SH ATTRIBUTES |
153 | For an explanation of the terms used in this section, see | |
154 | .BR attributes (7). | |
155 | .TS | |
156 | allbox; | |
157 | lb lb lb | |
158 | l l l. | |
159 | Interface Attribute Value | |
160 | T{ | |
02989b14 | 161 | .BR fmemopen (), |
c49cfc4f MS |
162 | T} Thread safety MT-Safe |
163 | .TE | |
847e0d88 | 164 | .sp 1 |
47297adb | 165 | .SH CONFORMING TO |
aed04a0a | 166 | POSIX.1-2008. |
09ffd9ca MK |
167 | This function is not specified in POSIX.1-2001, |
168 | and is not widely available on other systems. | |
847e0d88 | 169 | .PP |
360e0be2 MK |
170 | POSIX.1-2008 specifies that \(aqb\(aq in |
171 | .IR mode | |
172 | shall be ignored. | |
173 | However, Technical Corrigendum 1 | |
174 | .\" http://austingroupbugs.net/view.php?id=396 | |
175 | adjusts the standard to allow implementation-specific treatment for this case, | |
176 | thus permitting the glibc treatment of \(aqb\(aq. | |
a76ca000 PB |
177 | .SH NOTES |
178 | There is no file descriptor associated with the file stream | |
09ffd9ca | 179 | returned by this function |
e80aa4d8 | 180 | (i.e., |
a76ca000 PB |
181 | .BR fileno (3) |
182 | will return an error if called on the returned stream). | |
847e0d88 | 183 | .PP |
1e9eb6c1 MK |
184 | With version 2.22, binary mode (see below) was removed, |
185 | many longstanding bugs in the implementation of | |
39ef79ba MK |
186 | .BR fmemopen () |
187 | were fixed, and a new versioned symbol was created for this interface. | |
1e9eb6c1 MK |
188 | .\" |
189 | .SS Binary mode | |
190 | From version 2.9 to 2.21, the glibc implementation of | |
191 | .BR fmemopen () | |
192 | supported a "binary" mode, | |
193 | enabled by specifying the letter \(aqb\(aq as the second character in | |
194 | .IR mode . | |
195 | In this mode, | |
196 | writes don't implicitly add a terminating null byte, and | |
197 | .BR fseek (3) | |
198 | .B SEEK_END | |
199 | is relative to the end of the buffer (i.e., the value specified by the | |
200 | .I size | |
201 | argument), rather than the current string length. | |
847e0d88 | 202 | .PP |
1e9eb6c1 MK |
203 | An API bug afflicted the implementation of binary mode: |
204 | to specify binary mode, the \(aqb\(aq must be the | |
205 | .I second | |
206 | character in | |
207 | .IR mode . | |
208 | Thus, for example, "wb+" has the desired effect, but "w+b" does not. | |
209 | This is inconsistent with the treatment of | |
210 | .\" http://sourceware.org/bugzilla/show_bug.cgi?id=12836 | |
211 | .IR mode | |
212 | by | |
213 | .BR fopen (3). | |
847e0d88 | 214 | .PP |
1e9eb6c1 MK |
215 | Binary mode was removed in glibc 2.22; a \(aqb\(aq specified in |
216 | .I mode | |
217 | has no effect. | |
28c1dc49 | 218 | .SH BUGS |
39ef79ba | 219 | In versions of glibc before 2.22, if |
8154f292 MK |
220 | .I size |
221 | is specified as zero, | |
222 | .BR fmemopen () | |
223 | fails with the error | |
224 | .BR EINVAL . | |
39ef79ba | 225 | .\" http://sourceware.org/bugzilla/show_bug.cgi?id=11216 |
8154f292 | 226 | It would be more consistent if this case successfully created |
ddef8b95 | 227 | a stream that then returned end-of-file on the first attempt at reading; |
39ef79ba | 228 | since version 2.22, the glibc implementation provides that behavior. |
847e0d88 | 229 | .PP |
39ef79ba MK |
230 | In versions of glibc before 2.22, |
231 | specifying append mode ("a" or "a+") for | |
8f60b371 | 232 | .BR fmemopen () |
36ad3781 | 233 | sets the initial buffer position to the first null byte, but |
39ef79ba | 234 | .\" http://sourceware.org/bugzilla/show_bug.cgi?id=13152 |
ddef8b95 | 235 | (if the current position is reset to a location other than |
8f60b371 MK |
236 | the end of the stream) |
237 | does not force subsequent writes to append at the end of the stream. | |
39ef79ba | 238 | This bug is fixed in glibc 2.22. |
847e0d88 | 239 | .PP |
39ef79ba | 240 | In versions of glibc before 2.22, if the |
005e6bb8 MK |
241 | .I mode |
242 | argument to | |
243 | .BR fmemopen () | |
244 | specifies append ("a" or "a+"), and the | |
245 | .I size | |
246 | argument does not cover a null byte in | |
21fe8eeb | 247 | .IR buf , |
005e6bb8 | 248 | then, according to POSIX.1-2008, |
36ad3781 | 249 | the initial buffer position should be set to |
005e6bb8 MK |
250 | the next byte after the end of the buffer. |
251 | However, in this case the glibc | |
39ef79ba | 252 | .\" http://sourceware.org/bugzilla/show_bug.cgi?id=13151 |
005e6bb8 | 253 | .BR fmemopen () |
36ad3781 | 254 | sets the buffer position to \-1. |
39ef79ba | 255 | This bug is fixed in glibc 2.22. |
847e0d88 | 256 | .PP |
9c048ec1 MK |
257 | In versions of glibc before 2.22, |
258 | .\" https://sourceware.org/bugzilla/show_bug.cgi?id=14292 | |
259 | when a call to | |
260 | .BR fseek (3) | |
261 | with a | |
262 | .I whence | |
263 | value of | |
264 | .B SEEK_END | |
265 | was performed on a stream created by | |
266 | .BR fmemopen (), | |
267 | the | |
268 | .I offset | |
269 | was | |
270 | .IR subtracted | |
271 | from the end-of-stream position, instead of being added. | |
272 | This bug is fixed in glibc 2.22. | |
847e0d88 | 273 | .PP |
84133057 MK |
274 | The glibc 2.9 addition of "binary" mode for |
275 | .BR fmemopen () | |
276 | .\" http://sourceware.org/bugzilla/show_bug.cgi?id=6544 | |
277 | silently changed the ABI: previously, | |
278 | .BR fmemopen () | |
279 | ignored \(aqb\(aq in | |
280 | .IR mode . | |
47297adb | 281 | .SH EXAMPLE |
c13182ef | 282 | The program below uses |
86cfe9cb MK |
283 | .BR fmemopen () |
284 | to open an input buffer, and | |
09ffd9ca | 285 | .BR open_memstream (3) |
86cfe9cb MK |
286 | to open a dynamically sized output buffer. |
287 | The program scans its input string (taken from the program's | |
288 | first command-line argument) reading integers, | |
289 | and writes the squares of these integers to the output buffer. | |
89c9a314 | 290 | An example of the output produced by this program is the following: |
e646a1ba | 291 | .PP |
54973458 | 292 | .in +4n |
e646a1ba | 293 | .EX |
b43a3b30 | 294 | .RB "$" " ./a.out \(aq1 23 43\(aq" |
86cfe9cb | 295 | size=11; ptr=1 529 1849 |
b8302363 | 296 | .EE |
54973458 | 297 | .in |
9c330504 | 298 | .SS Program source |
d84d0300 | 299 | \& |
e7d0bb47 | 300 | .EX |
86cfe9cb | 301 | #define _GNU_SOURCE |
86cfe9cb MK |
302 | #include <string.h> |
303 | #include <stdio.h> | |
304 | #include <stdlib.h> | |
305 | ||
d1a71985 | 306 | #define handle_error(msg) \e |
6a578b88 | 307 | do { perror(msg); exit(EXIT_FAILURE); } while (0) |
d3b5ab82 | 308 | |
c13182ef | 309 | int |
cf0a9ace | 310 | main(int argc, char *argv[]) |
86cfe9cb MK |
311 | { |
312 | FILE *out, *in; | |
313 | int v, s; | |
314 | size_t size; | |
315 | char *ptr; | |
316 | ||
6b34fb3f | 317 | if (argc != 2) { |
d1a71985 | 318 | fprintf(stderr, "Usage: %s \(aq<num>...\(aq\en", argv[0]); |
5a6194a4 | 319 | exit(EXIT_FAILURE); |
6b34fb3f | 320 | } |
86cfe9cb MK |
321 | |
322 | in = fmemopen(argv[1], strlen(argv[1]), "r"); | |
d3b5ab82 | 323 | if (in == NULL) |
6a578b88 | 324 | handle_error("fmemopen"); |
86cfe9cb MK |
325 | |
326 | out = open_memstream(&ptr, &size); | |
d3b5ab82 | 327 | if (out == NULL) |
84112433 | 328 | handle_error("open_memstream"); |
86cfe9cb MK |
329 | |
330 | for (;;) { | |
331 | s = fscanf(in, "%d", &v); | |
332 | if (s <= 0) | |
333 | break; | |
334 | ||
335 | s = fprintf(out, "%d ", v * v); | |
29059a65 | 336 | if (s == \-1) |
6a578b88 | 337 | handle_error("fprintf"); |
86cfe9cb | 338 | } |
2841079c | 339 | |
86cfe9cb MK |
340 | fclose(in); |
341 | fclose(out); | |
2841079c | 342 | |
d1a71985 | 343 | printf("size=%zu; ptr=%s\en", size, ptr); |
2841079c | 344 | |
86cfe9cb MK |
345 | free(ptr); |
346 | exit(EXIT_SUCCESS); | |
347 | } | |
e7d0bb47 | 348 | .EE |
47297adb | 349 | .SH SEE ALSO |
a5dbb527 | 350 | .BR fopen (3), |
b5a636d6 | 351 | .BR fopencookie (3), |
09ffd9ca | 352 | .BR open_memstream (3) |