2  * Copyright (c) 2000 Poul-Henning Kamp and Dag-Erling Co\95dan Sm¿rgrav 
   5  * Redistribution and use in source and binary forms, with or without 
   6  * modification, are permitted provided that the following conditions 
   8  * 1. Redistributions of source code must retain the above copyright 
   9  *    notice, this list of conditions and the following disclaimer 
  10  *    in this position and unchanged. 
  11  * 2. Redistributions in binary form must reproduce the above copyright 
  12  *    notice, this list of conditions and the following disclaimer in the 
  13  *    documentation and/or other materials provided with the distribution. 
  14  * 3. The name of the author may not be used to endorse or promote products 
  15  *    derived from this software without specific prior written permission. 
  17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
  18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
  19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
  20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 
  21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
  22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
  23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
  26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  29 #include <sys/cdefs.h> 
  31 #include <sys/param.h> 
  34 /* #include <ctype.h> */ 
  35 #include <sys/kernel.h> 
  36 #include <sys/malloc.h> 
  37 #include <sys/systm.h> 
  39 #include <sys/uio_internal.h> 
  40 #include <sys/systm.h> 
  53 /* MALLOC_DEFINE(M_SBUF, "sbuf", "string buffers"); */ 
  54 #define SBMALLOC(size)          _MALLOC(size, M_SBUF, M_WAITOK) 
  55 #define SBFREE(buf)             FREE(buf, M_SBUF) 
  58 #define SBMALLOC(size)          malloc(size) 
  59 #define SBFREE(buf)             free(buf) 
  60 #define min(x, y)                MIN(x,y) 
  67 #define SBUF_ISDYNAMIC(s)       ((s)->s_flags & SBUF_DYNAMIC) 
  68 #define SBUF_ISDYNSTRUCT(s)     ((s)->s_flags & SBUF_DYNSTRUCT) 
  69 #define SBUF_ISFINISHED(s)      ((s)->s_flags & SBUF_FINISHED) 
  70 #define SBUF_HASOVERFLOWED(s)   ((s)->s_flags & SBUF_OVERFLOWED) 
  71 #define SBUF_HASROOM(s)         ((s)->s_len < (s)->s_size - 1) 
  72 #define SBUF_FREESPACE(s)       ((s)->s_size - (s)->s_len - 1) 
  73 #define SBUF_CANEXTEND(s)       ((s)->s_flags & SBUF_AUTOEXTEND) 
  78 #define SBUF_SETFLAG(s, f)      do { (s)->s_flags |= (f); } while (0) 
  79 #define SBUF_CLEARFLAG(s, f)    do { (s)->s_flags &= ~(f); } while (0) 
  81 #define SBUF_MINEXTENDSIZE      16              /* Should be power of 2. */ 
  82 #define SBUF_MAXEXTENDSIZE      PAGE_SIZE 
  83 #define SBUF_MAXEXTENDINCR      PAGE_SIZE 
  88 #if defined(KERNEL) && defined(INVARIANTS) 
  90 _assert_sbuf_integrity(const char *fun
, struct sbuf 
*s
) 
  93             ("%s called with a NULL sbuf pointer", fun
)); 
  94         KASSERT(s
->s_buf 
!= NULL
, 
  95             ("%s called with uninitialized or corrupt sbuf", fun
)); 
  96         KASSERT(s
->s_len 
< s
->s_size
, 
  97             ("wrote past end of sbuf (%d >= %d)", s
->s_len
, s
->s_size
)); 
 101 _assert_sbuf_state(const char *fun
, struct sbuf 
*s
, int state
) 
 103         KASSERT((s
->s_flags 
& SBUF_FINISHED
) == state
, 
 104             ("%s called with %sfinished or corrupt sbuf", fun
, 
 105             (state 
? "un" : ""))); 
 107 #define assert_sbuf_integrity(s) _assert_sbuf_integrity(__func__, (s)) 
 108 #define assert_sbuf_state(s, i)  _assert_sbuf_state(__func__, (s), (i)) 
 109 #else /* KERNEL && INVARIANTS */ 
 110 #define assert_sbuf_integrity(s) do { } while (0) 
 111 #define assert_sbuf_state(s, i)  do { } while (0) 
 112 #endif /* KERNEL && INVARIANTS */ 
 115 sbuf_extendsize(int size
) 
 119         newsize 
