diff options
author | mdf <mdf@FreeBSD.org> | 2010-09-09 17:49:18 +0000 |
---|---|---|
committer | mdf <mdf@FreeBSD.org> | 2010-09-09 17:49:18 +0000 |
commit | 73d2d3f18e68d936aadff54bb3b15b6dcc61e805 (patch) | |
tree | 6a93387cb5edf1079ae335b9e16743977276216d /share | |
parent | c35a7592ebf347e53345d160cdb932a094861810 (diff) | |
download | FreeBSD-src-73d2d3f18e68d936aadff54bb3b15b6dcc61e805.zip FreeBSD-src-73d2d3f18e68d936aadff54bb3b15b6dcc61e805.tar.gz |
Add drain functionality to sbufs. The drain is a function that is
called when the sbuf internal buffer is filled. For kernel sbufs with a
drain, the internal buffer will never be expanded. For userland sbufs
with a drain, the internal buffer may still be expanded by
sbuf_[v]printf(3).
Sbufs now have three basic uses:
1) static string manipulation. Overflow is marked.
2) dynamic string manipulation. Overflow triggers string growth.
3) drained string manipulation. Overflow triggers draining.
In all cases the manipulation is 'safe' in that overflow is detected and
managed.
Reviewed by: phk (the previous version)
Diffstat (limited to 'share')
-rw-r--r-- | share/man/man9/Makefile | 1 | ||||
-rw-r--r-- | share/man/man9/sbuf.9 | 106 |
2 files changed, 100 insertions, 7 deletions
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index e6d8881..6abafe1 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -1031,6 +1031,7 @@ MLINKS+=sbuf.9 sbuf_bcat.9 \ sbuf.9 sbuf_overflowed.9 \ sbuf.9 sbuf_printf.9 \ sbuf.9 sbuf_putc.9 \ + sbuf.9 sbuf_set_drain.9 \ sbuf.9 sbuf_setpos.9 \ sbuf.9 sbuf_trim.9 \ sbuf.9 sbuf_vprintf.9 diff --git a/share/man/man9/sbuf.9 b/share/man/man9/sbuf.9 index abe5831..7389064 100644 --- a/share/man/man9/sbuf.9 +++ b/share/man/man9/sbuf.9 @@ -43,6 +43,7 @@ .Nm sbuf_printf , .Nm sbuf_vprintf , .Nm sbuf_putc , +.Nm sbuf_set_drain , .Nm sbuf_trim , .Nm sbuf_overflowed , .Nm sbuf_finish , @@ -54,6 +55,8 @@ .Sh SYNOPSIS .In sys/types.h .In sys/sbuf.h +.Ft typedef\ int ( sbuf_drain_func ) ( void\ *arg, const\ char\ *data, int\ len ) ; +.Pp .Ft struct sbuf * .Fn sbuf_new "struct sbuf *s" "char *buf" "int length" "int flags" .Ft struct sbuf * @@ -80,11 +83,13 @@ .Fn sbuf_vprintf "struct sbuf *s" "const char *fmt" "va_list ap" .Ft int .Fn sbuf_putc "struct sbuf *s" "int c" +.Ft void +.Fn sbuf_set_drain "struct sbuf *s" "sbuf_drain_func *func" "void *arg" .Ft int .Fn sbuf_trim "struct sbuf *s" .Ft int .Fn sbuf_overflowed "struct sbuf *s" -.Ft void +.Ft int .Fn sbuf_finish "struct sbuf *s" .Ft char * .Fn sbuf_data "struct sbuf *s" @@ -224,6 +229,51 @@ to the 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 . +The returned drained length cannot be zero. +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_copyin , +.Fn sbuf_trim , +and +.Fn sbuf_data +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 @@ -289,10 +339,17 @@ overflowed. .Pp The .Fn sbuf_finish -function NUL-terminates the +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 -and marks it as finished, which means that it may no longer be -modified using +as finished, which means that it may no longer be modified using .Fn sbuf_setpos , .Fn sbuf_cat , .Fn sbuf_cpy , @@ -305,12 +362,21 @@ is used to reset the sbuf. .Pp The .Fn sbuf_data -and -.Fn sbuf_len -functions return the actual string and its length, respectively; +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. .Fn sbuf_done returns non-zero if the .Fa sbuf @@ -329,6 +395,22 @@ 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 @@ -372,6 +454,14 @@ The function returns \-1 if copying string from userland failed, and number of bytes copied otherwise. +The +.Fn sbuf_finish +function returns ENOMEM if the sbuf overflowed before being finished, +or returns the error code from the drain if one is attached. +When used as +.Xr sbuf_finish 3 , +.Fn sbuf_finish +will return \-1 and set errno on error instead. .Sh SEE ALSO .Xr printf 3 , .Xr strcat 3 , @@ -396,6 +486,8 @@ Additional improvements were suggested by .An Justin T. Gibbs Aq gibbs@FreeBSD.org . Auto-extend support added by .An Kelly Yancey Aq kbyanc@FreeBSD.org . +Drain functionality added by +.An Matthew Fleming Aq mdf@FreeBSD.org . .Pp This manual page was written by .An Dag-Erling Sm\(/orgrav Aq des@FreeBSD.org . |