diff options
-rw-r--r-- | share/man/man9/sbuf.9 | 14 | ||||
-rw-r--r-- | sys/dev/sound/pcm/sound.c | 2 | ||||
-rw-r--r-- | sys/kern/subr_sbuf.c | 28 | ||||
-rw-r--r-- | sys/sys/sbuf.h | 25 |
4 files changed, 46 insertions, 23 deletions
diff --git a/share/man/man9/sbuf.9 b/share/man/man9/sbuf.9 index 220bec6..6c5b112 100644 --- a/share/man/man9/sbuf.9 +++ b/share/man/man9/sbuf.9 @@ -45,7 +45,7 @@ .Sh SYNOPSIS .Fd #include <sys/types.h> .Fd #include <sys/sbuf.h> -.Ft int +.Ft struct sbuf *s .Fn sbuf_new "struct sbuf *s" "char *buf" "int length" "int flags" .Ft void .Fn sbuf_clear "struct sbuf *s" @@ -85,6 +85,13 @@ The function initializes the .Fa sbuf pointed to by its first argument. +If that pointer is +.Dv NULL , +.Fn sbuf_new +allocates a +.Fa struct sbuf +using +.Xr malloc 9 . The .Fa buf argument is a pointer to a buffer in which to store the actual string; @@ -213,7 +220,10 @@ or it is reinitialized to a sufficiently short string using .Fn sbuf_cpy . .Sh RETURN VALUES .Fn sbuf_new -returns \-1 if it failed to allocate a storage buffer, and zero +returns +.Dv NULL +if it failed to allocate a storage buffer, and a pointer to the new +.Fa sbuf otherwise. .Pp .Fn sbuf_setpos diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c index da3c05e..7e693e3 100644 --- a/sys/dev/sound/pcm/sound.c +++ b/sys/dev/sound/pcm/sound.c @@ -881,7 +881,7 @@ do_status(int action, struct uio *buf) case 0: /* open */ if (status_open) return EBUSY; - if (sbuf_new(&s, NULL, 4096, 0)) + if (sbuf_new(&s, NULL, 4096, 0) == NULL) return ENXIO; bufptr = 0; err = (status_init(&s) > 0)? 0 : ENOMEM; diff --git a/sys/kern/subr_sbuf.c b/sys/kern/subr_sbuf.c index 11fc64f..6de352d 100644 --- a/sys/kern/subr_sbuf.c +++ b/sys/kern/subr_sbuf.c @@ -55,6 +55,7 @@ MALLOC_DEFINE(M_SBUF, "sbuf", "string buffers"); * Predicates */ #define SBUF_ISDYNAMIC(s) ((s)->s_flags & SBUF_DYNAMIC) +#define SBUF_ISDYNSTRUCT(s) ((s)->s_flags & SBUF_DYNSTRUCT) #define SBUF_ISFINISHED(s) ((s)->s_flags & SBUF_FINISHED) #define SBUF_HASOVERFLOWED(s) ((s)->s_flags & SBUF_OVERFLOWED) #define SBUF_HASROOM(s) ((s)->s_len < (s)->s_size - 1) @@ -99,27 +100,36 @@ _assert_sbuf_state(char *fun, struct sbuf *s, int state) * If buf is non-NULL, it points to a static or already-allocated string * big enough to hold at least length characters. */ -int +struct sbuf * sbuf_new(struct sbuf *s, char *buf, int length, int flags) { KASSERT(length >= 0, ("attempt to create an sbuf of negative length (%d)", length)); KASSERT(flags == 0, (__FUNCTION__ " called with non-zero flags")); - KASSERT(s != NULL, - (__FUNCTION__ " called with a NULL sbuf pointer")); - bzero(s, sizeof *s); + if (s == NULL) { + s = (struct sbuf *)SBMALLOC(sizeof *s); + if (s == NULL) + return (NULL); + bzero(s, sizeof *s); + SBUF_SETFLAG(s, SBUF_DYNSTRUCT); + } else { + bzero(s, sizeof *s); + } s->s_size = length; if (buf) { s->s_buf = buf; - return (0); + return (s); } s->s_buf = (char *)SBMALLOC(s->s_size); - if (s->s_buf == NULL) - return (-1); + if (s->s_buf == NULL) { + if (SBUF_ISDYNSTRUCT(s)) + SBFREE(s); + return (NULL); + } SBUF_SETFLAG(s, SBUF_DYNAMIC); - return (0); + return (s); } /* @@ -315,4 +325,6 @@ sbuf_delete(struct sbuf *s) if (SBUF_ISDYNAMIC(s)) SBFREE(s->s_buf); bzero(s, sizeof *s); + if (SBUF_ISDYNSTRUCT(s)) + SBFREE(s); } diff --git a/sys/sys/sbuf.h b/sys/sys/sbuf.h index e2f0a6b..0e0d7d5 100644 --- a/sys/sys/sbuf.h +++ b/sys/sys/sbuf.h @@ -43,6 +43,7 @@ struct sbuf { #define SBUF_DYNAMIC 0x00010000 /* s_buf must be freed */ #define SBUF_FINISHED 0x00020000 /* set by sbuf_finish() */ #define SBUF_OVERFLOWED 0x00040000 /* sbuf overflowed */ +#define SBUF_DYNSTRUCT 0x00080000 /* sbuf must be freed */ int s_flags; /* flags */ }; @@ -50,18 +51,18 @@ __BEGIN_DECLS /* * API functions */ -int sbuf_new(struct sbuf *s, char *buf, int length, int flags); -void sbuf_clear(struct sbuf *s); -int sbuf_setpos(struct sbuf *s, int pos); -int sbuf_cat(struct sbuf *s, const char *str); -int sbuf_cpy(struct sbuf *s, const char *str); -int sbuf_printf(struct sbuf *s, char *fmt, ...); -int sbuf_putc(struct sbuf *s, int c); -int sbuf_overflowed(struct sbuf *s); -void sbuf_finish(struct sbuf *s); -char *sbuf_data(struct sbuf *s); -int sbuf_len(struct sbuf *s); -void sbuf_delete(struct sbuf *s); +struct sbuf *sbuf_new(struct sbuf *s, char *buf, int length, int flags); +void sbuf_clear(struct sbuf *s); +int sbuf_setpos(struct sbuf *s, int pos); +int sbuf_cat(struct sbuf *s, const char *str); +int sbuf_cpy(struct sbuf *s, const char *str); +int sbuf_printf(struct sbuf *s, char *fmt, ...); +int sbuf_putc(struct sbuf *s, int c); +int sbuf_overflowed(struct sbuf *s); +void sbuf_finish(struct sbuf *s); +char *sbuf_data(struct sbuf *s); +int sbuf_len(struct sbuf *s); +void sbuf_delete(struct sbuf *s); __END_DECLS #endif |