Annotation of 41BSD/4.0.upgrade/sys/dev/ttynew.c, revision 1.1

1.1     ! root        1: /*     ttynew.c        4.13    81/07/22        */
        !             2: 
        !             3: /*
        !             4:  * New version of tty driver, supported
        !             5:  * as NTTYDISC.  Adapted from a tty.c written
        !             6:  * by J.E.Kulp of IIASA, Austria (jekulp@mc)
        !             7:  */
        !             8: #include "../h/param.h"
        !             9: #include "../h/systm.h"
        !            10: #include "../h/dir.h"
        !            11: #include "../h/user.h"
        !            12: #include "../h/tty.h"
        !            13: #include "../h/proc.h"
        !            14: #include "../h/mx.h"
        !            15: #include "../h/inode.h"
        !            16: #include "../h/file.h"
        !            17: #include "../h/reg.h"
        !            18: #include "../h/conf.h"
        !            19: #include "../h/buf.h"
        !            20: #include "../h/dk.h"
        !            21: 
        !            22: char   partab[];
        !            23: 
        !            24: /*
        !            25:  * Input mapping table-- if an entry is non-zero, when the
        !            26:  * corresponding character is typed preceded by "\" the escape
        !            27:  * sequence is replaced by the table value.  Mostly used for
        !            28:  * upper-case only terminals.
        !            29:  */
        !            30: 
        !            31: char   maptab[];               /* see tty.c */
        !            32: 
        !            33: /*
        !            34:  * shorthand
        !            35:  */
        !            36: #define        q1      tp->t_rawq
        !            37: #define        q2      tp->t_canq
        !            38: #define        q3      tp->t_outq
        !            39: #define        q4      tp->t_un.t_ctlq
        !            40: 
        !            41: #define        OBUFSIZ 100
        !            42: 
        !            43: /*
        !            44:  * routine called on opens while tp->t_line == NTTYDISC
        !            45:  * establishes a process group for distribution of
        !            46:  * quits and interrupts from the tty.
        !            47:  * (actually, pp->p_pgrp can't be 0 when this routine
        !            48:  * is called since NTTYDISC is not the default discipline)
        !            49:  */
        !            50: ntyopen(dev, tp)
        !            51: dev_t dev;
        !            52: register struct tty *tp;
        !            53: {
        !            54:        register struct proc *pp;
        !            55: 
        !            56:        pp = u.u_procp;
        !            57:        tp->t_dev = dev;
        !            58:        if(pp->p_pgrp == 0) {
        !            59:                u.u_ttyp = tp;
        !            60:                u.u_ttyd = dev;
        !            61:                if (tp->t_pgrp == 0)
        !            62:                        tp->t_pgrp = pp->p_pid;
        !            63:                pp->p_pgrp = tp->t_pgrp;
        !            64:        }
        !            65:        tp->t_state &= ~WOPEN;
        !            66:        tp->t_state |= ISOPEN;
        !            67:        if (tp->t_line != NTTYDISC)
        !            68:                wflushtty(tp);
        !            69: }
        !            70: 
        !            71: /*
        !            72:  * clean tp on last close
        !            73:  */
        !            74: ntyclose(tp)
        !            75: register struct tty *tp;
        !            76: {
        !            77: 
        !            78:        wflushtty(tp);
        !            79:        /* let ttyclose do the work if we are really closing */
        !            80: }
        !            81: 
        !            82: /*
        !            83:  * block transfer input handler.
        !            84:  */
        !            85: ntyrend(tp, pb, pe)
        !            86: register struct tty *tp;
        !            87: register char *pb, *pe;
        !            88: {
        !            89:        int     tandem;
        !            90: 
        !            91:        tandem = tp->t_flags&TANDEM;
        !            92:        if (tp->t_flags&RAW) {
        !            93:                (void) b_to_q(pb, pe-pb, &tp->t_rawq);
        !            94:                if (tp->t_chan)
        !            95:                        (void) sdata(tp->t_chan);
        !            96:                wakeup((caddr_t)&tp->t_rawq);
        !            97:        } else {
        !            98:                tp->t_flags &= ~TANDEM;
        !            99:                while (pb < pe)
        !           100:                        ntyinput(*pb++, tp);
        !           101:                tp->t_flags |= tandem;
        !           102:        }
        !           103:        if (tandem)
        !           104:                ttyblock(tp);
        !           105: }
        !           106: 
        !           107: /*
        !           108:  * reinput pending characters after state switch
        !           109:  * call at spl5().
        !           110:  */
        !           111: ntypend(tp)
        !           112: register struct tty *tp;
        !           113: {
        !           114:        struct clist tq;
        !           115:        register c;
        !           116: 
        !           117:        tp->t_local &= ~LPENDIN;
        !           118:        tp->t_lstate |= LSTYPEN;
        !           119:        tq = tp->t_rawq;
        !           120:        tp->t_rawq.c_cc = 0;
        !           121:        tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0;
        !           122:        while ((c = getc(&tq)) >= 0)
        !           123:                ntyinput(c, tp);
        !           124:        tp->t_lstate &= ~LSTYPEN;
        !           125: }
        !           126: 
        !           127: /*
        !           128:  * Place a character on raw TTY input queue, putting in delimiters
        !           129:  * and waking up top half as needed.
        !           130:  * Also echo if required.
        !           131:  * The arguments are the character and the appropriate
        !           132:  * tty structure.
        !           133:  */
        !           134: ntyinput(c, tp)
        !           135: register c;
        !           136: register struct tty *tp;
        !           137: {
        !           138:        register int t_flags;
        !           139:        int i;
        !           140: 
        !           141:        if (tp->t_local&LPENDIN)
        !           142:                ntypend(tp);
        !           143:        tk_nin++;
        !           144:        c &= 0377;
        !           145:        t_flags = tp->t_flags;
        !           146:        if (t_flags&TANDEM)
        !           147:                ttyblock(tp);
        !           148:        if ((t_flags&RAW)==0) {
        !           149:                if ((tp->t_lstate&LSTYPEN) == 0)
        !           150:                        c &= 0177;
        !           151:        /* check for literal nexting very first */
        !           152:                if (tp->t_lstate&LSLNCH) {
        !           153:                        c |= 0200;
        !           154:                        tp->t_lstate &= ~LSLNCH;
        !           155:                }
        !           156:                if (c==tlun.t_lnextc) {
        !           157:                        if (tp->t_flags&ECHO)
        !           158:                                ntyout("^\b", tp);
        !           159:                        tp->t_lstate |= LSLNCH;
        !           160:        /* check for output control functions */
        !           161:                } else if (c==tun.t_stopc) {
        !           162:                        if ((tp->t_state&TTSTOP)==0) {
        !           163:                                tp->t_state |= TTSTOP;
        !           164:                                (*cdevsw[major(tp->t_dev)].d_stop)(tp);
        !           165:                                return;
        !           166:                        }
        !           167:                        if (c!=tun.t_startc)
        !           168:                                return;
        !           169:                } else if (c==tun.t_startc) {
        !           170:                        tp->t_state &= ~TTSTOP;
        !           171:                        tp->t_local &= ~LFLUSHO;
        !           172:                        ttstart(tp);
        !           173:                        return;
        !           174:                } else if (c==tlun.t_flushc) {
        !           175:                        if (tp->t_local & LFLUSHO)
        !           176:                                tp->t_local &= ~LFLUSHO;
        !           177:                        else {
        !           178:                                flushtty(tp, FWRITE);
        !           179:                                ntyecho(c, tp);
        !           180:                                if (tp->t_rawq.c_cc+tp->t_canq.c_cc)
        !           181:                                        ntyretype(tp);
        !           182:                                tp->t_local |= LFLUSHO;
        !           183:                        }
        !           184:                        ttstart(tp);
        !           185:                        return;
        !           186:                } else if (c==tlun.t_suspc || c==tun.t_intrc ||
        !           187:                           c==tun.t_quitc) {
        !           188:                        if ((tp->t_local & LNOFLSH) == 0)
        !           189:                                flushtty(tp,
        !           190:                                    c==tlun.t_suspc ? FREAD : FREAD|FWRITE);
        !           191:                        ntyecho(c, tp);
        !           192:                        c = c==tun.t_intrc ? SIGINT :
        !           193:                                ((c==tun.t_quitc) ? SIGQUIT : SIGTSTP);
        !           194:                        if (tp->t_chan)
        !           195:                                scontrol(tp->t_chan, M_SIG, c);
        !           196:                        gsignal(tp->t_pgrp, c);
        !           197:        /* check for buffer editing functions - cooked mode */
        !           198:                } else if ((t_flags&CBREAK) == 0) {
        !           199:                        if ((tp->t_lstate&LSQUOT) &&
        !           200:                            (c==tp->t_erase||c==tp->t_kill)) {
        !           201:                                ntyrub(unputc(&tp->t_rawq), tp);
        !           202:                                c |= 0200;
        !           203:                        }
        !           204:                        if (c==tp->t_erase) {
        !           205:                                if (tp->t_rawq.c_cc)
        !           206:                                        ntyrub(unputc(&tp->t_rawq), tp);
        !           207:                        } else if (c==tp->t_kill) {
        !           208:                                if (tp->t_local&LCRTKIL &&
        !           209:                                    tp->t_rawq.c_cc == tp->t_rocount) {
        !           210:                                        while (tp->t_rawq.c_cc)
        !           211:                                                ntyrub(unputc(&tp->t_rawq), tp);
        !           212:                                } else {
        !           213:                                        ntyecho(c, tp);
        !           214:                                        ntyecho('\n', tp);
        !           215:                                        while (getc(&tp->t_rawq) > 0)
        !           216:                                                ;
        !           217:                                        tp->t_rocount = 0;
        !           218:                                }
        !           219:                                tp->t_lstate = 0;
        !           220:                        } else if (c==tlun.t_werasc) {
        !           221:                                if (tp->t_rawq.c_cc == 0)
        !           222:                                        goto out;
        !           223:                                do {
        !           224:                                        c = unputc(&tp->t_rawq);
        !           225:                                        if (c != ' ' && c != '\t')
        !           226:                                                goto erasenb;
        !           227:                                        ntyrub(c, tp);
        !           228:                                } while (tp->t_rawq.c_cc);
        !           229:                                goto out;
        !           230:                            erasenb:
        !           231:                                do {
        !           232:                                        ntyrub(c, tp);
        !           233:                                        if (tp->t_rawq.c_cc == 0)
        !           234:                                                goto out;
        !           235:                                        c = unputc(&tp->t_rawq);
        !           236:                                } while (c != ' ' && c != '\t');
        !           237:                                (void) putc(c, &tp->t_rawq);
        !           238:                        } else if (c==tlun.t_rprntc) {
        !           239:                                ntyretype(tp);
        !           240:        /* check for cooked mode input buffer overflow */
        !           241:                        } else if (tp->t_rawq.c_cc + tp->t_canq.c_cc > TTYHOG) {
        !           242:                                /* we should start a timeout that flushes the
        !           243:                                   buffer if it stays full - same in CBREAK */
        !           244:                                if (tp->t_outq.c_cc < TTHIWAT(tp))
        !           245:                                        (void) ntyoutput(CTRL(g), tp);
        !           246:        /* put data char in q for user and wakeup if a break char */
        !           247:                        } else if (putc(c, &tp->t_rawq) >= 0) {
        !           248:                                if (!ntbreakc(c, tp)) {
        !           249:                                        if (tp->t_rocount++ == 0)
        !           250:                                                tp->t_rocol = tp->t_col;
        !           251:                                } else {
        !           252:                                        tp->t_rocount = 0;
        !           253:                                        catq(&tp->t_rawq, &tp->t_canq);
        !           254:                                        if (tp->t_chan)
        !           255:                                                (void) sdata(tp->t_chan);
        !           256:                                        wakeup((caddr_t)&tp->t_rawq);
        !           257:                                        if (tp->t_local&LINTRUP)
        !           258:                                                gsignal(tp->t_pgrp, SIGTINT);
        !           259:                                }
        !           260:                                tp->t_lstate &= ~LSQUOT;
        !           261:                                if (c == '\\')
        !           262:                                        tp->t_lstate |= LSQUOT;
        !           263:                                if (tp->t_lstate&LSERASE) {
        !           264:                                        tp->t_lstate &= ~LSERASE;
        !           265:                                        (void) ntyoutput('/', tp);
        !           266:                                }
        !           267:                                i = tp->t_col;
        !           268:                                ntyecho(c, tp);
        !           269:                                if (c==tun.t_eofc && tp->t_flags&ECHO) {
        !           270:                                        i = MIN(2, tp->t_col - i);
        !           271:                                        while (i > 0) {
        !           272:                                                (void) ntyoutput('\b', tp);
        !           273:                                                i--;
        !           274:                                        }
        !           275:                                }
        !           276:                        }
        !           277:        /* CBREAK mode */
        !           278:                } else if (tp->t_rawq.c_cc > TTYHOG) {
        !           279:                        if (tp->t_outq.c_cc < TTHIWAT(tp))
        !           280:                                (void) ntyoutput(CTRL(g), tp);
        !           281:                } else if (putc(c, &tp->t_rawq) >= 0) {
        !           282:                        if (tp->t_local&LINTRUP)
        !           283:                                gsignal(tp->t_pgrp, SIGTINT);
        !           284:                        if (tp->t_chan)
        !           285:                                (void) sdata(tp->t_chan);
        !           286:                        wakeup((caddr_t)&tp->t_rawq);
        !           287:                        ntyecho(c, tp);
        !           288:                }
        !           289:        /* RAW mode */
        !           290:        } else if (tp->t_rawq.c_cc > TTYHOG) 
        !           291:                flushtty(tp, FREAD|FWRITE);
        !           292:        else {
        !           293:                if (putc(c, &tp->t_rawq) >= 0) {
        !           294:                        if (tp->t_local&LINTRUP)
        !           295:                                gsignal(tp->t_pgrp, SIGTINT);
        !           296:                        if (tp->t_chan)
        !           297:                                (void) sdata(tp->t_chan);
        !           298:                        wakeup((caddr_t)&tp->t_rawq);
        !           299:                }
        !           300:                ntyecho(c, tp);
        !           301:        }
        !           302: out:
        !           303:        if (tp->t_local & LDECCTQ && tp->t_state & TTSTOP &&
        !           304:            tun.t_startc != tun.t_stopc)
        !           305:                return;
        !           306:        tp->t_state &= ~TTSTOP;
        !           307:        tp->t_local &= ~LFLUSHO;
        !           308:        ttstart(tp);
        !           309: }
        !           310: 
        !           311: /*
        !           312:  * put character on TTY output queue, adding delays,
        !           313:  * expanding tabs, and handling the CR/NL bit.
        !           314:  * It is called both from the top half for output, and from
        !           315:  * interrupt level for echoing.
        !           316:  * The arguments are the character and the tty structure.
        !           317:  * Returns < 0 if putc succeeds, otherwise returns char to resend
        !           318:  * Must be recursive.
        !           319:  */
        !           320: ntyoutput(c, tp)
        !           321: register c;
        !           322: register struct tty *tp;
        !           323: {
        !           324:        register char *colp;
        !           325:        register ctype;
        !           326: 
        !           327:        if (tp->t_flags&RAW || tp->t_local&LLITOUT) {
        !           328:                if (tp->t_local&LFLUSHO)
        !           329:                        return (-1);
        !           330:                if (putc(c, &tp->t_outq))
        !           331:                        return(c);
        !           332:                tk_nout++;
        !           333:                return (-1);
        !           334:        }
        !           335:        /*
        !           336:         * Ignore EOT in normal mode to avoid hanging up
        !           337:         * certain terminals.
        !           338:         */
        !           339:        c &= 0177;
        !           340:        if (c==CEOT && (tp->t_flags&CBREAK)==0)
        !           341:                return (-1);
        !           342:        /*
        !           343:         * Turn tabs to spaces as required
        !           344:         */
        !           345:        if (c=='\t' && (tp->t_flags&TBDELAY)==XTABS) {
        !           346:                register int s;
        !           347: 
        !           348:                c = 8 - (tp->t_col&7);
        !           349:                if ((tp->t_local&LFLUSHO) == 0) {
        !           350:                        s = spl5();             /* don't interrupt tabs */
        !           351:                        c -= b_to_q("        ", c, &tp->t_outq);
        !           352:                        tk_nout += c;
        !           353:                        splx(s);
        !           354:                }
        !           355:                tp->t_col += c;
        !           356:                return (c ? -1 : '\t');
        !           357:        }
        !           358:        tk_nout++;
        !           359:        /*
        !           360:         * for upper-case-only terminals,
        !           361:         * generate escapes.
        !           362:         */
        !           363:        if (tp->t_flags&LCASE) {
        !           364:                colp = "({)}!|^~'`";
        !           365:                while(*colp++)
        !           366:                        if(c == *colp++) {
        !           367:                                if (ntyoutput('\\', tp) >= 0)
        !           368:                                        return (c);
        !           369:                                c = colp[-2];
        !           370:                                break;
        !           371:                        }
        !           372:                if ('A'<=c && c<='Z') {
        !           373:                        if (ntyoutput('\\', tp) >= 0)
        !           374:                                return (c);
        !           375:                } else if ('a'<=c && c<='z')
        !           376:                        c += 'A' - 'a';
        !           377:        }
        !           378:        /*
        !           379:         * turn <nl> to <cr><lf> if desired.
        !           380:         */
        !           381:        if (c=='\n' && tp->t_flags&CRMOD)
        !           382:                if (ntyoutput('\r', tp) >= 0)
        !           383:                        return (c);
        !           384:        if (c=='~' && tp->t_local&LTILDE)
        !           385:                c = '`';
        !           386:        if ((tp->t_local&LFLUSHO) == 0 && putc(c, &tp->t_outq))
        !           387:                return (c);
        !           388:        /*
        !           389:         * Calculate delays.
        !           390:         * The numbers here represent clock ticks
        !           391:         * and are not necessarily optimal for all terminals.
        !           392:         * The delays are indicated by characters above 0200.
        !           393:         * In raw mode there are no delays and the
        !           394:         * transmission path is 8 bits wide.
        !           395:         */
        !           396:        colp = &tp->t_col;
        !           397:        ctype = partab[c];
        !           398:        c = 0;
        !           399:        switch (ctype&077) {
        !           400: 
        !           401:        case ORDINARY:
        !           402:                (*colp)++;
        !           403: 
        !           404:        case CONTROL:
        !           405:                break;
        !           406: 
        !           407:        case BACKSPACE:
        !           408:                if (*colp)
        !           409:                        (*colp)--;
        !           410:                break;
        !           411: 
        !           412:        case NEWLINE:
        !           413:                ctype = (tp->t_flags >> 8) & 03;
        !           414:                if(ctype == 1) { /* tty 37 */
        !           415:                        if (*colp)
        !           416:                                c = max(((unsigned)*colp>>4) + 3, (unsigned)6);
        !           417:                } else
        !           418:                if(ctype == 2) { /* vt05 */
        !           419:                        c = 6;
        !           420:                }
        !           421:                *colp = 0;
        !           422:                break;
        !           423: 
        !           424:        case TAB:
        !           425:                ctype = (tp->t_flags >> 10) & 03;
        !           426:                if(ctype == 1) { /* tty 37 */
        !           427:                        c = 1 - (*colp | ~07);
        !           428:                        if(c < 5)
        !           429:                                c = 0;
        !           430:                }
        !           431:                *colp |= 07;
        !           432:                (*colp)++;
        !           433:                break;
        !           434: 
        !           435:        case VTAB:
        !           436:                if(tp->t_flags & VTDELAY) /* tty 37 */
        !           437:                        c = 0177;
        !           438:                break;
        !           439: 
        !           440:        case RETURN:
        !           441:                ctype = (tp->t_flags >> 12) & 03;
        !           442:                if(ctype == 1) { /* tn 300 */
        !           443:                        c = 5;
        !           444:                } else if(ctype == 2) { /* ti 700 */
        !           445:                        c = 10;
        !           446:                } else if(ctype == 3) { /* concept 100 */
        !           447:                        int i;
        !           448:                        if ((i = *colp) >= 0)
        !           449:                                for (; i<9; i++)
        !           450:                                        (void) putc(0177, &tp->t_outq);
        !           451:                }
        !           452:                *colp = 0;
        !           453:        }
        !           454:        if(c && (tp->t_local&LFLUSHO) == 0)
        !           455:                (void) putc(c|0200, &tp->t_outq);
        !           456:        return (-1);
        !           457: }
        !           458: 
        !           459: /*
        !           460:  * Called from device's read routine after it has
        !           461:  * calculated the tty-structure given as argument.
        !           462:  */
        !           463: ntread(tp)
        !           464: register struct tty *tp;
        !           465: {
        !           466:        register struct clist *qp;
        !           467:        register c, first;
        !           468: 
        !           469:        if ((tp->t_state&CARR_ON)==0)
        !           470:                return(0);
        !           471: loop:
        !           472:        (void) spl5();
        !           473:        if (tp->t_local&LPENDIN)
        !           474:                ntypend(tp);
        !           475:        (void) spl0();
        !           476:        while (tp == u.u_ttyp && u.u_procp->p_pgrp != tp->t_pgrp) {
        !           477:                if (u.u_signal[SIGTTIN] == SIG_IGN ||
        !           478:                    u.u_signal[SIGTTIN] == SIG_HOLD ||
        !           479:                    (u.u_procp->p_flag&SDETACH) ||
        !           480:                    u.u_procp->p_flag&SVFORK)
        !           481:                        return (0);
        !           482:                gsignal(u.u_procp->p_pgrp, SIGTTIN);
        !           483:                sleep((caddr_t)&lbolt, TTIPRI);
        !           484:        }
        !           485:        if (tp->t_flags&RAW) {
        !           486:                (void) spl5();
        !           487:                if (tp->t_rawq.c_cc <= 0) {
        !           488:                        if ((tp->t_state&CARR_ON)==0 ||
        !           489:                            (tp->t_chan && getf(u.u_ap[0])->f_flag&FMP)) {
        !           490:                                (void) spl0();
        !           491:                                return (0);
        !           492:                        }
        !           493:                        if (tp->t_local&LINTRUP &&
        !           494:                            u.u_signal[SIGTINT] != SIG_DFL) {
        !           495:                                u.u_error = EIO;
        !           496:                                (void) spl0();
        !           497:                                return (0);
        !           498:                        }
        !           499:                        sleep((caddr_t)&tp->t_rawq, TTIPRI);
        !           500:                        (void) spl0();
        !           501:                        goto loop;
        !           502:                }
        !           503:                (void) spl0();
        !           504:                while (tp->t_rawq.c_cc && passc(getc(&tp->t_rawq))>=0)
        !           505:                        ;
        !           506:                return (0);
        !           507:        } else {
        !           508:                qp = tp->t_flags & CBREAK ? &tp->t_rawq : &tp->t_canq;
        !           509:                (void) spl5();
        !           510:                if (qp->c_cc <= 0) {
        !           511:                        if ((tp->t_state&CARR_ON)==0 ||
        !           512:                            (tp->t_chan!=NULL && getf(u.u_ap[0])->f_flag&FMP)) {
        !           513:                                (void) spl0();
        !           514:                                return (0);
        !           515:                        }
        !           516:                        if (tp->t_local&LINTRUP &&
        !           517:                            u.u_signal[SIGTINT] != SIG_DFL) {
        !           518:                                u.u_error = EIO;
        !           519:                                (void) spl0();
        !           520:                                return (0);
        !           521:                        }
        !           522:                        sleep((caddr_t)&tp->t_rawq, TTIPRI);
        !           523:                        (void) spl0();
        !           524:                        goto loop;
        !           525:                }
        !           526:                (void) spl0();
        !           527:                first = 1;
        !           528:                while ((c = getc(qp)) >= 0) {
        !           529:                        if (tp->t_flags&CRMOD && c == '\r')
        !           530:                                c = '\n';
        !           531:                        if (tp->t_flags&LCASE && c <= 0177)
        !           532:                                if (tp->t_lstate&LSBKSL) {
        !           533:                                        if (maptab[c])
        !           534:                                                c = maptab[c];
        !           535:                                        tp->t_lstate &= ~LSBKSL;
        !           536:                                } else if (c >= 'A' && c <= 'Z')
        !           537:                                        c += 'a' - 'A';
        !           538:                                else if (c == '\\') {
        !           539:                                        tp->t_lstate |= LSBKSL;
        !           540:                                        continue;
        !           541:                                }
        !           542:                        if (c == tlun.t_dsuspc) {
        !           543:                                gsignal(tp->t_pgrp, SIGTSTP);
        !           544:                                if (first) {
        !           545:                                        sleep((caddr_t)&lbolt, TTIPRI);
        !           546:                                        goto loop;
        !           547:                                }
        !           548:                                break;
        !           549:                        }
        !           550:                        if (c == tun.t_eofc && (tp->t_flags&CBREAK)==0)
        !           551:                                break;
        !           552:                        if (passc(c & 0177) < 0)
        !           553:                                break;
        !           554:                        if ((tp->t_flags&CBREAK)==0 && ntbreakc(c, tp))
        !           555:                                break;
        !           556:                        first = 0;
        !           557:                }
        !           558:                tp->t_lstate &= ~LSBKSL;
        !           559:        }
        !           560: 
        !           561:        if (tp->t_state&TBLOCK && tp->t_rawq.c_cc < TTYHOG/5) {
        !           562:                if (putc(tun.t_startc, &tp->t_outq)==0) {
        !           563:                        tp->t_state &= ~TBLOCK;
        !           564:                        ttstart(tp);
        !           565:                }
        !           566:                tp->t_char = 0;
        !           567:        }
        !           568: 
        !           569:        return (tp->t_rawq.c_cc + tp->t_canq.c_cc);
        !           570: }
        !           571: 
        !           572: /*
        !           573:  * Called from the device's write routine after it has
        !           574:  * calculated the tty-structure given as argument.
        !           575:  */
        !           576: caddr_t
        !           577: ntwrite(tp)
        !           578: register struct tty *tp;
        !           579: {
        !           580: #ifdef vax
        !           581:        /*
        !           582:         * THE POSITIONING OF CP, CC, AND CE ARE CRITICAL
        !           583:         * AND MUST NOT BE CHANGED WITHOUT PATCHING
        !           584:         * THE 'ASM' INLINES BELOW.  WATCH OUT.
        !           585:         */
        !           586: #endif
        !           587:        register char *cp;
        !           588:        register int cc, ce;
        !           589:        register i;
        !           590:        char obuf[OBUFSIZ];
        !           591:        register c;
        !           592:        int hiwat = TTHIWAT(tp);
        !           593: 
        !           594:        if ((tp->t_state&CARR_ON)==0)
        !           595:                return (NULL);
        !           596: loop:
        !           597:        while (u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp &&
        !           598:            (tp->t_local&LTOSTOP) && (u.u_procp->p_flag&SVFORK)==0 &&
        !           599:            u.u_signal[SIGTTOU] != SIG_IGN &&
        !           600:            u.u_signal[SIGTTOU] != SIG_HOLD &&
        !           601:            (u.u_procp->p_flag&SDETACH)==0) {
        !           602:                gsignal(u.u_procp->p_pgrp, SIGTTOU);
        !           603:                sleep((caddr_t)&lbolt, TTIPRI);
        !           604:        }
        !           605:        while (u.u_count) {
        !           606:                cc = MIN(u.u_count, OBUFSIZ);
        !           607:                cp = obuf;
        !           608:                iomove(cp, (unsigned)cc, B_WRITE);
        !           609:                if (u.u_error)
        !           610:                        break;
        !           611:                if (tp->t_outq.c_cc > hiwat)
        !           612:                        goto ovhiwat;
        !           613:                if (tp->t_local&LFLUSHO)
        !           614:                        continue;
        !           615:                if (tp->t_flags&LCASE || tp->t_local&LTILDE) {
        !           616:                        while (cc--) {
        !           617:                                c = *cp++;
        !           618:                                tp->t_rocount = 0;
        !           619:                                while((c = ntyoutput(c, tp)) >= 0) {
        !           620:                                        /* out of clists, wait a bit */
        !           621:                                        ttstart(tp);
        !           622:                                        sleep((caddr_t)&lbolt, TTOPRI);
        !           623:                                        tp->t_rocount = 0;
        !           624:                                }
        !           625:                                if (tp->t_outq.c_cc > hiwat)
        !           626:                                        goto ovhiwat;
        !           627:                        }
        !           628:                        continue;
        !           629:                }
        !           630:                while (cc) {
        !           631:                        if (tp->t_flags&RAW || tp->t_local&LLITOUT)
        !           632:                                ce = cc;
        !           633:                        else {
        !           634: #ifdef vax
        !           635:                                asm("   scanc   r9,(r10),_partab,$077");
        !           636:                                asm("   subl3   r0,r9,r8");
        !           637: #else
        !           638:                                ce=0;
        !           639:                                while(((partab[*(unsigned char *)(cp+ce)]&077)==0)&&(ce<cc))
        !           640:                                        ce++;
        !           641: #endif
        !           642:                                if (ce==0) {
        !           643:                                        tp->t_rocount = 0;
        !           644:                                        if (ntyoutput(*cp, tp) >= 0) {
        !           645:                                                ttstart(tp);
        !           646:                                                sleep((caddr_t)&lbolt, TTOPRI);
        !           647:                                                continue;
        !           648:                                        }
        !           649:                                        cp++;
        !           650:                                        cc--;
        !           651:                                        if (tp->t_outq.c_cc > hiwat)
        !           652:                                                goto ovhiwat;
        !           653:                                }
        !           654:                        }
        !           655:                        tp->t_rocount = 0;
        !           656:                        i=b_to_q(cp,ce,&tp->t_outq);
        !           657:                        ce-=i;
        !           658:                        tk_nout+=ce;
        !           659:                        tp->t_col+=ce;
        !           660:                        cp+=ce;
        !           661:                        cc-=ce;
        !           662:                        if (i) {
        !           663:                                ttstart(tp);
        !           664:                                sleep((caddr_t)&lbolt, TTOPRI);
        !           665:                        }
        !           666:                        if (ce || tp->t_outq.c_cc > hiwat)
        !           667:                                goto ovhiwat;
        !           668:                }
        !           669:        }
        !           670:        ttstart(tp);
        !           671:        return(NULL);
        !           672: 
        !           673: ovhiwat:
        !           674:        (void) spl5();
        !           675:        u.u_base -= cc;
        !           676:        u.u_offset -= cc;
        !           677:        u.u_count += cc;
        !           678:        if (tp->t_outq.c_cc <= hiwat) {
        !           679:                (void) spl0();
        !           680:                goto loop;
        !           681:        }
        !           682:        ttstart(tp);
        !           683:        tp->t_state |= ASLEEP;
        !           684:        if (tp->t_chan && u.u_segflg == 0 && (getf(u.u_ap[0])->f_flag&FMP)) {
        !           685:                (void) spl0();
        !           686:                return ((caddr_t)&tp->t_outq);
        !           687:        }
        !           688:        sleep((caddr_t)&tp->t_outq, TTOPRI);
        !           689:        (void) spl0();
        !           690:        goto loop;
        !           691: }
        !           692: 
        !           693: /*
        !           694:  * Rubout one character from the rawq of tp
        !           695:  * as cleanly as possible.
        !           696:  */
        !           697: ntyrub(c, tp)
        !           698: register c;
        !           699: register struct tty *tp;
        !           700: {
        !           701:        register char *cp;
        !           702:        register int savecol;
        !           703:        int s;
        !           704:        char *nextc();
        !           705: 
        !           706:        if ((tp->t_flags&ECHO)==0)
        !           707:                return;
        !           708:        tp->t_local &= ~LFLUSHO;
        !           709:        c &= 0377;
        !           710:        if (tp->t_local&LCRTBS) {
        !           711:                if (tp->t_rocount == 0) {
        !           712:                        /*
        !           713:                         * Screwed by ttwrite; retype
        !           714:                         */
        !           715:                        ntyretype(tp);
        !           716:                        return;
        !           717:                }
        !           718:                if (c==('\t'|0200) || c==('\n'|0200))
        !           719:                        ntyrubo(tp, 2);
        !           720:                else switch(partab[c&=0177] & 0177) {
        !           721: 
        !           722:                case ORDINARY:
        !           723:                        if (tp->t_flags&LCASE && c >= 'A' && c <= 'Z')
        !           724:                                ntyrubo(tp, 2);
        !           725:                        else
        !           726:                                ntyrubo(tp, 1);
        !           727:                        break;
        !           728: 
        !           729:                case VTAB:
        !           730:                case BACKSPACE:
        !           731:                case CONTROL:
        !           732:                case RETURN:
        !           733:                        if (tp->t_local & LCTLECH)
        !           734:                                ntyrubo(tp, 2);
        !           735:                        break;
        !           736: 
        !           737:                case TAB:
        !           738:                        if (tp->t_rocount < tp->t_rawq.c_cc) {
        !           739:                                ntyretype(tp);
        !           740:                                return;
        !           741:                        }
        !           742:                        s = spl5();
        !           743:                        savecol = tp->t_col;
        !           744:                        tp->t_lstate |= LSCNTTB;
        !           745:                        tp->t_local |= LFLUSHO;
        !           746:                        tp->t_col = tp->t_rocol;
        !           747:                        for (cp = tp->t_rawq.c_cf; cp; cp = nextc(&tp->t_rawq, cp))
        !           748:                                ntyecho(*cp, tp);
        !           749:                        tp->t_local &= ~LFLUSHO;
        !           750:                        tp->t_lstate &= ~LSCNTTB;
        !           751:                        splx(s);
        !           752:                        /*
        !           753:                         * savecol will now be length of the tab
        !           754:                         */
        !           755:                        savecol -= tp->t_col;
        !           756:                        tp->t_col += savecol;
        !           757:                        if (savecol > 8)
        !           758:                                savecol = 8;            /* overflow screw */
        !           759:                        while (--savecol >= 0)
        !           760:                                (void) ntyoutput('\b', tp);
        !           761:                        break;
        !           762: 
        !           763:                default:
        !           764:                        panic("ttyrub");
        !           765:                }
        !           766:        } else if (tp->t_local&LPRTERA) {
        !           767:                if ((tp->t_lstate&LSERASE) == 0) {
        !           768:                        (void) ntyoutput('\\', tp);
        !           769:                        tp->t_lstate |= LSERASE;
        !           770:                }
        !           771:                ntyecho(c, tp);
        !           772:        } else
        !           773:                ntyecho(tp->t_erase, tp);
        !           774:        tp->t_rocount--;
        !           775: }
        !           776: 
        !           777: /*
        !           778:  * Crt back over cnt chars perhaps
        !           779:  * erasing them.
        !           780:  */
        !           781: ntyrubo(tp, cnt)
        !           782: register struct tty *tp;
        !           783: int cnt;
        !           784: {
        !           785: 
        !           786:        while (--cnt >= 0)
        !           787:                ntyout(tp->t_local&LCRTERA ? "\b \b" : "\b", tp);
        !           788: }
        !           789: 
        !           790: /*
        !           791:  * Reprint the rawq line.
        !           792:  * We assume c_cc has already been checked.
        !           793:  */
        !           794: ntyretype(tp)
        !           795: register struct tty *tp;
        !           796: {
        !           797:        register char *cp;
        !           798:        char *nextc();
        !           799:        int s;
        !           800: 
        !           801:        if (tlun.t_rprntc != 0377)
        !           802:                ntyecho(tlun.t_rprntc, tp);
        !           803:        (void) ntyoutput('\n', tp);
        !           804:        s = spl5();
        !           805:        for (cp = tp->t_canq.c_cf; cp; cp = nextc(&tp->t_canq, cp))
        !           806:                ntyecho(*cp, tp);
        !           807:        for (cp = tp->t_rawq.c_cf; cp; cp = nextc(&tp->t_rawq, cp))
        !           808:                ntyecho(*cp, tp);
        !           809:        tp->t_lstate &= ~LSERASE;
        !           810:        splx(s);
        !           811:        tp->t_rocount = tp->t_rawq.c_cc;
        !           812:        tp->t_rocol = 0;
        !           813: }
        !           814: 
        !           815: /*
        !           816:  * Echo a typed character to the terminal
        !           817:  */
        !           818: ntyecho(c, tp)
        !           819: register c;
        !           820: register struct tty *tp;
        !           821: {
        !           822: 
        !           823:        if ((tp->t_lstate & LSCNTTB) == 0)
        !           824:                tp->t_local &= ~LFLUSHO;
        !           825:        if ((tp->t_flags&ECHO) == 0)
        !           826:                return;
        !           827:        c &= 0377;
        !           828:        if (tp->t_flags&RAW) {
        !           829:                (void) ntyoutput(c, tp);
        !           830:                return;
        !           831:        }
        !           832:        if (c == '\r' && tp->t_flags&CRMOD)
        !           833:                c = '\n';
        !           834:        if (tp->t_local&LCTLECH) {
        !           835:                if ((c&0177) <= 037 && c!='\t' && c!='\n' || (c&0177)==0177) {
        !           836:                        (void) ntyoutput('^', tp);
        !           837:                        c &= 0177;
        !           838:                        if (c == 0177)
        !           839:                                c = '?';
        !           840:                        else if (tp->t_flags&LCASE)
        !           841:                                c += 'a' - 1;
        !           842:                        else
        !           843:                                c += 'A' - 1;
        !           844:                }
        !           845:        }
        !           846:        (void) ntyoutput(c & 0177, tp);
        !           847: }
        !           848: 
        !           849: /*
        !           850:  * Is c a break char for tp?
        !           851:  */
        !           852: ntbreakc(c, tp)
        !           853: register c;
        !           854: register struct tty *tp;
        !           855: {
        !           856:        return (c == '\n' || c == tun.t_eofc || c == tun.t_brkc ||
        !           857:                c == '\r' && (tp->t_flags&CRMOD));
        !           858: }
        !           859: 
        !           860: /*
        !           861:  * send string cp to tp
        !           862:  */
        !           863: ntyout(cp, tp)
        !           864: register char *cp;
        !           865: register struct tty *tp;
        !           866: {
        !           867:        register char c;
        !           868: 
        !           869:        while (c = *cp++)
        !           870:                (void) ntyoutput(c, tp);
        !           871: }

unix.superglobalmegacorp.com

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