diff options
-rw-r--r-- | sys/kern/subr_sbuf.c | 52 | ||||
-rw-r--r-- | sys/sys/sbuf.h | 3 |
2 files changed, 54 insertions, 1 deletions
diff --git a/sys/kern/subr_sbuf.c b/sys/kern/subr_sbuf.c index 3c3b93b..330c556 100644 --- a/sys/kern/subr_sbuf.c +++ b/sys/kern/subr_sbuf.c @@ -29,18 +29,22 @@ */ #include <sys/param.h> -#include <sys/sbuf.h> #ifdef _KERNEL +#include <sys/ctype.h> #include <sys/kernel.h> #include <sys/malloc.h> #include <sys/systm.h> +#include <sys/uio.h> #include <machine/stdarg.h> #else /* _KERNEL */ +#include <ctype.h> #include <stdarg.h> #include <stdlib.h> #endif /* _KERNEL */ +#include <sys/sbuf.h> + #ifdef _KERNEL MALLOC_DEFINE(M_SBUF, "sbuf", "string buffers"); #define SBMALLOC(size) malloc(size, M_SBUF, M_WAITOK) @@ -133,6 +137,34 @@ sbuf_new(struct sbuf *s, char *buf, int length, int flags) return (s); } +#ifdef _KERNEL +/* + * Create an sbuf with uio data + */ +struct sbuf * +sbuf_uionew(struct sbuf *s, struct uio *uio, int *error) +{ + KASSERT(uio != NULL, + (__FUNCTION__ " called with NULL uio pointer")); + KASSERT(error != NULL, + (__FUNCTION__ " called with NULL error pointer")); + + s = sbuf_new(s, NULL, uio->uio_resid + 1, 0); + if (s == NULL) { + *error = ENOMEM; + return (NULL); + } + *error = uiomove(s->s_buf, uio->uio_resid, uio); + if (*error != 0) { + sbuf_delete(s); + return (NULL); + } + s->s_len = s->s_size - 1; + *error = 0; + return (s); +} +#endif + /* * Clear an sbuf and reset its position */ @@ -357,6 +389,24 @@ sbuf_putc(struct sbuf *s, int c) } /* + * Trim whitespace characters from an sbuf. + */ +int +sbuf_trim(struct sbuf *s) +{ + assert_sbuf_integrity(s); + assert_sbuf_state(s, 0); + + if (SBUF_HASOVERFLOWED(s)) + return (-1); + + while (s->s_len && isspace(s->s_buf[s->s_len-1])) + --s->s_len; + + return (0); +} + +/* * Check if an sbuf overflowed */ int diff --git a/sys/sys/sbuf.h b/sys/sys/sbuf.h index b671c0c..995e745 100644 --- a/sys/sys/sbuf.h +++ b/sys/sys/sbuf.h @@ -60,6 +60,7 @@ int sbuf_cat(struct sbuf *s, const char *str); int sbuf_cpy(struct sbuf *s, const char *str); int sbuf_printf(struct sbuf *s, const char *fmt, ...) __printflike(2, 3); int sbuf_putc(struct sbuf *s, int c); +int sbuf_trim(struct sbuf *s); int sbuf_overflowed(struct sbuf *s); void sbuf_finish(struct sbuf *s); char *sbuf_data(struct sbuf *s); @@ -67,6 +68,8 @@ int sbuf_len(struct sbuf *s); void sbuf_delete(struct sbuf *s); #ifdef _KERNEL +struct uio; +struct sbuf *sbuf_uionew(struct sbuf *s, struct uio *uio, int *error); int sbuf_bcopyin(struct sbuf *s, const void *uaddr, size_t len); int sbuf_copyin(struct sbuf *s, const void *uaddr, size_t len); #endif |