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