NAME
fmemopen — open a
memory buffer stream
SYNOPSIS
FILE *fmemopen(void *restrict buf, size_t max_size,
const char *restrict mode);
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(3). 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(3) or
fseeko(3) 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:
- Zero, if buf is a null pointer
- The position of the first null byte in the buffer, if one is found
- The value of the max_size argument, if buf is not a null pointer and no null byte is found
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.
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(3); 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(3), 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(3), fopen(3), freopen(3), fseek(3), malloc(3), open_memstream(3)
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.