fopencookie
—open a stream with custom callbacks#include <stdio.h> FILE *fopencookie(const void *cookie, const char *mode, cookie_io_functions_t functions);
Description
fopencookie
creates a FILE
stream where I/O is performed using
custom callbacks. The callbacks are registered via the structure:
typedef ssize_t (*cookie_read_function_t)(void *_cookie, char *_buf, size_t _n); typedef ssize_t (*cookie_write_function_t)(void *_cookie, const char *_buf, size_t _n); typedef int (*cookie_seek_function_t)(void *_cookie, off_t *_off, int _whence); typedef int (*cookie_close_function_t)(void *_cookie);
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;
The stream is opened with mode treated as in fopen
. The
callbacks functions.read and functions.write may only be NULL
when mode does not require them.
functions.read should return -1 on failure, or else the number of
bytes read (0 on EOF). It is similar to read
, except that
cookie will be passed as the first argument.
functions.write should return -1 on failure, or else the number of
bytes written. It is similar to write
, except that cookie
will be passed as the first argument.
functions.seek should return -1 on failure, and 0 on success, with
_off set to the current file position. It is a cross between
lseek
and fseek
, with the _whence argument interpreted in
the same manner. A NULL functions.seek makes the stream behave
similarly to a pipe in relation to stdio functions that require
positioning.
functions.close should return -1 on failure, or 0 on success. It
is similar to close
, except that cookie will be passed as the
first argument. A NULL functions.close merely flushes all data
then lets fclose
succeed. A failed close will still invalidate
the stream.
Read and write I/O functions are allowed to change the underlying
buffer on fully buffered or line buffered streams by calling
setvbuf
. They are also not required to completely fill or empty
the buffer. They are not, however, allowed to change streams from
unbuffered to buffered or to change the state of the line buffering
flag. They must also be prepared to have read or write calls occur on
buffers other than the one most recently specified.
Returns
NULL
is returned, and errno
will be set to EINVAL if a
function pointer is missing or mode is invalid, ENOMEM if the
stream cannot be created, or EMFILE if too many streams are already
open.
Portability
funopen
interface from BSD.
Supporting OS subroutines required: sbrk
.