Annotation of researchv9/sys/dev/ttyld.c, revision 1.1.1.1

1.1       root        1: #include "../h/param.h"
                      2: #include "../h/stream.h"
                      3: #include "../h/ttyio.h"
                      4: #include "../h/ttyld.h"
                      5: #include "../h/conf.h"
                      6: #include "tty.h"
                      7: 
                      8: extern char    partab[];
                      9: 
                     10: #define        CANBSIZ 256             /* size of largest input line */
                     11: 
                     12: struct ttyld   tty[NTTY];
                     13: 
                     14: char   maptab[] = {
                     15:        000,000,000,000,000,000,000,000,
                     16:        000,000,000,000,000,000,000,000,
                     17:        000,000,000,000,000,000,000,000,
                     18:        000,000,000,000,000,000,000,000,
                     19:        000,'|',000,000,000,000,000,'`',
                     20:        '{','}',000,000,000,000,000,000,
                     21:        000,000,000,000,000,000,000,000,
                     22:        000,000,000,000,000,000,000,000,
                     23:        000,000,000,000,000,000,000,000,
                     24:        000,000,000,000,000,000,000,000,
                     25:        000,000,000,000,000,000,000,000,
                     26:        000,000,000,000,'\\',000,'~',000,
                     27:        000,'A','B','C','D','E','F','G',
                     28:        'H','I','J','K','L','M','N','O',
                     29:        'P','Q','R','S','T','U','V','W',
                     30:        'X','Y','Z',000,000,000,000,000,
                     31: };
                     32: 
                     33: int    ttyopen(), ttyclose(), ttyldin(), ttyinsrv(), ttyosrv();
                     34: static struct qinit ttrinit = { ttyldin, ttyinsrv, ttyopen, ttyclose, 600, 60};
                     35: static struct qinit ttwinit = { putq, ttyosrv, ttyopen, ttyclose, 300, 200};
                     36: struct streamtab ttyinfo = { &ttrinit, &ttwinit};
                     37: 
                     38: /*
                     39:  * TTY open
                     40:  */
                     41: ttyopen(qp, dev)
                     42: register struct queue *qp;
                     43: {
                     44:        register struct ttyld *tp;
                     45:        static struct tchars tchars = {CINTR,CQUIT,CSTART,CSTOP,CEOT,0377};
                     46: 
                     47:        if (qp->ptr)                            /* already attached */
                     48:                return(1);
                     49:        for (tp = tty; tp->t_state&TTUSE; tp++)
                     50:                if (tp >= &tty[NTTY-1])
                     51:                        return(0);
                     52:        tp->t_state = TTUSE;
                     53:        tp->t_flags = ECHO|CRMOD;
                     54:        tp->t_delct = 0;
                     55:        tp->t_col = 0;
                     56:        tp->t_erase = CERASE;
                     57:        tp->t_kill = CKILL;
                     58:        tp->t_chr = tchars;
                     59:        qp->ptr = (caddr_t)tp;
                     60:        qp->flag |= QDELIM|QNOENB;
                     61:        WR(qp)->ptr = (caddr_t)tp;
                     62:        return(1);
                     63: }
                     64: 
                     65: ttyclose(qp)
                     66: register struct queue *qp;
                     67: {
                     68:        register struct ttyld *tp = (struct ttyld *)qp->ptr;
                     69: 
                     70:        tp->t_state = 0;
                     71: }
                     72: 
                     73: /*
                     74:  * Queue put procedure for tty input
                     75:  */
                     76: ttyldin(q, bp)
                     77: struct queue *q;
                     78: register struct block *bp;
                     79: {
                     80:        register struct ttyld *tp;
                     81:        register c;
                     82:        register struct queue *wrq = WR(q);     /* writer side */
                     83:        int escape, flags;
                     84: 
                     85:        tp = (struct ttyld *)q->ptr;
                     86:        flags = tp->t_flags;
                     87:        if (bp->type!=M_DATA) {
                     88:                switch(bp->type) {
                     89: 
                     90:                case M_DELIM:
                     91:                        freeb(bp);
                     92:                        return;
                     93: 
                     94:                case M_BREAK:
                     95:                        if (tp->t_flags&RAW) {          /* speed-change hack*/
                     96:                                bp->type = M_DATA;
                     97:                                if (bp->wptr<bp->lim)
                     98:                                        *bp->wptr++ = '\0';
                     99:                                break;
                    100:                        }
                    101:                        ttysig(q, SIGINT);
                    102:                        freeb(bp);
                    103:                        return;
                    104: 
                    105:                case M_HANGUP:
                    106:                case M_IOCACK:
                    107:                case M_IOCNAK:
                    108:                        (*q->next->qinfo->putp)(q->next, bp);
                    109:                        return;
                    110: 
                    111:                case M_IOCTL:
                    112:                        ttldioc(WR(q), bp, q, 1);
                    113:                        return;
                    114:                }
                    115:                flags |= RAW;
                    116:        }
                    117:        if (tp->t_flags&TANDEM && tp->t_state&TTBLOCK
                    118:         && q->count <= q->qinfo->lolimit) {
                    119:                tp->t_state &= ~TTBLOCK;
                    120:                putd(putq, WR(q), tp->t_chr.t_startc);
                    121:        }
                    122:        if (flags&RAW) {
                    123:                if ((q->next->flag&QFULL)==0 && q->count==0)
                    124:                        (*q->next->qinfo->putp)(q->next, bp);
                    125:                else
                    126:                        putq(q, bp);
                    127:                return;
                    128:        }
                    129:        while (bp->rptr<bp->wptr) {
                    130:                c = *bp->rptr++ & 0177;
                    131:                if (tp->t_state&TTSTOP) {
                    132:                        if (c==tp->t_chr.t_startc || c==tp->t_chr.t_intrc) {
                    133:                                tp->t_state &= ~TTSTOP;
                    134:                                putctl(wrq->next, M_START);
                    135:                        }
                    136:                } else {
                    137:                        if (c==tp->t_chr.t_stopc) {
                    138:                                tp->t_state |= TTSTOP;
                    139:                                putctl(wrq->next, M_STOP);
                    140:                        }
                    141:                }
                    142:                if (c==tp->t_chr.t_stopc || c==tp->t_chr.t_startc)
                    143:                        continue;
                    144:                if (c==tp->t_chr.t_intrc) {
                    145:                        ttysig(q, SIGINT);
                    146:                        continue;
                    147:                }
                    148:                if (c==tp->t_chr.t_quitc) {
                    149:                        ttysig(q, SIGQUIT);
                    150:                        continue;
                    151:                }
                    152:                if (c=='\r' && tp->t_flags&CRMOD)
                    153:                        c = '\n';
                    154:                if (tp->t_flags&LCASE && c>='A' && c<='Z')
                    155:                        c += 'a'-'A';
                    156:                escape = 0;
                    157:                if (tp->t_flags & CBREAK) {
                    158:                        if ((q->next->flag&QFULL)==0 && q->count==0)
                    159:                                putd(q->next->qinfo->putp, q->next, c);
                    160:                        else
                    161:                                putd(putq, q, c);
                    162:                } else {
                    163:                        if (tp->t_state&TTESC) {
                    164:                                escape = 1;
                    165:                                c |= 0200;
                    166:                        }
                    167:                        if (c == '\\')
                    168:                                tp->t_state |= TTESC;
                    169:                        else {
                    170:                                tp->t_state &= ~TTESC;
                    171:                                if (c == ('\\'|0200)) {
                    172:                                        c &= 0177;
                    173:                                        tp->t_state |= TTESC;
                    174:                                }
                    175:                                /* ttyhog? */
                    176:                                if (q->count<512 || (c=='\n' && tp->t_delct==0))
                    177:                                        putd(putq, q, c);
                    178:                                else
                    179:                                        c = '\007';
                    180:                        }
                    181:                        c &= 0177;
                    182:                        if (c=='\n'||c==tp->t_chr.t_eofc||c==tp->t_chr.t_brkc) {
                    183:                                register struct block *bp1;
                    184:                                if (bp1 = allocb(1)) {
                    185:                                        bp1->type = M_DELIM;
                    186:                                        putq(q, bp1);
                    187:                                        tp->t_delct++;
                    188:                                }
                    189:                                qenable(q);
                    190:                        }
                    191:                }
                    192:                if (tp->t_flags&TANDEM && (tp->t_state&TTBLOCK) == 0
                    193:                 && q->count >= (q->qinfo->limit+q->qinfo->lolimit)/2 ) {
                    194:                        q->next->flag |= QWANTW;
                    195:                        tp->t_state |= TTBLOCK;
                    196:                        putd(putq, wrq, tp->t_chr.t_stopc);
                    197:                }
                    198:                if (tp->t_flags&ECHO && (wrq->flag&QFULL)==0) {
                    199:                        register c1 = c&0177;
                    200:                        if (c1!=CEOT) {
                    201:                                putd(putq, wrq, c1);
                    202:                                if(wrq->next->flag&QDELIM && bp->wptr==bp->rptr)
                    203:                                        putctl(wrq, M_DELIM);
                    204:                        }
                    205:                        if (c==tp->t_kill && (tp->t_flags&CBREAK)==0
                    206:                         && !escape) {
                    207:                                putd(putq, wrq, '\n');
                    208:                                if (wrq->next->flag&QDELIM)
                    209:                                        putctl(wrq, M_DELIM);
                    210:                        }
                    211:                }
                    212:        }
                    213:        freeb(bp);
                    214: }
                    215: 
                    216: /*
                    217:  * tty input server processing.  Erase-kill and escape processing;
                    218:  * gathering into lines.
                    219:  */
                    220: 
                    221: ttyinsrv(q)
                    222: register struct queue *q;
                    223: {
                    224:        register struct ttyld *tp;
                    225:        register struct block *bp;
                    226:        register char *op;
                    227:        register c;
                    228:        static char canonb[CANBSIZ];
                    229: 
                    230:        tp = (struct ttyld *)q->ptr;
                    231:        if (q->next->flag&QFULL)
                    232:                return;
                    233:        if (tp->t_flags&(CBREAK|RAW)) {
                    234:                while ((q->next->flag&QFULL)==0 && (bp = getq(q)))
                    235:                        (*q->next->qinfo->putp)(q->next, bp);
                    236:        } else {
                    237:                op = canonb;
                    238:                while (tp->t_delct) {
                    239:                        bp = getq(q);
                    240:                        if (bp==NULL || bp->type!=M_DATA) {
                    241:                                if (op > canonb)
                    242:                                        putcpy(q->next, canonb, op-canonb);
                    243:                                if (bp) {
                    244:                                        (*q->next->qinfo->putp)(q->next, bp);
                    245:                                        tp->t_delct--;
                    246:                                        op = canonb;
                    247:                                        continue;
                    248:                                }
                    249:                                return;
                    250:                        }
                    251:                        while (bp->rptr<bp->wptr) {
                    252:                                c = *bp->rptr++;
                    253:                                if ((c&0200) == 0) {    /* not escaped */
                    254:                                        if (c == tp->t_erase) {
                    255:                                                if (op > canonb)
                    256:                                                        op--;
                    257:                                                continue;
                    258:                                        }
                    259:                                        if (c == tp->t_kill) {
                    260:                                                op = canonb;
                    261:                                                continue;
                    262:                                        }
                    263:                                        if (c == tp->t_chr.t_eofc)
                    264:                                                continue;
                    265:                                } else {
                    266:                                        c &= 0177;
                    267:                                        if (tp->t_flags&LCASE && maptab[c])
                    268:                                                c = maptab[c];
                    269:                                        else if (c==tp->t_erase || c==tp->t_kill
                    270:                                              || c==tp->t_chr.t_eofc)
                    271:                                                ;
                    272:                                        else
                    273:                                                *op++ = '\\';
                    274:                                }
                    275:                                *op++ = c;
                    276:                                if (op >= &canonb[CANBSIZ-1]) {
                    277:                                        putcpy(q->next, canonb, op-canonb);
                    278:                                        op = canonb;
                    279:                                }
                    280:                        }
                    281:                        freeb(bp);
                    282:                }
                    283:        }
                    284:        if (tp->t_flags&TANDEM && tp->t_state&TTBLOCK
                    285:         && q->count <= q->qinfo->lolimit) {
                    286:                tp->t_state &= ~TTBLOCK;
                    287:                putd(putq, WR(q), tp->t_chr.t_startc);
                    288:        }
                    289: }
                    290: 
                    291: /*
                    292:  * TTY write processing: delays, tabs, CR/NL and the like.
                    293:  */
                    294: ttyosrv(q)
                    295: register struct queue *q;
                    296: {
                    297:        register struct ttyld *tp;
                    298:        register struct block *bp;
                    299: 
                    300:        tp = (struct ttyld *)q->ptr;
                    301:        while (bp = getq(q)) {
                    302:                switch(bp->type) {
                    303: 
                    304:                default:
                    305:                        freeb(bp);
                    306:                        continue;
                    307: 
                    308:                case M_DELIM:
                    309:                        if ((q->next->flag & QDELIM) == 0) {
                    310:                                freeb(bp);
                    311:                                continue;
                    312:                        }
                    313:                        if (q->next->flag & QFULL) {
                    314:                                putbq(q, bp);
                    315:                                return;
                    316:                        }
                    317:                        (*q->next->qinfo->putp)(q->next, bp);
                    318:                        continue;
                    319: 
                    320:                case M_IOCTL:
                    321:                        if (q->next->flag & QFULL) {
                    322:                                putbq(q, bp);
                    323:                                return;
                    324:                        }
                    325:                        ttldioc(q, bp, RD(q), 0);
                    326:                        continue;
                    327: 
                    328:                case M_FLUSH:
                    329:                        flushq(q, 0);
                    330:                case M_IOCNAK:          /* flow through */
                    331:                case M_IOCACK:
                    332:                        (*q->next->qinfo->putp)(q->next, bp);
                    333:                        continue;
                    334: 
                    335:                case M_DATA:
                    336:                case M_BREAK:
                    337:                        if (q->next->flag & QFULL) {
                    338:                                putbq(q, bp);
                    339:                                return;
                    340:                        }
                    341:                        if (tp->t_flags&RAW || bp->type==M_BREAK) {
                    342:                                (*q->next->qinfo->putp)(q->next, bp);
                    343:                        } else
                    344:                                outconv(q, bp);
                    345:                        continue;
                    346:                }
                    347:        }
                    348: }
                    349: 
                    350: outconv(q, ibp)
                    351: struct queue *q;
                    352: register struct block *ibp;
                    353: {
                    354:        register struct ttyld *tp;
                    355:        register struct block *obp = NULL;
                    356:        register c;
                    357:        register count, ctype;
                    358: 
                    359:        tp = (struct ttyld *)q->ptr;
                    360:    more:
                    361:        while (ibp->rptr < ibp->wptr) {
                    362:                if (obp==NULL || obp->wptr >= obp->lim) {
                    363:                        if (obp)
                    364:                                (*q->next->qinfo->putp)(q->next, obp);
                    365:                        if (q->next->flag&QFULL || (obp=allocb(QBSIZE))==NULL) {
                    366:                                putbq(q, ibp);
                    367:                                return;
                    368:                        }
                    369:                }
                    370:                /*
                    371:                 * The following dance is an inner loop
                    372:                 */
                    373:                count = ibp->wptr - ibp->rptr;
                    374:                if ((c = obp->lim - obp->wptr) < count)
                    375:                        count = c;
                    376:                while ((ctype = partab[c = *ibp->rptr++ & 0177] & 077) == 0) {
                    377:                        tp->t_col++;
                    378:                        *obp->wptr++ = c;
                    379:                        if (--count <= 0)
                    380:                                goto more;
                    381:                }
                    382:                if (c=='\t' && (tp->t_flags&TBDELAY)==XTABS) {
                    383:                        for (;;) {
                    384:                                *obp->wptr++ = ' ';
                    385:                                tp->t_col++;
                    386:                                if ((tp->t_col & 07) == 0)      /* every 8 */
                    387:                                        break;
                    388:                                if (obp->wptr >= obp->lim) {
                    389:                                        ibp->rptr--;
                    390:                                        break;
                    391:                                }
                    392:                        }
                    393:                        continue;
                    394:                }
                    395: 
                    396:                /*
                    397:                 * turn <nl> to <cr><lf> if desired.
                    398:                 */
                    399:                if (c=='\n' && tp->t_flags&CRMOD) {
                    400:                        if ((tp->t_state&TTCR)==0) {
                    401:                                tp->t_state |= TTCR;
                    402:                                c = '\r';
                    403:                                ctype = partab['\r'] & 077;
                    404:                                --ibp->rptr;
                    405:                        } else
                    406:                                tp->t_state &= ~TTCR;
                    407:                }
                    408:                /*
                    409:                 * store character
                    410:                 */
                    411:                *obp->wptr++ = c;
                    412:                /*
                    413:                 * Calculate delays and column movement
                    414:                 */
                    415:                count = 0;
                    416:                switch (ctype) {
                    417: 
                    418:                /* ordinary */
                    419:                case 0:
                    420:                        tp->t_col++;
                    421:                        break;
                    422:        
                    423:                /* non-printing */
                    424:                case 1:
                    425:                        break;
                    426:        
                    427:                /* backspace */
                    428:                case 2:
                    429:                        if (tp->t_col)
                    430:                                tp->t_col--;
                    431:                        break;
                    432:        
                    433:                /* newline */
                    434:                case 3:
                    435:                        ctype = (tp->t_flags >> 8) & 03;
                    436:                        if(ctype == 1) { /* tty 37 */
                    437:                                if (tp->t_col)
                    438:                                        count = max(((unsigned)tp->t_col>>4) + 3, (unsigned)6);
                    439:                        } else if (ctype == 2)  /* vt05 */
                    440:                                count = 6;
                    441:                        if ((tp->t_flags&CRMOD)==0)
                    442:                                tp->t_col = 0;
                    443:                        break;
                    444:        
                    445:                /* tab */
                    446:                case 4:
                    447:                        ctype = (tp->t_flags >> 10) & 03;
                    448:                        if(ctype == 1) { /* tty 37 */
                    449:                                count = 1 - (tp->t_col | ~07);
                    450:                                if (count < 5)
                    451:                                        count = 0;
                    452:                        }
                    453:                        tp->t_col |= 07;
                    454:                        tp->t_col++;
                    455:                        break;
                    456:        
                    457:                /* vertical motion */
                    458:                case 5:
                    459:                        if(tp->t_flags & VTDELAY)
                    460:                                count = 127;
                    461:                        break;
                    462:        
                    463:                /* carriage return */
                    464:                case 6:
                    465:                        ctype = (tp->t_flags >> 12) & 03;
                    466:                        if (ctype == 1)          /* tn 300 */
                    467:                                count = 5;
                    468:                        else if (ctype == 2)    /* ti 700 */
                    469:                                count = 10;
                    470:                        else if (ctype == 3)
                    471:                                count = 20;
                    472:                        tp->t_col = 0;
                    473:                        break;
                    474:                }
                    475:                if (count) {
                    476:                        (*q->next->qinfo->putp)(q->next, obp);
                    477:                        if (obp = allocb(1)) {
                    478:                                obp->type = M_DELAY;
                    479:                                *obp->wptr++ = count;
                    480:                                (*q->next->qinfo->putp)(q->next, obp);
                    481:                        }
                    482:                        obp = NULL;
                    483:                }
                    484:        }
                    485:        if (obp)
                    486:                (*q->next->qinfo->putp)(q->next, obp);
                    487:        freeb(ibp);
                    488: }
                    489: 
                    490: /*
                    491:  * Reader generates a signal and passes it up
                    492:  */
                    493: ttysig(q, sig)
                    494: register struct queue *q;
                    495: {
                    496:        register struct ttyld *tp = (struct ttyld *)q->ptr;
                    497: 
                    498:        flushq(q, 0);                   /* flush reader */
                    499:        flushq(WR(q), 0);
                    500:        tp->t_state &= ~TTESC;
                    501:        tp->t_delct = 0;
                    502:        putctl(q->next, M_FLUSH);
                    503:        putctl1(q->next, M_SIGNAL, sig);
                    504:        putctl(WR(q)->next, M_FLUSH);
                    505: }
                    506: 
                    507: ttldioc(q, bp, rdq, fromdev)
                    508: register struct block *bp;
                    509: struct queue *q, *rdq;
                    510: {
                    511:        register struct ttyld *tp;
                    512:        register union stmsg *sp;
                    513:        int s;
                    514: 
                    515:        sp = (union stmsg *)bp->rptr;
                    516:        tp = (struct ttyld *)q->ptr;
                    517:        switch (sp->ioc0.com) {
                    518: 
                    519:        /*
                    520:         * Set new parameters
                    521:         */
                    522:        case TIOCSETP:
                    523:        case TIOCSETN:
                    524:                s = spl6();
                    525:                if (sp->ioc1.sb.sg_flags & (RAW|CBREAK)
                    526:                  && (rdq->next->flag&QFULL)==0) {
                    527:                        register struct block *bp1;
                    528:                        ttyinsrv(rdq);
                    529:                        while (bp1 = getq(rdq))
                    530:                                (*rdq->next->qinfo->putp)(rdq->next, bp1);
                    531:                }
                    532:                tp->t_erase = sp->ioc1.sb.sg_erase;
                    533:                tp->t_kill = sp->ioc1.sb.sg_kill;
                    534:                tp->t_flags = sp->ioc1.sb.sg_flags;
                    535:                splx(s);
                    536:                bp->type = M_IOCACK;
                    537:                if (fromdev)
                    538:                        qreply(rdq, bp); /* reply to device side */
                    539:                else
                    540:                        qreply(q, bp); /* reply to process side */
                    541:                if (tp->t_flags & (RAW|CBREAK))
                    542:                        rdq->flag &= ~(QDELIM|QNOENB);
                    543:                else
                    544:                        rdq->flag |= QDELIM|QNOENB;
                    545:                break;
                    546: 
                    547:        /*
                    548:         * Send current parameters to user
                    549:         */
                    550:        case TIOCGETP:
                    551:                sp->ioc1.sb.sg_erase = tp->t_erase;
                    552:                sp->ioc1.sb.sg_kill = tp->t_kill;
                    553:                sp->ioc1.sb.sg_flags = tp->t_flags;
                    554:                sp->ioc1.sb.sg_ispeed =
                    555:                 sp->ioc1.sb.sg_ospeed = B9600;
                    556:                bp->wptr = bp->rptr+sizeof(struct ioc1);
                    557:                bp->type = M_IOCACK;
                    558:                if (fromdev)
                    559:                        qreply(rdq, bp); /* reply to device side */
                    560:                else
                    561:                        qreply(q, bp); /* reply to process side */
                    562:                break;
                    563: 
                    564:        /*
                    565:         * Set and fetch special characters
                    566:         */
                    567:        case TIOCSETC:
                    568:                tp->t_chr = sp->ioc2.sb;
                    569:                bp->wptr = bp->rptr;
                    570:                bp->type = M_IOCACK;
                    571:                if (fromdev)
                    572:                        qreply(rdq, bp); /* reply to device side */
                    573:                else
                    574:                        qreply(q, bp); /* reply to process side */
                    575:                break;
                    576: 
                    577:        case TIOCGETC:
                    578:                sp->ioc2.sb = tp->t_chr;
                    579:                bp->wptr = bp->rptr+sizeof(struct ioc2);
                    580:                bp->type = M_IOCACK;
                    581:                if (fromdev)
                    582:                        qreply(rdq, bp); /* reply to device side */
                    583:                else
                    584:                        qreply(q, bp); /* reply to process side */
                    585:                break;
                    586: 
                    587:        default:
                    588:                if (fromdev) {
                    589:                        bp->type = M_IOCACK;
                    590:                        qreply(rdq, bp); /* reply to device side */
                    591:                } else
                    592:                        (*q->next->qinfo->putp)(q->next, bp); /* pass to device */
                    593:                break;
                    594: 
                    595:        }
                    596: }

unix.superglobalmegacorp.com

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