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/tty_subr.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  * Copyright (c) 1994, David Greenman
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice unmodified, this list of conditions, and the following
   10  *    disclaimer.
   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  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  *
   27  * $FreeBSD: releng/5.0/sys/kern/tty_subr.c 92723 2002-03-19 21:25:46Z alfred $
   28  */
   29 
   30 /*
   31  * clist support routines
   32  */
   33 
   34 #include <sys/param.h>
   35 #include <sys/kernel.h>
   36 #include <sys/systm.h>
   37 #include <sys/malloc.h>
   38 #include <sys/tty.h>
   39 #include <sys/clist.h>
   40 
   41 static void clist_init(void *);
   42 SYSINIT(clist, SI_SUB_CLIST, SI_ORDER_FIRST, clist_init, NULL)
   43 
   44 static struct cblock *cfreelist = 0;
   45 int cfreecount = 0;
   46 static int cslushcount;
   47 static int ctotcount;
   48 
   49 #ifndef INITIAL_CBLOCKS
   50 #define INITIAL_CBLOCKS 50
   51 #endif
   52 
   53 static struct cblock *cblock_alloc(void);
   54 static void cblock_alloc_cblocks(int number);
   55 static void cblock_free(struct cblock *cblockp);
   56 static void cblock_free_cblocks(int number);
   57 
   58 #include "opt_ddb.h"
   59 #ifdef DDB
   60 #include <ddb/ddb.h>
   61 
   62 DB_SHOW_COMMAND(cbstat, cbstat)
   63 {
   64         int cbsize = CBSIZE;
   65 
   66         printf(
   67         "tot = %d (active = %d, free = %d (reserved = %d, slush = %d))\n",
   68                ctotcount * cbsize, ctotcount * cbsize - cfreecount, cfreecount,
   69                cfreecount - cslushcount * cbsize, cslushcount * cbsize);
   70 }
   71 #endif /* DDB */
   72 
   73 /*
   74  * Called from init_main.c
   75  */
   76 /* ARGSUSED*/
   77 static void
   78 clist_init(dummy)
   79         void *dummy;
   80 {
   81         /*
   82          * Allocate an initial base set of cblocks as a 'slush'.
   83          * We allocate non-slush cblocks with each initial ttyopen() and
   84          * deallocate them with each ttyclose().
   85          * We should adjust the slush allocation.  This can't be done in
   86          * the i/o routines because they are sometimes called from
   87          * interrupt handlers when it may be unsafe to call malloc().
   88          */
   89         cblock_alloc_cblocks(cslushcount = INITIAL_CBLOCKS);
   90 }
   91 
   92 /*
   93  * Remove a cblock from the cfreelist queue and return a pointer
   94  * to it.
   95  */
   96 static __inline struct cblock *
   97 cblock_alloc()
   98 {
   99         struct cblock *cblockp;
  100 
  101         cblockp = cfreelist;
  102         if (cblockp == NULL)
  103                 panic("clist reservation botch");
  104         cfreelist = cblockp->c_next;
  105         cblockp->c_next = NULL;
  106         cfreecount -= CBSIZE;
  107         return (cblockp);
  108 }
  109 
  110 /*
  111  * Add a cblock to the cfreelist queue.
  112  */
  113 static __inline void
  114 cblock_free(cblockp)
  115         struct cblock *cblockp;
  116 {
  117         if (isset(cblockp->c_quote, CBQSIZE * NBBY - 1))
  118                 bzero(cblockp->c_quote, sizeof cblockp->c_quote);
  119         cblockp->c_next = cfreelist;
  120         cfreelist = cblockp;
  121         cfreecount += CBSIZE;
  122 }
  123 
  124 /*
  125  * Allocate some cblocks for the cfreelist queue.
  126  */
  127 static void
  128 cblock_alloc_cblocks(number)
  129         int number;
  130 {
  131         int i;
  132         struct cblock *cbp;
  133 
  134         for (i = 0; i < number; ++i) {
  135                 cbp = malloc(sizeof *cbp, M_TTYS, M_NOWAIT);
  136                 if (cbp == NULL) {
  137                         printf(
  138 "cblock_alloc_cblocks: M_NOWAIT malloc failed, trying M_WAITOK\n");
  139                         cbp = malloc(sizeof *cbp, M_TTYS, M_WAITOK);
  140                 }
  141                 /*
  142                  * Freed cblocks have zero quotes and garbage elsewhere.
  143                  * Set the may-have-quote bit to force zeroing the quotes.
  144                  */
  145                 setbit(cbp->c_quote, CBQSIZE * NBBY - 1);
  146                 cblock_free(cbp);
  147         }
  148         ctotcount += number;
  149 }
  150 
  151 /*
  152  * Set the cblock allocation policy for a a clist.
  153  * Must be called in process context at spltty().
  154  */
  155 void
  156 clist_alloc_cblocks(clistp, ccmax, ccreserved)
  157         struct clist *clistp;
  158         int ccmax;
  159         int ccreserved;
  160 {
  161         int dcbr;
  162 
  163         /*
  164          * Allow for wasted space at the head.
  165          */
  166         if (ccmax != 0)
  167                 ccmax += CBSIZE - 1;
  168         if (ccreserved != 0)
  169                 ccreserved += CBSIZE - 1;
  170 
  171         clistp->c_cbmax = roundup(ccmax, CBSIZE) / CBSIZE;
  172         dcbr = roundup(ccreserved, CBSIZE) / CBSIZE - clistp->c_cbreserved;
  173         if (dcbr >= 0)
  174                 cblock_alloc_cblocks(dcbr);
  175         else {
  176                 if (clistp->c_cbreserved + dcbr < clistp->c_cbcount)
  177                         dcbr = clistp->c_cbcount - clistp->c_cbreserved;
  178                 cblock_free_cblocks(-dcbr);
  179         }
  180         clistp->c_cbreserved += dcbr;
  181 }
  182 
  183 /*
  184  * Free some cblocks from the cfreelist queue back to the
  185  * system malloc pool.
  186  */
  187 static void
  188 cblock_free_cblocks(number)
  189         int number;
  190 {
  191         int i;
  192 
  193         for (i = 0; i < number; ++i)
  194                 free(cblock_alloc(), M_TTYS);
  195         ctotcount -= number;
  196 }
  197 
  198 /*
  199  * Free the cblocks reserved for a clist.
  200  * Must be called at spltty().
  201  */
  202 void
  203 clist_free_cblocks(clistp)
  204         struct clist *clistp;
  205 {
  206         if (clistp->c_cbcount != 0)
  207                 panic("freeing active clist cblocks");
  208         cblock_free_cblocks(clistp->c_cbreserved);
  209         clistp->c_cbmax = 0;
  210         clistp->c_cbreserved = 0;
  211 }
  212 
  213 /*
  214  * Get a character from the head of a clist.
  215  */
  216 int
  217 getc(clistp)
  218         struct clist *clistp;
  219 {
  220         int chr = -1;
  221         int s;
  222         struct cblock *cblockp;
  223 
  224         s = spltty();
  225 
  226         /* If there are characters in the list, get one */
  227         if (clistp->c_cc) {
  228                 cblockp = (struct cblock *)((intptr_t)clistp->c_cf & ~CROUND);
  229                 chr = (u_char)*clistp->c_cf;
  230 
  231                 /*
  232                  * If this char is quoted, set the flag.
  233                  */
  234                 if (isset(cblockp->c_quote, clistp->c_cf - (char *)cblockp->c_info))
  235                         chr |= TTY_QUOTE;
  236 
  237                 /*
  238                  * Advance to next character.
  239                  */
  240                 clistp->c_cf++;
  241                 clistp->c_cc--;
  242                 /*
  243                  * If we have advanced the 'first' character pointer
  244                  * past the end of this cblock, advance to the next one.
  245                  * If there are no more characters, set the first and
  246                  * last pointers to NULL. In either case, free the
  247                  * current cblock.
  248                  */
  249                 if ((clistp->c_cf >= (char *)(cblockp+1)) || (clistp->c_cc == 0)) {
  250                         if (clistp->c_cc > 0) {
  251                                 clistp->c_cf = cblockp->c_next->c_info;
  252                         } else {
  253                                 clistp->c_cf = clistp->c_cl = NULL;
  254                         }
  255                         cblock_free(cblockp);
  256                         if (--clistp->c_cbcount >= clistp->c_cbreserved)
  257                                 ++cslushcount;
  258                 }
  259         }
  260 
  261         splx(s);
  262         return (chr);
  263 }
  264 
  265 /*
  266  * Copy 'amount' of chars, beginning at head of clist 'clistp' to
  267  * destination linear buffer 'dest'. Return number of characters
  268  * actually copied.
  269  */
  270 int
  271 q_to_b(clistp, dest, amount)
  272         struct clist *clistp;
  273         char *dest;
  274         int amount;
  275 {
  276         struct cblock *cblockp;
  277         struct cblock *cblockn;
  278         char *dest_orig = dest;
  279         int numc;
  280         int s;
  281 
  282         s = spltty();
  283 
  284         while (clistp && amount && (clistp->c_cc > 0)) {
  285                 cblockp = (struct cblock *)((intptr_t)clistp->c_cf & ~CROUND);
  286                 cblockn = cblockp + 1; /* pointer arithmetic! */
  287                 numc = min(amount, (char *)cblockn - clistp->c_cf);
  288                 numc = min(numc, clistp->c_cc);
  289                 bcopy(clistp->c_cf, dest, numc);
  290                 amount -= numc;
  291                 clistp->c_cf += numc;
  292                 clistp->c_cc -= numc;
  293                 dest += numc;
  294                 /*
  295                  * If this cblock has been emptied, advance to the next
  296                  * one. If there are no more characters, set the first
  297                  * and last pointer to NULL. In either case, free the
  298                  * current cblock.
  299                  */
  300                 if ((clistp->c_cf >= (char *)cblockn) || (clistp->c_cc == 0)) {
  301                         if (clistp->c_cc > 0) {
  302                                 clistp->c_cf = cblockp->c_next->c_info;
  303                         } else {
  304                                 clistp->c_cf = clistp->c_cl = NULL;
  305                         }
  306                         cblock_free(cblockp);
  307                         if (--clistp->c_cbcount >= clistp->c_cbreserved)
  308                                 ++cslushcount;
  309                 }
  310         }
  311 
  312         splx(s);
  313         return (dest - dest_orig);
  314 }
  315 
  316 /*
  317  * Flush 'amount' of chars, beginning at head of clist 'clistp'.
  318  */
  319 void
  320 ndflush(clistp, amount)
  321         struct clist *clistp;
  322         int amount;
  323 {
  324         struct cblock *cblockp;
  325         struct cblock *cblockn;
  326         int numc;
  327         int s;
  328 
  329         s = spltty();
  330 
  331         while (amount && (clistp->c_cc > 0)) {
  332                 cblockp = (struct cblock *)((intptr_t)clistp->c_cf & ~CROUND);
  333                 cblockn = cblockp + 1; /* pointer arithmetic! */
  334                 numc = min(amount, (char *)cblockn - clistp->c_cf);
  335                 numc = min(numc, clistp->c_cc);
  336                 amount -= numc;
  337                 clistp->c_cf += numc;
  338                 clistp->c_cc -= numc;
  339                 /*
  340                  * If this cblock has been emptied, advance to the next
  341                  * one. If there are no more characters, set the first
  342                  * and last pointer to NULL. In either case, free the
  343                  * current cblock.
  344                  */
  345                 if ((clistp->c_cf >= (char *)cblockn) || (clistp->c_cc == 0)) {
  346                         if (clistp->c_cc > 0) {
  347                                 clistp->c_cf = cblockp->c_next->c_info;
  348                         } else {
  349                                 clistp->c_cf = clistp->c_cl = NULL;
  350                         }
  351                         cblock_free(cblockp);
  352                         if (--clistp->c_cbcount >= clistp->c_cbreserved)
  353                                 ++cslushcount;
  354                 }
  355         }
  356 
  357         splx(s);
  358 }
  359 
  360 /*
  361  * Add a character to the end of a clist. Return -1 is no
  362  * more clists, or 0 for success.
  363  */
  364 int
  365 putc(chr, clistp)
  366         int chr;
  367         struct clist *clistp;
  368 {
  369         struct cblock *cblockp;
  370         int s;
  371 
  372         s = spltty();
  373 
  374         if (clistp->c_cl == NULL) {
  375                 if (clistp->c_cbreserved < 1) {
  376                         splx(s);
  377                         printf("putc to a clist with no reserved cblocks\n");
  378                         return (-1);            /* nothing done */
  379                 }
  380                 cblockp = cblock_alloc();
  381                 clistp->c_cbcount = 1;
  382                 clistp->c_cf = clistp->c_cl = cblockp->c_info;
  383                 clistp->c_cc = 0;
  384         } else {
  385                 cblockp = (struct cblock *)((intptr_t)clistp->c_cl & ~CROUND);
  386                 if (((intptr_t)clistp->c_cl & CROUND) == 0) {
  387                         struct cblock *prev = (cblockp - 1);
  388 
  389                         if (clistp->c_cbcount >= clistp->c_cbreserved) {
  390                                 if (clistp->c_cbcount >= clistp->c_cbmax
  391                                     || cslushcount <= 0) {
  392                                         splx(s);
  393                                         return (-1);
  394                                 }
  395                                 --cslushcount;
  396                         }
  397                         cblockp = cblock_alloc();
  398                         clistp->c_cbcount++;
  399                         prev->c_next = cblockp;
  400                         clistp->c_cl = cblockp->c_info;
  401                 }
  402         }
  403 
  404         /*
  405          * If this character is quoted, set the quote bit, if not, clear it.
  406          */
  407         if (chr & TTY_QUOTE) {
  408                 setbit(cblockp->c_quote, clistp->c_cl - (char *)cblockp->c_info);
  409                 /*
  410                  * Use one of the spare quote bits to record that something
  411                  * may be quoted.
  412                  */
  413                 setbit(cblockp->c_quote, CBQSIZE * NBBY - 1);
  414         } else
  415                 clrbit(cblockp->c_quote, clistp->c_cl - (char *)cblockp->c_info);
  416 
  417         *clistp->c_cl++ = chr;
  418         clistp->c_cc++;
  419 
  420         splx(s);
  421         return (0);
  422 }
  423 
  424 /*
  425  * Copy data from linear buffer to clist chain. Return the
  426  * number of characters not copied.
  427  */
  428 int
  429 b_to_q(src, amount, clistp)
  430         char *src;
  431         int amount;
  432         struct clist *clistp;
  433 {
  434         struct cblock *cblockp;
  435         char *firstbyte, *lastbyte;
  436         u_char startmask, endmask;
  437         int startbit, endbit, num_between, numc;
  438         int s;
  439 
  440         /*
  441          * Avoid allocating an initial cblock and then not using it.
  442          * c_cc == 0 must imply c_cbount == 0.
  443          */
  444         if (amount <= 0)
  445                 return (amount);
  446 
  447         s = spltty();
  448 
  449         /*
  450          * If there are no cblocks assigned to this clist yet,
  451          * then get one.
  452          */
  453         if (clistp->c_cl == NULL) {
  454                 if (clistp->c_cbreserved < 1) {
  455                         splx(s);
  456                         printf("b_to_q to a clist with no reserved cblocks.\n");
  457                         return (amount);        /* nothing done */
  458                 }
  459                 cblockp = cblock_alloc();
  460                 clistp->c_cbcount = 1;
  461                 clistp->c_cf = clistp->c_cl = cblockp->c_info;
  462                 clistp->c_cc = 0;
  463         } else {
  464                 cblockp = (struct cblock *)((intptr_t)clistp->c_cl & ~CROUND);
  465         }
  466 
  467         while (amount) {
  468                 /*
  469                  * Get another cblock if needed.
  470                  */
  471                 if (((intptr_t)clistp->c_cl & CROUND) == 0) {
  472                         struct cblock *prev = cblockp - 1;
  473 
  474                         if (clistp->c_cbcount >= clistp->c_cbreserved) {
  475                                 if (clistp->c_cbcount >= clistp->c_cbmax
  476                                     || cslushcount <= 0) {
  477                                         splx(s);
  478                                         return (amount);
  479                                 }
  480                                 --cslushcount;
  481                         }
  482                         cblockp = cblock_alloc();
  483                         clistp->c_cbcount++;
  484                         prev->c_next = cblockp;
  485                         clistp->c_cl = cblockp->c_info;
  486                 }
  487 
  488                 /*
  489                  * Copy a chunk of the linear buffer up to the end
  490                  * of this cblock.
  491                  */
  492                 numc = min(amount, (char *)(cblockp + 1) - clistp->c_cl);
  493                 bcopy(src, clistp->c_cl, numc);
  494 
  495                 /*
  496                  * Clear quote bits if they aren't known to be clear.
  497                  * The following could probably be made into a separate
  498                  * "bitzero()" routine, but why bother?
  499                  */
  500                 if (isset(cblockp->c_quote, CBQSIZE * NBBY - 1)) {
  501                         startbit = clistp->c_cl - (char *)cblockp->c_info;
  502                         endbit = startbit + numc - 1;
  503 
  504                         firstbyte = (u_char *)cblockp->c_quote + (startbit / NBBY);
  505                         lastbyte = (u_char *)cblockp->c_quote + (endbit / NBBY);
  506 
  507                         /*
  508                          * Calculate mask of bits to preserve in first and
  509                          * last bytes.
  510                          */
  511                         startmask = NBBY - (startbit % NBBY);
  512                         startmask = 0xff >> startmask;
  513                         endmask = (endbit % NBBY);
  514                         endmask = 0xff << (endmask + 1);
  515 
  516                         if (firstbyte != lastbyte) {
  517                                 *firstbyte &= startmask;
  518                                 *lastbyte &= endmask;
  519 
  520                                 num_between = lastbyte - firstbyte - 1;
  521                                 if (num_between)
  522                                         bzero(firstbyte + 1, num_between);
  523                         } else {
  524                                 *firstbyte &= (startmask | endmask);
  525                         }
  526                 }
  527 
  528                 /*
  529                  * ...and update pointer for the next chunk.
  530                  */
  531                 src += numc;
  532                 clistp->c_cl += numc;
  533                 clistp->c_cc += numc;
  534                 amount -= numc;
  535                 /*
  536                  * If we go through the loop again, it's always
  537                  * for data in the next cblock, so by adding one (cblock),
  538                  * (which makes the pointer 1 beyond the end of this
  539                  * cblock) we prepare for the assignment of 'prev'
  540                  * above.
  541                  */
  542                 cblockp += 1;
  543 
  544         }
  545 
  546         splx(s);
  547         return (amount);
  548 }
  549 
  550 /*
  551  * Get the next character in the clist. Store it at dst. Don't
  552  * advance any clist pointers, but return a pointer to the next
  553  * character position.
  554  */
  555 char *
  556 nextc(clistp, cp, dst)
  557         struct clist *clistp;
  558         char *cp;
  559         int *dst;
  560 {
  561         struct cblock *cblockp;
  562 
  563         ++cp;
  564         /*
  565          * See if the next character is beyond the end of
  566          * the clist.
  567          */
  568         if (clistp->c_cc && (cp != clistp->c_cl)) {
  569                 /*
  570                  * If the next character is beyond the end of this
  571                  * cblock, advance to the next cblock.
  572                  */
  573                 if (((intptr_t)cp & CROUND) == 0)
  574                         cp = ((struct cblock *)cp - 1)->c_next->c_info;
  575                 cblockp = (struct cblock *)((intptr_t)cp & ~CROUND);
  576 
  577                 /*
  578                  * Get the character. Set the quote flag if this character
  579                  * is quoted.
  580                  */
  581                 *dst = (u_char)*cp | (isset(cblockp->c_quote, cp - (char *)cblockp->c_info) ? TTY_QUOTE : 0);
  582 
  583                 return (cp);
  584         }
  585 
  586         return (NULL);
  587 }
  588 
  589 /*
  590  * "Unput" a character from a clist.
  591  */
  592 int
  593 unputc(clistp)
  594         struct clist *clistp;
  595 {
  596         struct cblock *cblockp = 0, *cbp = 0;
  597         int s;
  598         int chr = -1;
  599 
  600 
  601         s = spltty();
  602 
  603         if (clistp->c_cc) {
  604                 --clistp->c_cc;
  605                 --clistp->c_cl;
  606 
  607                 chr = (u_char)*clistp->c_cl;
  608 
  609                 cblockp = (struct cblock *)((intptr_t)clistp->c_cl & ~CROUND);
  610 
  611                 /*
  612                  * Set quote flag if this character was quoted.
  613                  */
  614                 if (isset(cblockp->c_quote, (u_char *)clistp->c_cl - cblockp->c_info))
  615                         chr |= TTY_QUOTE;
  616 
  617                 /*
  618                  * If all of the characters have been unput in this
  619                  * cblock, then find the previous one and free this
  620                  * one.
  621                  */
  622                 if (clistp->c_cc && (clistp->c_cl <= (char *)cblockp->c_info)) {
  623                         cbp = (struct cblock *)((intptr_t)clistp->c_cf & ~CROUND);
  624 
  625                         while (cbp->c_next != cblockp)
  626                                 cbp = cbp->c_next;
  627 
  628                         /*
  629                          * When the previous cblock is at the end, the 'last'
  630                          * pointer always points (invalidly) one past.
  631                          */
  632                         clistp->c_cl = (char *)(cbp+1);
  633                         cblock_free(cblockp);
  634                         if (--clistp->c_cbcount >= clistp->c_cbreserved)
  635                                 ++cslushcount;
  636                         cbp->c_next = NULL;
  637                 }
  638         }
  639 
  640         /*
  641          * If there are no more characters on the list, then
  642          * free the last cblock.
  643          */
  644         if ((clistp->c_cc == 0) && clistp->c_cl) {
  645                 cblockp = (struct cblock *)((intptr_t)clistp->c_cl & ~CROUND);
  646                 cblock_free(cblockp);
  647                 if (--clistp->c_cbcount >= clistp->c_cbreserved)
  648                         ++cslushcount;
  649                 clistp->c_cf = clistp->c_cl = NULL;
  650         }
  651 
  652         splx(s);
  653         return (chr);
  654 }
  655 
  656 /*
  657  * Move characters in source clist to destination clist,
  658  * preserving quote bits.
  659  */
  660 void
  661 catq(src_clistp, dest_clistp)
  662         struct clist *src_clistp, *dest_clistp;
  663 {
  664         int chr, s;
  665 
  666         s = spltty();
  667         /*
  668          * If the destination clist is empty (has no cblocks atttached),
  669          * and there are no possible complications with the resource counters,
  670          * then we simply assign the current clist to the destination.
  671          */
  672         if (!dest_clistp->c_cf
  673             && src_clistp->c_cbcount <= src_clistp->c_cbmax
  674             && src_clistp->c_cbcount <= dest_clistp->c_cbmax) {
  675                 dest_clistp->c_cf = src_clistp->c_cf;
  676                 dest_clistp->c_cl = src_clistp->c_cl;
  677                 src_clistp->c_cf = src_clistp->c_cl = NULL;
  678 
  679                 dest_clistp->c_cc = src_clistp->c_cc;
  680                 src_clistp->c_cc = 0;
  681                 dest_clistp->c_cbcount = src_clistp->c_cbcount;
  682                 src_clistp->c_cbcount = 0;
  683 
  684                 splx(s);
  685                 return;
  686         }
  687 
  688         splx(s);
  689 
  690         /*
  691          * XXX  This should probably be optimized to more than one
  692          * character at a time.
  693          */
  694         while ((chr = getc(src_clistp)) != -1)
  695                 putc(chr, dest_clistp);
  696 }

Cache object: eb243b13342244c25922ea10e6140df1


[ 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.