29 #include <sys/cdefs.h>
32 #include <sys/param.h>
35 #include <sys/ctype.h>
36 #include <sys/errno.h>
37 #include <sys/kernel.h>
38 #include <sys/malloc.h>
39 #include <sys/systm.h>
41 #include <machine/stdarg.h>
55 #define SBMALLOC(size) malloc(size, M_SBUF, M_WAITOK)
56 #define SBFREE(buf) free(buf, M_SBUF)
59 #define SBMALLOC(size) malloc(size)
60 #define SBFREE(buf) free(buf)
66 #define SBUF_ISDYNAMIC(s) ((s)->s_flags & SBUF_DYNAMIC)
67 #define SBUF_ISDYNSTRUCT(s) ((s)->s_flags & SBUF_DYNSTRUCT)
68 #define SBUF_ISFINISHED(s) ((s)->s_flags & SBUF_FINISHED)
69 #define SBUF_HASROOM(s) ((s)->s_len < (s)->s_size - 1)
70 #define SBUF_FREESPACE(s) ((s)->s_size - ((s)->s_len + 1))
71 #define SBUF_CANEXTEND(s) ((s)->s_flags & SBUF_AUTOEXTEND)
72 #define SBUF_ISSECTION(s) ((s)->s_flags & SBUF_INSECTION)
77 #define SBUF_SETFLAG(s, f) do { (s)->s_flags |= (f); } while (0)
78 #define SBUF_CLEARFLAG(s, f) do { (s)->s_flags &= ~(f); } while (0)
80 #define SBUF_MINEXTENDSIZE 16
83 #define SBUF_MAXEXTENDSIZE PAGE_SIZE
84 #define SBUF_MAXEXTENDINCR PAGE_SIZE
86 #define SBUF_MAXEXTENDSIZE 4096
87 #define SBUF_MAXEXTENDINCR 4096
93 #if defined(_KERNEL) && defined(INVARIANTS)
96 _assert_sbuf_integrity(
const char *fun,
struct sbuf *s)
100 (
"%s called with a NULL sbuf pointer", fun));
101 KASSERT(s->s_buf != NULL,
102 (
"%s called with uninitialized or corrupt sbuf", fun));
103 KASSERT(s->s_len < s->s_size,
104 (
"wrote past end of sbuf (%jd >= %jd)",
105 (intmax_t)s->s_len, (intmax_t)s->s_size));
109 _assert_sbuf_state(
const char *fun,
struct sbuf *s,
int state)
112 KASSERT((s->s_flags & SBUF_FINISHED) == state,
113 (
"%s called with %sfinished or corrupt sbuf", fun,
114 (state ?
"un" :
"")));
117 #define assert_sbuf_integrity(s) _assert_sbuf_integrity(__func__, (s))
118 #define assert_sbuf_state(s, i) _assert_sbuf_state(__func__, (s), (i))
122 #define assert_sbuf_integrity(s) do { } while (0)
123 #define assert_sbuf_state(s, i) do { } while (0)
139 while (newsize < size)
144 KASSERT(newsize >= size, (
"%s: %d < %d\n", __func__, newsize, size));
163 memcpy(newbuf, s->s_buf, s->s_size);
182 memset(s, 0,
sizeof(*s));
187 if ((s->s_flags & SBUF_AUTOEXTEND) == 0) {
188 KASSERT(s->s_size >= 0,
189 (
"attempt to create a too small sbuf"));
192 if (s->s_buf != NULL)
195 if ((flags & SBUF_AUTOEXTEND) != 0)
199 if (s->s_buf == NULL)
215 (
"attempt to create an sbuf of negative length (%d)", length));
216 KASSERT((flags & ~SBUF_USRFLAGMSK) == 0,
217 (
"%s called with invalid flags", __func__));
219 flags &= SBUF_USRFLAGMSK;
243 (
"%s called with NULL uio pointer", __func__));
244 KASSERT(error != NULL,
245 (
"%s called with NULL error pointer", __func__));
247 s =
sbuf_new(s, NULL, uio->uio_resid + 1, 0);
252 *error =
uiomove(s->s_buf, uio->uio_resid, uio);
257 s->s_len = s->s_size - 1;
259 s->s_sect_len = s->s_size - 1;
293 (
"attempt to seek to a negative position (%jd)", (intmax_t)pos));
294 KASSERT(pos < s->s_size,
295 (
"attempt to seek past end of sbuf (%jd >= %jd)",
296 (intmax_t)pos, (intmax_t)s->s_size));
298 (
"attempt to seek when in a section"));
300 if (pos < 0 || pos > s->s_len)
316 KASSERT(func == s->s_drain_func || s->s_len == 0,
317 (
"Cannot change drain to %p on non-empty sbuf %p", func, s));
318 s->s_drain_func = func;
319 s->s_drain_arg = ctx;
330 KASSERT(s->s_len > 0, (
"Shouldn't drain empty sbuf %p", s));
331 KASSERT(s->s_error == 0, (
"Called %s with error on %p", __func__, s));
332 len = s->s_drain_func(s->s_drain_arg, s->s_buf, s->s_len);
337 KASSERT(len > 0 && len <= s->s_len,
338 (
"Bad drain amount %d for sbuf %p", len, s));
350 memmove(s->s_buf, s->s_buf + len, s->s_len);
373 if (s->s_drain_func != NULL)
380 s->s_buf[s->s_len++] = c;
391 const char *str =
buf;
392 const char *end = str + len;
399 for (; str < end; str++) {
417 KASSERT(s->s_drain_func == NULL,
418 (
"Nonsensical copyin to sbuf %p with a drain", s));
429 if (copyin(uaddr, s->s_buf + s->s_len, len) != 0)
464 while (*str !=
'\0') {
483 KASSERT(s->s_drain_func == NULL,
484 (
"Nonsensical copyin to sbuf %p with a drain", s));
496 switch (copyinstr(uaddr, s->s_buf + s->s_len, len + 1, &done)) {
501 s->s_len += done - 1;
503 s->s_sect_len += done - 1;
552 (
"%s called with a NULL format string", __func__));
561 sbuf_vprintf(
struct sbuf *s,
const char *fmt, va_list ap)
570 (
"%s called with a NULL format string", __func__));
588 va_copy(ap_copy, ap);
596 if (s->s_drain_func != NULL && s->s_len > 0)
600 }
while (error == 0);
615 s->s_sect_len += len;
619 KASSERT(s->s_len < s->s_size,
620 (
"wrote past end of sbuf (%d >= %d)", s->s_len, s->s_size));
665 KASSERT(s->s_drain_func == NULL,
666 (
"%s makes no sense on sbuf %p with drain", __func__, s));
671 while (s->s_len > 0 && isspace(s->s_buf[s->s_len-1])) {
700 if (s->s_drain_func != NULL) {
701 while (s->s_len > 0 && s->s_error == 0)
704 s->s_buf[s->s_len] =
'\0';
709 if (s->s_error != 0) {
726 KASSERT(s->s_drain_func == NULL,
727 (
"%s makes no sense on sbuf %p with drain", __func__, s));
741 KASSERT(s->s_drain_func == NULL,
742 (
"%s makes no sense on sbuf %p with drain", __func__, s));
763 memset(s, 0,
sizeof(*s));
789 KASSERT(s->s_sect_len == 0,
790 (
"s_sect_len != 0 when starting a section"));
791 if (old_lenp != NULL)
795 KASSERT(old_lenp != NULL,
796 (
"s_sect_len should be saved when starting a subsection"));
797 *old_lenp = s->s_sect_len;
814 (
"attempt to end a section when not in a section"));
817 len = roundup(s->s_sect_len, pad) - s->s_sect_len;
818 for (; s->s_error == 0 && len > 0; len--)
826 s->s_sect_len += old_len;
int sbuf_error(const struct sbuf *s)
int sbuf_done(const struct sbuf *s)
int sbuf_putc(struct sbuf *s, int c)
ssize_t sbuf_len(struct sbuf *s)
struct sbuf * sbuf_uionew(struct sbuf *s, struct uio *uio, int *error)
int kvprintf(char const *fmt, void(*func)(int, void *), void *arg, int radix, va_list ap)
#define SBUF_CLEARFLAG(s, f)
#define assert_sbuf_integrity(s)
CTASSERT(MAXSHELLCMDLEN >=MAXINTERP+3)
int sbuf_setpos(struct sbuf *s, ssize_t pos)
static int sbuf_extend(struct sbuf *s, int addlen)
#define SBUF_SETFLAG(s, f)
static void sbuf_putc_func(int c, void *arg)
#define SBUF_ISDYNSTRUCT(s)
#define SBUF_ISSECTION(s)
#define SBUF_CANEXTEND(s)
int sbuf_vprintf(struct sbuf *s, const char *fmt, va_list ap)
int sbuf_bcpy(struct sbuf *s, const void *buf, size_t len)
static void sbuf_put_byte(struct sbuf *s, int c)
int vsnprintf(char *str, size_t size, const char *format, va_list ap)
#define SBUF_FREESPACE(s)
#define SBUF_ISDYNAMIC(s)
ssize_t sbuf_end_section(struct sbuf *s, ssize_t old_len, size_t pad, int c)
#define assert_sbuf_state(s, i)
#define SBUF_MAXEXTENDSIZE
static struct sbuf * sbuf_newbuf(struct sbuf *s, char *buf, int length, int flags)
void sbuf_clear(struct sbuf *s)
#define SBUF_MINEXTENDSIZE
void sbuf_set_drain(struct sbuf *s, sbuf_drain_func *func, void *ctx)
int sbuf_printf(struct sbuf *s, const char *fmt,...)
#define SBUF_ISFINISHED(s)
static int sbuf_drain(struct sbuf *s)
struct sbuf * sbuf_new(struct sbuf *s, char *buf, int length, int flags)
static int sbuf_extendsize(int size)
int uiomove(void *cp, int n, struct uio *uio)
void sbuf_delete(struct sbuf *s)
void sbuf_start_section(struct sbuf *s, ssize_t *old_lenp)
char * sbuf_data(struct sbuf *s)
int sbuf_bcat(struct sbuf *s, const void *buf, size_t len)
static MALLOC_DEFINE(M_SBUF,"sbuf","string buffers")
int sbuf_finish(struct sbuf *s)
int sbuf_cat(struct sbuf *s, const char *str)
int sbuf_cpy(struct sbuf *s, const char *str)
int sbuf_bcopyin(struct sbuf *s, const void *uaddr, size_t len)
int sbuf_trim(struct sbuf *s)
#define SBUF_MAXEXTENDINCR
int sbuf_copyin(struct sbuf *s, const void *uaddr, size_t len)