summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--share/man/man9/sbuf.914
-rw-r--r--sys/dev/sound/pcm/sound.c2
-rw-r--r--sys/kern/subr_sbuf.c28
-rw-r--r--sys/sys/sbuf.h25
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
OpenPOWER on IntegriCloud