NAME

fmemopen — open a memory buffer stream

SYNOPSIS

[CX] [Option Start] #include <stdio.h>

FILE *fmemopen(void *restrict
buf, size_t max_size,
       const char *restrict
mode); [Option End]

DESCRIPTION

The fmemopen() function shall associate the buffer given by the buf and max_size arguments with a stream. The buf argument shall be either a null pointer or point to a buffer that is at least max_size bytes long.

The mode argument points to a string. If the string is one of the following, the stream shall be opened in the indicated mode. Otherwise, the behavior is undefined.

r or rb
Open the stream for reading.
w or wb
Open the stream for writing.
a or ab
Append; open the stream for writing.
r+ or rb+ or r+b
Open the stream for update (reading and writing).
w+ or wb+ or w+b
Open the stream for update (reading and writing).
a+ or ab+ or a+b
Append; open the stream for update (reading and writing).

If the mode argument begins with 'w' and max_size is not zero, the buffer contents shall be truncated by writing a null byte at the beginning. If the mode argument includes 'b', the results are implementation-defined.

If a null pointer is specified as the buf argument, fmemopen() shall allocate max_size bytes of memory as if by a call to malloc(). This buffer shall be automatically freed when the stream is closed. Because this feature is only useful when the stream is opened for updating (because there is no way to get a pointer to the buffer) the fmemopen() call may fail if the mode argument does not include a '+'.

When a stream is opened for reading only and buf is not a null pointer, the buffer pointed to by buf shall not be modified by any operation performed on the stream.

The stream shall maintain a current position in the buffer. This position shall be initially set to either the beginning of the buffer (for r and w modes) or to the first null byte in the buffer (for a modes). If no null byte is found in append mode, the initial position shall be set to one byte after the end of the buffer.

If buf is a null pointer, the initial position shall always be set to the beginning of the buffer.

The stream shall also maintain the end position of the current buffer contents; use of fseek() or fseeko() on the stream with SEEK_END shall seek relative to this end position. If mode starts with 'r', the end position shall be set to the value given by the max_size argument and shall not change. Otherwise, the stream is writable and the end position shall be variable; for modes w and w+ the initial end position shall be zero and for modes a and a+ the initial end position shall be:

A read operation on the stream shall not advance the current buffer position beyond the current buffer end position. Reaching the buffer end position in a read operation shall count as "end-of-file". Null bytes in the buffer shall have no special meaning for reads. The read operation shall start at the current buffer position of the stream.

A write operation shall start either at the current position of the stream (if mode has not specified 'a' as the first character) or at the current end position of the stream (if mode had 'a' as the first character). If the current position at the end of the write is larger than the current buffer end position, the current buffer end position shall be set to the current position. A write operation on the stream shall not advance the current buffer end position beyond the size given in the max_size argument.

When a stream open for update (the mode argument includes '+') or for writing only is successfully written and the write advances the current buffer end position, a null byte shall be written at the new buffer end position if it fits.

An attempt to seek a memory buffer stream to a negative position or to a position larger than the buffer size given in the max_size argument shall fail.

RETURN VALUE

Upon successful completion, fmemopen() shall return a pointer to the object controlling the stream. Otherwise, a null pointer shall be returned, and errno shall be set to indicate the error.

ERRORS

The fmemopen() function shall fail if:

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

The fmemopen() function may fail if:

[EINVAL]
The value of the mode argument is not valid.
[EINVAL]
The buf argument is a null pointer and the mode argument does not include a '+' character.
[EINVAL]
The max_size argument specifies a buffer size of zero and the implementation does not support this.
[ENOMEM]
The buf argument is a null pointer and the allocation of a buffer of length max_size has failed.
[EMFILE]
{FOPEN_MAX} streams are currently open in the calling process.

The following sections are informative.

EXAMPLES

#include <stdio.h>
#include <string.h>

static char buffer[] = "foobar";
int main (void) { int ch; FILE *stream;
stream = fmemopen(buffer, strlen (buffer), "r"); if (stream == NULL) /* handle error */;
while ((ch = fgetc(stream)) != EOF) printf("Got %c\n", ch);
fclose(stream); return (0); }

This program produces the following output:

Got f
Got o
Got o
Got b
Got a
Got r

APPLICATION USAGE

Implementations differ as regards how a 'b' in the mode argument affects the behavior. For some the 'b' has no effect, as is required for fopen(); others distinguish between text and binary modes.

Note that buf will not be null terminated if max_size bytes are written to the memory stream. Applications wanting to guarantee that the buffer will be null terminated need to call fmemopen() with max_size set to one byte smaller than the actual size of buf and set buf[max_size] to a null byte.

This standard intentionally leaves the behavior of 'e' and 'x' in the mode argument undefined; implementations might silently ignore them so that fmemopen() may accept the same mode strings as fopen(), or may reject them as invalid.

RATIONALE

This interface has been introduced to eliminate many of the errors encountered in the construction of strings, notably overflowing of strings. This interface prevents overflow.

FUTURE DIRECTIONS

A future version of this standard may require support of zero-length buffer streams explicitly.

SEE ALSO

fdopen , fopen , freopen , fseek , malloc , open_memstream

XBD <stdio.h>

CHANGE HISTORY

First released in Issue 7.

POSIX.1-2008, Technical Corrigendum 1, XSH/TC1-2008/0142 [461], XSH/TC1-2008/0143 [396], XSH/TC1-2008/0144 [396], XSH/TC1-2008/0145 [461], XSH/TC1-2008/0146 [461], XSH/TC1-2008/0147 [461], XSH/TC1-2008/0148 [461], XSH/TC1-2008/0149 [461], and XSH/TC1-2008/0150 [396] are applied.

POSIX.1-2008, Technical Corrigendum 2, XSH/TC2-2008/0117 [587], XSH/TC2-2008/0118 [586,818], and XSH/TC2-2008/0119 [818] are applied.

Issue 8

Austin Group Defects 456 and 657 are applied, making the behavior implementation-defined when the mode argument includes 'b'.

Austin Group Defect 1144 is applied, adding a requirement that operations on streams opened for reading only do not modify the buffer pointed to by buf.

End of informative text.