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

Cache object: 96b98c48ba8a2966b4d4e7c3d8e73666


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