= SBUF_MINEXTENDSIZE
; 
 120         while (newsize 
< size
) { 
 121                 if (newsize 
< (int)SBUF_MAXEXTENDSIZE
) { 
 124                         newsize 
+= SBUF_MAXEXTENDINCR
; 
 136 sbuf_extend(struct sbuf 
*s
, int addlen
) 
 141         if (!SBUF_CANEXTEND(s
)) { 
 145         newsize 
= sbuf_extendsize(s
->s_size 
+ addlen
); 
 146         newbuf 
= (char *)SBMALLOC(newsize
); 
 147         if (newbuf 
== NULL
) { 
 150         bcopy(s
->s_buf
, newbuf
, s
->s_size
); 
 151         if (SBUF_ISDYNAMIC(s
)) { 
 154                 SBUF_SETFLAG(s
, SBUF_DYNAMIC
); 
 162  * Initialize an sbuf. 
 163  * If buf is non-NULL, it points to a static or already-allocated string 
 164  * big enough to hold at least length characters. 
 167 sbuf_new(struct sbuf 
*s
, char *buf
, int length
, int flags
) 
 170             ("attempt to create an sbuf of negative length (%d)", length
)); 
 171         KASSERT((flags 
& ~SBUF_USRFLAGMSK
) == 0, 
 172             ("%s called with invalid flags", __func__
)); 
 174         flags 
&= SBUF_USRFLAGMSK
; 
 176                 s 
= (struct sbuf 
*)SBMALLOC(sizeof *s
); 
 182                 SBUF_SETFLAG(s
, SBUF_DYNSTRUCT
); 
 192         if (flags 
& SBUF_AUTOEXTEND
) { 
 193                 s
->s_size 
= sbuf_extendsize(s
->s_size
); 
 195         s
->s_buf 
= (char *)SBMALLOC(s
->s_size
); 
 196         if (s
->s_buf 
== NULL
) { 
 197                 if (SBUF_ISDYNSTRUCT(s
)) { 
 202         SBUF_SETFLAG(s
, SBUF_DYNAMIC
); 
 208  * Create an sbuf with uio data 
 211 sbuf_uionew(struct sbuf 
*s
, struct uio 
*uio
, int *error
) 
 214             ("%s called with NULL uio pointer", __func__
)); 
 215         KASSERT(error 
!= NULL
, 
 216             ("%s called with NULL error pointer", __func__
)); 
 218         s 
= sbuf_new(s
, NULL
, uio_resid(uio
) + 1, 0); 
 223         *error 
= uiomove(s
->s_buf
, uio_resid(uio
), uio
); 
 228         s
->s_len 
= s
->s_size 
- 1; 
 235  * Clear an sbuf and reset its position. 
 238 sbuf_clear(struct sbuf 
*s
) 
 240         assert_sbuf_integrity(s
); 
 241         /* don't care if it's finished or not */ 
 243         SBUF_CLEARFLAG(s
, SBUF_FINISHED
); 
 244         SBUF_CLEARFLAG(s
, SBUF_OVERFLOWED
); 
 249  * Set the sbuf's end position to an arbitrary value. 
 250  * Effectively truncates the sbuf at the new position. 
 253 sbuf_setpos(struct sbuf 
*s
, int pos
) 
 255         assert_sbuf_integrity(s
); 
 256         assert_sbuf_state(s
, 0); 
 259             ("attempt to seek to a negative position (%d)", pos
)); 
 260         KASSERT(pos 
< s
->s_size
, 
 261             ("attempt to seek past end of sbuf (%d >= %d)", pos
, s
->s_size
)); 
 263         if (pos 
< 0 || pos 
> s
->s_len
) { 
 271  * Append a byte string to an sbuf. 
 274 sbuf_bcat(struct sbuf 
*s
, const void *buf
, size_t len
) 
 276         const char *str 
= buf
; 
 278         assert_sbuf_integrity(s
); 
 279         assert_sbuf_state(s
, 0); 
 281         if (SBUF_HASOVERFLOWED(s
)) { 
 286                 if (!SBUF_HASROOM(s
) && sbuf_extend(s
, len
) < 0) { 
 289                 s
->s_buf
[s
->s_len
++] = *str
++; 
 292                 SBUF_SETFLAG(s
, SBUF_OVERFLOWED
); 
 300  * Copy a byte string from userland into an sbuf. 
 303 sbuf_bcopyin(struct sbuf 
*s
, const void *uaddr
, size_t len
) 
 305         assert_sbuf_integrity(s
); 
 306         assert_sbuf_state(s
, 0); 
 308         if (SBUF_HASOVERFLOWED(s
)) { 
 315         if (len 
> (unsigned) SBUF_FREESPACE(s
)) { 
 316                 sbuf_extend(s
, len 
- SBUF_FREESPACE(s
)); 
 317                 len 
= min(len
, SBUF_FREESPACE(s
)); 
 319         if (copyin(CAST_USER_ADDR_T(uaddr
), s
->s_buf 
+ s
->s_len
, len
) != 0) { 
 329  * Copy a byte string into an sbuf. 
 332 sbuf_bcpy(struct sbuf 
*s
, const void *buf
, size_t len
) 
 334         assert_sbuf_integrity(s
); 
 335         assert_sbuf_state(s
, 0); 
 338         return sbuf_bcat(s
, buf
, len
); 
 342  * Append a string to an sbuf. 
 345 sbuf_cat(struct sbuf 
*s
, const char *str
) 
 347         assert_sbuf_integrity(s
); 
 348         assert_sbuf_state(s
, 0); 
 350         if (SBUF_HASOVERFLOWED(s
)) { 
 355                 if (!SBUF_HASROOM(s
) && sbuf_extend(s
, strlen(str
)) < 0) { 
 358                 s
->s_buf
[s
->s_len
++] = *str
++; 
 361                 SBUF_SETFLAG(s
, SBUF_OVERFLOWED
); 
 369  * Append a string from userland to an sbuf. 
 372 sbuf_copyin(struct sbuf 
*s
, const void *uaddr
, size_t len
) 
 376         assert_sbuf_integrity(s
); 
 377         assert_sbuf_state(s
, 0); 
 379         if (SBUF_HASOVERFLOWED(s
)) { 
 384                 len 
= SBUF_FREESPACE(s
);        /* XXX return 0? */ 
 386         if (len 
> (unsigned) SBUF_FREESPACE(s
)) { 
 388                 len 
= min(len
, SBUF_FREESPACE(s
)); 
 390         switch (copyinstr(CAST_USER_ADDR_T(uaddr
), s
->s_buf 
+ s
->s_len
, len 
+ 1, &done
)) { 
 392                 SBUF_SETFLAG(s
, SBUF_OVERFLOWED
); 
 395                 s
->s_len 
+= done 
- 1; 
 406  * Copy a string into an sbuf. 
 409 sbuf_cpy(struct sbuf 
*s
, const char *str
) 
 411         assert_sbuf_integrity(s
); 
 412         assert_sbuf_state(s
, 0); 
 415         return sbuf_cat(s
, str
); 
 419  * Format the given argument list and append the resulting string to an sbuf. 
 422 sbuf_vprintf(struct sbuf 
*s
, const char *fmt
, va_list ap
) 
 424         __builtin_va_list ap_copy
; /* XXX tduffy - blame on him */ 
 427         assert_sbuf_integrity(s
); 
 428         assert_sbuf_state(s
, 0); 
 431             ("%s called with a NULL format string", __func__
)); 
 433         if (SBUF_HASOVERFLOWED(s
)) { 
 438                 va_copy(ap_copy
, ap
); 
 439                 len 
= vsnprintf(&s
->s_buf
[s
->s_len
], SBUF_FREESPACE(s
) + 1, 
 442         } while (len 
> SBUF_FREESPACE(s
) && 
 443             sbuf_extend(s
, len 
- SBUF_FREESPACE(s
)) == 0); 
 446          * s->s_len is the length of the string, without the terminating nul. 
 447          * When updating s->s_len, we must subtract 1 from the length that 
 448          * we passed into vsnprintf() because that length includes the 
 451          * vsnprintf() returns the amount that would have been copied, 
 452          * given sufficient space, hence the min() calculation below. 
 454         s
->s_len 
+= min(len
, SBUF_FREESPACE(s
)); 
 455         if (!SBUF_HASROOM(s
) && !SBUF_CANEXTEND(s
)) { 
 456                 SBUF_SETFLAG(s
, SBUF_OVERFLOWED
); 
 459         KASSERT(s
->s_len 
< s
->s_size
, 
 460             ("wrote past end of sbuf (%d >= %d)", s
->s_len
, s
->s_size
)); 
 462         if (SBUF_HASOVERFLOWED(s
)) { 
 469  * Format the given arguments and append the resulting string to an sbuf. 
 472 sbuf_printf(struct sbuf 
*s
, const char *fmt
, ...) 
 478         result 
= sbuf_vprintf(s
, fmt
, ap
); 
 484  * Append a character to an sbuf. 
 487 sbuf_putc(struct sbuf 
*s
, int c
) 
 489         assert_sbuf_integrity(s
); 
 490         assert_sbuf_state(s
, 0); 
 492         if (SBUF_HASOVERFLOWED(s
)) { 
 496         if (!SBUF_HASROOM(s
) && sbuf_extend(s
, 1) < 0) { 
 497                 SBUF_SETFLAG(s
, SBUF_OVERFLOWED
); 
 501                 s
->s_buf
[s
->s_len
++] = c
; 
 509         return ch 
== ' ' || ch 
== '\n' || ch 
== '\t'; 
 513  * Trim whitespace characters from end of an sbuf. 
 516 sbuf_trim(struct sbuf 
*s
) 
 518         assert_sbuf_integrity(s
); 
 519         assert_sbuf_state(s
, 0); 
 521         if (SBUF_HASOVERFLOWED(s
)) { 
 525         while (s
->s_len 
&& isspace(s
->s_buf
[s
->s_len 
- 1])) { 
 533  * Check if an sbuf overflowed 
 536 sbuf_overflowed(struct sbuf 
*s
) 
 538         return SBUF_HASOVERFLOWED(s
); 
 542  * Finish off an sbuf. 
 545 sbuf_finish(struct sbuf 
*s
) 
 547         assert_sbuf_integrity(s
); 
 548         assert_sbuf_state(s
, 0); 
 550         s
->s_buf
[s
->s_len
] = '\0'; 
 551         SBUF_CLEARFLAG(s
, SBUF_OVERFLOWED
); 
 552         SBUF_SETFLAG(s
, SBUF_FINISHED
); 
 556  * Return a pointer to the sbuf data. 
 559 sbuf_data(struct sbuf 
*s
) 
 561         assert_sbuf_integrity(s
); 
 562         assert_sbuf_state(s
, SBUF_FINISHED
); 
 568  * Return the length of the sbuf data. 
 571 sbuf_len(struct sbuf 
*s
) 
 573         assert_sbuf_integrity(s
); 
 574         /* don't care if it's finished or not */ 
 576         if (SBUF_HASOVERFLOWED(s
)) { 
 583  * Clear an sbuf, free its buffer if necessary. 
 586 sbuf_delete(struct sbuf 
*s
) 
 590         assert_sbuf_integrity(s
); 
 591         /* don't care if it's finished or not */ 
 593         if (SBUF_ISDYNAMIC(s
)) { 
 596         isdyn 
= SBUF_ISDYNSTRUCT(s
); 
 604  * Check if an sbuf has been finished. 
 607 sbuf_done(struct sbuf 
*s
) 
 609         return SBUF_ISFINISHED(s
);