Annotation of kernel/bsd/kern/tty_subr.c, revision 1.1.1.1

1.1       root        1: /*-
                      2:  * Copyright (c) 1982, 1986, 1993
                      3:  *     The Regents of the University of California.  All rights reserved.
                      4:  * (c) UNIX System Laboratories, Inc.
                      5:  * All or some portions of this file are derived from material licensed
                      6:  * to the University of California by American Telephone and Telegraph
                      7:  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
                      8:  * the permission of UNIX System Laboratories, Inc.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. All advertising materials mentioning features or use of this software
                     19:  *    must display the following acknowledgement:
                     20:  *     This product includes software developed by the University of
                     21:  *     California, Berkeley and its contributors.
                     22:  * 4. Neither the name of the University nor the names of its contributors
                     23:  *    may be used to endorse or promote products derived from this software
                     24:  *    without specific prior written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     27:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     28:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     29:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     30:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     31:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     32:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     33:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     34:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     35:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     36:  * SUCH DAMAGE.
                     37:  *
                     38:  *     from: @(#)tty_subr.c    8.2 (Berkeley) 9/5/93
                     39:  */
                     40: 
                     41: #include <sys/param.h>
                     42: #include <sys/systm.h>
                     43: #include <sys/buf.h>
                     44: #include <sys/ioctl.h>
                     45: #include <sys/tty.h>
                     46: #include <sys/malloc.h>
                     47: 
                     48: #include <machine/spl.h>
                     49: 
                     50: /*
                     51:  * At compile time, choose:
                     52:  * There are two ways the TTY_QUOTE bit can be stored. If QBITS is
                     53:  * defined we allocate an array of bits -- 1/8th as much memory but
                     54:  * setbit(), clrbit(), and isset() take more cpu. If QBITS is
                     55:  * undefined, we just use an array of bytes.
                     56:  * 
                     57:  * If TTY_QUOTE functionality isn't required by a line discipline,
                     58:  * it can free c_cq and set it to NULL. This speeds things up,
                     59:  * and also does not use any extra memory. This is useful for (say)
                     60:  * a SLIP line discipline that wants a 32K ring buffer for data
                     61:  * but doesn't need quoting.
                     62:  */
                     63: #define QBITS
                     64: 
                     65: #ifdef QBITS
                     66: #define QMEM(n)                ((((n)-1)/NBBY)+1)
                     67: #else
                     68: #define QMEM(n)                (n)
                     69: #endif
                     70: 
                     71: 
                     72: /*
                     73:  * Initialize clists.
                     74:  */
                     75: void
                     76: cinit()
                     77: {
                     78: }
                     79: 
                     80: /*
                     81:  * Initialize a particular clist. Ok, they are really ring buffers,
                     82:  * of the specified length, with/without quoting support.
                     83:  */
                     84: int
                     85: clalloc(clp, size, quot)
                     86:        struct clist *clp;
                     87:        int size;
                     88:        int quot;
                     89: {
                     90: 
                     91:        MALLOC(clp->c_cs, u_char *, size, M_TTYS, M_WAITOK);
                     92:        if (!clp->c_cs)
                     93:                return (-1);
                     94:        bzero(clp->c_cs, size);
                     95: 
                     96:        if(quot) {
                     97:                MALLOC(clp->c_cq, u_char *, QMEM(size), M_TTYS, M_WAITOK);
                     98:                if (!clp->c_cq) {
                     99:                        FREE(clp->c_cs, M_TTYS);
                    100:                        return (-1);
                    101:                }
                    102:                bzero(clp->c_cs, QMEM(size));
                    103:        } else
                    104:                clp->c_cq = (u_char *)0;
                    105: 
                    106:        clp->c_cf = clp->c_cl = (u_char *)0;
                    107:        clp->c_ce = clp->c_cs + size;
                    108:        clp->c_cn = size;
                    109:        clp->c_cc = 0;
                    110:        return (0);
                    111: }
                    112: 
                    113: void
                    114: clfree(clp)
                    115:        struct clist *clp;
                    116: {
                    117:        if(clp->c_cs)
                    118:                FREE(clp->c_cs, M_TTYS);
                    119:        if(clp->c_cq)
                    120:                FREE(clp->c_cq, M_TTYS);
                    121:        clp->c_cs = clp->c_cq = (u_char *)0;
                    122: }
                    123: 
                    124: 
                    125: /*
                    126:  * Get a character from a clist.
                    127:  */
                    128: int
                    129: getc(clp)
                    130:        struct clist *clp;
                    131: {
                    132:        register int c = -1;
                    133:        int s;
                    134: 
                    135:        s = spltty();
                    136:        if (clp->c_cc == 0)
                    137:                goto out;
                    138: 
                    139:        c = *clp->c_cf & 0xff;
                    140:        if (clp->c_cq) {
                    141: #ifdef QBITS
                    142:                if (isset(clp->c_cq, clp->c_cf - clp->c_cs) )
                    143:                        c |= TTY_QUOTE;
                    144: #else
                    145:                if (*(clp->c_cf - clp->c_cs + clp->c_cq))
                    146:                        c |= TTY_QUOTE;
                    147: #endif
                    148:        }
                    149:        if (++clp->c_cf == clp->c_ce)
                    150:                clp->c_cf = clp->c_cs;
                    151:        if (--clp->c_cc == 0)
                    152:                clp->c_cf = clp->c_cl = (u_char *)0;
                    153: out:
                    154:        splx(s);
                    155:        return c;
                    156: }
                    157: 
                    158: /*
                    159:  * Copy clist to buffer.
                    160:  * Return number of bytes moved.
                    161:  */
                    162: int
                    163: q_to_b(clp, cp, count)
                    164:        struct clist *clp;
                    165:        u_char *cp;
                    166:        int count;
                    167: {
                    168:        register int cc;
                    169:        u_char *p = cp;
                    170:        int s;
                    171: 
                    172:        s = spltty();
                    173:        /* optimize this while loop */
                    174:        while (count > 0 && clp->c_cc > 0) {
                    175:                cc = clp->c_cl - clp->c_cf;
                    176:                if (clp->c_cf >= clp->c_cl)
                    177:                        cc = clp->c_ce - clp->c_cf;
                    178:                if (cc > count)
                    179:                        cc = count;
                    180:                bcopy(clp->c_cf, p, cc);
                    181:                count -= cc;
                    182:                p += cc;
                    183:                clp->c_cc -= cc;
                    184:                clp->c_cf += cc;
                    185:                if (clp->c_cf == clp->c_ce)
                    186:                        clp->c_cf = clp->c_cs;
                    187:        }
                    188:        if (clp->c_cc == 0)
                    189:                clp->c_cf = clp->c_cl = (u_char *)0;
                    190:        splx(s);
                    191:        return p - cp;
                    192: }
                    193: 
                    194: /*
                    195:  * Return count of contiguous characters in clist.
                    196:  * Stop counting if flag&character is non-null.
                    197:  */
                    198: int
                    199: ndqb(clp, flag)
                    200:        struct clist *clp;
                    201:        int flag;
                    202: {
                    203:        int count = 0;
                    204:        register int i;
                    205:        register int cc;
                    206:        int s;
                    207: 
                    208:        s = spltty();
                    209:        if ((cc = clp->c_cc) == 0)
                    210:                goto out;
                    211: 
                    212:        if (flag == 0) {
                    213:                count = clp->c_cl - clp->c_cf;
                    214:                if (count <= 0)
                    215:                        count = clp->c_ce - clp->c_cf;
                    216:                goto out;
                    217:        }
                    218: 
                    219:        i = clp->c_cf - clp->c_cs;
                    220:        if (flag & TTY_QUOTE) {
                    221:                while (cc-- > 0 && !(clp->c_cs[i++] & (flag & ~TTY_QUOTE) ||
                    222:                    isset(clp->c_cq, i))) {
                    223:                        count++;
                    224:                        if (i == clp->c_cn)
                    225:                                break;
                    226:                }
                    227:        } else {
                    228:                while (cc-- > 0 && !(clp->c_cs[i++] & flag)) {
                    229:                        count++;
                    230:                        if (i == clp->c_cn)
                    231:                                break;
                    232:                }
                    233:        }
                    234: out:
                    235:        splx(s);
                    236:        return count;
                    237: }
                    238: 
                    239: /*
                    240:  * Flush count bytes from clist.
                    241:  */
                    242: void
                    243: ndflush(clp, count)
                    244:        struct clist *clp;
                    245:        int count;
                    246: {
                    247:        register int cc;
                    248:        int s;
                    249: 
                    250:        s = spltty();
                    251:        if (count == clp->c_cc) {
                    252:                clp->c_cc = 0;
                    253:                clp->c_cf = clp->c_cl = (u_char *)0;
                    254:                goto out;
                    255:        }
                    256:        /* optimize this while loop */
                    257:        while (count > 0 && clp->c_cc > 0) {
                    258:                cc = clp->c_cl - clp->c_cf;
                    259:                if (clp->c_cf >= clp->c_cl)
                    260:                        cc = clp->c_ce - clp->c_cf;
                    261:                if (cc > count)
                    262:                        cc = count;
                    263:                count -= cc;
                    264:                clp->c_cc -= cc;
                    265:                clp->c_cf += cc;
                    266:                if (clp->c_cf == clp->c_ce)
                    267:                        clp->c_cf = clp->c_cs;
                    268:        }
                    269:        if (clp->c_cc == 0)
                    270:                clp->c_cf = clp->c_cl = (u_char *)0;
                    271: out:
                    272:        splx(s);
                    273: }
                    274: 
                    275: /*
                    276:  * Put a character into the output queue.
                    277:  */
                    278: int
                    279: putc(c, clp)
                    280:        int c;
                    281:        struct clist *clp;
                    282: {
                    283:        register int i;
                    284:        int s;
                    285: 
                    286:        s = spltty();
                    287:        if (clp->c_cc == 0) {
                    288:                if (!clp->c_cs) {
                    289: #if DIAGNOSTIC
                    290:                        //printf("putc: required clalloc\n");
                    291: #endif
                    292:                        if(clalloc(clp, 1024, 1)) {
                    293: out:
                    294:                                splx(s);
                    295:                                return -1;
                    296:                        }
                    297:                }
                    298:                clp->c_cf = clp->c_cl = clp->c_cs;
                    299:        }
                    300: 
                    301:        if (clp->c_cc == clp->c_cn)
                    302:                goto out;
                    303: 
                    304:        *clp->c_cl = c & 0xff;
                    305:        i = clp->c_cl - clp->c_cs;
                    306:        if (clp->c_cq) {
                    307: #ifdef QBITS
                    308:                if (c & TTY_QUOTE)
                    309:                        setbit(clp->c_cq, i); 
                    310:                else
                    311:                        clrbit(clp->c_cq, i);
                    312: #else
                    313:                q = clp->c_cq + i;
                    314:                *q = (c & TTY_QUOTE) ? 1 : 0;
                    315: #endif
                    316:        }
                    317:        clp->c_cc++;
                    318:        clp->c_cl++;
                    319:        if (clp->c_cl == clp->c_ce)
                    320:                clp->c_cl = clp->c_cs;
                    321:        splx(s);
                    322:        return 0;
                    323: }
                    324: 
                    325: #ifdef QBITS
                    326: /*
                    327:  * optimized version of
                    328:  *
                    329:  * for (i = 0; i < len; i++)
                    330:  *     clrbit(cp, off + len);
                    331:  */
                    332: void
                    333: clrbits(cp, off, len)
                    334:        u_char *cp;
                    335:        int off;
                    336:        int len;
                    337: {
                    338:        int sby, sbi, eby, ebi;
                    339:        register int i;
                    340:        u_char mask;
                    341: 
                    342:        if(len==1) {
                    343:                clrbit(cp, off);
                    344:                return;
                    345:        }
                    346: 
                    347:        sby = off / NBBY;
                    348:        sbi = off % NBBY;
                    349:        eby = (off+len) / NBBY;
                    350:        ebi = (off+len) % NBBY;
                    351:        if (sby == eby) {
                    352:                mask = ((1 << (ebi - sbi)) - 1) << sbi;
                    353:                cp[sby] &= ~mask;
                    354:        } else {
                    355:                mask = (1<<sbi) - 1;
                    356:                cp[sby++] &= mask;
                    357: 
                    358:                mask = (1<<ebi) - 1;
                    359:                cp[eby] &= ~mask;
                    360: 
                    361:                for (i = sby; i < eby; i++)
                    362:                        cp[i] = 0x00;
                    363:        }
                    364: }
                    365: #endif
                    366: 
                    367: /*
                    368:  * Copy buffer to clist.
                    369:  * Return number of bytes not transfered.
                    370:  */
                    371: int
                    372: b_to_q(cp, count, clp)
                    373:        u_char *cp;
                    374:        int count;
                    375:        struct clist *clp;
                    376: {
                    377:        register int cc;
                    378:        register u_char *p = cp;
                    379:        int s;
                    380: 
                    381:        if (count <= 0)
                    382:                return 0;
                    383: 
                    384:        s = spltty();
                    385: 
                    386:        if (clp->c_cc == 0) {
                    387:                if (!clp->c_cs) {
                    388: #if DIAGNOSTIC
                    389:                        printf("b_to_q: required clalloc\n");
                    390: #endif
                    391:                        if(clalloc(clp, 1024, 1))
                    392:                                goto out;
                    393:                }
                    394:                clp->c_cf = clp->c_cl = clp->c_cs;
                    395:        }
                    396: 
                    397:        if (clp->c_cc == clp->c_cn)
                    398:                goto out;
                    399: 
                    400:        /* optimize this while loop */
                    401:        while (count > 0 && clp->c_cc < clp->c_cn) {
                    402:                cc = clp->c_ce - clp->c_cl;
                    403:                if (clp->c_cf > clp->c_cl)
                    404:                        cc = clp->c_cf - clp->c_cl;
                    405:                if (cc > count)
                    406:                        cc = count;
                    407:                bcopy(p, clp->c_cl, cc);
                    408:                if (clp->c_cq) {
                    409: #ifdef QBITS
                    410:                        clrbits(clp->c_cq, clp->c_cl - clp->c_cs, cc);
                    411: #else
                    412:                        bzero(clp->c_cl - clp->c_cs + clp->c_cq, cc);
                    413: #endif
                    414:                }
                    415:                p += cc;
                    416:                count -= cc;
                    417:                clp->c_cc += cc;
                    418:                clp->c_cl += cc;
                    419:                if (clp->c_cl == clp->c_ce)
                    420:                        clp->c_cl = clp->c_cs;
                    421:        }
                    422: out:
                    423:        splx(s);
                    424:        return count;
                    425: }
                    426: 
                    427: static int cc;
                    428: 
                    429: /*
                    430:  * Given a non-NULL pointer into the clist return the pointer
                    431:  * to the next character in the list or return NULL if no more chars.
                    432:  *
                    433:  * Callers must not allow getc's to happen between firstc's and getc's
                    434:  * so that the pointer becomes invalid.  Note that interrupts are NOT
                    435:  * masked.
                    436:  */
                    437: u_char *
                    438: nextc(clp, cp, c)
                    439:        struct clist *clp;
                    440:        register u_char *cp;
                    441:        int *c;
                    442: {
                    443: 
                    444:        if (clp->c_cf == cp) {
                    445:                /*
                    446:                 * First time initialization.
                    447:                 */
                    448:                cc = clp->c_cc;
                    449:        }
                    450:        if (cc == 0 || cp == NULL)
                    451:                return NULL;
                    452:        if (--cc == 0)
                    453:                return NULL;
                    454:        if (++cp == clp->c_ce)
                    455:                cp = clp->c_cs;
                    456:        *c = *cp & 0xff;
                    457:        if (clp->c_cq) {
                    458: #ifdef QBITS
                    459:                if (isset(clp->c_cq, cp - clp->c_cs))
                    460:                        *c |= TTY_QUOTE;
                    461: #else
                    462:                if (*(clp->c_cf - clp->c_cs + clp->c_cq))
                    463:                        *c |= TTY_QUOTE;
                    464: #endif
                    465:        }
                    466:        return cp;
                    467: }
                    468: 
                    469: /*
                    470:  * Given a non-NULL pointer into the clist return the pointer
                    471:  * to the first character in the list or return NULL if no more chars.
                    472:  *
                    473:  * Callers must not allow getc's to happen between firstc's and getc's
                    474:  * so that the pointer becomes invalid.  Note that interrupts are NOT
                    475:  * masked.
                    476:  *
                    477:  * *c is set to the NEXT character
                    478:  */
                    479: u_char *
                    480: firstc(clp, c)
                    481:        struct clist *clp;
                    482:        int *c;
                    483: {
                    484:        register u_char *cp;
                    485: 
                    486:        cc = clp->c_cc;
                    487:        if (cc == 0)
                    488:                return NULL;
                    489:        cp = clp->c_cf;
                    490:        *c = *cp & 0xff;
                    491:        if(clp->c_cq) {
                    492: #ifdef QBITS
                    493:                if (isset(clp->c_cq, cp - clp->c_cs))
                    494:                        *c |= TTY_QUOTE;
                    495: #else
                    496:                if (*(cp - clp->c_cs + clp->c_cq))
                    497:                        *c |= TTY_QUOTE;
                    498: #endif
                    499:        }
                    500:        return clp->c_cf;
                    501: }
                    502: 
                    503: /*
                    504:  * Remove the last character in the clist and return it.
                    505:  */
                    506: int
                    507: unputc(clp)
                    508:        struct clist *clp;
                    509: {
                    510:        unsigned int c = -1;
                    511:        int s;
                    512: 
                    513:        s = spltty();
                    514:        if (clp->c_cc == 0)
                    515:                goto out;
                    516: 
                    517:        if (clp->c_cl == clp->c_cs)
                    518:                clp->c_cl = clp->c_ce - 1;
                    519:        else
                    520:                --clp->c_cl;
                    521:        clp->c_cc--;
                    522: 
                    523:        c = *clp->c_cl & 0xff;
                    524:        if (clp->c_cq) {
                    525: #ifdef QBITS
                    526:                if (isset(clp->c_cq, clp->c_cl - clp->c_cs))
                    527:                        c |= TTY_QUOTE;
                    528: #else
                    529:                if (*(clp->c_cf - clp->c_cs + clp->c_cq))
                    530:                        c |= TTY_QUOTE;
                    531: #endif
                    532:        }
                    533:        if (clp->c_cc == 0)
                    534:                clp->c_cf = clp->c_cl = (u_char *)0;
                    535: out:
                    536:        splx(s);
                    537:        return c;
                    538: }
                    539: 
                    540: /*
                    541:  * Put the chars in the from queue on the end of the to queue.
                    542:  */
                    543: void
                    544: catq(from, to)
                    545:        struct clist *from, *to;
                    546: {
                    547:        int c;
                    548: 
                    549:        while ((c = getc(from)) != -1)
                    550:                putc(c, to);
                    551: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.