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

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

unix.superglobalmegacorp.com

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