diff options
Diffstat (limited to '')
-rw-r--r-- | man3/fmemopen.3 | 353 |
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) |