Annotation of kernel/bsd/kern/tty_subr.c, revision 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.