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