FMEMOPEN(3C) | Standard C Library Functions | FMEMOPEN(3C) |
fmemopen
— open a
memory stream
#include
<stdio.h>
FILE *
fmemopen
(void *restrict buf,
size_t size, const char *restrict
mode);
The
fmemopen
()
function provides a means of associating a file stream with a corresponding
memory buffer of a fixed size. The resulting stream can then be used just
like any other stream, and when done should be released by calling the
fclose(3C) function.
The stream can either dynamically allocate memory or it can use an
existing memory buffer. If buf is
NULL
, then a buffer size bytes
long will be allocated for the stream and initialized to zero. This buffer
will be allocated as though a call to
malloc(3C) and will be freed when
fclose(3C) is called. When using this
mode, the stream must be created for update (indicated by a
‘+’ character in the mode argument).
Otherwise, it is assumed that buf is at least
size bytes long.
The mode argument determines whether the stream is opened for read, write, or append. The mode argument accepts all the same values as fopen(3C).
The resulting stream behaves in a similar way to a stream backed by a file. The stream can be read and written to. The stream is seekable and can either be byte or wide-character oriented. A NUL byte has no special meaning when reading.
The stream logically tracks three different values:
The current position is where reads or writes take place. When the stream is opened for read or write (r, r+, w, w+) then the initial position is set to zero. If the stream is opened for update (a, a+) then the initial position is set to the first NUL byte in the buffer.
The current size of the stream represents the length of the stream. Like a file, this starts at a specific size and then can grow over time. Unlike a file, where the maximum size is determined by the file system, the maximum size here is determined at the creation of the stream.
This size is used when using SEEK_END
as
an argument to functions like
fseek(3C). Reads cannot advance beyond
the current size of the stream and attempting to read beyond it is
considered hitting the end-of-file. Writes beyond the end of the current
size will cause the current size to increase, though it cannot increase
beyond the maximum size.
The initial size of the stream varies. It is set depending on the mode and works as follows:
NULL
pointer, the current size is set to zero.The maximum size of the stream is determined by the size argument. Writes beyond this size are dropped. Attempts to seek beyond the maximum size will result in an error.
If the stream was open for writing or update, when the stream is flushed or closed, a NUL byte will be written to terminate the stream based on the current position and size of the stream. If the stream was open for update, if the stream is flushed or closed and the last write changed the current buffer size, a NUL byte will be written if there is still space for it within the buffer.
By default, all streams are buffered. This means that writes beyond the size of the memory buffer could fail, but not be seen until the stream is flushed or closed. To detect errors right away, one can explicitly disable buffering with the setvbuf(3C) function or perform explicit buffer flushes with the fflush(3C) function.
Upon successful completion, the fmemopen
()
function returns a pointer to a stream. Otherwise,
NULL
is returned and errno
is set to indicate the error.
The fmemopen
() function will fail if:
EINVAL
The size argument was zero.
The buf argument is
NULL
and the mode argument
does not contain a ‘+’ character.
EMFILE
{STREAM_MAX} streams are currently open in the calling process.
ENOMEM
fclose(3C), fflush(3C), fopen(3C), fseek(3C), malloc(3C), open_memstream(3C)
February 17, 2023 | OmniOS |