summaryrefslogtreecommitdiffstats
path: root/man3/fopencookie.3
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-24 04:52:22 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-24 04:52:22 +0000
commit3d08cd331c1adcf0d917392f7e527b3f00511748 (patch)
tree312f0d1e1632f48862f044b8bb87e602dcffb5f9 /man3/fopencookie.3
parentAdding debian version 6.7-2. (diff)
downloadmanpages-3d08cd331c1adcf0d917392f7e527b3f00511748.tar.xz
manpages-3d08cd331c1adcf0d917392f7e527b3f00511748.zip
Merging upstream version 6.8.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'man3/fopencookie.3')
-rw-r--r--man3/fopencookie.3466
1 files changed, 0 insertions, 466 deletions
diff --git a/man3/fopencookie.3 b/man3/fopencookie.3
deleted file mode 100644
index 5d5d1d3..0000000
--- a/man3/fopencookie.3
+++ /dev/null
@@ -1,466 +0,0 @@
-'\" t
-.\" Copyright (c) 2008, Linux Foundation, written by Michael Kerrisk
-.\" <mtk.manpages@gmail.com>
-.\"
-.\" SPDX-License-Identifier: Linux-man-pages-copyleft
-.\"
-.TH fopencookie 3 2023-12-29 "Linux man-pages 6.7"
-.SH NAME
-fopencookie \- open a custom stream
-.SH LIBRARY
-Standard C library
-.RI ( libc ", " \-lc )
-.SH SYNOPSIS
-.nf
-.BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */"
-.B #define _FILE_OFFSET_BITS 64
-.B #include <stdio.h>
-.P
-.BI "FILE *fopencookie(void *restrict " cookie ", const char *restrict " mode ,
-.BI " cookie_io_functions_t " io_funcs );
-.fi
-.SH DESCRIPTION
-The
-.BR fopencookie ()
-function allows the programmer to create a custom implementation
-for a standard I/O stream.
-This implementation can store the stream's data at a location of
-its own choosing; for example,
-.BR fopencookie ()
-is used to implement
-.BR fmemopen (3),
-which provides a stream interface to data that is stored in a
-buffer in memory.
-.P
-In order to create a custom stream the programmer must:
-.IP \[bu] 3
-Implement four "hook" functions that are used internally by the
-standard I/O library when performing I/O on the stream.
-.IP \[bu]
-Define a "cookie" data type,
-a structure that provides bookkeeping information
-(e.g., where to store data) used by the aforementioned hook functions.
-The standard I/O package knows nothing about the contents of this cookie
-(thus it is typed as
-.I void\~*
-when passed to
-.BR fopencookie ()),
-but automatically supplies the cookie
-as the first argument when calling the hook functions.
-.IP \[bu]
-Call
-.BR fopencookie ()
-to open a new stream and associate the cookie and hook functions
-with that stream.
-.P
-The
-.BR fopencookie ()
-function serves a purpose similar to
-.BR fopen (3):
-it opens a new stream and returns a pointer to a
-.I FILE
-object that is used to operate on that stream.
-.P
-The
-.I cookie
-argument is a pointer to the caller's cookie structure
-that is to be associated with the new stream.
-This pointer is supplied as the first argument when the standard I/O
-library invokes any of the hook functions described below.
-.P
-The
-.I mode
-argument serves the same purpose as for
-.BR fopen (3).
-The following modes are supported:
-.IR r ,
-.IR w ,
-.IR a ,
-.IR r+ ,
-.IR w+ ,
-and
-.IR a+ .
-See
-.BR fopen (3)
-for details.
-.P
-The
-.I io_funcs
-argument is a structure that contains four fields pointing to the
-programmer-defined hook functions that are used to implement this stream.
-The structure is defined as follows
-.P
-.in +4n
-.EX
-typedef struct {
- cookie_read_function_t *read;
- cookie_write_function_t *write;
- cookie_seek_function_t *seek;
- cookie_close_function_t *close;
-} cookie_io_functions_t;
-.EE
-.in
-.P
-The four fields are as follows:
-.TP
-.I cookie_read_function_t *read
-This function implements read operations for the stream.
-When called, it receives three arguments:
-.IP
-.in +4n
-.EX
-ssize_t read(void *cookie, char *buf, size_t size);
-.EE
-.in
-.IP
-The
-.I buf
-and
-.I size
-arguments are, respectively,
-a buffer into which input data can be placed and the size of that buffer.
-As its function result, the
-.I read
-function should return the number of bytes copied into
-.IR buf ,
-0 on end of file, or \-1 on error.
-The
-.I read
-function should update the stream offset appropriately.
-.IP
-If
-.I *read
-is a null pointer,
-then reads from the custom stream always return end of file.
-.TP
-.I cookie_write_function_t *write
-This function implements write operations for the stream.
-When called, it receives three arguments:
-.IP
-.in +4n
-.EX
-ssize_t write(void *cookie, const char *buf, size_t size);
-.EE
-.in
-.IP
-The
-.I buf
-and
-.I size
-arguments are, respectively,
-a buffer of data to be output to the stream and the size of that buffer.
-As its function result, the
-.I write
-function should return the number of bytes copied from
-.IR buf ,
-or 0 on error.
-(The function must not return a negative value.)
-The
-.I write
-function should update the stream offset appropriately.
-.IP
-If
-.I *write
-is a null pointer,
-then output to the stream is discarded.
-.TP
-.I cookie_seek_function_t *seek
-This function implements seek operations on the stream.
-When called, it receives three arguments:
-.IP
-.in +4n
-.EX
-int seek(void *cookie, off_t *offset, int whence);
-.EE
-.in
-.IP
-The
-.I *offset
-argument specifies the new file offset depending on which
-of the following three values is supplied in
-.IR whence :
-.RS
-.TP
-.B SEEK_SET
-The stream offset should be set
-.I *offset
-bytes from the start of the stream.
-.TP
-.B SEEK_CUR
-.I *offset
-should be added to the current stream offset.
-.TP
-.B SEEK_END
-The stream offset should be set to the size of the stream plus
-.IR *offset .
-.RE
-.IP
-Before returning, the
-.I seek
-function should update
-.I *offset
-to indicate the new stream offset.
-.IP
-As its function result, the
-.I seek
-function should return 0 on success, and \-1 on error.
-.IP
-If
-.I *seek
-is a null pointer,
-then it is not possible to perform seek operations on the stream.
-.TP
-.I cookie_close_function_t *close
-This function closes the stream.
-The hook function can do things such as freeing buffers allocated
-for the stream.
-When called, it receives one argument:
-.IP
-.in +4n
-.EX
-int close(void *cookie);
-.EE
-.in
-.IP
-The
-.I cookie
-argument is the cookie that the programmer supplied when calling
-.BR fopencookie ().
-.IP
-As its function result, the
-.I close
-function should return 0 on success, and
-.B EOF
-on error.
-.IP
-If
-.I *close
-is NULL, then no special action is performed when the stream is closed.
-.SH RETURN VALUE
-On success
-.BR fopencookie ()
-returns a pointer to the new stream.
-On error, NULL is returned.
-.\" .SH ERRORS
-.\" It's not clear if errno ever gets set...
-.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 fopencookie ()
-T} Thread safety MT-Safe
-.TE
-.SH STANDARDS
-GNU.
-.SH EXAMPLES
-The program below implements a custom stream whose functionality
-is similar (but not identical) to that available via
-.BR fmemopen (3).
-It implements a stream whose data is stored in a memory buffer.
-The program writes its command-line arguments to the stream,
-and then seeks through the stream reading two out of every
-five characters and writing them to standard output.
-The following shell session demonstrates the use of the program:
-.P
-.in +4n
-.EX
-.RB "$" " ./a.out \[aq]hello world\[aq]"
-/he/
-/ w/
-/d/
-Reached end of file
-.EE
-.in
-.P
-Note that a more general version of the program below
-could be improved to more robustly handle various error situations
-(e.g., opening a stream with a cookie that already has an open stream;
-closing a stream that has already been closed).
-.SS Program source
-\&
-.\" SRC BEGIN (fopencookie.c)
-.EX
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-\&
-#define INIT_BUF_SIZE 4
-\&
-struct memfile_cookie {
- char *buf; /* Dynamically sized buffer for data */
- size_t allocated; /* Size of buf */
- size_t endpos; /* Number of characters in buf */
- off_t offset; /* Current file offset in buf */
-};
-\&
-ssize_t
-memfile_write(void *c, const char *buf, size_t size)
-{
- char *new_buff;
- struct memfile_cookie *cookie = c;
-\&
- /* Buffer too small? Keep doubling size until big enough. */
-\&
- while (size + cookie\->offset > cookie\->allocated) {
- new_buff = realloc(cookie\->buf, cookie\->allocated * 2);
- if (new_buff == NULL)
- return \-1;
- cookie\->allocated *= 2;
- cookie\->buf = new_buff;
- }
-\&
- memcpy(cookie\->buf + cookie\->offset, buf, size);
-\&
- cookie\->offset += size;
- if (cookie\->offset > cookie\->endpos)
- cookie\->endpos = cookie\->offset;
-\&
- return size;
-}
-\&
-ssize_t
-memfile_read(void *c, char *buf, size_t size)
-{
- ssize_t xbytes;
- struct memfile_cookie *cookie = c;
-\&
- /* Fetch minimum of bytes requested and bytes available. */
-\&
- xbytes = size;
- if (cookie\->offset + size > cookie\->endpos)
- xbytes = cookie\->endpos \- cookie\->offset;
- if (xbytes < 0) /* offset may be past endpos */
- xbytes = 0;
-\&
- memcpy(buf, cookie\->buf + cookie\->offset, xbytes);
-\&
- cookie\->offset += xbytes;
- return xbytes;
-}
-\&
-int
-memfile_seek(void *c, off_t *offset, int whence)
-{
- off_t new_offset;
- struct memfile_cookie *cookie = c;
-\&
- if (whence == SEEK_SET)
- new_offset = *offset;
- else if (whence == SEEK_END)
- new_offset = cookie\->endpos + *offset;
- else if (whence == SEEK_CUR)
- new_offset = cookie\->offset + *offset;
- else
- return \-1;
-\&
- if (new_offset < 0)
- return \-1;
-\&
- cookie\->offset = new_offset;
- *offset = new_offset;
- return 0;
-}
-\&
-int
-memfile_close(void *c)
-{
- struct memfile_cookie *cookie = c;
-\&
- free(cookie\->buf);
- cookie\->allocated = 0;
- cookie\->buf = NULL;
-\&
- return 0;
-}
-\&
-int
-main(int argc, char *argv[])
-{
- cookie_io_functions_t memfile_func = {
- .read = memfile_read,
- .write = memfile_write,
- .seek = memfile_seek,
- .close = memfile_close
- };
- FILE *stream;
- struct memfile_cookie mycookie;
- size_t nread;
- char buf[1000];
-\&
- /* Set up the cookie before calling fopencookie(). */
-\&
- mycookie.buf = malloc(INIT_BUF_SIZE);
- if (mycookie.buf == NULL) {
- perror("malloc");
- exit(EXIT_FAILURE);
- }
-\&
- mycookie.allocated = INIT_BUF_SIZE;
- mycookie.offset = 0;
- mycookie.endpos = 0;
-\&
- stream = fopencookie(&mycookie, "w+", memfile_func);
- if (stream == NULL) {
- perror("fopencookie");
- exit(EXIT_FAILURE);
- }
-\&
- /* Write command\-line arguments to our file. */
-\&
- for (size_t j = 1; j < argc; j++)
- if (fputs(argv[j], stream) == EOF) {
- perror("fputs");
- exit(EXIT_FAILURE);
- }
-\&
- /* Read two bytes out of every five, until EOF. */
-\&
- for (long p = 0; ; p += 5) {
- if (fseek(stream, p, SEEK_SET) == \-1) {
- perror("fseek");
- exit(EXIT_FAILURE);
- }
- nread = fread(buf, 1, 2, stream);
- if (nread == 0) {
- if (ferror(stream) != 0) {
- fprintf(stderr, "fread failed\en");
- exit(EXIT_FAILURE);
- }
- printf("Reached end of file\en");
- break;
- }
-\&
- printf("/%.*s/\en", (int) nread, buf);
- }
-\&
- free(mycookie.buf);
-\&
- exit(EXIT_SUCCESS);
-}
-.EE
-.\" SRC END
-.SH NOTES
-.B _FILE_OFFSET_BITS
-should be defined to be 64 in code that uses non-null
-.I seek
-or that takes the address of
-.BR fopencookie ,
-if the code is intended to be portable
-to traditional 32-bit x86 and ARM platforms where
-.BR off_t 's
-width defaults to 32 bits.
-.SH SEE ALSO
-.BR fclose (3),
-.BR fmemopen (3),
-.BR fopen (3),
-.BR fseek (3)