summaryrefslogtreecommitdiffstats
path: root/man3/fmemopen.3
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--man3/fmemopen.3353
1 files changed, 353 insertions, 0 deletions
diff --git a/man3/fmemopen.3 b/man3/fmemopen.3
new file mode 100644
index 0000000..081a33f
--- /dev/null
+++ b/man3/fmemopen.3
@@ -0,0 +1,353 @@
+'\" t
+.\" Copyright 2005, 2012, 2016 Michael Kerrisk <mtk.manpages@gmail.com>
+.\"
+.\" SPDX-License-Identifier: GPL-1.0-or-later
+.\"
+.TH fmemopen 3 2023-07-20 "Linux man-pages 6.05.01"
+.SH NAME
+fmemopen \- open memory as stream
+.SH LIBRARY
+Standard C library
+.RI ( libc ", " \-lc )
+.SH SYNOPSIS
+.nf
+.B #include <stdio.h>
+.PP
+.BI "FILE *fmemopen(void " buf [. size "], size_t " size ", \
+const char *" mode );
+.fi
+.PP
+.RS -4
+Feature Test Macro Requirements for glibc (see
+.BR feature_test_macros (7)):
+.RE
+.PP
+.BR fmemopen ():
+.nf
+ Since glibc 2.10:
+ _POSIX_C_SOURCE >= 200809L
+ Before glibc 2.10:
+ _GNU_SOURCE
+.fi
+.SH DESCRIPTION
+The
+.BR fmemopen ()
+function opens a stream that permits the access specified by
+.IR mode .
+The stream allows I/O to be performed on the string or memory buffer
+pointed to by
+.IR buf .
+.PP
+The
+.I mode
+argument specifies the semantics of I/O on the stream,
+and is one of the following:
+.TP
+.I r
+The stream is opened for reading.
+.TP
+.I w
+The stream is opened for writing.
+.TP
+.I a
+Append; open the stream for writing,
+with the initial buffer position set to the first null byte.
+.TP
+.I r+
+Open the stream for reading and writing.
+.TP
+.I w+
+Open the stream for reading and writing.
+The buffer contents are truncated
+(i.e., \[aq]\e0\[aq] is placed in the first byte of the buffer).
+.TP
+.I a+
+Append; open the stream for reading and writing,
+with the initial buffer position set to the first null byte.
+.PP
+The stream maintains the notion of a current position,
+the location where the next I/O operation will be performed.
+The current position is implicitly updated by I/O operations.
+It can be explicitly updated using
+.BR fseek (3),
+and determined using
+.BR ftell (3).
+In all modes other than append,
+the initial position is set to the start of the buffer.
+In append mode, if no null byte is found within the buffer,
+then the initial position is
+.IR size+1 .
+.PP
+If
+.I buf
+is specified as NULL, then
+.BR fmemopen ()
+allocates a buffer of
+.I size
+bytes.
+This is useful for an application that wants to write data to
+a temporary buffer and then read it back again.
+The initial position is set to the start of the buffer.
+The buffer is automatically freed when the stream is closed.
+Note that the caller has no way to obtain a pointer to the
+temporary buffer allocated by this call (but see
+.BR open_memstream (3)).
+.PP
+If
+.I buf
+is not NULL, then it should point to a buffer of at least
+.I size
+bytes allocated by the caller.
+.PP
+When a stream that has been opened for writing is flushed
+.RB ( fflush (3))
+or closed
+.RB ( fclose (3)),
+a null byte is written at the end of the buffer if there is space.
+The caller should ensure that an extra byte is available in the
+buffer
+(and that
+.I size
+counts that byte)
+to allow for this.
+.PP
+In a stream opened for reading,
+null bytes (\[aq]\e0\[aq]) in the buffer do not cause read
+operations to return an end-of-file indication.
+A read from the buffer will indicate end-of-file
+only when the current buffer position advances
+.I size
+bytes past the start of the buffer.
+.PP
+Write operations take place either at the current position
+(for modes other than append), or at the current size of the stream
+(for append modes).
+.PP
+Attempts to write more than
+.I size
+bytes to the buffer result in an error.
+By default, such errors will be visible
+(by the absence of data) only when the
+.I stdio
+buffer is flushed.
+Disabling buffering with the following call
+may be useful to detect errors at the time of an output operation:
+.PP
+.in +4n
+.EX
+setbuf(stream, NULL);
+.EE
+.in
+.SH RETURN VALUE
+Upon successful completion,
+.BR fmemopen ()
+returns a
+.I FILE
+pointer.
+Otherwise, NULL is returned and
+.I errno
+is set to indicate the error.
+.SH ATTRIBUTES
+For an explanation of the terms used in this section, see
+.BR attributes (7).
+.TS
+allbox;
+lbx lb lb
+l l l.
+Interface Attribute Value
+T{
+.na
+.nh
+.BR fmemopen (),
+T} Thread safety MT-Safe
+.TE
+.sp 1
+.SH STANDARDS
+POSIX.1-2008.
+.SH HISTORY
+glibc 1.0.x.
+POSIX.1-2008.
+.PP
+POSIX.1-2008 specifies that \[aq]b\[aq] in
+.I mode
+shall be ignored.
+However, Technical Corrigendum 1
+.\" http://austingroupbugs.net/view.php?id=396
+adjusts the standard to allow implementation-specific treatment for this case,
+thus permitting the glibc treatment of \[aq]b\[aq].
+.PP
+With glibc 2.22, binary mode (see below) was removed,
+many longstanding bugs in the implementation of
+.BR fmemopen ()
+were fixed, and a new versioned symbol was created for this interface.
+.\"
+.SS Binary mode
+From glibc 2.9 to glibc 2.21, the glibc implementation of
+.BR fmemopen ()
+supported a "binary" mode,
+enabled by specifying the letter \[aq]b\[aq] as the second character in
+.IR mode .
+In this mode,
+writes don't implicitly add a terminating null byte, and
+.BR fseek (3)
+.B SEEK_END
+is relative to the end of the buffer (i.e., the value specified by the
+.I size
+argument), rather than the current string length.
+.PP
+An API bug afflicted the implementation of binary mode:
+to specify binary mode, the \[aq]b\[aq] must be the
+.I second
+character in
+.IR mode .
+Thus, for example, "wb+" has the desired effect, but "w+b" does not.
+This is inconsistent with the treatment of
+.\" http://sourceware.org/bugzilla/show_bug.cgi?id=12836
+.I mode
+by
+.BR fopen (3).
+.PP
+Binary mode was removed in glibc 2.22; a \[aq]b\[aq] specified in
+.I mode
+has no effect.
+.SH NOTES
+There is no file descriptor associated with the file stream
+returned by this function
+(i.e.,
+.BR fileno (3)
+will return an error if called on the returned stream).
+.SH BUGS
+Before glibc 2.22, if
+.I size
+is specified as zero,
+.BR fmemopen ()
+fails with the error
+.BR EINVAL .
+.\" http://sourceware.org/bugzilla/show_bug.cgi?id=11216
+It would be more consistent if this case successfully created
+a stream that then returned end-of-file on the first attempt at reading;
+since glibc 2.22, the glibc implementation provides that behavior.
+.PP
+Before glibc 2.22,
+specifying append mode ("a" or "a+") for
+.BR fmemopen ()
+sets the initial buffer position to the first null byte, but
+.\" http://sourceware.org/bugzilla/show_bug.cgi?id=13152
+(if the current position is reset to a location other than
+the end of the stream)
+does not force subsequent writes to append at the end of the stream.
+This bug is fixed in glibc 2.22.
+.PP
+Before glibc 2.22, if the
+.I mode
+argument to
+.BR fmemopen ()
+specifies append ("a" or "a+"), and the
+.I size
+argument does not cover a null byte in
+.IR buf ,
+then, according to POSIX.1-2008,
+the initial buffer position should be set to
+the next byte after the end of the buffer.
+However, in this case the glibc
+.\" http://sourceware.org/bugzilla/show_bug.cgi?id=13151
+.BR fmemopen ()
+sets the buffer position to \-1.
+This bug is fixed in glibc 2.22.
+.PP
+Before glibc 2.22,
+.\" https://sourceware.org/bugzilla/show_bug.cgi?id=14292
+when a call to
+.BR fseek (3)
+with a
+.I whence
+value of
+.B SEEK_END
+was performed on a stream created by
+.BR fmemopen (),
+the
+.I offset
+was
+.I subtracted
+from the end-of-stream position, instead of being added.
+This bug is fixed in glibc 2.22.
+.PP
+The glibc 2.9 addition of "binary" mode for
+.BR fmemopen ()
+.\" http://sourceware.org/bugzilla/show_bug.cgi?id=6544
+silently changed the ABI: previously,
+.BR fmemopen ()
+ignored \[aq]b\[aq] in
+.IR mode .
+.SH EXAMPLES
+The program below uses
+.BR fmemopen ()
+to open an input buffer, and
+.BR open_memstream (3)
+to open a dynamically sized output buffer.
+The program scans its input string (taken from the program's
+first command-line argument) reading integers,
+and writes the squares of these integers to the output buffer.
+An example of the output produced by this program is the following:
+.PP
+.in +4n
+.EX
+.RB "$" " ./a.out \[aq]1 23 43\[aq]"
+size=11; ptr=1 529 1849
+.EE
+.in
+.SS Program source
+\&
+.\" SRC BEGIN (fmemopen.c)
+.EX
+#define _GNU_SOURCE
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+\&
+int
+main(int argc, char *argv[])
+{
+ FILE *out, *in;
+ int v, s;
+ size_t size;
+ char *ptr;
+\&
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s \[aq]<num>...\[aq]\en", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+\&
+ in = fmemopen(argv[1], strlen(argv[1]), "r");
+ if (in == NULL)
+ err(EXIT_FAILURE, "fmemopen");
+\&
+ out = open_memstream(&ptr, &size);
+ if (out == NULL)
+ err(EXIT_FAILURE, "open_memstream");
+\&
+ for (;;) {
+ s = fscanf(in, "%d", &v);
+ if (s <= 0)
+ break;
+\&
+ s = fprintf(out, "%d ", v * v);
+ if (s == \-1)
+ err(EXIT_FAILURE, "fprintf");
+ }
+\&
+ fclose(in);
+ fclose(out);
+\&
+ printf("size=%zu; ptr=%s\en", size, ptr);
+\&
+ free(ptr);
+ exit(EXIT_SUCCESS);
+}
+.EE
+.\" SRC END
+.SH SEE ALSO
+.BR fopen (3),
+.BR fopencookie (3),
+.BR open_memstream (3)