diff options
Diffstat (limited to 'static/freebsd/man9/sbuf.9')
| -rw-r--r-- | static/freebsd/man9/sbuf.9 | 769 |
1 files changed, 769 insertions, 0 deletions
diff --git a/static/freebsd/man9/sbuf.9 b/static/freebsd/man9/sbuf.9 new file mode 100644 index 00000000..d4ffa050 --- /dev/null +++ b/static/freebsd/man9/sbuf.9 @@ -0,0 +1,769 @@ +.\"- +.\" Copyright (c) 2000 Poul-Henning Kamp and Dag-Erling Smørgrav +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd October 3, 2023 +.Dt SBUF 9 +.Os +.Sh NAME +.Nm sbuf , +.Nm sbuf_new , +.Nm sbuf_new_auto , +.Nm sbuf_new_for_sysctl , +.Nm sbuf_clear , +.Nm sbuf_get_flags , +.Nm sbuf_set_flags , +.Nm sbuf_clear_flags , +.Nm sbuf_setpos , +.Nm sbuf_bcat , +.Nm sbuf_bcopyin , +.Nm sbuf_bcpy , +.Nm sbuf_cat , +.Nm sbuf_copyin , +.Nm sbuf_cpy , +.Nm sbuf_nl_terminate , +.Nm sbuf_printf , +.Nm sbuf_vprintf , +.Nm sbuf_putc , +.Nm sbuf_set_drain , +.Nm sbuf_trim , +.Nm sbuf_error , +.Nm sbuf_finish , +.Nm sbuf_data , +.Nm sbuf_len , +.Nm sbuf_done , +.Nm sbuf_delete , +.Nm sbuf_start_section , +.Nm sbuf_end_section , +.Nm sbuf_hexdump , +.Nm sbuf_printf_drain , +.Nm sbuf_putbuf +.Nd safe string composition +.Sh LIBRARY +.Lb libsbuf +.Sh SYNOPSIS +.In sys/types.h +.In sys/sbuf.h +.Ft typedef int +.Fo (sbuf_drain_func) +.Fa "void *arg" +.Fa "const char *data" +.Fa "int len" +.Fc +.Pp +.Ft struct sbuf * +.Fo sbuf_new +.Fa "struct sbuf *s" +.Fa "char *buf" +.Fa "int length" +.Fa "int flags" +.Fc +.Ft struct sbuf * +.Fo sbuf_new_auto +.Fa "void" +.Fc +.Ft void +.Fo sbuf_clear +.Fa "struct sbuf *s" +.Fc +.Ft int +.Fo sbuf_get_flags +.Fa "struct sbuf *s" +.Fc +.Ft void +.Fo sbuf_set_flags +.Fa "struct sbuf *s" +.Fa "int flags" +.Fc +.Ft void +.Fo sbuf_clear_flags +.Fa "struct sbuf *s" +.Fa "int flags" +.Fc +.Ft int +.Fo sbuf_setpos +.Fa "struct sbuf *s" +.Fa "int pos" +.Fc +.Ft int +.Fo sbuf_bcat +.Fa "struct sbuf *s" +.Fa "const void *buf" +.Fa "size_t len" +.Fc +.Ft int +.Fo sbuf_bcpy +.Fa "struct sbuf *s" +.Fa "const void *buf" +.Fa "size_t len" +.Fc +.Ft int +.Fo sbuf_cat +.Fa "struct sbuf *s" +.Fa "const char *str" +.Fc +.Ft int +.Fo sbuf_cpy +.Fa "struct sbuf *s" +.Fa "const char *str" +.Fc +.Ft int +.Fn sbuf_nl_terminate "struct sbuf *" +.Ft int +.Fo sbuf_printf +.Fa "struct sbuf *s" +.Fa "const char *fmt" "..." +.Fc +.Ft int +.Fo sbuf_vprintf +.Fa "struct sbuf *s" +.Fa "const char *fmt" +.Fa "va_list ap" +.Fc +.Ft int +.Fo sbuf_putc +.Fa "struct sbuf *s" +.Fa "int c" +.Fc +.Ft void +.Fo sbuf_set_drain +.Fa "struct sbuf *s" +.Fa "sbuf_drain_func *func" +.Fa "void *arg" +.Fc +.Ft int +.Fo sbuf_trim +.Fa "struct sbuf *s" +.Fc +.Ft int +.Fo sbuf_error +.Fa "struct sbuf *s" +.Fc +.Ft int +.Fo sbuf_finish +.Fa "struct sbuf *s" +.Fc +.Ft char * +.Fo sbuf_data +.Fa "struct sbuf *s" +.Fc +.Ft ssize_t +.Fo sbuf_len +.Fa "struct sbuf *s" +.Fc +.Ft int +.Fo sbuf_done +.Fa "struct sbuf *s" +.Fc +.Ft void +.Fo sbuf_delete +.Fa "struct sbuf *s" +.Fc +.Ft void +.Fo sbuf_start_section +.Fa "struct sbuf *s" +.Fa "ssize_t *old_lenp" +.Fc +.Ft ssize_t +.Fo sbuf_end_section +.Fa "struct sbuf *s" +.Fa "ssize_t old_len" +.Fa "size_t pad" +.Fa "int c" +.Fc +.Ft void +.Fo sbuf_hexdump +.Fa "struct sbuf *sb" +.Fa "void *ptr" +.Fa "int length" +.Fa "const char *hdr" +.Fa "int flags" +.Fc +.Ft int +.Fo sbuf_printf_drain +.Fa "void *arg" +.Fa "const char *data" +.Fa "int len" +.Fc +.Ft void +.Fo sbuf_putbuf +.Fa "struct sbuf *s" +.Fc +.Fd #ifdef _KERNEL +.In sys/types.h +.In sys/sbuf.h +.Ft int +.Fo sbuf_bcopyin +.Fa "struct sbuf *s" +.Fa "const void *uaddr" +.Fa "size_t len" +.Fc +.Ft int +.Fo sbuf_copyin +.Fa "struct sbuf *s" +.Fa "const void *uaddr" +.Fa "size_t len" +.Fc +.In sys/sysctl.h +.Ft struct sbuf * +.Fo sbuf_new_for_sysctl +.Fa "struct sbuf *s" +.Fa "char *buf" +.Fa "int length" +.Fa "struct sysctl_req *req" +.Fc +.Fd #endif /* _KERNEL */ +.Sh DESCRIPTION +The +.Nm +family of functions allows one to safely allocate, compose and +release strings in kernel or user space. +.Pp +Instead of arrays of characters, these functions operate on structures +called +.Fa sbufs , +defined in +.In sys/sbuf.h . +.Pp +Any errors encountered during the allocation or composition of the +string will be latched in the data structure, +making a single error test at the end of the composition +sufficient to determine success or failure of the entire process. +.Pp +The +.Fn sbuf_new +function initializes the +.Fa sbuf +pointed to by its first argument. +If that pointer is +.Dv NULL , +.Fn sbuf_new +allocates a +.Vt struct sbuf +using +.Xr malloc 9 . +The +.Fa buf +argument is a pointer to a buffer in which to store the actual string; +if it is +.Dv NULL , +.Fn sbuf_new +will allocate one using +.Xr malloc 9 . +The +.Fa length +is the initial size of the storage buffer. +The fourth argument, +.Fa flags , +may be comprised of the following flags: +.Bl -tag -width ".Dv SBUF_AUTOEXTEND" +.It Dv SBUF_FIXEDLEN +The storage buffer is fixed at its initial size. +Attempting to extend the sbuf beyond this size results in an overflow condition. +.It Dv SBUF_AUTOEXTEND +This indicates that the storage buffer may be extended as necessary, so long +as resources allow, to hold additional data. +.It Dv SBUF_INCLUDENUL +This causes the final nulterm byte to be counted in the length of the data. +.It Dv SBUF_DRAINTOEOR +Treat top-level sections started with +.Fn sbuf_start_section +as a record boundary marker that will be used during drain operations to avoid +records being split. +If a record grows sufficiently large such that it fills the +.Fa sbuf +and therefore cannot be drained without being split, an error of +.Er EDEADLK +is set. +.It Dv SBUF_NOWAIT +Indicates that attempts to extend the storage buffer should fail in low memory +conditions, like +.Xr malloc 9 +.Dv M_NOWAIT . +.El +.Pp +Note that if +.Fa buf +is not +.Dv NULL , +it must point to an array of at least +.Fa length +characters. +The result of accessing that array directly while it is in use by the +sbuf is undefined. +.Pp +The +.Fn sbuf_new_auto +function is a shortcut for creating a completely dynamic +.Nm . +It is the equivalent of calling +.Fn sbuf_new +with values +.Dv NULL , +.Dv NULL , +.Dv 0 , +and +.Dv SBUF_AUTOEXTEND . +.Pp +The +.Fn sbuf_new_for_sysctl +function will set up an sbuf with a drain function to use +.Fn SYSCTL_OUT +when the internal buffer fills. +Note that if the various functions which append to an sbuf are used while +a non-sleepable lock is held, the user buffer should be wired using +.Fn sysctl_wire_old_buffer . +.Pp +The +.Fn sbuf_delete +function clears the +.Fa sbuf +and frees any memory allocated for it. +There must be a call to +.Fn sbuf_delete +for every call to +.Fn sbuf_new . +Any attempt to access the sbuf after it has been deleted will fail. +.Pp +The +.Fn sbuf_clear +function invalidates the contents of the +.Fa sbuf +and resets its position to zero. +.Pp +The +.Fn sbuf_get_flags +function returns the current user flags. +The +.Fn sbuf_set_flags +and +.Fn sbuf_clear_flags +functions set or clear one or more user flags, respectively. +The user flags are described under the +.Fn sbuf_new +function. +.Pp +The +.Fn sbuf_setpos +function sets the +.Fa sbuf Ns 's +end position to +.Fa pos , +which is a value between zero and the current position in the buffer. +It can only truncate the sbuf to the new position. +.Pp +The +.Fn sbuf_bcat +function appends the first +.Fa len +bytes from the buffer +.Fa buf +to the +.Fa sbuf . +.Pp +The +.Fn sbuf_bcopyin +function copies +.Fa len +bytes from the specified userland address into the +.Fa sbuf . +.Pp +The +.Fn sbuf_bcpy +function replaces the contents of the +.Fa sbuf +with the first +.Fa len +bytes from the buffer +.Fa buf . +.Pp +The +.Fn sbuf_cat +function appends the NUL-terminated string +.Fa str +to the +.Fa sbuf +at the current position. +.Pp +The +.Fn sbuf_set_drain +function sets a drain function +.Fa func +for the +.Fa sbuf , +and records a pointer +.Fa arg +to be passed to the drain on callback. +The drain function cannot be changed while +.Fa sbuf_len +is non-zero. +.Pp +The registered drain function +.Vt sbuf_drain_func +will be called with the argument +.Fa arg +provided to +.Fn sbuf_set_drain , +a pointer +.Fa data +to a byte string that is the contents of the sbuf, and the length +.Fa len +of the data. +If the drain function exists, it will be called when the sbuf internal +buffer is full, or on behalf of +.Fn sbuf_finish . +The drain function may drain some or all of the data, but must drain +at least 1 byte. +The return value from the drain function, if positive, indicates how +many bytes were drained. +If negative, the return value indicates the negative error code which +will be returned from this or a later call to +.Fn sbuf_finish . +If the returned drained length is 0, an error of +.Er EDEADLK +is set. +To do unbuffered draining, initialize the sbuf with a two-byte buffer. +The drain will be called for every byte added to the sbuf. +The +.Fn sbuf_bcopyin , +.Fn sbuf_bcpy , +.Fn sbuf_clear , +.Fn sbuf_copyin , +.Fn sbuf_cpy , +.Fn sbuf_trim , +.Fn sbuf_data , +and +.Fn sbuf_len +functions cannot be used on an sbuf with a drain. +.Pp +The +.Fn sbuf_copyin +function copies a NUL-terminated string from the specified userland +address into the +.Fa sbuf . +If the +.Fa len +argument is non-zero, no more than +.Fa len +characters (not counting the terminating NUL) are copied; otherwise +the entire string, or as much of it as can fit in the +.Fa sbuf , +is copied. +.Pp +The +.Fn sbuf_cpy +function replaces the contents of the +.Fa sbuf +with those of the NUL-terminated string +.Fa str . +This is equivalent to calling +.Fn sbuf_cat +with a fresh +.Fa sbuf +or one which position has been reset to zero with +.Fn sbuf_clear +or +.Fn sbuf_setpos . +.Pp +The +.Fn sbuf_nl_terminate +function appends a trailing newline character, if the current line is non-empty +and not already terminated by a newline character. +.Pp +The +.Fn sbuf_printf +function formats its arguments according to the format string pointed +to by +.Fa fmt +and appends the resulting string to the +.Fa sbuf +at the current position. +.Pp +The +.Fn sbuf_vprintf +function behaves the same as +.Fn sbuf_printf +except that the arguments are obtained from the variable-length argument list +.Fa ap . +.Pp +The +.Fn sbuf_putc +function appends the character +.Fa c +to the +.Fa sbuf +at the current position. +.Pp +The +.Fn sbuf_trim +function removes trailing whitespace from the +.Fa sbuf . +.Pp +The +.Fn sbuf_error +function returns any error value that the +.Fa sbuf +may have accumulated, either from the drain function, or +.Er ENOMEM +if the +.Fa sbuf +overflowed. +This function is generally not needed and instead the error code from +.Fn sbuf_finish +is the preferred way to discover whether an sbuf had an error. +.Pp +The +.Fn sbuf_finish +function will call the attached drain function if one exists until all +the data in the +.Fa sbuf +is flushed. +If there is no attached drain, +.Fn sbuf_finish +NUL-terminates the +.Fa sbuf . +In either case it marks the +.Fa sbuf +as finished, which means that it may no longer be modified using +.Fn sbuf_setpos , +.Fn sbuf_cat , +.Fn sbuf_cpy , +.Fn sbuf_printf +or +.Fn sbuf_putc , +until +.Fn sbuf_clear +is used to reset the sbuf. +.Pp +The +.Fn sbuf_data +function returns the actual string; +.Fn sbuf_data +only works on a finished +.Fa sbuf . +The +.Fn sbuf_len +function returns the length of the string. +For an +.Fa sbuf +with an attached drain, +.Fn sbuf_len +returns the length of the un-drained data. +.Fn sbuf_done +returns non-zero if the +.Fa sbuf +is finished. +.Pp +The +.Fn sbuf_start_section +and +.Fn sbuf_end_section +functions may be used for automatic section alignment. +The arguments +.Fa pad +and +.Fa c +specify the padding size and a character used for padding. +The arguments +.Fa old_lenp +and +.Fa old_len +are to save and restore the current section length when nested sections +are used. +For the top level section +.Dv NULL +and \-1 can be specified for +.Fa old_lenp +and +.Fa old_len +respectively. +.Pp +The +.Fn sbuf_hexdump +function prints an array of bytes to the supplied sbuf, along with an ASCII +representation of the bytes if possible. +See the +.Xr hexdump 3 +man page for more details on the interface. +.Pp +The +.Fn sbuf_printf_drain +function is a drain function that will call printf, or log to the console. +The argument +.Fa arg +must be either +.Dv NULL , +or a valid pointer to a +.Vt size_t . +If +.Fa arg +is not +.Dv NULL , +the total bytes drained will be added to the value pointed to by +.Fa arg . +.Pp +The +.Fn sbuf_putbuf +function printfs the sbuf to stdout if in userland, and to the console +and log if in the kernel. +The +.Fa sbuf +must be finished before calling +.Fn sbuf_putbuf . +It does not drain the buffer or update any pointers. +.Sh NOTES +If an operation caused an +.Fa sbuf +to overflow, most subsequent operations on it will fail until the +.Fa sbuf +is finished using +.Fn sbuf_finish +or reset using +.Fn sbuf_clear , +or its position is reset to a value between 0 and one less than the +size of its storage buffer using +.Fn sbuf_setpos , +or it is reinitialized to a sufficiently short string using +.Fn sbuf_cpy . +.Pp +Drains in user-space will not always function as indicated. +While the drain function will be called immediately on overflow from +the +.Fa sbuf_putc , +.Fa sbuf_bcat , +.Fa sbuf_cat +functions, +.Fa sbuf_printf +and +.Fa sbuf_vprintf +currently have no way to determine whether there will be an overflow +until after it occurs, and cannot do a partial expansion of the format +string. +Thus when using libsbuf the buffer may be extended to allow completion +of a single printf call, even though a drain is attached. +.Sh RETURN VALUES +The +.Fn sbuf_new +function returns +.Dv NULL +if it failed to allocate a storage buffer, and a pointer to the new +.Fa sbuf +otherwise. +.Pp +The +.Fn sbuf_setpos +function returns \-1 if +.Fa pos +was invalid, and zero otherwise. +.Pp +The +.Fn sbuf_bcat , +.Fn sbuf_cat , +.Fn sbuf_cpy , +.Fn sbuf_printf , +.Fn sbuf_putc , +and +.Fn sbuf_trim +functions +all return \-1 if the buffer overflowed, and zero otherwise. +.Pp +The +.Fn sbuf_error +function returns a non-zero value if the buffer has an overflow or +drain error, and zero otherwise. +.Pp +The +.Fn sbuf_len +function returns \-1 if the buffer overflowed. +.Pp +The +.Fn sbuf_copyin +function +returns \-1 if copying string from userland failed, and number of bytes +copied otherwise. +.Pp +The +.Fn sbuf_end_section +function returns the section length or \-1 if the buffer has an error. +.Pp +The +.Fn sbuf_finish 9 +function (the kernel version) returns +.Er ENOMEM +if the sbuf overflowed before being finished, +or returns the error code from the drain if one is attached. +.Pp +The +.Fn sbuf_finish 3 +function (the userland version) +will return zero for success and \-1 and set errno on error. +.Sh EXAMPLES +.Bd -literal -compact +#include <sys/types.h> +#include <sys/sbuf.h> + +struct sbuf *sb; + +sb = sbuf_new_auto(); +sbuf_cat(sb, "Customers found:\en"); +TAILQ_FOREACH(foo, &foolist, list) { + sbuf_printf(sb, " %4d %s\en", foo->index, foo->name); + sbuf_printf(sb, " Address: %s\en", foo->address); + sbuf_printf(sb, " Zip: %s\en", foo->zipcode); +} +if (sbuf_finish(sb) != 0) /* Check for any and all errors */ + err(1, "Could not generate message"); +transmit_msg(sbuf_data(sb), sbuf_len(sb)); +sbuf_delete(sb); +.Ed +.Sh SEE ALSO +.Xr hexdump 3 , +.Xr printf 3 , +.Xr strcat 3 , +.Xr strcpy 3 , +.Xr copyin 9 , +.Xr copyinstr 9 , +.Xr printf 9 +.Sh HISTORY +The +.Nm +family of functions first appeared in +.Fx 4.4 . +.Sh AUTHORS +.An -nosplit +The +.Nm +family of functions was designed by +.An Poul-Henning Kamp Aq Mt phk@FreeBSD.org +and implemented by +.An Dag-Erling Sm\(/orgrav Aq Mt des@FreeBSD.org . +Additional improvements were suggested by +.An Justin T. Gibbs Aq Mt gibbs@FreeBSD.org . +Auto-extend support added by +.An Kelly Yancey Aq Mt kbyanc@FreeBSD.org . +Drain functionality added by +.An Matthew Fleming Aq Mt mdf@FreeBSD.org . +.Pp +This manual page was written by +.An Dag-Erling Sm\(/orgrav Aq Mt des@FreeBSD.org . |
