FMEMOPEN(3C) Standard C Library Functions FMEMOPEN(3C)

NAME


fmemopen - open a memory stream

SYNOPSIS


#include <stdio.h>

FILE *
fmemopen(void *restrict buf, size_t size, const char *restrict mode);

DESCRIPTION


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:

1. The current position in the stream.

2. The current size of the stream.

3. The maximum size of the stream.

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:

r, r+ The size is set to the size argument.

w, w+ The initial size is set to zero.

a, a+ The initial size is set according to the following rules:

1. If buf is a NULL pointer, the current size is set to
zero.

2. If a NUL byte is found in the first size bytes of buf,
then the current size is set to the first NUL byte.

3. The position is set to the size argument (the maximum
size) if no NUL byte was found in buf.

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.

RETURN VALUES


Upon successful completion, the fmemopen() function returns a pointer to a
stream. Otherwise, NULL is returned and errno is set to indicate the
error.

ERRORS


The fmemopen() function will fail if:

EINVAL The value of mode is invalid.

The size argument was zero.

The buf argument is NULL and the mode argument does not
contain a `+' character.

EMFILE {FOPEN_MAX} streams are currently open in the calling
process.

{STREAM_MAX} streams are currently open in the calling
process.

ENOMEM The system was unable to allocate memory for the stream
or its backing buffer.

MT-LEVEL
MT-Safe

INTERFACE STABILITY


Committed

SEE ALSO


fclose(3C), fflush(3C), fopen(3C), fseek(3C), malloc(3C),
open_memstream(3C)

illumos February 17, 2023 illumos