xref: /freebsd/sys/kern/subr_sbuf.c (revision d23813cdb9a927b0c2965fcb4979edaad5f21dae)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2000-2008 Poul-Henning Kamp
5  * Copyright (c) 2000-2008 Dag-Erling Coïdan Smørgrav
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer
13  *    in this position and unchanged.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33 
34 #include <sys/param.h>
35 
36 #ifdef _KERNEL
37 #include <sys/ctype.h>
38 #include <sys/errno.h>
39 #include <sys/kernel.h>
40 #include <sys/limits.h>
41 #include <sys/malloc.h>
42 #include <sys/systm.h>
43 #include <sys/uio.h>
44 #include <machine/stdarg.h>
45 #else /* _KERNEL */
46 #include <ctype.h>
47 #include <errno.h>
48 #include <limits.h>
49 #include <stdarg.h>
50 #include <stdio.h>
51 #include <stdlib.h>
52 #include <string.h>
53 #endif /* _KERNEL */
54 
55 #include <sys/sbuf.h>
56 
57 #ifdef _KERNEL
58 static MALLOC_DEFINE(M_SBUF, "sbuf", "string buffers");
59 #define	SBMALLOC(size, flags)	malloc(size, M_SBUF, (flags) | M_ZERO)
60 #define	SBFREE(buf)		free(buf, M_SBUF)
61 #else /* _KERNEL */
62 #define	KASSERT(e, m)
63 #define	SBMALLOC(size, flags)	calloc(1, size)
64 #define	SBFREE(buf)		free(buf)
65 #endif /* _KERNEL */
66 
67 /*
68  * Predicates
69  */
70 #define	SBUF_ISDYNAMIC(s)	((s)->s_flags & SBUF_DYNAMIC)
71 #define	SBUF_ISDYNSTRUCT(s)	((s)->s_flags & SBUF_DYNSTRUCT)
72 #define	SBUF_ISFINISHED(s)	((s)->s_flags & SBUF_FINISHED)
73 #define	SBUF_HASROOM(s)		((s)->s_len < (s)->s_size - 1)
74 #define	SBUF_FREESPACE(s)	((s)->s_size - ((s)->s_len + 1))
75 #define	SBUF_CANEXTEND(s)	((s)->s_flags & SBUF_AUTOEXTEND)
76 #define	SBUF_ISSECTION(s)	((s)->s_flags & SBUF_INSECTION)
77 #define	SBUF_NULINCLUDED(s)	((s)->s_flags & SBUF_INCLUDENUL)
78 #define	SBUF_ISDRAINTOEOR(s)	((s)->s_flags & SBUF_DRAINTOEOR)
79 #define	SBUF_DODRAINTOEOR(s)	(SBUF_ISSECTION(s) && SBUF_ISDRAINTOEOR(s))
80 #define	SBUF_MALLOCFLAG(s)	\
81 	(((s)->s_flags & SBUF_NOWAIT) ? M_NOWAIT : M_WAITOK)
82 
83 /*
84  * Set / clear flags
85  */
86 #define	SBUF_SETFLAG(s, f)	do { (s)->s_flags |= (f); } while (0)
87 #define	SBUF_CLEARFLAG(s, f)	do { (s)->s_flags &= ~(f); } while (0)
88 
89 #define	SBUF_MINSIZE		 2		/* Min is 1 byte + nulterm. */
90 #define	SBUF_MINEXTENDSIZE	16		/* Should be power of 2. */
91 
92 #ifdef PAGE_SIZE
93 #define	SBUF_MAXEXTENDSIZE	PAGE_SIZE
94 #define	SBUF_MAXEXTENDINCR	PAGE_SIZE
95 #else
96 #define	SBUF_MAXEXTENDSIZE	4096
97 #define	SBUF_MAXEXTENDINCR	4096
98 #endif
99 
100 /*
101  * Debugging support
102  */
103 #if defined(_KERNEL) && defined(INVARIANTS)
104 
105 static void
106 _assert_sbuf_integrity(const char *fun, struct sbuf *s)
107 {
108 
109 	KASSERT(s != NULL,
110 	    ("%s called with a NULL sbuf pointer", fun));
111 	KASSERT(s->s_buf != NULL,
112 	    ("%s called with uninitialized or corrupt sbuf", fun));
113 	if (SBUF_ISFINISHED(s) && SBUF_NULINCLUDED(s)) {
114 		KASSERT(s->s_len <= s->s_size,
115 		    ("wrote past end of sbuf (%jd >= %jd)",
116 		    (intmax_t)s->s_len, (intmax_t)s->s_size));
117 	} else {
118 		KASSERT(s->s_len < s->s_size,
119 		    ("wrote past end of sbuf (%jd >= %jd)",
120 		    (intmax_t)s->s_len, (intmax_t)s->s_size));
121 	}
122 }
123 
124 static void
125 _assert_sbuf_state(const char *fun, struct sbuf *s, int state)
126 {
127 
128 	KASSERT((s->s_flags & SBUF_FINISHED) == state,
129 	    ("%s called with %sfinished or corrupt sbuf", fun,
130 	    (state ? "un" : "")));
131 }
132 
133 #define	assert_sbuf_integrity(s) _assert_sbuf_integrity(__func__, (s))
134 #define	assert_sbuf_state(s, i)	 _assert_sbuf_state(__func__, (s), (i))
135 
136 #else /* _KERNEL && INVARIANTS */
137 
138 #define	assert_sbuf_integrity(s) do { } while (0)
139 #define	assert_sbuf_state(s, i)	 do { } while (0)
140 
141 #endif /* _KERNEL && INVARIANTS */
142 
143 #ifdef CTASSERT
144 CTASSERT(powerof2(SBUF_MAXEXTENDSIZE));
145 CTASSERT(powerof2(SBUF_MAXEXTENDINCR));
146 #endif
147 
148 static int
149 sbuf_extendsize(int size)
150 {
151 	int newsize;
152 
153 	if (size < (int)SBUF_MAXEXTENDSIZE) {
154 		newsize = SBUF_MINEXTENDSIZE;
155 		while (newsize < size)
156 			newsize *= 2;
157 	} else {
158 		newsize = roundup2(size, SBUF_MAXEXTENDINCR);
159 	}
160 	KASSERT(newsize >= size, ("%s: %d < %d\n", __func__, newsize, size));
161 	return (newsize);
162 }
163 
164 /*
165  * Extend an sbuf.
166  */
167 static int
168 sbuf_extend(struct sbuf *s, int addlen)
169 {
170 	char *newbuf;
171 	int newsize;
172 
173 	if (!SBUF_CANEXTEND(s))
174 		return (-1);
175 	newsize = sbuf_extendsize(s->s_size + addlen);
176 	newbuf = SBMALLOC(newsize, SBUF_MALLOCFLAG(s));
177 	if (newbuf == NULL)
178 		return (-1);
179 	memcpy(newbuf, s->s_buf, s->s_size);
180 	if (SBUF_ISDYNAMIC(s))
181 		SBFREE(s->s_buf);
182 	else
183 		SBUF_SETFLAG(s, SBUF_DYNAMIC);
184 	s->s_buf = newbuf;
185 	s->s_size = newsize;
186 	return (0);
187 }
188 
189 /*
190  * Initialize an sbuf.
191  * If buf is non-NULL, it points to a static or already-allocated string
192  * big enough to hold at least length characters.
193  */
194 struct sbuf *
195 sbuf_new(struct sbuf *s, char *buf, int length, int flags)
196 {
197 
198 	KASSERT(length >= 0,
199 	    ("attempt to create an sbuf of negative length (%d)", length));
200 	KASSERT((flags & ~SBUF_USRFLAGMSK) == 0,
201 	    ("%s called with invalid flags", __func__));
202 	KASSERT((flags & SBUF_AUTOEXTEND) || length >= SBUF_MINSIZE,
203 	    ("sbuf buffer %d smaller than minimum %d bytes", length,
204 	    SBUF_MINSIZE));
205 
206 	flags &= SBUF_USRFLAGMSK;
207 
208 	/*
209 	 * Allocate 'DYNSTRUCT' sbuf from the heap, if NULL 's' was provided.
210 	 */
211 	if (s == NULL) {
212 		s = SBMALLOC(sizeof(*s),
213 		    (flags & SBUF_NOWAIT) ?  M_NOWAIT : M_WAITOK);
214 		if (s == NULL)
215 			goto out;
216 		SBUF_SETFLAG(s, SBUF_DYNSTRUCT);
217 	} else {
218 		/*
219 		 * DYNSTRUCT SBMALLOC sbufs are allocated with M_ZERO, but
220 		 * user-provided sbuf objects must be initialized.
221 		 */
222 		memset(s, 0, sizeof(*s));
223 	}
224 
225 	s->s_flags |= flags;
226 	s->s_size = length;
227 	s->s_buf = buf;
228 
229 	/*
230 	 * Allocate DYNAMIC, i.e., heap data buffer backing the sbuf, if no
231 	 * buffer was provided.
232 	 */
233 	if (s->s_buf == NULL) {
234 		if (SBUF_CANEXTEND(s))
235 			s->s_size = sbuf_extendsize(s->s_size);
236 		s->s_buf = SBMALLOC(s->s_size, SBUF_MALLOCFLAG(s));
237 		if (s->s_buf == NULL)
238 			goto out;
239 		SBUF_SETFLAG(s, SBUF_DYNAMIC);
240 	}
241 
242 out:
243 	if (s != NULL && s->s_buf == NULL) {
244 		if (SBUF_ISDYNSTRUCT(s))
245 			SBFREE(s);
246 		s = NULL;
247 	}
248 	return (s);
249 }
250 
251 #ifdef _KERNEL
252 /*
253  * Create an sbuf with uio data
254  */
255 struct sbuf *
256 sbuf_uionew(struct sbuf *s, struct uio *uio, int *error)
257 {
258 
259 	KASSERT(uio != NULL,
260 	    ("%s called with NULL uio pointer", __func__));
261 	KASSERT(error != NULL,
262 	    ("%s called with NULL error pointer", __func__));
263 
264 	s = sbuf_new(s, NULL, uio->uio_resid + 1, 0);
265 	if (s == NULL) {
266 		*error = ENOMEM;
267 		return (NULL);
268 	}
269 	*error = uiomove(s->s_buf, uio->uio_resid, uio);
270 	if (*error != 0) {
271 		sbuf_delete(s);
272 		return (NULL);
273 	}
274 	s->s_len = s->s_size - 1;
275 	if (SBUF_ISSECTION(s))
276 		s->s_sect_len = s->s_size - 1;
277 	*error = 0;
278 	return (s);
279 }
280 #endif
281 
282 int
283 sbuf_get_flags(struct sbuf *s)
284 {
285 
286 	return (s->s_flags & SBUF_USRFLAGMSK);
287 }
288 
289 void
290 sbuf_clear_flags(struct sbuf *s, int flags)
291 {
292 
293 	s->s_flags &= ~(flags & SBUF_USRFLAGMSK);
294 }
295 
296 void
297 sbuf_set_flags(struct sbuf *s, int flags)
298 {
299 
300 
301 	s->s_flags |= (flags & SBUF_USRFLAGMSK);
302 }
303 
304 /*
305  * Clear an sbuf and reset its position.
306  */
307 void
308 sbuf_clear(struct sbuf *s)
309 {
310 
311 	assert_sbuf_integrity(s);
312 	/* don't care if it's finished or not */
313 
314 	SBUF_CLEARFLAG(s, SBUF_FINISHED);
315 	s->s_error = 0;
316 	s->s_len = 0;
317 	s->s_rec_off = 0;
318 	s->s_sect_len = 0;
319 }
320 
321 /*
322  * Set the sbuf's end position to an arbitrary value.
323  * Effectively truncates the sbuf at the new position.
324  */
325 int
326 sbuf_setpos(struct sbuf *s, ssize_t pos)
327 {
328 
329 	assert_sbuf_integrity(s);
330 	assert_sbuf_state(s, 0);
331 
332 	KASSERT(pos >= 0,
333 	    ("attempt to seek to a negative position (%jd)", (intmax_t)pos));
334 	KASSERT(pos < s->s_size,
335 	    ("attempt to seek past end of sbuf (%jd >= %jd)",
336 	    (intmax_t)pos, (intmax_t)s->s_size));
337 	KASSERT(!SBUF_ISSECTION(s),
338 	    ("attempt to seek when in a section"));
339 
340 	if (pos < 0 || pos > s->s_len)
341 		return (-1);
342 	s->s_len = pos;
343 	return (0);
344 }
345 
346 /*
347  * Drain into a counter.  Counts amount of data without producing output.
348  * Useful for cases like sysctl, where user may first request only size.
349  * This allows to avoid pointless allocation/freeing of large buffers.
350  */
351 int
352 sbuf_count_drain(void *arg, const char *data __unused, int len)
353 {
354 	size_t *sizep;
355 
356 	sizep = (size_t *)arg;
357 	*sizep += len;
358 	return (len);
359 }
360 
361 /*
362  * Set up a drain function and argument on an sbuf to flush data to
363  * when the sbuf buffer overflows.
364  */
365 void
366 sbuf_set_drain(struct sbuf *s, sbuf_drain_func *func, void *ctx)
367 {
368 
369 	assert_sbuf_state(s, 0);
370 	assert_sbuf_integrity(s);
371 	KASSERT(func == s->s_drain_func || s->s_len == 0,
372 	    ("Cannot change drain to %p on non-empty sbuf %p", func, s));
373 	s->s_drain_func = func;
374 	s->s_drain_arg = ctx;
375 }
376 
377 /*
378  * Call the drain and process the return.
379  */
380 static int
381 sbuf_drain(struct sbuf *s)
382 {
383 	int len;
384 
385 	KASSERT(s->s_len > 0, ("Shouldn't drain empty sbuf %p", s));
386 	KASSERT(s->s_error == 0, ("Called %s with error on %p", __func__, s));
387 	if (SBUF_DODRAINTOEOR(s) && s->s_rec_off == 0)
388 		return (s->s_error = EDEADLK);
389 	len = s->s_drain_func(s->s_drain_arg, s->s_buf,
390 	    SBUF_DODRAINTOEOR(s) ? s->s_rec_off : s->s_len);
391 	if (len <= 0) {
392 		s->s_error = len ? -len : EDEADLK;
393 		return (s->s_error);
394 	}
395 	KASSERT(len > 0 && len <= s->s_len,
396 	    ("Bad drain amount %d for sbuf %p", len, s));
397 	s->s_len -= len;
398 	s->s_rec_off -= len;
399 	/*
400 	 * Fast path for the expected case where all the data was
401 	 * drained.
402 	 */
403 	if (s->s_len == 0)
404 		return (0);
405 	/*
406 	 * Move the remaining characters to the beginning of the
407 	 * string.
408 	 */
409 	memmove(s->s_buf, s->s_buf + len, s->s_len);
410 	return (0);
411 }
412 
413 /*
414  * Append bytes to an sbuf.  This is the core function for appending
415  * to an sbuf and is the main place that deals with extending the
416  * buffer and marking overflow.
417  */
418 static void
419 sbuf_put_bytes(struct sbuf *s, const char *buf, size_t len)
420 {
421 	size_t n;
422 
423 	assert_sbuf_integrity(s);
424 	assert_sbuf_state(s, 0);
425 
426 	if (s->s_error != 0)
427 		return;
428 	while (len > 0) {
429 		if (SBUF_FREESPACE(s) <= 0) {
430 			/*
431 			 * If there is a drain, use it, otherwise extend the
432 			 * buffer.
433 			 */
434 			if (s->s_drain_func != NULL)
435 				(void)sbuf_drain(s);
436 			else if (sbuf_extend(s, len > INT_MAX ? INT_MAX : len)
437 			    < 0)
438 				s->s_error = ENOMEM;
439 			if (s->s_error != 0)
440 				return;
441 		}
442 		n = SBUF_FREESPACE(s);
443 		if (len < n)
444 			n = len;
445 		memcpy(&s->s_buf[s->s_len], buf, n);
446 		s->s_len += n;
447 		if (SBUF_ISSECTION(s))
448 			s->s_sect_len += n;
449 		len -= n;
450 		buf += n;
451 	}
452 }
453 
454 static void
455 sbuf_put_byte(struct sbuf *s, char c)
456 {
457 
458 	sbuf_put_bytes(s, &c, 1);
459 }
460 
461 /*
462  * Append a byte string to an sbuf.
463  */
464 int
465 sbuf_bcat(struct sbuf *s, const void *buf, size_t len)
466 {
467 
468 	sbuf_put_bytes(s, buf, len);
469 	if (s->s_error != 0)
470 		return (-1);
471 	return (0);
472 }
473 
474 #ifdef _KERNEL
475 /*
476  * Copy a byte string from userland into an sbuf.
477  */
478 int
479 sbuf_bcopyin(struct sbuf *s, const void *uaddr, size_t len)
480 {
481 
482 	assert_sbuf_integrity(s);
483 	assert_sbuf_state(s, 0);
484 	KASSERT(s->s_drain_func == NULL,
485 	    ("Nonsensical copyin to sbuf %p with a drain", s));
486 
487 	if (s->s_error != 0)
488 		return (-1);
489 	if (len == 0)
490 		return (0);
491 	if (len > SBUF_FREESPACE(s)) {
492 		sbuf_extend(s, len - SBUF_FREESPACE(s));
493 		if (SBUF_FREESPACE(s) < len)
494 			len = SBUF_FREESPACE(s);
495 	}
496 	if (copyin(uaddr, s->s_buf + s->s_len, len) != 0)
497 		return (-1);
498 	s->s_len += len;
499 
500 	return (0);
501 }
502 #endif
503 
504 /*
505  * Copy a byte string into an sbuf.
506  */
507 int
508 sbuf_bcpy(struct sbuf *s, const void *buf, size_t len)
509 {
510 
511 	assert_sbuf_integrity(s);
512 	assert_sbuf_state(s, 0);
513 
514 	sbuf_clear(s);
515 	return (sbuf_bcat(s, buf, len));
516 }
517 
518 /*
519  * Append a string to an sbuf.
520  */
521 int
522 sbuf_cat(struct sbuf *s, const char *str)
523 {
524 	size_t n;
525 
526 	n = strlen(str);
527 	sbuf_put_bytes(s, str, n);
528 	if (s->s_error != 0)
529 		return (-1);
530 	return (0);
531 }
532 
533 #ifdef _KERNEL
534 /*
535  * Append a string from userland to an sbuf.
536  */
537 int
538 sbuf_copyin(struct sbuf *s, const void *uaddr, size_t len)
539 {
540 	size_t done;
541 
542 	assert_sbuf_integrity(s);
543 	assert_sbuf_state(s, 0);
544 	KASSERT(s->s_drain_func == NULL,
545 	    ("Nonsensical copyin to sbuf %p with a drain", s));
546 
547 	if (s->s_error != 0)
548 		return (-1);
549 
550 	if (len == 0)
551 		len = SBUF_FREESPACE(s);	/* XXX return 0? */
552 	if (len > SBUF_FREESPACE(s)) {
553 		sbuf_extend(s, len);
554 		if (SBUF_FREESPACE(s) < len)
555 			len = SBUF_FREESPACE(s);
556 	}
557 	switch (copyinstr(uaddr, s->s_buf + s->s_len, len + 1, &done)) {
558 	case ENAMETOOLONG:
559 		s->s_error = ENOMEM;
560 		/* fall through */
561 	case 0:
562 		s->s_len += done - 1;
563 		if (SBUF_ISSECTION(s))
564 			s->s_sect_len += done - 1;
565 		break;
566 	default:
567 		return (-1);	/* XXX */
568 	}
569 
570 	return (done);
571 }
572 #endif
573 
574 /*
575  * Copy a string into an sbuf.
576  */
577 int
578 sbuf_cpy(struct sbuf *s, const char *str)
579 {
580 
581 	assert_sbuf_integrity(s);
582 	assert_sbuf_state(s, 0);
583 
584 	sbuf_clear(s);
585 	return (sbuf_cat(s, str));
586 }
587 
588 /*
589  * Format the given argument list and append the resulting string to an sbuf.
590  */
591 #ifdef _KERNEL
592 
593 /*
594  * Append a non-NUL character to an sbuf.  This prototype signature is
595  * suitable for use with kvprintf(9).
596  */
597 static void
598 sbuf_putc_func(int c, void *arg)
599 {
600 
601 	if (c != '\0')
602 		sbuf_put_byte(arg, c);
603 }
604 
605 int
606 sbuf_vprintf(struct sbuf *s, const char *fmt, va_list ap)
607 {
608 
609 	assert_sbuf_integrity(s);
610 	assert_sbuf_state(s, 0);
611 
612 	KASSERT(fmt != NULL,
613 	    ("%s called with a NULL format string", __func__));
614 
615 	(void)kvprintf(fmt, sbuf_putc_func, s, 10, ap);
616 	if (s->s_error != 0)
617 		return (-1);
618 	return (0);
619 }
620 #else /* !_KERNEL */
621 int
622 sbuf_vprintf(struct sbuf *s, const char *fmt, va_list ap)
623 {
624 	va_list ap_copy;
625 	int error, len;
626 
627 	assert_sbuf_integrity(s);
628 	assert_sbuf_state(s, 0);
629 
630 	KASSERT(fmt != NULL,
631 	    ("%s called with a NULL format string", __func__));
632 
633 	if (s->s_error != 0)
634 		return (-1);
635 
636 	/*
637 	 * For the moment, there is no way to get vsnprintf(3) to hand
638 	 * back a character at a time, to push everything into
639 	 * sbuf_putc_func() as was done for the kernel.
640 	 *
641 	 * In userspace, while drains are useful, there's generally
642 	 * not a problem attempting to malloc(3) on out of space.  So
643 	 * expand a userland sbuf if there is not enough room for the
644 	 * data produced by sbuf_[v]printf(3).
645 	 */
646 
647 	error = 0;
648 	do {
649 		va_copy(ap_copy, ap);
650 		len = vsnprintf(&s->s_buf[s->s_len], SBUF_FREESPACE(s) + 1,
651 		    fmt, ap_copy);
652 		if (len < 0) {
653 			s->s_error = errno;
654 			return (-1);
655 		}
656 		va_end(ap_copy);
657 
658 		if (SBUF_FREESPACE(s) >= len)
659 			break;
660 		/* Cannot print with the current available space. */
661 		if (s->s_drain_func != NULL && s->s_len > 0)
662 			error = sbuf_drain(s); /* sbuf_drain() sets s_error. */
663 		else if (sbuf_extend(s, len - SBUF_FREESPACE(s)) != 0)
664 			s->s_error = error = ENOMEM;
665 	} while (error == 0);
666 
667 	/*
668 	 * s->s_len is the length of the string, without the terminating nul.
669 	 * When updating s->s_len, we must subtract 1 from the length that
670 	 * we passed into vsnprintf() because that length includes the
671 	 * terminating nul.
672 	 *
673 	 * vsnprintf() returns the amount that would have been copied,
674 	 * given sufficient space, so don't over-increment s_len.
675 	 */
676 	if (SBUF_FREESPACE(s) < len)
677 		len = SBUF_FREESPACE(s);
678 	s->s_len += len;
679 	if (SBUF_ISSECTION(s))
680 		s->s_sect_len += len;
681 
682 	KASSERT(s->s_len < s->s_size,
683 	    ("wrote past end of sbuf (%d >= %d)", s->s_len, s->s_size));
684 
685 	if (s->s_error != 0)
686 		return (-1);
687 	return (0);
688 }
689 #endif /* _KERNEL */
690 
691 /*
692  * Format the given arguments and append the resulting string to an sbuf.
693  */
694 int
695 sbuf_printf(struct sbuf *s, const char *fmt, ...)
696 {
697 	va_list ap;
698 	int result;
699 
700 	va_start(ap, fmt);
701 	result = sbuf_vprintf(s, fmt, ap);
702 	va_end(ap);
703 	return (result);
704 }
705 
706 /*
707  * Append a character to an sbuf.
708  */
709 int
710 sbuf_putc(struct sbuf *s, int c)
711 {
712 
713 	sbuf_put_byte(s, c);
714 	if (s->s_error != 0)
715 		return (-1);
716 	return (0);
717 }
718 
719 /*
720  * Trim whitespace characters from end of an sbuf.
721  */
722 int
723 sbuf_trim(struct sbuf *s)
724 {
725 
726 	assert_sbuf_integrity(s);
727 	assert_sbuf_state(s, 0);
728 	KASSERT(s->s_drain_func == NULL,
729 	    ("%s makes no sense on sbuf %p with drain", __func__, s));
730 
731 	if (s->s_error != 0)
732 		return (-1);
733 
734 	while (s->s_len > 0 && isspace(s->s_buf[s->s_len-1])) {
735 		--s->s_len;
736 		if (SBUF_ISSECTION(s))
737 			s->s_sect_len--;
738 	}
739 
740 	return (0);
741 }
742 
743 /*
744  * Check if an sbuf has an error.
745  */
746 int
747 sbuf_error(const struct sbuf *s)
748 {
749 
750 	return (s->s_error);
751 }
752 
753 /*
754  * Finish off an sbuf.
755  */
756 int
757 sbuf_finish(struct sbuf *s)
758 {
759 
760 	assert_sbuf_integrity(s);
761 	assert_sbuf_state(s, 0);
762 
763 	s->s_buf[s->s_len] = '\0';
764 	if (SBUF_NULINCLUDED(s))
765 		s->s_len++;
766 	if (s->s_drain_func != NULL) {
767 		while (s->s_len > 0 && s->s_error == 0)
768 			s->s_error = sbuf_drain(s);
769 	}
770 	SBUF_SETFLAG(s, SBUF_FINISHED);
771 #ifdef _KERNEL
772 	return (s->s_error);
773 #else
774 	if (s->s_error != 0) {
775 		errno = s->s_error;
776 		return (-1);
777 	}
778 	return (0);
779 #endif
780 }
781 
782 /*
783  * Return a pointer to the sbuf data.
784  */
785 char *
786 sbuf_data(struct sbuf *s)
787 {
788 
789 	assert_sbuf_integrity(s);
790 	assert_sbuf_state(s, SBUF_FINISHED);
791 	KASSERT(s->s_drain_func == NULL,
792 	    ("%s makes no sense on sbuf %p with drain", __func__, s));
793 
794 	return (s->s_buf);
795 }
796 
797 /*
798  * Return the length of the sbuf data.
799  */
800 ssize_t
801 sbuf_len(struct sbuf *s)
802 {
803 
804 	assert_sbuf_integrity(s);
805 	/* don't care if it's finished or not */
806 	KASSERT(s->s_drain_func == NULL,
807 	    ("%s makes no sense on sbuf %p with drain", __func__, s));
808 
809 	if (s->s_error != 0)
810 		return (-1);
811 
812 	/* If finished, nulterm is already in len, else add one. */
813 	if (SBUF_NULINCLUDED(s) && !SBUF_ISFINISHED(s))
814 		return (s->s_len + 1);
815 	return (s->s_len);
816 }
817 
818 /*
819  * Clear an sbuf, free its buffer if necessary.
820  */
821 void
822 sbuf_delete(struct sbuf *s)
823 {
824 	int isdyn;
825 
826 	assert_sbuf_integrity(s);
827 	/* don't care if it's finished or not */
828 
829 	if (SBUF_ISDYNAMIC(s))
830 		SBFREE(s->s_buf);
831 	isdyn = SBUF_ISDYNSTRUCT(s);
832 	memset(s, 0, sizeof(*s));
833 	if (isdyn)
834 		SBFREE(s);
835 }
836 
837 /*
838  * Check if an sbuf has been finished.
839  */
840 int
841 sbuf_done(const struct sbuf *s)
842 {
843 
844 	return (SBUF_ISFINISHED(s));
845 }
846 
847 /*
848  * Start a section.
849  */
850 void
851 sbuf_start_section(struct sbuf *s, ssize_t *old_lenp)
852 {
853 
854 	assert_sbuf_integrity(s);
855 	assert_sbuf_state(s, 0);
856 
857 	if (!SBUF_ISSECTION(s)) {
858 		KASSERT(s->s_sect_len == 0,
859 		    ("s_sect_len != 0 when starting a section"));
860 		if (old_lenp != NULL)
861 			*old_lenp = -1;
862 		s->s_rec_off = s->s_len;
863 		SBUF_SETFLAG(s, SBUF_INSECTION);
864 	} else {
865 		KASSERT(old_lenp != NULL,
866 		    ("s_sect_len should be saved when starting a subsection"));
867 		*old_lenp = s->s_sect_len;
868 		s->s_sect_len = 0;
869 	}
870 }
871 
872 /*
873  * End the section padding to the specified length with the specified
874  * character.
875  */
876 ssize_t
877 sbuf_end_section(struct sbuf *s, ssize_t old_len, size_t pad, int c)
878 {
879 	ssize_t len;
880 
881 	assert_sbuf_integrity(s);
882 	assert_sbuf_state(s, 0);
883 	KASSERT(SBUF_ISSECTION(s),
884 	    ("attempt to end a section when not in a section"));
885 
886 	if (pad > 1) {
887 		len = roundup(s->s_sect_len, pad) - s->s_sect_len;
888 		for (; s->s_error == 0 && len > 0; len--)
889 			sbuf_put_byte(s, c);
890 	}
891 	len = s->s_sect_len;
892 	if (old_len == -1) {
893 		s->s_rec_off = s->s_sect_len = 0;
894 		SBUF_CLEARFLAG(s, SBUF_INSECTION);
895 	} else {
896 		s->s_sect_len += old_len;
897 	}
898 	if (s->s_error != 0)
899 		return (-1);
900 	return (len);
901 }
902