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 s->s_flags |= (flags & SBUF_USRFLAGMSK); 306 } 307 308 /* 309 * Clear an sbuf and reset its position. 310 */ 311 void 312 sbuf_clear(struct sbuf *s) 313 { 314 315 assert_sbuf_integrity(s); 316 /* don't care if it's finished or not */ 317 KASSERT(s->s_drain_func == NULL, 318 ("%s makes no sense on sbuf %p with drain", __func__, s)); 319 320 SBUF_CLEARFLAG(s, SBUF_FINISHED); 321 s->s_error = 0; 322 s->s_len = 0; 323 s->s_rec_off = 0; 324 s->s_sect_len = 0; 325 } 326 327 /* 328 * Set the sbuf's end position to an arbitrary value. 329 * Effectively truncates the sbuf at the new position. 330 */ 331 int 332 sbuf_setpos(struct sbuf *s, ssize_t pos) 333 { 334 335 assert_sbuf_integrity(s); 336 assert_sbuf_state(s, 0); 337 338 KASSERT(pos >= 0, 339 ("attempt to seek to a negative position (%jd)", (intmax_t)pos)); 340 KASSERT(pos < s->s_size, 341 ("attempt to seek past end of sbuf (%jd >= %jd)", 342 (intmax_t)pos, (intmax_t)s->s_size)); 343 KASSERT(!SBUF_ISSECTION(s), 344 ("attempt to seek when in a section")); 345 346 if (pos < 0 || pos > s->s_len) 347 return (-1); 348 s->s_len = pos; 349 return (0); 350 } 351 352 /* 353 * Drain into a counter. Counts amount of data without producing output. 354 * Useful for cases like sysctl, where user may first request only size. 355 * This allows to avoid pointless allocation/freeing of large buffers. 356 */ 357 int 358 sbuf_count_drain(void *arg, const char *data __unused, int len) 359 { 360 size_t *sizep; 361 362 sizep = (size_t *)arg; 363 *sizep += len; 364 return (len); 365 } 366 367 /* 368 * Set up a drain function and argument on an sbuf to flush data to 369 * when the sbuf buffer overflows. 370 */ 371 void 372 sbuf_set_drain(struct sbuf *s, sbuf_drain_func *func, void *ctx) 373 { 374 375 assert_sbuf_state(s, 0); 376 assert_sbuf_integrity(s); 377 KASSERT(func == s->s_drain_func || s->s_len == 0, 378 ("Cannot change drain to %p on non-empty sbuf %p", func, s)); 379 s->s_drain_func = func; 380 s->s_drain_arg = ctx; 381 } 382 383 /* 384 * Call the drain and process the return. 385 */ 386 int 387 sbuf_drain(struct sbuf *s) 388 { 389 int len; 390 391 /* 392 * Immediately return when no work to do, 393 * or an error has already been accumulated. 394 */ 395 if ((s->s_len == 0) || (s->s_error != 0)) 396 return(s->s_error); 397 398 if (SBUF_DODRAINTOEOR(s) && s->s_rec_off == 0) 399 return (s->s_error = EDEADLK); 400 len = s->s_drain_func(s->s_drain_arg, s->s_buf, 401 SBUF_DODRAINTOEOR(s) ? s->s_rec_off : s->s_len); 402 if (len <= 0) { 403 s->s_error = len ? -len : EDEADLK; 404 return (s->s_error); 405 } 406 KASSERT(len > 0 && len <= s->s_len, 407 ("Bad drain amount %d for sbuf %p", len, s)); 408 s->s_len -= len; 409 s->s_rec_off -= len; 410 /* 411 * Fast path for the expected case where all the data was 412 * drained. 413 */ 414 if (s->s_len == 0) { 415 /* 416 * When the s_buf is entirely drained, we need to remember if 417 * the last character was a '\n' or not for 418 * sbuf_nl_terminate(). 419 */ 420 if (s->s_buf[len - 1] == '\n') 421 SBUF_SETFLAG(s, SBUF_DRAINATEOL); 422 else 423 SBUF_CLEARFLAG(s, SBUF_DRAINATEOL); 424 return (0); 425 } 426 /* 427 * Move the remaining characters to the beginning of the 428 * string. 429 */ 430 memmove(s->s_buf, s->s_buf + len, s->s_len); 431 return (0); 432 } 433 434 /* 435 * Append bytes to an sbuf. This is the core function for appending 436 * to an sbuf and is the main place that deals with extending the 437 * buffer and marking overflow. 438 */ 439 static void 440 sbuf_put_bytes(struct sbuf *s, const char *buf, size_t len) 441 { 442 size_t n; 443 444 assert_sbuf_integrity(s); 445 assert_sbuf_state(s, 0); 446 447 if (s->s_error != 0) 448 return; 449 while (len > 0) { 450 if (SBUF_FREESPACE(s) <= 0) { 451 /* 452 * If there is a drain, use it, otherwise extend the 453 * buffer. 454 */ 455 if (s->s_drain_func != NULL) 456 (void)sbuf_drain(s); 457 else if (sbuf_extend(s, len > INT_MAX ? INT_MAX : len) 458 < 0) 459 s->s_error = ENOMEM; 460 if (s->s_error != 0) 461 return; 462 } 463 n = SBUF_FREESPACE(s); 464 if (len < n) 465 n = len; 466 memcpy(&s->s_buf[s->s_len], buf, n); 467 s->s_len += n; 468 if (SBUF_ISSECTION(s)) 469 s->s_sect_len += n; 470 len -= n; 471 buf += n; 472 } 473 } 474 475 static void 476 sbuf_put_byte(struct sbuf *s, char c) 477 { 478 479 sbuf_put_bytes(s, &c, 1); 480 } 481 482 /* 483 * Append a byte string to an sbuf. 484 */ 485 int 486 sbuf_bcat(struct sbuf *s, const void *buf, size_t len) 487 { 488 489 sbuf_put_bytes(s, buf, len); 490 if (s->s_error != 0) 491 return (-1); 492 return (0); 493 } 494 495 #ifdef _KERNEL 496 /* 497 * Copy a byte string from userland into an sbuf. 498 */ 499 int 500 sbuf_bcopyin(struct sbuf *s, const void *uaddr, size_t len) 501 { 502 503 assert_sbuf_integrity(s); 504 assert_sbuf_state(s, 0); 505 KASSERT(s->s_drain_func == NULL, 506 ("Nonsensical copyin to sbuf %p with a drain", s)); 507 508 if (s->s_error != 0) 509 return (-1); 510 if (len == 0) 511 return (0); 512 if (len > SBUF_FREESPACE(s)) { 513 sbuf_extend(s, len - SBUF_FREESPACE(s)); 514 if (SBUF_FREESPACE(s) < len) 515 len = SBUF_FREESPACE(s); 516 } 517 if (copyin(uaddr, s->s_buf + s->s_len, len) != 0) 518 return (-1); 519 s->s_len += len; 520 521 return (0); 522 } 523 #endif 524 525 /* 526 * Copy a byte string into an sbuf. 527 */ 528 int 529 sbuf_bcpy(struct sbuf *s, const void *buf, size_t len) 530 { 531 532 assert_sbuf_integrity(s); 533 assert_sbuf_state(s, 0); 534 535 sbuf_clear(s); 536 return (sbuf_bcat(s, buf, len)); 537 } 538 539 /* 540 * Append a string to an sbuf. 541 */ 542 int 543 sbuf_cat(struct sbuf *s, const char *str) 544 { 545 size_t n; 546 547 n = strlen(str); 548 sbuf_put_bytes(s, str, n); 549 if (s->s_error != 0) 550 return (-1); 551 return (0); 552 } 553 554 #ifdef _KERNEL 555 /* 556 * Append a string from userland to an sbuf. 557 */ 558 int 559 sbuf_copyin(struct sbuf *s, const void *uaddr, size_t len) 560 { 561 size_t done; 562 563 assert_sbuf_integrity(s); 564 assert_sbuf_state(s, 0); 565 KASSERT(s->s_drain_func == NULL, 566 ("Nonsensical copyin to sbuf %p with a drain", s)); 567 568 if (s->s_error != 0) 569 return (-1); 570 571 if (len == 0) 572 len = SBUF_FREESPACE(s); /* XXX return 0? */ 573 if (len > SBUF_FREESPACE(s)) { 574 sbuf_extend(s, len); 575 if (SBUF_FREESPACE(s) < len) 576 len = SBUF_FREESPACE(s); 577 } 578 switch (copyinstr(uaddr, s->s_buf + s->s_len, len + 1, &done)) { 579 case ENAMETOOLONG: 580 s->s_error = ENOMEM; 581 /* fall through */ 582 case 0: 583 s->s_len += done - 1; 584 if (SBUF_ISSECTION(s)) 585 s->s_sect_len += done - 1; 586 break; 587 default: 588 return (-1); /* XXX */ 589 } 590 591 return (done); 592 } 593 #endif 594 595 /* 596 * Copy a string into an sbuf. 597 */ 598 int 599 sbuf_cpy(struct sbuf *s, const char *str) 600 { 601 602 assert_sbuf_integrity(s); 603 assert_sbuf_state(s, 0); 604 605 sbuf_clear(s); 606 return (sbuf_cat(s, str)); 607 } 608 609 /* 610 * Format the given argument list and append the resulting string to an sbuf. 611 */ 612 #ifdef _KERNEL 613 614 /* 615 * Append a non-NUL character to an sbuf. This prototype signature is 616 * suitable for use with kvprintf(9). 617 */ 618 static void 619 sbuf_putc_func(int c, void *arg) 620 { 621 622 if (c != '\0') 623 sbuf_put_byte(arg, c); 624 } 625 626 int 627 sbuf_vprintf(struct sbuf *s, const char *fmt, va_list ap) 628 { 629 630 assert_sbuf_integrity(s); 631 assert_sbuf_state(s, 0); 632 633 KASSERT(fmt != NULL, 634 ("%s called with a NULL format string", __func__)); 635 636 (void)kvprintf(fmt, sbuf_putc_func, s, 10, ap); 637 if (s->s_error != 0) 638 return (-1); 639 return (0); 640 } 641 #else /* !_KERNEL */ 642 int 643 sbuf_vprintf(struct sbuf *s, const char *fmt, va_list ap) 644 { 645 va_list ap_copy; 646 int error, len; 647 648 assert_sbuf_integrity(s); 649 assert_sbuf_state(s, 0); 650 651 KASSERT(fmt != NULL, 652 ("%s called with a NULL format string", __func__)); 653 654 if (s->s_error != 0) 655 return (-1); 656 657 /* 658 * For the moment, there is no way to get vsnprintf(3) to hand 659 * back a character at a time, to push everything into 660 * sbuf_putc_func() as was done for the kernel. 661 * 662 * In userspace, while drains are useful, there's generally 663 * not a problem attempting to malloc(3) on out of space. So 664 * expand a userland sbuf if there is not enough room for the 665 * data produced by sbuf_[v]printf(3). 666 */ 667 668 error = 0; 669 do { 670 va_copy(ap_copy, ap); 671 len = vsnprintf(&s->s_buf[s->s_len], SBUF_FREESPACE(s) + 1, 672 fmt, ap_copy); 673 if (len < 0) { 674 s->s_error = errno; 675 return (-1); 676 } 677 va_end(ap_copy); 678 679 if (SBUF_FREESPACE(s) >= len) 680 break; 681 /* Cannot print with the current available space. */ 682 if (s->s_drain_func != NULL && s->s_len > 0) 683 error = sbuf_drain(s); /* sbuf_drain() sets s_error. */ 684 else if (sbuf_extend(s, len - SBUF_FREESPACE(s)) != 0) 685 s->s_error = error = ENOMEM; 686 } while (error == 0); 687 688 /* 689 * s->s_len is the length of the string, without the terminating nul. 690 * When updating s->s_len, we must subtract 1 from the length that 691 * we passed into vsnprintf() because that length includes the 692 * terminating nul. 693 * 694 * vsnprintf() returns the amount that would have been copied, 695 * given sufficient space, so don't over-increment s_len. 696 */ 697 if (SBUF_FREESPACE(s) < len) 698 len = SBUF_FREESPACE(s); 699 s->s_len += len; 700 if (SBUF_ISSECTION(s)) 701 s->s_sect_len += len; 702 703 KASSERT(s->s_len < s->s_size, 704 ("wrote past end of sbuf (%d >= %d)", s->s_len, s->s_size)); 705 706 if (s->s_error != 0) 707 return (-1); 708 return (0); 709 } 710 #endif /* _KERNEL */ 711 712 /* 713 * Format the given arguments and append the resulting string to an sbuf. 714 */ 715 int 716 sbuf_printf(struct sbuf *s, const char *fmt, ...) 717 { 718 va_list ap; 719 int result; 720 721 va_start(ap, fmt); 722 result = sbuf_vprintf(s, fmt, ap); 723 va_end(ap); 724 return (result); 725 } 726 727 /* 728 * Append a character to an sbuf. 729 */ 730 int 731 sbuf_putc(struct sbuf *s, int c) 732 { 733 734 sbuf_put_byte(s, c); 735 if (s->s_error != 0) 736 return (-1); 737 return (0); 738 } 739 740 /* 741 * Append a trailing newline to a non-empty sbuf, if one is not already 742 * present. Handles sbufs with drain functions correctly. 743 */ 744 int 745 sbuf_nl_terminate(struct sbuf *s) 746 { 747 748 assert_sbuf_integrity(s); 749 assert_sbuf_state(s, 0); 750 751 /* 752 * If the s_buf isn't empty, the last byte is simply s_buf[s_len - 1]. 753 * 754 * If the s_buf is empty because a drain function drained it, we 755 * remember if the last byte was a \n with the SBUF_DRAINATEOL flag in 756 * sbuf_drain(). 757 * 758 * In either case, we only append a \n if the previous character was 759 * something else. 760 */ 761 if (s->s_len == 0) { 762 if (!SBUF_ISDRAINATEOL(s)) 763 sbuf_put_byte(s, '\n'); 764 } else if (s->s_buf[s->s_len - 1] != '\n') 765 sbuf_put_byte(s, '\n'); 766 767 if (s->s_error != 0) 768 return (-1); 769 return (0); 770 } 771 772 /* 773 * Trim whitespace characters from end of an sbuf. 774 */ 775 int 776 sbuf_trim(struct sbuf *s) 777 { 778 779 assert_sbuf_integrity(s); 780 assert_sbuf_state(s, 0); 781 KASSERT(s->s_drain_func == NULL, 782 ("%s makes no sense on sbuf %p with drain", __func__, s)); 783 784 if (s->s_error != 0) 785 return (-1); 786 787 while (s->s_len > 0 && isspace(s->s_buf[s->s_len-1])) { 788 --s->s_len; 789 if (SBUF_ISSECTION(s)) 790 s->s_sect_len--; 791 } 792 793 return (0); 794 } 795 796 /* 797 * Check if an sbuf has an error. 798 */ 799 int 800 sbuf_error(const struct sbuf *s) 801 { 802 803 return (s->s_error); 804 } 805 806 /* 807 * Finish off an sbuf. 808 */ 809 int 810 sbuf_finish(struct sbuf *s) 811 { 812 813 assert_sbuf_integrity(s); 814 assert_sbuf_state(s, 0); 815 816 s->s_buf[s->s_len] = '\0'; 817 if (SBUF_NULINCLUDED(s)) 818 s->s_len++; 819 if (s->s_drain_func != NULL) { 820 while (s->s_len > 0 && s->s_error == 0) 821 s->s_error = sbuf_drain(s); 822 } 823 SBUF_SETFLAG(s, SBUF_FINISHED); 824 #ifdef _KERNEL 825 return (s->s_error); 826 #else 827 if (s->s_error != 0) { 828 errno = s->s_error; 829 return (-1); 830 } 831 return (0); 832 #endif 833 } 834 835 /* 836 * Return a pointer to the sbuf data. 837 */ 838 char * 839 sbuf_data(struct sbuf *s) 840 { 841 842 assert_sbuf_integrity(s); 843 assert_sbuf_state(s, SBUF_FINISHED); 844 KASSERT(s->s_drain_func == NULL, 845 ("%s makes no sense on sbuf %p with drain", __func__, s)); 846 847 return (s->s_buf); 848 } 849 850 /* 851 * Return the length of the sbuf data. 852 */ 853 ssize_t 854 sbuf_len(struct sbuf *s) 855 { 856 857 assert_sbuf_integrity(s); 858 /* don't care if it's finished or not */ 859 KASSERT(s->s_drain_func == NULL, 860 ("%s makes no sense on sbuf %p with drain", __func__, s)); 861 862 if (s->s_error != 0) 863 return (-1); 864 865 /* If finished, nulterm is already in len, else add one. */ 866 if (SBUF_NULINCLUDED(s) && !SBUF_ISFINISHED(s)) 867 return (s->s_len + 1); 868 return (s->s_len); 869 } 870 871 /* 872 * Clear an sbuf, free its buffer if necessary. 873 */ 874 void 875 sbuf_delete(struct sbuf *s) 876 { 877 int isdyn; 878 879 assert_sbuf_integrity(s); 880 /* don't care if it's finished or not */ 881 882 if (SBUF_ISDYNAMIC(s)) 883 SBFREE(s->s_buf); 884 isdyn = SBUF_ISDYNSTRUCT(s); 885 memset(s, 0, sizeof(*s)); 886 if (isdyn) 887 SBFREE(s); 888 } 889 890 /* 891 * Check if an sbuf has been finished. 892 */ 893 int 894 sbuf_done(const struct sbuf *s) 895 { 896 897 return (SBUF_ISFINISHED(s)); 898 } 899 900 /* 901 * Start a section. 902 */ 903 void 904 sbuf_start_section(struct sbuf *s, ssize_t *old_lenp) 905 { 906 907 assert_sbuf_integrity(s); 908 assert_sbuf_state(s, 0); 909 910 if (!SBUF_ISSECTION(s)) { 911 KASSERT(s->s_sect_len == 0, 912 ("s_sect_len != 0 when starting a section")); 913 if (old_lenp != NULL) 914 *old_lenp = -1; 915 s->s_rec_off = s->s_len; 916 SBUF_SETFLAG(s, SBUF_INSECTION); 917 } else { 918 KASSERT(old_lenp != NULL, 919 ("s_sect_len should be saved when starting a subsection")); 920 *old_lenp = s->s_sect_len; 921 s->s_sect_len = 0; 922 } 923 } 924 925 /* 926 * End the section padding to the specified length with the specified 927 * character. 928 */ 929 ssize_t 930 sbuf_end_section(struct sbuf *s, ssize_t old_len, size_t pad, int c) 931 { 932 ssize_t len; 933 934 assert_sbuf_integrity(s); 935 assert_sbuf_state(s, 0); 936 KASSERT(SBUF_ISSECTION(s), 937 ("attempt to end a section when not in a section")); 938 939 if (pad > 1) { 940 len = roundup(s->s_sect_len, pad) - s->s_sect_len; 941 for (; s->s_error == 0 && len > 0; len--) 942 sbuf_put_byte(s, c); 943 } 944 len = s->s_sect_len; 945 if (old_len == -1) { 946 s->s_rec_off = s->s_sect_len = 0; 947 SBUF_CLEARFLAG(s, SBUF_INSECTION); 948 } else { 949 s->s_sect_len += old_len; 950 } 951 if (s->s_error != 0) 952 return (-1); 953 return (len); 954 } 955