/*++ /* NAME /* vstream 3 /* SUMMARY /* light-weight buffered I/O package /* SYNOPSIS /* #include <vstream.h> /* /* VSTREAM *vstream_fopen(path, flags, mode) /* const char *path; /* int flags; /* mode_t mode; /* /* VSTREAM *vstream_fdopen(fd, flags) /* int fd; /* int flags; /* /* VSTREAM *vstream_memopen(string, flags) /* VSTRING *string; /* int flags; /* /* VSTREAM *vstream_memreopen(stream, string, flags) /* VSTREAM *stream; /* VSTRING *string; /* int flags; /* /* int vstream_fclose(stream) /* VSTREAM *stream; /* /* int vstream_fdclose(stream) /* VSTREAM *stream; /* /* VSTREAM *vstream_printf(format, ...) /* const char *format; /* /* VSTREAM *vstream_fprintf(stream, format, ...) /* VSTREAM *stream; /* const char *format; /* /* int VSTREAM_GETC(stream) /* VSTREAM *stream; /* /* int VSTREAM_PUTC(ch, stream) /* int ch; /* /* int VSTREAM_GETCHAR(void) /* /* int VSTREAM_PUTCHAR(ch) /* int ch; /* /* int vstream_ungetc(stream, ch) /* VSTREAM *stream; /* int ch; /* /* int vstream_fputs(str, stream) /* const char *str; /* VSTREAM *stream; /* /* off_t vstream_ftell(stream) /* VSTREAM *stream; /* /* off_t vstream_fseek(stream, offset, whence) /* VSTREAM *stream; /* off_t offset; /* int whence; /* /* int vstream_fflush(stream) /* VSTREAM *stream; /* /* int vstream_fpurge(stream, direction) /* VSTREAM *stream; /* int direction; /* /* ssize_t vstream_fread(stream, buf, len) /* VSTREAM *stream; /* void *buf; /* ssize_t len; /* /* ssize_t vstream_fwrite(stream, buf, len) /* VSTREAM *stream; /* void *buf; /* ssize_t len; /* /* ssize_t vstream_fread_app(stream, buf, len) /* VSTREAM *stream; /* VSTRING *buf; /* ssize_t len; /* /* ssize_t vstream_fread_buf(stream, buf, len) /* VSTREAM *stream; /* VSTRING *buf; /* ssize_t len; /* /* void vstream_control(stream, name, ...) /* VSTREAM *stream; /* int name; /* /* int vstream_fileno(stream) /* VSTREAM *stream; /* /* const ssize_t vstream_req_bufsize(stream) /* VSTREAM *stream; /* /* void *vstream_context(stream) /* VSTREAM *stream; /* /* int vstream_ferror(stream) /* VSTREAM *stream; /* /* int vstream_ftimeout(stream) /* VSTREAM *stream; /* /* int vstream_feof(stream) /* VSTREAM *stream; /* /* int vstream_clearerr(stream) /* VSTREAM *stream; /* /* const char *VSTREAM_PATH(stream) /* VSTREAM *stream; /* /* char *vstream_vprintf(format, ap) /* const char *format; /* va_list *ap; /* /* char *vstream_vfprintf(stream, format, ap) /* VSTREAM *stream; /* const char *format; /* va_list *ap; /* /* ssize_t vstream_bufstat(stream, command) /* VSTREAM *stream; /* int command; /* /* ssize_t vstream_peek(stream) /* VSTREAM *stream; /* /* const char *vstream_peek_data(stream) /* VSTREAM *stream; /* /* int vstream_setjmp(stream) /* VSTREAM *stream; /* /* void vstream_longjmp(stream, val) /* VSTREAM *stream; /* int val; /* /* time_t vstream_ftime(stream) /* VSTREAM *stream; /* /* struct timeval vstream_ftimeval(stream) /* VSTREAM *stream; /* /* int vstream_rd_error(stream) /* VSTREAM *stream; /* /* int vstream_wr_error(stream) /* VSTREAM *stream; /* /* int vstream_rd_timeout(stream) /* VSTREAM *stream; /* /* int vstream_wr_timeout(stream) /* VSTREAM *stream; /* /* int vstream_fstat(stream, flags) /* VSTREAM *stream; /* int flags; /* /* void vstream_no_debug(stream) /* VSTREAM *stream; /* DESCRIPTION /* The \fIvstream\fR module implements light-weight buffered I/O /* similar to the standard I/O routines. /* /* The interface is implemented in terms of VSTREAM structure /* pointers, also called streams. For convenience, three streams /* are predefined: VSTREAM_IN, VSTREAM_OUT, and VSTREAM_ERR. These /* streams are connected to the standard input, output and error /* file descriptors, respectively. /* /* Although the interface is patterned after the standard I/O /* library, there are some major differences: /* .IP \(bu /* File descriptors are not limited to the range 0..255. This /* was reason #1 to write these routines in the first place. /* .IP \(bu /* The application can switch between reading and writing on /* the same stream without having to perform a flush or seek /* operation, and can change write position without having to /* flush. This was reason #2. Upon position or direction change, /* unread input is discarded, and unwritten output is flushed /* automatically. Exception: with double-buffered streams, unread /* input is not discarded upon change of I/O direction, and /* output flushing is delayed until the read buffer must be refilled. /* .IP \(bu /* A bidirectional stream can read and write with the same buffer /* and file descriptor, or it can have separate read/write /* buffers and/or file descriptors. /* .IP \(bu /* No automatic flushing of VSTREAM_OUT upon program exit, or of /* VSTREAM_ERR at any time. No unbuffered or line buffered modes. /* This functionality may be added when it is really needed. /* .PP /* vstream_fopen() opens the named file and associates a buffered /* stream with it. The \fIpath\fR, \fIflags\fR and \fImode\fR /* arguments are passed on to the open(2) routine. The result is /* a null pointer in case of problems. The \fIpath\fR argument is /* copied and can be looked up with VSTREAM_PATH(). /* /* vstream_fdopen() takes an open file and associates a buffered /* stream with it. The \fIflags\fR argument specifies how the file /* was opened. vstream_fdopen() either succeeds or never returns. /* /* vstream_memopen() opens a VSTRING as a stream. The \fIflags\fR /* argument must specify one of O_RDONLY, O_WRONLY, or O_APPEND. /* vstream_memopen() either succeeds or never returns. Streams /* opened with vstream_memopen() have limitations: they can't /* be opened in read/write mode, they can't seek beyond the /* end of the VSTRING, and they don't support vstream_control() /* methods that manipulate buffers, file descriptors, or I/O /* functions. After a VSTRING is opened for writing, its content /* will be in an indeterminate state while the stream is open, /* and will be null-terminated when the stream is closed. /* /* vstream_memreopen() reopens a memory stream. When the /* \fIstream\fR argument is a null pointer, the behavior is that /* of vstream_memopen(). /* /* vstream_fclose() closes the named buffered stream. The result /* is 0 in case of success, VSTREAM_EOF in case of problems. /* vstream_fclose() reports the same errors as vstream_ferror(). /* /* vstream_fdclose() leaves the file(s) open but is otherwise /* identical to vstream_fclose(). /* /* vstream_fprintf() formats its arguments according to the /* \fIformat\fR argument and writes the result to the named stream. /* The result is the stream argument. It understands the s, c, d, u, /* o, x, X, e, f and g format types, the l modifier, field width and /* precision, sign, and padding with zeros or spaces. In addition, /* vstream_fprintf() recognizes the %m format specifier and expands /* it to the error message corresponding to the current value of the /* global \fIerrno\fR variable. /* /* vstream_printf() performs formatted output to the standard output /* stream. /* /* VSTREAM_GETC() reads the next character from the named stream. /* The result is VSTREAM_EOF when end-of-file is reached or if a read /* error was detected. VSTREAM_GETC() is an unsafe macro that /* evaluates some arguments more than once. /* /* VSTREAM_GETCHAR() is an alias for VSTREAM_GETC(VSTREAM_IN). /* /* VSTREAM_PUTC() appends the specified character to the specified /* stream. The result is the stored character, or VSTREAM_EOF in /* case of problems. VSTREAM_PUTC() is an unsafe macro that /* evaluates some arguments more than once. /* /* VSTREAM_PUTCHAR(c) is an alias for VSTREAM_PUTC(c, VSTREAM_OUT). /* /* vstream_ungetc() pushes back a character onto the specified stream /* and returns the character, or VSTREAM_EOF in case of problems. /* It is an error to push back before reading (or immediately after /* changing the stream offset via vstream_fseek()). Upon successful /* return, vstream_ungetc() clears the end-of-file stream flag. /* /* vstream_fputs() appends the given null-terminated string to the /* specified buffered stream. The result is 0 in case of success, /* VSTREAM_EOF in case of problems. /* /* vstream_ftell() returns the file offset for the specified stream, /* -1 if the stream is connected to a non-seekable file. /* /* vstream_fseek() changes the file position for the next read or write /* operation. Unwritten output is flushed. With unidirectional streams, /* unread input is discarded. The \fIoffset\fR argument specifies the file /* position from the beginning of the file (\fIwhence\fR is SEEK_SET), /* from the current file position (\fIwhence\fR is SEEK_CUR), or from /* the file end (SEEK_END). The result value is the file offset /* from the beginning of the file, -1 in case of problems. /* /* vstream_fflush() flushes unwritten data to a file that was /* opened in read-write or write-only mode. /* vstream_fflush() returns 0 in case of success, VSTREAM_EOF in /* case of problems. It is an error to flush a read-only stream. /* vstream_fflush() reports the same errors as vstream_ferror(). /* /* vstream_fpurge() discards the contents of the stream buffer. /* If direction is VSTREAM_PURGE_READ, it discards unread data, /* else if direction is VSTREAM_PURGE_WRITE, it discards unwritten /* data. In the case of a double-buffered stream, if direction is /* VSTREAM_PURGE_BOTH, it discards the content of both the read /* and write buffers. vstream_fpurge() returns 0 in case of success, /* VSTREAM_EOF in case of problems. /* /* vstream_fread() and vstream_fwrite() perform unformatted I/O /* on the named stream. The result value is the number of bytes /* transferred. A short count is returned in case of end-of-file /* or error conditions. /* /* vstream_fread_buf() resets the buffer write position, /* allocates space for the specified number of bytes in the /* buffer, reads the bytes from the specified VSTREAM, and /* adjusts the buffer write position. The buffer is NOT /* null-terminated. The result value is as with vstream_fread(). /* NOTE: do not skip calling vstream_fread_buf() when len == 0. /* This function has side effects including resetting the buffer /* write position, and skipping the call would invalidate the /* buffer state. /* /* vstream_fread_app() is like vstream_fread_buf() but appends /* to existing buffer content, instead of writing over it. /* /* vstream_control() allows the user to fine tune the behavior of /* the specified stream. The arguments are a list of macros with /* zero or more arguments, terminated with CA_VSTREAM_CTL_END /* which has none. The following lists the names and the types /* of the corresponding value arguments. /* .IP "CA_VSTREAM_CTL_READ_FN(ssize_t (*)(int, void *, size_t, int, void *))" /* The argument specifies an alternative for the timed_read(3) function, /* for example, a read function that performs decryption. /* This function receives as arguments a file descriptor, buffer pointer, /* buffer length, timeout value, and the VSTREAM's context value. /* A timeout value <= 0 disables the time limit. /* This function should return the positive number of bytes transferred, /* 0 upon EOF, and -1 upon error with errno set appropriately. /* .IP "CA_VSTREAM_CTL_WRITE_FN(ssize_t (*)(int, void *, size_t, int, void *))" /* The argument specifies an alternative for the timed_write(3) function, /* for example, a write function that performs encryption. /* This function receives as arguments a file descriptor, buffer pointer, /* buffer length, timeout value, and the VSTREAM's context value. /* A timeout value <= 0 disables the time limit. /* This function should return the positive number of bytes transferred, /* and -1 upon error with errno set appropriately. Instead of -1 it may /* also return 0, e.g., upon remote party-initiated protocol shutdown. /* .IP "CA_VSTREAM_CTL_CONTEXT(void *)" /* The argument specifies application context that is passed on to /* the application-specified read/write routines. No copy is made. /* .IP "CA_VSTREAM_CTL_PATH(const char *)" /* Updates the stored pathname of the specified stream. The pathname /* is copied. /* .IP "CA_VSTREAM_CTL_DOUBLE (no arguments)" /* Use separate buffers for reading and for writing. This prevents /* unread input from being discarded upon change of I/O direction. /* .IP "CA_VSTREAM_CTL_READ_FD(int)" /* The argument specifies the file descriptor to be used for reading. /* This feature is limited to double-buffered streams, and makes the /* stream non-seekable. /* .IP "CA_VSTREAM_CTL_WRITE_FD(int)" /* The argument specifies the file descriptor to be used for writing. /* This feature is limited to double-buffered streams, and makes the /* stream non-seekable. /* .IP "CA_VSTREAM_CTL_SWAP_FD(VSTREAM *)" /* The argument specifies a VSTREAM pointer; the request swaps the /* file descriptor members of the two streams. This feature is limited /* to streams that are both double-buffered or both single-buffered. /* .IP "CA_VSTREAM_CTL_DUPFD(int)" /* The argument specifies a minimum file descriptor value. If /* the actual stream's file descriptors are below the minimum, /* reallocate the descriptors to the first free value greater /* than or equal to the minimum. The VSTREAM_CTL_DUPFD macro /* is defined only on systems with fcntl() F_DUPFD support. /* .IP "CA_VSTREAM_CTL_WAITPID_FN(int (*)(pid_t, WAIT_STATUS_T *, int))" /* A pointer to function that behaves like waitpid(). This information /* is used by the vstream_pclose() routine. /* .IP "CA_VSTREAM_CTL_TIMEOUT(int)" /* The deadline for a descriptor to become readable in case of a read /* request, or writable in case of a write request. Specify a value /* of 0 to disable deadlines. /* .IP "CA_VSTREAM_CTL_EXCEPT (no arguments)" /* Enable exception handling with vstream_setjmp() and vstream_longjmp(). /* This involves allocation of additional memory that normally isn't /* used. /* .IP "CA_VSTREAM_CTL_BUFSIZE(ssize_t)" /* Specify a non-default buffer size for the next read(2) or /* write(2) operation, or zero to implement a no-op. Requests /* to reduce the buffer size are silently ignored (i.e. any /* positive value <= vstream_req_bufsize()). To get a buffer /* size smaller than VSTREAM_BUFSIZE, make the VSTREAM_CTL_BUFSIZE /* request before the first stream read or write operation /* (i.e., vstream_req_bufsize() returns zero). Requests to /* change a fixed-size buffer (i.e., VSTREAM_ERR) are not /* allowed. /* /* NOTE: the vstream_*printf() routines may silently expand a /* buffer, so that the result of some %letter specifiers can /* be written to contiguous memory. /* .IP CA_VSTREAM_CTL_START_DEADLINE (no arguments) /* Change the VSTREAM_CTL_TIMEOUT behavior, to a deadline for /* the total amount of time for all subsequent file descriptor /* read or write operations, and recharge the deadline timer. /* .IP CA_VSTREAM_CTL_STOP_DEADLINE (no arguments) /* Revert VSTREAM_CTL_TIMEOUT behavior to the default, i.e. /* a time limit for individual file descriptor read or write /* operations. /* .IP CA_VSTREAM_CTL_MIN_DATA_RATE (int) /* When the DEADLINE is enabled, the amount of data that must /* be transferred to add 1 second to the deadline. However, /* the deadline will never exceed the timeout specified with /* VSTREAM_CTL_TIMEOUT. A zero value requests no update to the /* deadline as data is transferred; that is appropriate for /* request/reply interactions. /* .IP CA_VSTREAM_CTL_OWN_VSTRING (no arguments) /* Transfer ownership of the VSTRING that was opened with /* vstream_memopen() etc. to the stream, so that the VSTRING /* is automatically destroyed when the stream is closed. /* .PP /* vstream_fileno() gives access to the file handle associated with /* a buffered stream. With streams that have separate read/write /* file descriptors, the result is the current descriptor. /* /* vstream_req_bufsize() returns the buffer size that will be /* used for the next read(2) or write(2) operation on the named /* stream. A zero result means that the next read(2) or write(2) /* operation will use the default buffer size (VSTREAM_BUFSIZE). /* /* vstream_context() returns the application context that is passed on to /* the application-specified read/write routines. /* /* VSTREAM_PATH() is an unsafe macro that returns the name stored /* with vstream_fopen() or with vstream_control(). The macro is /* unsafe because it evaluates some arguments more than once. /* /* vstream_feof() returns non-zero when a previous operation on the /* specified stream caused an end-of-file condition. /* Although further read requests after EOF may complete /* successfully, vstream_feof() will keep returning non-zero /* until vstream_clearerr() is called for that stream. /* /* vstream_ferror() returns non-zero when a previous operation on the /* specified stream caused a non-EOF error condition, including timeout. /* After a non-EOF error on a stream, no I/O request will /* complete until after vstream_clearerr() is called for that stream. /* /* vstream_ftimeout() returns non-zero when a previous operation on the /* specified stream caused a timeout error condition. See /* vstream_ferror() for error persistence details. /* /* vstream_clearerr() resets the timeout, error and end-of-file indication /* of the specified stream, and returns no useful result. /* /* vstream_vfprintf() provides an alternate interface /* for formatting an argument list according to a format string. /* /* vstream_vprintf() provides a similar alternative interface. /* /* vstream_bufstat() provides input and output buffer status /* information. The command is one of the following: /* .IP VSTREAM_BST_IN_PEND /* Return the number of characters that can be read without /* refilling the read buffer. /* .IP VSTREAM_BST_OUT_PEND /* Return the number of characters that are waiting in the /* write buffer. /* .PP /* vstream_peek() returns the number of characters that can be /* read from the named stream without refilling the read buffer. /* This is an alias for vstream_bufstat(stream, VSTREAM_BST_IN_PEND). /* /* vstream_peek_data() returns a pointer to the unread bytes /* that exist according to vstream_peek(), or null if no unread /* bytes are available. /* /* vstream_setjmp() saves processing context and makes that context /* available for use with vstream_longjmp(). Normally, vstream_setjmp() /* returns zero. A non-zero result means that vstream_setjmp() returned /* through a vstream_longjmp() call; the result is the \fIval\fR argument /* given to vstream_longjmp(). /* /* NB: non-local jumps such as vstream_longjmp() are not safe /* for jumping out of any routine that manipulates VSTREAM data. /* longjmp() like calls are best avoided in signal handlers. /* /* vstream_ftime() returns the time of initialization, the last buffer /* fill operation, or the last buffer flush operation for the specified /* stream. This information is maintained only when stream timeouts are /* enabled. /* /* vstream_ftimeval() is like vstream_ftime() but returns more /* detail. /* /* vstream_rd_mumble() and vstream_wr_mumble() report on /* read and write error conditions, respectively. /* /* vstream_fstat() queries stream status information about /* user-requested features. The \fIflags\fR argument is the /* bitwise OR of one or more of the following, and the result /* value is the bitwise OR of the features that are activated. /* .IP VSTREAM_FLAG_DEADLINE /* The deadline feature is activated. /* .IP VSTREAM_FLAG_DOUBLE /* The double-buffering feature is activated. /* .IP VSTREAM_FLAG_MEMORY /* The stream is connected to a VSTRING buffer. /* .IP VSTREAM_FLAG_OWN_VSTRING /* The stream 'owns' the VSTRING buffer, and is responsible /* for cleaning up when the stream is closed. /* /* vstream_no_debug() disables 'spontaneous' logging of output /* activity on the last specified VSTREAM, to prevent recursive /* logging. /* DIAGNOSTICS /* Panics: interface violations. Fatal errors: out of memory. /* SEE ALSO /* timed_read(3) default read routine /* timed_write(3) default write routine /* vbuf_print(3) formatting engine /* setjmp(3) non-local jumps /* BUGS /* Should use mmap() on reasonable systems. /* LICENSE /* .ad /* .fi /* The Secure Mailer license must be distributed with this software. /* AUTHOR(S) /* Wietse Venema /* IBM T.J. Watson Research /* P.O. Box 704 /* Yorktown Heights, NY 10598, USA /* /* Wietse Venema /* Google, Inc. /* 111 8th Avenue /* New York, NY 10011, USA
/*--*/
/* vstream_fpurge - discard unread or unwritten content */
int vstream_fpurge(VSTREAM *stream, int direction)
{ constchar *myname = "vstream_fpurge";
VBUF *bp = &stream->buf;
#define VSTREAM_MAYBE_PURGE_WRITE(d, b) if ((d) & VSTREAM_PURGE_WRITE) \
VSTREAM_BUF_AT_START((b)) #define VSTREAM_MAYBE_PURGE_READ(d, b) if ((d) & VSTREAM_PURGE_READ) \
VSTREAM_BUF_AT_END((b))
/* *Todiscardallunreadcontents,positionthereadbufferatitsend, *sothatweskipoveranyunreaddata,andsothatthenextread *operationwillrefillthebuffer. * *Todiscardallunwrittencontent,positionthewritebufferatits *beginning,sothatthenextwriteoperationclobbersanyunwritten *data.
*/ switch (bp->flags & (VSTREAM_FLAG_READ_DOUBLE | VSTREAM_FLAG_WRITE)) { case VSTREAM_FLAG_READ_DOUBLE:
VSTREAM_MAYBE_PURGE_WRITE(direction, &stream->write_buf); /* FALLTHROUGH */ case VSTREAM_FLAG_READ:
VSTREAM_MAYBE_PURGE_READ(direction, bp); break; case VSTREAM_FLAG_DOUBLE:
VSTREAM_MAYBE_PURGE_WRITE(direction, &stream->write_buf);
VSTREAM_MAYBE_PURGE_READ(direction, &stream->read_buf); break; case VSTREAM_FLAG_WRITE_DOUBLE:
VSTREAM_MAYBE_PURGE_READ(direction, &stream->read_buf); /* FALLTHROUGH */ case VSTREAM_FLAG_WRITE:
VSTREAM_MAYBE_PURGE_WRITE(direction, bp); break; case VSTREAM_FLAG_READ_DOUBLE | VSTREAM_FLAG_WRITE: case VSTREAM_FLAG_READ | VSTREAM_FLAG_WRITE:
msg_panic("%s: read/write stream", myname);
}
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.34Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-08-09)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.