The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/subr_sbuf.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 6dd471696e80ebe8c38f38815222eb06


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.