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

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

unix.superglobalmegacorp.com

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