Annotation of Net2/kern/tty_subr.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

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