xref: /illumos-gate/usr/src/man/man3c/fmemopen.3c (revision 6446bd46ed1b4e9f69da153665f82181ccaedad5)
1.\"
2.\" This file and its contents are supplied under the terms of the
3.\" Common Development and Distribution License ("CDDL"), version 1.0.
4.\" You may only use this file in accordance with the terms of version
5.\" 1.0 of the CDDL.
6.\"
7.\" A full copy of the text of the CDDL should have accompanied this
8.\" source.  A copy of the CDDL is also available via the Internet at
9.\" http://www.illumos.org/license/CDDL.
10.\"
11.\"
12.\" Copyright 2020 Robert Mustacchi
13.\"
14.Dd March 25, 2020
15.Dt FMEMOPEN 3C
16.Os
17.Sh NAME
18.Nm fmemopen
19.Nd open a memory stream
20.Sh SYNOPSIS
21.In stdio.h
22.Ft "FILE *"
23.Fo fmemopen
24.Fa "void *restrict buf"
25.Fa "size_t size"
26.Fa "const char *restrict mode"
27.Fc
28.Sh DESCRIPTION
29The
30.Fn fmemopen
31function provides a means of associating a file stream with a
32corresponding memory buffer of a fixed size.
33The resulting stream can then be used just like any other stream, and
34when done should be released by calling the
35.Xr fclose 3C
36function.
37.Pp
38The stream can either dynamically allocate memory or it can use an
39existing memory buffer.
40If
41.Fa buf
42is
43.Dv NULL ,
44then a buffer
45.Fa size
46bytes long will be allocated for the stream and initialized to zero.
47This buffer will be allocated as though a call to
48.Xr malloc 3C
49and will be freed when
50.Xr fclose 3C
51is called.
52When using this mode, the stream must be created for update
53.Po
54indicated by a
55.Sq +
56character in the
57.Fa mode
58argument
59.Pc .
60Otherwise, it is assumed that
61.Fa buf
62is at least
63.Fa size
64bytes long.
65.Pp
66The
67.Fa mode
68argument determines whether the stream is opened for read, write, or
69append.
70The
71.Fa mode
72argument accepts all the same values as
73.Xr fopen 3C .
74.Pp
75The resulting stream behaves in a similar way to a stream backed by a
76file.
77The stream can be read and written to.
78The stream is seekeable and can either be byte or wide-character
79oriented.
80A NUL byte has no special meaning when reading.
81.Pp
82The stream logically tracks three different values:
83.Bl -enum -offset indent
84.It
85The current position in the stream.
86.It
87The current size of the stream.
88.It
89The maximum size of the stream.
90.El
91.Pp
92The current position is where reads or writes take place.
93When the stream is opened for read or write
94.Pq r, r+, w, w+
95then the initial position is set to zero.
96If the stream is opened for update
97.Pq a, a+
98then the initial position is set to the first NUL byte in the buffer.
99.Pp
100The current size of the stream represents the length of the stream.
101Like a file, this starts at a specific size and then can grow over time.
102Unlike a file, where the maximum size is determined by the file system,
103the maximum size here is determined at the creation of the stream.
104.Pp
105This size is used when using
106.Dv SEEK_END
107as an argument to functions like
108.Xr fseek 3C .
109Reads cannot advance beyond the current size of the stream and
110attempting to read beyond it is considered hitting the end-of-file.
111Writes beyond the end of the current size will cause the current size to
112increase, though it cannot increase beyond the maximum size.
113.Pp
114The initial size of the stream varies.
115It is set depending on the mode and works as follows:
116.Bl -tag -width Sy -offset indent
117.It Sy r, r+
118The size is set to the
119.Fa size
120argument.
121.It Sy w, w+
122The initial size is set to zero.
123.It Sy a, a+
124The initial size is set according to the following rules:
125.Bl -enum
126.It
127If
128.Fa buf
129is a
130.Dv NULL
131pointer, the current size is set to zero.
132.It
133If a NUL byte is found in the first
134.Fa size
135bytes of
136.Fa buf ,
137then the current size is set to the first NUL byte.
138.It
139The position is set to the
140.Fa size
141argument
142.Pq the maximum size
143if no NUL byte was found in
144.Fa buf .
145.El
146.El
147.Pp
148The maximum size of the stream is determined by the
149.Fa size
150argument.
151Writes beyond this size are dropped.
152Attempts to seek beyond the maximum size will result in an error.
153.Pp
154If the stream was open for writing or update, when the stream is flushed
155or closed, a NUL byte will be written to terminate the stream based on
156the current position and size of the stream.
157If the stream was open for update, if the stream is flushed or closed
158and the last write changed the current buffer size, a NUL byte will be
159written if there is still space for it within the buffer.
160.Pp
161By default, all streams are buffered.
162This means that writes beyond the size of the memory buffer could fail,
163but not be seen until the stream is flushed or closed.
164To detect errors right away, one can explicitly disable buffering with
165the
166.Xr setvbuf 3C
167function or perform explicit buffer flushes with the
168.Xr fflush 3C
169function.
170.Sh RETURN VALUES
171Upon successful completion, the
172.Fn fmemopen
173function returns a pointer to a stream.
174Otherwise,
175.Dv NULL
176is returned and
177.Dv errno
178is set to indicate the error.
179.Sh ERRORS
180The
181.Fn fmemopen
182function will fail if:
183.Bl -tag -width Er
184.It Er EINVAL
185The value of
186.Fa mode
187is invalid.
188.Pp
189The
190.Fa size
191argument was zero.
192.Pp
193The
194.Fa buf
195argument is
196.Dv NULL
197and the
198.Fa mode
199argument does not contain a
200.Sq +
201character.
202.It Er EMFILE
203.Brq FOPEN_MAX
204streams are currently open in the calling process.
205.Pp
206.Brq STREAM_MAX
207streams are currently open in the calling process.
208.It Er ENOMEM
209The system was unable to allocate memory for the stream or its backing
210buffer.
211.El
212.Sh MT-LEVEL
213.Sy MT-Safe
214.Sh INTERFACE STABILITY
215.Sy Committed
216.Sh SEE ALSO
217.Xr fclose 3C ,
218.Xr fflush 3C ,
219.Xr fopen 3C ,
220.Xr fseek 3C ,
221.Xr malloc 3C ,
222.Xr open_memstream 3C
223