Annotation of MiNT/src/tty.c, revision 1.1.1.6

1.1       root        1: /*
                      2: 
1.1.1.3   root        3: Copyright 1990,1991,1992 Eric R. Smith.
                      4: 
1.1.1.6 ! root        5: Copyright 1992,1993,1994 Atari Corporation.
1.1.1.3   root        6: 
                      7: All rights reserved.
1.1       root        8: 
                      9: */
                     10: 
                     11: 
                     12: 
                     13: /*
                     14: 
                     15:  * read/write routines for TTY devices
                     16: 
                     17:  */
                     18: 
                     19: 
                     20: 
                     21: #include "mint.h"
                     22: 
                     23: 
                     24: 
1.1.1.6 ! root       25: /* emulate mdm0 ioctls too */
        !            26: 
        !            27: #define MDM0_IOCTLS
        !            28: 
        !            29: #ifdef MDM0_IOCTLS
        !            30: 
        !            31: #define TIOCGHUPCL     (('T'<< 8) | 98)
        !            32: 
        !            33: #define TIOCSHUPCL     (('T'<< 8) | 99)
        !            34: 
        !            35: #define TIOCGSOFTCAR   (('T'<< 8) | 100)
        !            36: 
        !            37: #define TIOCSSOFTCAR   (('T'<< 8) | 101)
        !            38: 
        !            39: #endif
        !            40: 
        !            41: 
        !            42: 
        !            43: static void _erase P_((FILEPTR *, int, int));
1.1       root       44: 
                     45: static int escseq P_((struct tty *, int));
                     46: 
                     47: 
                     48: 
                     49: /* setting a special character to this value disables it */
                     50: 
                     51: #define UNDEF 0
                     52: 
                     53: 
                     54: 
1.1.1.6 ! root       55: #define HAS_WRITEB(f)  (((f)->fc.fs != &bios_filesys || \
        !            56: 
        !            57:                         (((struct bios_file *)(f)->fc.index)->drvsize > \
        !            58: 
        !            59:                                offsetof (DEVDRV, writeb))) && \
        !            60: 
        !            61:                         (f)->dev->writeb)
        !            62: 
        !            63: extern FILESYS bios_filesys;
        !            64: 
1.1       root       65: 
                     66: 
                     67: /* default terminal characteristics */
                     68: 
                     69: 
                     70: 
                     71: struct tty default_tty = {
                     72: 
                     73:        0,                      /* process group */
                     74: 
                     75:        0,                      /* state */
                     76: 
                     77:        0,                      /* use_cnt */
                     78: 
1.1.1.6 ! root       79:        0,                      /* aux_cnt */
1.1       root       80: 
                     81:        {
                     82: 
                     83:        13, 13,                 /* input speed == output speed == 9600 baud */
                     84: 
                     85:        CTRL('H'),              /* erase */
                     86: 
                     87:        CTRL('U'),              /* kill */
                     88: 
1.1.1.6 ! root       89:        T_ECHO|T_CRMOD|T_TOSTOP|T_XKEY|T_ECHOCTL, /* flags */
1.1       root       90: 
                     91:        },
                     92: 
                     93:        {
                     94: 
                     95:        CTRL('C'),              /* interrupt */
                     96: 
                     97:        CTRL('\\'),             /* quit */
                     98: 
                     99:        CTRL('Q'),              /* start */
                    100: 
                    101:        CTRL('S'),              /* stop */
                    102: 
                    103:        CTRL('D'),              /* EOF */
                    104: 
                    105:        '\r'                    /* alternate end of line */
                    106: 
                    107:        },
                    108: 
                    109:        {
                    110: 
                    111:        CTRL('Z'),              /* suspend */
                    112: 
                    113:        CTRL('Y'),              /* suspend after read */
                    114: 
                    115:        CTRL('R'),              /* reprint */
                    116: 
1.1.1.6 ! root      117:        CTRL('O'),              /* flush output */
1.1       root      118: 
1.1.1.2   root      119:        CTRL('W'),              /* erase word */
1.1       root      120: 
1.1.1.2   root      121:        CTRL('V')               /* quote next char */
1.1       root      122: 
                    123:        },
                    124: 
                    125:        {
                    126: 
                    127:        0, 0, 0, 0              /* window size is unknown */
                    128: 
                    129:        },
                    130: 
                    131:        0,                      /* no process is selecting us for reading */
                    132: 
                    133:        0,                      /* or for writing */
                    134: 
1.1.1.6 ! root      135:        0,                      /* use default XKEY map */
        !           136: 
        !           137:        0,                      /* not currently hanging up */
        !           138: 
        !           139:        1, 0                    /* RAW reads need 1 char, no timeout */
1.1       root      140: 
                    141: };
                    142: 
                    143: 
                    144: 
                    145: #define _put(f, c) (tty_putchar((f), (c), RAW))
                    146: 
                    147: 
                    148: 
                    149: static void
                    150: 
1.1.1.6 ! root      151: _erase(f, c, mode)
1.1       root      152: 
                    153:        FILEPTR *f;
                    154: 
1.1.1.6 ! root      155:        int c, mode;
1.1       root      156: 
                    157: {
                    158: 
                    159:        _put(f, '\010');
                    160: 
                    161:        _put(f, ' ');
                    162: 
                    163:        _put(f, '\010');
                    164: 
                    165: /* watch out for control characters -- they're printed as e.g. "^C" */
                    166: 
1.1.1.2   root      167: /* BUG: \t is messed up. We really need to keep track of the output
                    168: 
                    169:  * column
                    170: 
                    171:  */
                    172: 
1.1.1.6 ! root      173:        if ((mode & T_ECHOCTL) && c >= 0 && c < ' ' && c != '\t') {
1.1       root      174: 
                    175:                _put(f, '\010'); _put(f, ' '); _put(f, '\010');
                    176: 
                    177:        }
                    178: 
                    179: }
                    180: 
                    181: 
                    182: 
                    183: #define put(f, c)   { if (mode & T_ECHO) _put(f, c); }
                    184: 
1.1.1.6 ! root      185: #define erase(f, c) { if (mode & T_ECHO) _erase(f, c, mode); }
1.1       root      186: 
                    187: 
                    188: 
                    189: long
                    190: 
                    191: tty_read(f, buf, nbytes)
                    192: 
                    193:        FILEPTR *f;
                    194: 
                    195:        void *buf;
                    196: 
                    197:        long nbytes;
                    198: 
                    199: {
                    200: 
                    201:        long r;
                    202: 
                    203:        long bytes_read = 0;
                    204: 
                    205:        unsigned char ch, *ptr;
                    206: 
                    207:        int rdmode, mode;
                    208: 
                    209:        struct tty *tty;
                    210: 
                    211: 
                    212: 
                    213:        tty = (struct tty *)f->devinfo;
                    214: 
                    215:        assert(tty != 0);
                    216: 
                    217: 
                    218: 
                    219:        if (f->flags & O_HEAD) {        /* pty server side? */
                    220: 
                    221:                rdmode = RAW;           /* yes -- always raw mode */
                    222: 
                    223:                mode = T_RAW;
                    224: 
                    225:        }
                    226: 
                    227:        else if (curproc->domain == DOM_MINT) { /* MiNT domain process? */
                    228: 
                    229:                mode = tty->sg.sg_flags;
                    230: 
                    231:                rdmode = COOKED|NOECHO;
                    232: 
                    233:                if ( mode & (T_RAW | T_CBREAK) ) {
                    234: 
                    235:                        rdmode = (mode & T_RAW) ? RAW : COOKED;
                    236: 
                    237:                }
                    238: 
                    239:                if (mode & T_XKEY)
                    240: 
                    241:                        rdmode |= ESCSEQ;
                    242: 
                    243:        }
                    244: 
                    245:        else {
                    246: 
                    247:                rdmode = COOKED|NOECHO;
                    248: 
1.1.1.6 ! root      249:                mode = T_TOS | T_ECHO | T_ECHOCTL;
        !           250: 
        !           251:        }
        !           252: 
        !           253: 
        !           254: 
        !           255:        if (nbytes == 0) return bytes_read;
        !           256: 
        !           257: 
        !           258: 
        !           259:        /* if RAW or CBREAK do VTIME:  select for input, return on timeout */
        !           260: 
        !           261:        if (tty->vtime && (mode & (T_RAW|T_CBREAK)) &&
        !           262: 
        !           263:            !(f->flags & (O_NDELAY|O_HEAD)) &&
        !           264: 
        !           265:            (!(tty->state & TS_ESC) || !(rdmode & ESCSEQ))) {
        !           266: 
        !           267:                long r, bytes = 0;
        !           268: 
        !           269: 
        !           270: 
        !           271:                if ((r = (*f->dev->select)(f, (long)curproc, O_RDONLY)) != 1) {
        !           272: 
        !           273:                        TIMEOUT *t;
        !           274: 
        !           275: 
        !           276: 
        !           277:                        curproc->wait_cond = (long)wakeselect;  /* flag */
        !           278: 
        !           279:                        t = addtimeout((long)tty->vtime, (void (*)P_((PROC *)))wakeselect);
        !           280: 
        !           281:                        if (!t) {
        !           282: 
        !           283:                                (*f->dev->unselect)(f, (long)curproc, O_RDONLY);
        !           284: 
        !           285:                                return ENSMEM;
        !           286: 
        !           287:                        }
        !           288: 
        !           289:                        while (curproc->wait_cond == (long)wakeselect) {
        !           290: 
        !           291:                                TRACE(("sleeping in tty_read (VTIME)"));
        !           292: 
        !           293:                                if (sleep(SELECT_Q|0x100, (long)wakeselect))
        !           294: 
        !           295:                                        break;
        !           296: 
        !           297:                        }
        !           298: 
        !           299:                        canceltimeout(t);
        !           300: 
        !           301:                }
        !           302: 
        !           303:                (void)(*f->dev->ioctl)(f, FIONREAD, &bytes);
        !           304: 
        !           305:                if (!r) {
        !           306: 
        !           307:                        extern short select_coll;       /* in dosfile.c */
        !           308: 
        !           309:                        (*f->dev->unselect)(f, (long)curproc, O_RDONLY);
        !           310: 
        !           311:                        wake(SELECT_Q, (long)&select_coll);
        !           312: 
        !           313:                }
        !           314: 
        !           315:                if (!bytes)
        !           316: 
        !           317:                        return bytes_read;
1.1       root      318: 
                    319:        }
                    320: 
1.1.1.6 ! root      321: #if 1
        !           322: 
        !           323:        /* see if we can do fast RAW byte IO thru the device driver... */
        !           324: 
        !           325:        if (rdmode == RAW &&
        !           326: 
        !           327:            (!(tty->state & TS_ESC) || !(rdmode & ESCSEQ) ||
        !           328: 
        !           329:                (f->flags & O_HEAD)) &&
        !           330: 
        !           331:            (f->fc.fs != &bios_filesys ||
        !           332: 
        !           333:                (nbytes > 1 &&
        !           334: 
        !           335:                 ((struct bios_file *)f->fc.index)->drvsize >
        !           336: 
        !           337:                        offsetof (DEVDRV, readb))) &&
        !           338: 
        !           339:            f->dev->readb &&
        !           340: 
        !           341:            ((f->flags & O_HEAD) || ((tty->state &= ~TS_COOKED), !tty->pgrp) ||
        !           342: 
        !           343:                tty->pgrp == curproc->pgrp ||
        !           344: 
        !           345:                f->fc.dev != curproc->control->fc.dev ||
        !           346: 
        !           347:                f->fc.index != curproc->control->fc.index) &&
        !           348: 
        !           349:            !(tty->state & TS_BLIND) &&
        !           350: 
        !           351:            (r = (*f->dev->readb)(f, buf, nbytes)) != EUNDEV)
        !           352: 
        !           353:                return r;
        !           354: 
        !           355: #endif
        !           356: 
1.1       root      357: 
                    358: 
                    359:        ptr = buf;
                    360: 
                    361: 
                    362: 
                    363:        while (bytes_read < nbytes) {
                    364: 
                    365:                r = tty_getchar(f, rdmode);
                    366: 
                    367:                if (r < 0) {
                    368: 
1.1.1.2   root      369: tty_error:
                    370: 
                    371:                        DEBUG(("tty_read: tty_getchar returned %ld", r));
1.1       root      372: 
                    373:                        return (bytes_read) ? bytes_read : r;
                    374: 
                    375:                }
                    376: 
                    377:                else if (r == MiNTEOF)
                    378: 
                    379:                        return bytes_read;
                    380: 
                    381:                ch = r & 0xff;
                    382: 
                    383: 
                    384: 
1.1.1.6 ! root      385:                if ( (rdmode & COOKED) && (mode & T_CRMOD) && (ch == '\r') )
1.1       root      386: 
                    387:                        ch = '\n';
                    388: 
                    389: 
                    390: 
                    391: /* 1 character reads in TOS mode are always raw */
                    392: 
                    393:                if (nbytes == 1 && (mode & T_TOS)) {
                    394: 
                    395:                        put(f, ch);
                    396: 
                    397:                        *ptr = ch;
                    398: 
                    399:                        return 1;
                    400: 
                    401:                }
                    402: 
                    403: 
                    404: 
                    405: /* T_CBREAK mode doesn't do erase or kill processing */
                    406: 
                    407: /* also note that setting a special character to UNDEF disables it */
                    408: 
                    409: 
                    410: 
                    411:                if (rdmode & COOKED && !(mode & T_CBREAK) && ch != UNDEF) {
                    412: 
                    413:                        if ((char)ch == tty->sg.sg_erase) {  /* backspace */
                    414: 
                    415:                                if (bytes_read > 0) {
                    416: 
                    417:                                        --ptr;
                    418: 
                    419:                                        erase(f, *ptr);
                    420: 
                    421:                                        bytes_read--;
                    422: 
                    423:                                }
                    424: 
                    425:                                continue;
                    426: 
                    427:                        }
                    428: 
1.1.1.2   root      429:                        else if ((mode & T_TOS) && ch == CTRL('X')) {
1.1       root      430: 
                    431:                                while (bytes_read > 0) {
                    432: 
                    433:                                        --ptr;
                    434: 
                    435:                                        erase(f, *ptr);
                    436: 
                    437:                                        bytes_read--;
                    438: 
                    439:                                }
                    440: 
                    441:                                continue;
                    442: 
                    443:                        }
                    444: 
                    445:                        else if ((char)ch ==tty->ltc.t_rprntc || 
                    446: 
                    447:                                 (char)ch == tty->sg.sg_kill) {
                    448: 
                    449:                                if (mode & T_TOS)
                    450: 
                    451:                                        put(f, '#');
                    452: 
                    453:                                put(f, '\r');
                    454: 
                    455:                                put(f, '\n');
                    456: 
                    457:                                ptr = buf;
                    458: 
                    459:                                if ((char)ch == tty->sg.sg_kill) {
                    460: 
                    461:                                        bytes_read = 0;
                    462: 
                    463:                                }
                    464: 
                    465:                                else {
                    466: 
                    467:                                        for (r = 0; r < bytes_read; r++, ptr++)
                    468: 
                    469:                                                put(f, *ptr);
                    470: 
                    471:                                }
                    472: 
                    473:                                continue;
                    474: 
                    475:                        }
                    476: 
1.1.1.2   root      477:                        else if ((char)ch == tty->ltc.t_werasc) {
                    478: 
                    479:                                while (bytes_read > 0 &&
                    480: 
                    481:                                       !(ptr[-1] == ' ' || ptr[-1] == '\t')) {
                    482: 
                    483:                                        ptr--;
                    484: 
                    485:                                        erase(f, *ptr);
                    486: 
                    487:                                        bytes_read--;
                    488: 
                    489:                                }
                    490: 
                    491:                                continue;
                    492: 
                    493:                        }
                    494: 
                    495:                        else if ((char)ch == tty->ltc.t_lnextc) {
                    496: 
1.1.1.6 ! root      497:                                if (mode & T_ECHOCTL) {
        !           498: 
        !           499:                                        put(f, '^');
        !           500: 
        !           501:                                        put(f, '\b');
1.1.1.2   root      502: 
1.1.1.6 ! root      503:                                }
1.1.1.2   root      504: 
                    505:                                r = tty_getchar(f, RAW);
                    506: 
1.1.1.6 ! root      507:                                if (rdmode & COOKED)
        !           508: 
        !           509:                                        tty->state |= TS_COOKED;
        !           510: 
        !           511:                                else
        !           512: 
        !           513:                                        tty->state &= ~TS_COOKED;
        !           514: 
        !           515: 
        !           516: 
1.1.1.2   root      517:                                if (r < 0)
                    518: 
                    519:                                        goto tty_error;
                    520: 
                    521:                                else if (r == MiNTEOF)
                    522: 
                    523:                                        return bytes_read;
                    524: 
                    525:                                ch = r & 0xff;
                    526: 
                    527:                                goto stuff_it;
                    528: 
                    529:                        }
                    530: 
1.1       root      531:                        else if ((char)ch == tty->tc.t_eofc && !(mode & T_TOS))
                    532: 
                    533:                                return bytes_read;
                    534: 
                    535:                }
                    536: 
                    537: 
                    538: 
                    539: /* both T_CBREAK and T_COOKED modes have to do signals, though */
                    540: 
                    541:                if ((rdmode & COOKED) && ch != UNDEF) {
                    542: 
                    543:                        if ((char)ch == tty->tc.t_intrc
                    544: 
                    545:                                 || (char)ch == tty->tc.t_quitc
                    546: 
                    547:                                 || (char)ch == tty->ltc.t_dsuspc
                    548: 
                    549:                                 || (char)ch == tty->ltc.t_suspc
                    550: 
                    551:                                ) {
                    552: 
                    553: /* the device driver raised the appropriate signal; if we get here, the
                    554: 
                    555:    signal was caught by the user (or ignored). flush buffers and continue
                    556: 
                    557:  */
                    558: 
                    559:                                if (!(tty->sg.sg_flags & T_NOFLSH)) {
                    560: 
1.1.1.2   root      561:                                        DEBUG(("tty_read: flushing input"));
1.1       root      562: 
                    563:                                        bytes_read = 0;
                    564: 
                    565:                                        ptr = buf;
                    566: 
                    567:                                }
                    568: 
                    569:                                continue;
                    570: 
                    571:                        }
                    572: 
1.1.1.6 ! root      573:                        else if ((char)ch == tty->ltc.t_flushc) {
        !           574: 
        !           575:                                continue;
        !           576: 
        !           577:                        }
        !           578: 
1.1       root      579:                        else if (ch == '\n' || (char)ch == tty->tc.t_brkc) {
                    580: 
                    581:                                put(f, '\r');
                    582: 
                    583:                                if (!(mode & T_TOS)) {
                    584: 
1.1.1.2   root      585:                                        *ptr = ch;
1.1       root      586: 
                    587:                                        put(f, '\n');
                    588: 
                    589:                                        bytes_read++;
                    590: 
1.1.1.6 ! root      591:                                if (rdmode & COOKED)
        !           592: 
        !           593:                                        tty->state |= TS_COOKED;
        !           594: 
        !           595:                                else
        !           596: 
        !           597:                                        tty->state &= ~TS_COOKED;
        !           598: 
1.1       root      599:                                }
                    600: 
                    601:                                return bytes_read;
                    602: 
                    603:                        }
                    604: 
                    605: 
                    606: 
                    607:                }
                    608: 
                    609: 
                    610: 
                    611: /* do the following for both RAW and COOKED mode */
                    612: 
1.1.1.2   root      613: stuff_it:
                    614: 
1.1       root      615:                *ptr++ = ch;
                    616: 
1.1.1.6 ! root      617:                if ((mode & T_ECHOCTL) &&
        !           618: 
        !           619:                    ch < ' ' && ch != '\t') {   /* ch is unsigned */
1.1       root      620: 
                    621:                        put(f, '^'); put(f, ch+'@');
                    622: 
                    623:                }
                    624: 
                    625:                else
                    626: 
                    627:                        put(f, ch);
                    628: 
                    629:                bytes_read++;
                    630: 
                    631: 
                    632: 
                    633: /* for RAW mode, if there are no more characters then break */
                    634: 
                    635:                if ( (mode & (T_RAW|T_CBREAK)) &&
                    636: 
                    637:                    !((rdmode & ESCSEQ) && (tty->state & TS_ESC))) {
                    638: 
                    639:                        r = 1;
                    640: 
                    641:                        (void)(*f->dev->ioctl)(f, FIONREAD, &r);
                    642: 
                    643:                        if (r <= 0) break;
                    644: 
                    645:                }       
                    646: 
                    647:        }
                    648: 
1.1.1.6 ! root      649:        if (rdmode & COOKED)
        !           650: 
        !           651:                tty->state |= TS_COOKED;
        !           652: 
        !           653:        else
1.1       root      654: 
1.1.1.6 ! root      655:                tty->state &= ~TS_COOKED;
1.1       root      656: 
                    657:        return bytes_read;
                    658: 
                    659: }
                    660: 
                    661: 
                    662: 
1.1.1.6 ! root      663: /* job control checks */
        !           664: 
        !           665: /* AKP: added T_TOSTOP; don't stop BG output if T_TOSTOP is clear */
        !           666: 
        !           667: /*
        !           668: 
        !           669: entropy: only do the job control if SIGTTOU is neither blocked nor ignored,
        !           670: 
        !           671: and only for the controlling tty (IEEE 1003.1-1990 7.1.1.4 79-87).
        !           672: 
        !           673: BUG:  if the process group is orphaned and SIGTTOU *is not* blocked
        !           674: 
        !           675: or ignored, we should return EIO instead of signalling.
        !           676: 
        !           677: */
        !           678: 
        !           679: INLINE void
        !           680: 
        !           681: tty_checkttou (f, tty)
        !           682: 
        !           683:        FILEPTR *f;
        !           684: 
        !           685:        struct tty *tty;
        !           686: 
        !           687: {
        !           688: 
        !           689:        if (tty->pgrp && tty->pgrp != curproc->pgrp &&
        !           690: 
        !           691:                 (tty->sg.sg_flags & T_TOSTOP) &&
        !           692: 
        !           693:                  (curproc->sighandle[SIGTTOU] != SIG_IGN) &&
        !           694: 
        !           695:                  ((curproc->sigmask & (1L << SIGTTOU)) == 0L) &&
        !           696: 
        !           697:                  (f->fc.dev == curproc->control->fc.dev) &&
        !           698: 
        !           699:                  (f->fc.index == curproc->control->fc.index)) {
        !           700: 
        !           701:                TRACE(("job control: tty pgrp is %d proc pgrp is %d",
        !           702: 
        !           703:                        tty->pgrp, curproc->pgrp));
        !           704: 
        !           705:                killgroup(curproc->pgrp, SIGTTOU, 1);
        !           706: 
        !           707:                check_sigs();
        !           708: 
        !           709:        }
        !           710: 
        !           711: }
        !           712: 
        !           713: 
        !           714: 
1.1       root      715: long
                    716: 
                    717: tty_write(f, buf, nbytes)
                    718: 
                    719:        FILEPTR *f;
                    720: 
                    721:        const void *buf;
                    722: 
                    723:        long nbytes;
                    724: 
                    725: {
                    726: 
                    727:        unsigned const char *ptr;
                    728: 
                    729:        long c;
                    730: 
                    731:        long bytes_written;
                    732: 
                    733:        int mode, rwmode;
                    734: 
                    735:        struct tty *tty;
                    736: 
                    737:        int use_putchar = 0;
                    738: 
                    739:        static long cr_char = '\r';
                    740: 
                    741: #define LBUFSIZ 128
                    742: 
                    743:        long lbuf[LBUFSIZ];
                    744: 
                    745: 
                    746: 
                    747:        tty = (struct tty *)f->devinfo;
                    748: 
                    749:        assert(tty != 0);
                    750: 
                    751: 
                    752: 
1.1.1.6 ! root      753:        ptr = (unsigned const char *)buf;
1.1       root      754: 
                    755:        if (f->flags & O_HEAD) {
                    756: 
                    757:                use_putchar = 1;
                    758: 
                    759:                mode = T_RAW;
                    760: 
                    761:        }
                    762: 
                    763:        else if (curproc->domain == DOM_TOS)
                    764: 
                    765: /* for TOS programs, 1 byte writes are always in raw mode */
                    766: 
                    767:                mode = (nbytes == 1) ? T_RAW : T_TOS;
                    768: 
                    769:        else
                    770: 
                    771:                mode = tty->sg.sg_flags;
                    772: 
                    773: 
                    774: 
                    775:        rwmode = (mode & T_RAW) ? RAW : COOKED;
                    776: 
                    777: 
                    778: 
                    779:        bytes_written = 0;
                    780: 
                    781: 
                    782: 
                    783: /*
                    784: 
                    785:  * "mode" can now be reduced to just T_CRMODE or not
                    786: 
                    787:  */
                    788: 
                    789:        if ((curproc->domain == DOM_MINT) && (mode & T_CRMOD) &&
                    790: 
                    791:            !(mode & T_RAW))
                    792: 
                    793:                mode = T_CRMOD;
                    794: 
                    795:        else
                    796: 
                    797:                mode = 0;
                    798: 
                    799: 
                    800: 
1.1.1.6 ! root      801:        if (nbytes == 0) return bytes_written;
        !           802: 
        !           803: #if 1
        !           804: 
        !           805:        /* see if we can do fast RAW byte IO thru the device driver... */
        !           806: 
        !           807:        if (!use_putchar && HAS_WRITEB(f)) {
        !           808: 
        !           809: 
        !           810: 
        !           811:                tty_checkttou (f, tty);
        !           812: 
        !           813:                if (rwmode & COOKED)
        !           814: 
        !           815:                        tty->state |= TS_COOKED;
        !           816: 
        !           817:                else
        !           818: 
        !           819:                        tty->state &= ~TS_COOKED;
        !           820: 
        !           821:                if (tty->state & TS_BLIND)
        !           822: 
        !           823:                        return bytes_written;
        !           824: 
        !           825:                if (mode) {     /* i.e. T_CRMODE */
        !           826: 
        !           827:                        if ((*f->dev->writeb)(f, buf, 0L) != EUNDEV) {
        !           828: 
        !           829:        /* write in big chunks if possible; lines if CRMODE
        !           830: 
        !           831:         * (if we get here flow control is taken care of by the device)
        !           832: 
        !           833:         */
        !           834: 
        !           835:                                long bytes_to_write = 0;
        !           836: 
        !           837:                                unsigned const char *s = ptr;
        !           838: 
        !           839: 
        !           840: 
        !           841:                                while (nbytes-- > 0) {
        !           842: 
        !           843:                                        if (*ptr++ == '\n') {
        !           844: 
        !           845:                                                if (0 != (bytes_to_write = ptr-s-1)) {
        !           846: 
        !           847:                                                        c = (*f->dev->writeb)(f, (const char *)s,
        !           848: 
        !           849:                                                                bytes_to_write);
        !           850: 
        !           851:                                                        bytes_written += c;
        !           852: 
        !           853:                                                        if (c != bytes_to_write) {
        !           854: 
        !           855:                                                                if (c < 0)
        !           856: 
        !           857:                                                                        bytes_written = c;
        !           858: 
        !           859:                                                                return bytes_written;
        !           860: 
        !           861:                                                        }
        !           862: 
        !           863:                                                }
        !           864: 
        !           865:                                                s = ptr-1;
        !           866: 
        !           867:                                                c = (*f->dev->writeb)(f, "\r", 1);
        !           868: 
        !           869:                                                if (c != 1) {
        !           870: 
        !           871:                                                        if (c < 0)
        !           872: 
        !           873:                                                                bytes_written = c;
        !           874: 
        !           875:                                                        return bytes_written;
        !           876: 
        !           877:                                                }
        !           878: 
        !           879:                                        }
        !           880: 
        !           881:                                }
        !           882: 
        !           883:                                if (0 != (bytes_to_write = ptr-s)) {
        !           884: 
        !           885:                                        c = (*f->dev->writeb)(f, (const char *)s, bytes_to_write);
        !           886: 
        !           887:                                        bytes_written += c;
        !           888: 
        !           889:                                        if (c < 0)
        !           890: 
        !           891:                                                bytes_written = c;
        !           892: 
        !           893:                                }
        !           894: 
        !           895:                                return bytes_written;
        !           896: 
        !           897:                        }
        !           898: 
        !           899:                } else if ((c = (*f->dev->writeb)(f, buf, nbytes)) != EUNDEV)
        !           900: 
        !           901:                        return c;
        !           902: 
        !           903:        }
        !           904: 
        !           905: #endif
        !           906: 
        !           907: 
        !           908: 
1.1       root      909: /*
                    910: 
                    911:  * we always write at least 1 byte with tty_putchar, since that takes
                    912: 
                    913:  * care of job control and terminal states. After that, we may be able
                    914: 
                    915:  * to use (*f->dev->write) directly.
                    916: 
                    917:  */
                    918: 
                    919: 
                    920: 
                    921:        c = *ptr++;
                    922: 
                    923: 
                    924: 
                    925:        if (c == '\n' && mode) {        /* remember, "mode" now means CRMOD */
                    926: 
                    927:                tty_putchar(f, cr_char, rwmode);
                    928: 
                    929:        }
                    930: 
                    931:        tty_putchar(f, c, rwmode);
                    932: 
                    933:        nbytes--;
                    934: 
                    935:        bytes_written++;
                    936: 
                    937: 
                    938: 
                    939:        if (use_putchar) {
                    940: 
                    941:                while (nbytes-- > 0) {
                    942: 
                    943:                        c = *ptr++;
                    944: 
                    945:                        if (c == '\n' && mode)
                    946: 
                    947:                                tty_putchar(f, cr_char, rwmode);
                    948: 
                    949:                        tty_putchar(f, c, rwmode);
                    950: 
                    951:                        bytes_written++;
                    952: 
                    953:                }
                    954: 
                    955:        } else {
                    956: 
                    957: /* write in big chunks if possible; but never more than 1 line
                    958: 
                    959:  * (so that ^S/^Q can happen reasonably quickly for the user)
                    960: 
                    961:  */
                    962: 
                    963:                long bytes_to_write = 0;
                    964: 
                    965:                long *s = lbuf;
                    966: 
                    967: 
                    968: 
                    969:                while (nbytes-- > 0) {
                    970: 
                    971:                        c = *ptr++;
                    972: 
                    973:                        if (c == '\n') {
                    974: 
                    975:                                if (bytes_to_write) {
                    976: 
                    977:                                        (*f->dev->write)(f, (char *)lbuf,
                    978: 
                    979:                                                bytes_to_write);
                    980: 
                    981:                                        bytes_to_write = 0;
                    982: 
                    983:                                        s = lbuf;
                    984: 
                    985:                                }
                    986: 
                    987:                                if (mode)       /* i.e. T_CRMODE */
                    988: 
                    989:                                        tty_putchar(f, cr_char, rwmode);
                    990: 
                    991:                                tty_putchar(f, (long)c, rwmode);
                    992: 
                    993:                                bytes_written++;
                    994: 
                    995:                        } else {
                    996: 
                    997:                                *s++ = c;
                    998: 
                    999:                                bytes_written++;
                   1000: 
                   1001:                                bytes_to_write += 4;
                   1002: 
                   1003:                                if (bytes_to_write >= LBUFSIZ*4) {
                   1004: 
                   1005:                                        (*f->dev->write)(f, (char *)lbuf,
                   1006: 
                   1007:                                                         bytes_to_write);
                   1008: 
                   1009:                                        bytes_to_write = 0;
                   1010: 
                   1011:                                        s = lbuf;
                   1012: 
                   1013:                                }
                   1014: 
                   1015:                        }
                   1016: 
                   1017:                }
                   1018: 
                   1019:                if (bytes_to_write) {
                   1020: 
                   1021:                        (*f->dev->write)(f, (char *)lbuf, bytes_to_write);
                   1022: 
                   1023:                }
                   1024: 
                   1025:        }
                   1026: 
                   1027: 
                   1028: 
                   1029:        return bytes_written;
                   1030: 
                   1031: }
                   1032: 
                   1033: 
                   1034: 
                   1035: /* some notable scan codes */
                   1036: 
                   1037: #define K_INSERT       0x52
                   1038: 
                   1039: #define K_HOME         0x47
                   1040: 
                   1041: #define K_UNDO         0x61
                   1042: 
                   1043: #define K_HELP         0x62
                   1044: 
                   1045: #define CURS_UP                0x48
                   1046: 
                   1047: #define CURS_DN                0x50
                   1048: 
                   1049: #define CURS_RT                0x4d
                   1050: 
                   1051: #define CURS_LF                0x4b
                   1052: 
                   1053: #define F_1            0x3b
                   1054: 
                   1055: #define F_10           0x44
                   1056: 
                   1057: #define F_11           0x54
                   1058: 
                   1059: #define F_20           0x5d
                   1060: 
                   1061: #define ALT_1          0x78
                   1062: 
                   1063: #define ALT_0          0x81
                   1064: 
                   1065: 
                   1066: 
                   1067: /* Default function key table:
                   1068: 
                   1069:  * entries:    0-9 are F1-F10
                   1070: 
                   1071:  *             10-19 are F11-F20
                   1072: 
                   1073:  *             20-23 are cursor up, down, right, and left
                   1074: 
                   1075:  *             24-27 are help, undo, insert, and home
                   1076: 
                   1077:  *             28-31 are shift+cursor up, down, right, and left
                   1078: 
                   1079:  */
                   1080: 
                   1081: 
                   1082: 
                   1083: static char vt52xkey[256] = {
                   1084: 
                   1085: '\033', 'P', 0, 0, 0, 0, 0, 0,
                   1086: 
                   1087: '\033', 'Q', 0, 0, 0, 0, 0, 0,
                   1088: 
                   1089: '\033', 'R', 0, 0, 0, 0, 0, 0,
                   1090: 
                   1091: '\033', 'S', 0, 0, 0, 0, 0, 0,
                   1092: 
                   1093: '\033', 'T', 0, 0, 0, 0, 0, 0,
                   1094: 
                   1095: '\033', 'U', 0, 0, 0, 0, 0, 0,
                   1096: 
                   1097: '\033', 'V', 0, 0, 0, 0, 0, 0,
                   1098: 
                   1099: '\033', 'W', 0, 0, 0, 0, 0, 0,
                   1100: 
                   1101: '\033', 'X', 0, 0, 0, 0, 0, 0,
                   1102: 
                   1103: '\033', 'Y', 0, 0, 0, 0, 0, 0,
                   1104: 
                   1105: '\033', 'p', 0, 0, 0, 0, 0, 0,
                   1106: 
                   1107: '\033', 'q', 0, 0, 0, 0, 0, 0,
                   1108: 
                   1109: '\033', 'r', 0, 0, 0, 0, 0, 0,
                   1110: 
                   1111: '\033', 's', 0, 0, 0, 0, 0, 0,
                   1112: 
                   1113: '\033', 't', 0, 0, 0, 0, 0, 0,
                   1114: 
                   1115: '\033', 'u', 0, 0, 0, 0, 0, 0,
                   1116: 
                   1117: '\033', 'v', 0, 0, 0, 0, 0, 0,
                   1118: 
                   1119: '\033', 'w', 0, 0, 0, 0, 0, 0,
                   1120: 
                   1121: '\033', 'x', 0, 0, 0, 0, 0, 0,
                   1122: 
                   1123: '\033', 'y', 0, 0, 0, 0, 0, 0,
                   1124: 
                   1125: '\033', 'A', 0, 0, 0, 0, 0, 0,
                   1126: 
                   1127: '\033', 'B', 0, 0, 0, 0, 0, 0,
                   1128: 
                   1129: '\033', 'C', 0, 0, 0, 0, 0, 0,
                   1130: 
                   1131: '\033', 'D', 0, 0, 0, 0, 0, 0,
                   1132: 
                   1133: '\033', 'H', 0, 0, 0, 0, 0, 0,
                   1134: 
                   1135: '\033', 'K', 0, 0, 0, 0, 0, 0,
                   1136: 
                   1137: '\033', 'I', 0, 0, 0, 0, 0, 0,
                   1138: 
                   1139: '\033', 'E', 0, 0, 0, 0, 0, 0,
                   1140: 
                   1141: '\033', 'a', 0, 0, 0, 0, 0, 0,
                   1142: 
                   1143: '\033', 'b', 0, 0, 0, 0, 0, 0,
                   1144: 
                   1145: '\033', 'c', 0, 0, 0, 0, 0, 0,
                   1146: 
                   1147: '\033', 'd', 0, 0, 0, 0, 0, 0,
                   1148: 
                   1149: };
                   1150: 
                   1151: 
                   1152: 
                   1153: static char unxbaud P_((long));
                   1154: 
                   1155: 
                   1156: 
                   1157: /* convert a number describing the baud rate into a Unix
                   1158: 
                   1159:  * style baud rate number. Returns the Unix baud rate,
                   1160: 
                   1161:  * or 16 (EXTA) if the rate is unknown
                   1162: 
                   1163:  */
                   1164: 
                   1165: 
                   1166: 
                   1167: #define EXTA 16
                   1168: 
                   1169: 
                   1170: 
                   1171: static long ubaud[EXTA] = {
                   1172: 
                   1173: 0L, 50L, 75L, 110L, 134L, 150L, 200L, 300L,
                   1174: 
                   1175: 600L, 1200L, 1800L, 2400L, 4800L, 9600L, 19200L, 38400L
                   1176: 
                   1177: };
                   1178: 
                   1179: 
                   1180: 
                   1181: static char
                   1182: 
                   1183: unxbaud(baud)
                   1184: 
                   1185:        long baud;
                   1186: 
                   1187: {
                   1188: 
                   1189:        int i;
                   1190: 
                   1191:        for (i = 1; i < EXTA; i++) {
                   1192: 
                   1193:                if (ubaud[i] == baud)
                   1194: 
                   1195:                        break;
                   1196: 
                   1197:        }
                   1198: 
                   1199:        return i;
                   1200: 
                   1201: }
                   1202: 
                   1203: 
                   1204: 
1.1.1.2   root     1205: #define tosbaud(c) ( ((c) < 0 || (c) >= EXTA) ? -1L : ubaud[(unsigned)c] )
1.1       root     1206: 
                   1207: 
                   1208: 
                   1209: long
                   1210: 
                   1211: tty_ioctl(f, mode, arg)
                   1212: 
                   1213:        FILEPTR *f;
                   1214: 
                   1215:        int mode;
                   1216: 
                   1217:        void *arg;
                   1218: 
                   1219: {
                   1220: 
                   1221:        struct sgttyb *sg;
                   1222: 
                   1223:        struct tchars *tc;
                   1224: 
                   1225:        struct ltchars *ltc;
                   1226: 
                   1227:        struct tty *tty;
                   1228: 
                   1229:        struct winsize *sz;
                   1230: 
                   1231:        struct xkey *xk;
                   1232: 
                   1233:        char *xktab;
                   1234: 
                   1235:        int i;
                   1236: 
                   1237:        long baud;
                   1238: 
                   1239:        short flags;
                   1240: 
1.1.1.6 ! root     1241:        long outq;
        !          1242: 
1.1       root     1243: 
                   1244: 
                   1245:        if (!is_terminal(f)) {
                   1246: 
1.1.1.2   root     1247:                DEBUG(("tty_ioctl(mode %x): file is not a tty", mode));
1.1       root     1248: 
                   1249:                return EINVFN;
                   1250: 
                   1251:        }
                   1252: 
                   1253:        tty = (struct tty *)f->devinfo;
                   1254: 
                   1255:        assert(tty != 0);
                   1256: 
                   1257: 
                   1258: 
                   1259:        switch(mode) {
                   1260: 
1.1.1.6 ! root     1261:        case FIONREAD:
1.1       root     1262: 
1.1.1.6 ! root     1263:            {
1.1       root     1264: 
1.1.1.6 ! root     1265:                long r;
1.1       root     1266: 
                   1267: 
                   1268: 
1.1.1.6 ! root     1269:                r = (*f->dev->ioctl)(f, FIONREAD, (void *)arg);
1.1       root     1270: 
1.1.1.6 ! root     1271:                if (r || (f->flags & O_HEAD))
1.1       root     1272: 
1.1.1.6 ! root     1273:                        return r;
1.1       root     1274: 
1.1.1.6 ! root     1275:                if (tty->state & TS_BLIND)
1.1       root     1276: 
1.1.1.6 ! root     1277:                        *(long *)arg = 0;
1.1       root     1278: 
1.1.1.6 ! root     1279:                if ((tty->sg.sg_flags & T_XKEY) && (tty->state & TS_ESC) &&
1.1       root     1280: 
1.1.1.6 ! root     1281:                    !*(long *)arg)
1.1       root     1282: 
1.1.1.6 ! root     1283:                        *(long *)arg = 1;
1.1       root     1284: 
1.1.1.6 ! root     1285:                return 0;
1.1       root     1286: 
1.1.1.6 ! root     1287:            }
1.1       root     1288: 
1.1.1.6 ! root     1289:        case FIONWRITE:
1.1       root     1290: 
1.1.1.6 ! root     1291:            {
1.1       root     1292: 
1.1.1.6 ! root     1293:                long r;
1.1       root     1294: 
                   1295: 
                   1296: 
1.1.1.6 ! root     1297:                r = (*f->dev->ioctl)(f, FIONWRITE, (void *)arg);
1.1       root     1298: 
1.1.1.6 ! root     1299:                if (r || (f->flags & O_HEAD))
1.1       root     1300: 
1.1.1.6 ! root     1301:                        return r;
1.1       root     1302: 
1.1.1.6 ! root     1303:                if ((tty->state & (TS_BLIND|TS_HOLD)))
1.1       root     1304: 
1.1.1.6 ! root     1305:                        *(long *)arg = 0;
1.1       root     1306: 
1.1.1.6 ! root     1307:                return 0;
1.1       root     1308: 
1.1.1.6 ! root     1309:            }
1.1       root     1310: 
1.1.1.6 ! root     1311:        case TIOCSBRK:
1.1       root     1312: 
1.1.1.6 ! root     1313:                if (!(tty->state & TS_BLIND) || (f->flags & O_HEAD))
1.1       root     1314: 
1.1.1.6 ! root     1315:                        return (*f->dev->ioctl)(f, TIOCSBRK, (void *)arg);
1.1       root     1316: 
1.1.1.6 ! root     1317:                return 0;
1.1       root     1318: 
1.1.1.6 ! root     1319:        case TIOCFLUSH:
1.1       root     1320: 
1.1.1.6 ! root     1321:            {
1.1       root     1322: 
1.1.1.6 ! root     1323:                long r;
1.1       root     1324: 
                   1325: 
                   1326: 
1.1.1.6 ! root     1327:                r = (*f->dev->ioctl)(f, TIOCFLUSH, (void *)arg);
1.1       root     1328: 
1.1.1.6 ! root     1329:                if (r || (f->flags & O_HEAD))
        !          1330: 
        !          1331:                        return r;
        !          1332: 
        !          1333:                if (!arg || (*(int *)arg & 1))
        !          1334: 
        !          1335:                        tty->state &= ~TS_ESC;
        !          1336: 
        !          1337:                return 0;
        !          1338: 
        !          1339:            }
        !          1340: 
        !          1341:        case TIOCGETP:
        !          1342: 
        !          1343:            {
        !          1344: 
        !          1345:                unsigned long bits[2] = {-1, TF_FLAGS};
        !          1346: 
        !          1347:                sg = (struct sgttyb *)arg;
        !          1348: 
        !          1349:        /* get input and output baud rates from the terminal device */
        !          1350: 
        !          1351:                baud = -1L;
        !          1352: 
        !          1353:                (*f->dev->ioctl)(f, TIOCIBAUD, &baud);
        !          1354: 
        !          1355:                tty->sg.sg_ispeed = unxbaud(baud);
        !          1356: 
        !          1357:                baud = -1L;
        !          1358: 
        !          1359:                (*f->dev->ioctl)(f, TIOCOBAUD, &baud);
        !          1360: 
        !          1361:                tty->sg.sg_ospeed = unxbaud(baud);
        !          1362: 
        !          1363:        /* get terminal flags */
        !          1364: 
        !          1365:                flags = 0;
        !          1366: 
        !          1367:                if ((*f->dev->ioctl)(f, TIOCSFLAGSB, &bits) == 0) {
        !          1368: 
        !          1369:                        tty->sg.sg_flags &= ~TF_FLAGS;
        !          1370: 
        !          1371:                        tty->sg.sg_flags |= (*bits & TF_FLAGS);
        !          1372: 
        !          1373:                } else if ((*f->dev->ioctl)(f, TIOCGFLAGS, &flags) == 0) {
        !          1374: 
        !          1375:                        tty->sg.sg_flags &= ~TF_FLAGS;
        !          1376: 
        !          1377:                        tty->sg.sg_flags |= (flags & TF_FLAGS);
        !          1378: 
        !          1379:                }
        !          1380: 
        !          1381:                *sg = tty->sg;
        !          1382: 
        !          1383:                return 0;
        !          1384: 
        !          1385:            }
        !          1386: 
        !          1387:        case TIOCSETP:
        !          1388: 
        !          1389:                while (((*f->dev->ioctl)(f, TIOCOUTQ, &outq) == 0) && outq)
        !          1390: 
        !          1391:                        nap(200);
        !          1392: 
        !          1393:                /* FALL THROUGH */
        !          1394: 
        !          1395:        case TIOCSETN:
        !          1396: 
        !          1397:            {
        !          1398: 
        !          1399:                unsigned long bits[2];
        !          1400: 
        !          1401:                static unsigned short v[] = {1, 0};
        !          1402: 
        !          1403:                unsigned short oflags = tty->sg.sg_flags;
        !          1404: 
        !          1405: 
        !          1406: 
        !          1407:                sg = (struct sgttyb *)arg;
        !          1408: 
        !          1409:                tty->sg = *sg;
        !          1410: 
        !          1411:        /* change tty state */
        !          1412: 
        !          1413:                if (sg->sg_flags & T_RAW) {
        !          1414: 
        !          1415:                        tty->state &= ~TS_COOKED;
        !          1416: 
        !          1417:                } else {
        !          1418: 
        !          1419:                        tty->state |= TS_COOKED;
        !          1420: 
        !          1421:                }
        !          1422: 
        !          1423:                if (!(sg->sg_flags & T_XKEY)) {
        !          1424: 
        !          1425:                        tty->state &= ~TS_ESC;
        !          1426: 
        !          1427:                }
        !          1428: 
        !          1429:        /* set baud rates */
        !          1430: 
        !          1431:                baud = tosbaud(sg->sg_ispeed);
        !          1432: 
        !          1433:                (*f->dev->ioctl)(f, TIOCIBAUD, &baud);
        !          1434: 
        !          1435:                baud = tosbaud(sg->sg_ospeed);
        !          1436: 
        !          1437:                (*f->dev->ioctl)(f, TIOCOBAUD, &baud);
        !          1438: 
        !          1439:        /* reset VMIN/VTIME */
        !          1440: 
        !          1441:                if ((*f->dev->ioctl)(f, TIOCSVMIN, &v) < 0) {
        !          1442: 
        !          1443:                        tty->vmin = 1;
        !          1444: 
        !          1445:                        tty->vtime = 0;
        !          1446: 
        !          1447:                }
        !          1448: 
        !          1449:        /* set parity, etc. */
        !          1450: 
        !          1451:                flags = TF_8BIT;
        !          1452: 
        !          1453:                if (sg->sg_flags & (T_EVENP|T_ODDP)) {
        !          1454: 
        !          1455:                        flags = TF_7BIT;
        !          1456: 
        !          1457:                }
        !          1458: 
        !          1459:                flags |= (sg->sg_flags & TF_FLAGS);
        !          1460: 
        !          1461:        /* default allow breaks to SIGINT unless RAW and no echo... */
        !          1462: 
        !          1463:                if (!(sg->sg_flags & T_RAW) || (sg->sg_flags & T_ECHO))
        !          1464: 
        !          1465:                        flags |= TF_BRKINT;
        !          1466: 
        !          1467:        /* leave local mode bit alone */
        !          1468: 
        !          1469:                bits[0] = (unsigned)flags; bits[1] = ~TF_CAR;
        !          1470: 
        !          1471:                if ((*f->dev->ioctl)(f, TIOCSFLAGSB, &bits) >= 0)
        !          1472: 
        !          1473:                        return 0;
        !          1474: 
        !          1475:        /* if TIOCSFLAGSB failed clear TF_CAR, assume the device doesn't
        !          1476: 
        !          1477:         * know about carrier anyway... */
        !          1478: 
        !          1479:                if ((*f->dev->ioctl)(f, TIOCSFLAGS, &flags) >= 0)
        !          1480: 
        !          1481:                        return 0;
        !          1482: 
        !          1483:        /* cannot set flags, don't save them */
        !          1484: 
        !          1485:                tty->sg.sg_flags = (tty->sg.sg_flags & ~TF_FLAGS)|
        !          1486: 
        !          1487:                                                (oflags & TF_FLAGS);
        !          1488: 
        !          1489:                return 0;
        !          1490: 
        !          1491:            }
        !          1492: 
        !          1493:        case TIOCGETC:
        !          1494: 
        !          1495:                tc = (struct tchars *)arg;
        !          1496: 
        !          1497:                *tc = tty->tc;
        !          1498: 
        !          1499:                return 0;
        !          1500: 
        !          1501:        case TIOCSETC:
1.1       root     1502: 
                   1503:                tc = (struct tchars *)arg;
                   1504: 
                   1505:                tty->tc = *tc;
                   1506: 
                   1507:                return 0;
                   1508: 
                   1509:        case TIOCGLTC:
                   1510: 
                   1511:                ltc = (struct ltchars *)arg;
                   1512: 
                   1513:                *ltc = tty->ltc;
                   1514: 
                   1515:                return 0;
                   1516: 
                   1517:        case TIOCSLTC:
                   1518: 
                   1519:                ltc = (struct ltchars *)arg;
                   1520: 
                   1521:                tty->ltc = *ltc;
                   1522: 
                   1523:                return 0;
                   1524: 
                   1525:        case TIOCGWINSZ:
                   1526: 
                   1527:                sz = (struct winsize *)arg;
                   1528: 
                   1529:                *sz = tty->wsiz;
                   1530: 
                   1531:                return 0;
                   1532: 
                   1533:        case TIOCSWINSZ:
                   1534: 
                   1535:                sz = (struct winsize *)arg;
                   1536: 
1.1.1.6 ! root     1537:                if (sz->ws_row != tty->wsiz.ws_row
        !          1538: 
        !          1539:                    || sz->ws_col != tty->wsiz.ws_col
        !          1540: 
        !          1541:                    || sz->ws_xpixel != tty->wsiz.ws_xpixel
        !          1542: 
        !          1543:                    || sz->ws_ypixel != tty->wsiz.ws_ypixel)
        !          1544: 
        !          1545:                  i = 1;
        !          1546: 
        !          1547:                else
        !          1548: 
        !          1549:                  i = 0;
        !          1550: 
1.1       root     1551:                tty->wsiz = *sz;
                   1552: 
1.1.1.6 ! root     1553:                if (i && tty->pgrp) killgroup(tty->pgrp, SIGWINCH, 1);
        !          1554: 
1.1       root     1555:                return 0;
                   1556: 
                   1557:        case TIOCGPGRP:
                   1558: 
                   1559:                *((long *)arg) = tty->pgrp;
                   1560: 
                   1561:                return 0;
                   1562: 
                   1563:        case TIOCSPGRP:
                   1564: 
1.1.1.6 ! root     1565:                if (!tty->pgrp) {
        !          1566: 
        !          1567:                        tty->pgrp = (*((long *)arg) & 0x00007fffL);
        !          1568: 
        !          1569: 
        !          1570: 
        !          1571:                        if (!(f->flags & O_NDELAY) && (tty->state & TS_BLIND))
        !          1572: 
        !          1573:                                (*f->dev->ioctl)(f, TIOCWONLINE, 0);
        !          1574: 
        !          1575:                } else {
        !          1576: 
        !          1577:                        tty->pgrp = (*((long *)arg) & 0x00007fffL);
        !          1578: 
        !          1579:                }
1.1       root     1580: 
                   1581:                return 0;
                   1582: 
                   1583:        case TIOCSTART:
                   1584: 
1.1.1.6 ! root     1585:                /* tty in the middle of a hangup? */
        !          1586: 
        !          1587:                if (tty->hup_ospeed)
        !          1588: 
        !          1589:                        return 0;
        !          1590: 
        !          1591: /* if the device has writeb writers may sleep for TS_HOLD (instead of polling),
        !          1592: 
        !          1593:  * tell the device and wake them up
        !          1594: 
        !          1595:  */
        !          1596: 
        !          1597:                if (HAS_WRITEB(f)) {
        !          1598: 
        !          1599:                        (void)(*f->dev->ioctl)(f, TIOCSTART, &tty->state);
        !          1600: 
        !          1601:                        tty->state &= ~TS_HOLD;
        !          1602: 
        !          1603:                        wake (IO_Q, (long)&tty->state);
        !          1604: 
        !          1605:                }
        !          1606: 
1.1       root     1607:                tty->state &= ~TS_HOLD;
                   1608: 
1.1.1.6 ! root     1609:                if (tty->wsel) {
        !          1610: 
        !          1611:                        long r = 0;
        !          1612: 
        !          1613: 
        !          1614: 
        !          1615:                        (void)(*f->dev->ioctl)(f, FIONWRITE, &r);
        !          1616: 
        !          1617:                        if (r && !(tty->state & TS_BLIND))
        !          1618: 
        !          1619:                                wakeselect (tty->wsel);
        !          1620: 
        !          1621:                }
        !          1622: 
1.1       root     1623:                return 0;
                   1624: 
                   1625:        case TIOCSTOP:
                   1626: 
1.1.1.6 ! root     1627:                if (HAS_WRITEB(f))
        !          1628: 
        !          1629:                        (void)(*f->dev->ioctl)(f, TIOCSTOP, &tty->state);
        !          1630: 
1.1       root     1631:                tty->state |= TS_HOLD;
                   1632: 
                   1633:                return 0;
                   1634: 
                   1635:        case TIOCGXKEY:
                   1636: 
                   1637:                xk = (struct xkey *)arg;
                   1638: 
                   1639:                i = xk->xk_num;
                   1640: 
                   1641:                if (i < 0 || i > 31) return ERANGE;
                   1642: 
                   1643:                xktab = tty->xkey;
                   1644: 
                   1645:                if (!xktab) xktab = vt52xkey;
                   1646: 
                   1647:                xktab += i*8;
                   1648: 
                   1649:                for (i = 0; i < 8; i++)
                   1650: 
                   1651:                        xk->xk_def[i] = *xktab++;
                   1652: 
                   1653:                return 0;
                   1654: 
                   1655:        case TIOCSXKEY:
                   1656: 
                   1657:                xk = (struct xkey *)arg;
                   1658: 
                   1659:                xktab = tty->xkey;
                   1660: 
                   1661:                if (!xktab) {
                   1662: 
                   1663:                        xktab = kmalloc((long)256);
                   1664: 
                   1665:                        if (!xktab) return ENSMEM;
                   1666: 
                   1667:                        for (i = 0; i < 256; i++)
                   1668: 
                   1669:                                xktab[i] = vt52xkey[i];
                   1670: 
                   1671:                        tty->xkey = xktab;
                   1672: 
                   1673:                }
                   1674: 
                   1675:                i = xk->xk_num;
                   1676: 
                   1677:                if (i < 0 || i > 31) return ERANGE;
                   1678: 
                   1679:                xktab += i*8;
                   1680: 
                   1681:                for (i = 0; i < 7; i++)
                   1682: 
                   1683:                        xktab[i] = xk->xk_def[i];
                   1684: 
                   1685:                xktab[7] = 0;
                   1686: 
                   1687:                return 0;
                   1688: 
1.1.1.6 ! root     1689: /*
        !          1690: 
        !          1691:  * change tty->state bits...  really only makes sense to touch TS_HPCL
        !          1692: 
        !          1693:  * or maybe TS_COOKED.  (TS_HOLD is already handled by TIOCSTART/STOP)
        !          1694: 
        !          1695:  */
        !          1696: 
        !          1697:        case TIOCSSTATEB:
        !          1698: 
        !          1699:            {
        !          1700: 
        !          1701:                long mask = ((long *)arg)[1] & ~(TS_HOLD|TS_BLIND);
        !          1702: 
        !          1703:                if (!(tty->sg.sg_flags & T_XKEY))
        !          1704: 
        !          1705:                        mask &= ~TS_ESC;
        !          1706: 
        !          1707:                if (*(long *)arg != -1)
        !          1708: 
        !          1709:                        tty->state = (tty->state & ~mask) | (*((long *)arg) & mask);
        !          1710: 
        !          1711:                *(long *)arg = tty->state;
        !          1712: 
        !          1713:                return 0;
        !          1714: 
        !          1715:            }
        !          1716: 
        !          1717:        case TIOCGSTATE:
        !          1718: 
        !          1719:                *(long *)arg = tty->state;
        !          1720: 
        !          1721:                return 0;
        !          1722: 
        !          1723: /* hang up on close, handled by kernel if the device understands TIOCOBAUD */
        !          1724: 
        !          1725:        case TIOCHPCL:
        !          1726: 
        !          1727:                tty->state |= TS_HPCL;
        !          1728: 
        !          1729:                return 0;
        !          1730: 
        !          1731: /* set/reset local mode */
        !          1732: 
        !          1733:        case TIOCNCAR:
        !          1734: 
        !          1735:        case TIOCCAR:
        !          1736: 
        !          1737:            {
        !          1738: 
        !          1739:                unsigned long bits[2] = {0, TF_CAR};
        !          1740: 
        !          1741:                if (mode == TIOCCAR)
        !          1742: 
        !          1743:                        *bits = TF_CAR;
        !          1744: 
        !          1745:                (*f->dev->ioctl)(f, TIOCSFLAGSB, &bits);
        !          1746: 
        !          1747: /*
        !          1748: 
        !          1749:  * if the ioctl failed the device does not know about carrier but don't
        !          1750: 
        !          1751:  * return an error then since its the same as carrier always on
        !          1752: 
        !          1753:  * (and anyway who puts a dialup line on a port that doesn't know
        !          1754: 
        !          1755:  * how to SIGHUP or hang up safely... :)
        !          1756: 
        !          1757:  */
        !          1758: 
        !          1759:                return 0;
        !          1760: 
        !          1761:            }
        !          1762: 
        !          1763: /* emulate some new calls, they only get here when a device does not know them:
        !          1764: 
        !          1765:  */
        !          1766: 
        !          1767:        case TIOCSFLAGSB:
        !          1768: 
        !          1769:            {
        !          1770: 
        !          1771:                long fnew, mask = ((unsigned long *)arg)[1];
        !          1772: 
        !          1773:                if (*(long *)arg < 0) {
        !          1774: 
        !          1775:                        (*f->dev->ioctl)(f, TIOCGFLAGS, &flags);
        !          1776: 
        !          1777:                        *((unsigned long *)arg) = flags;
        !          1778: 
        !          1779:                        return 0;
        !          1780: 
        !          1781:                }
        !          1782: 
        !          1783:                flags = 0;
        !          1784: 
        !          1785:                if (mask != -1)
        !          1786: 
        !          1787:                        (*f->dev->ioctl)(f, TIOCGFLAGS, &flags);
        !          1788: 
        !          1789:                fnew = (flags & ~mask) | (*((unsigned long *)arg) & mask);
        !          1790: 
        !          1791:                if (mask == -1 || fnew != flags) {
        !          1792: 
        !          1793:                        flags = fnew;
        !          1794: 
        !          1795:                        (*f->dev->ioctl)(f, TIOCSFLAGS, &flags);
        !          1796: 
        !          1797:                        (*f->dev->ioctl)(f, TIOCGFLAGS, &flags);
        !          1798: 
        !          1799:                }
        !          1800: 
        !          1801:                *(unsigned long *)arg = flags;
        !          1802: 
        !          1803:                return 0;
        !          1804: 
        !          1805:            }
        !          1806: 
        !          1807: /*
        !          1808: 
        !          1809:  * tty_read handles VTIME itself but doing VMIN > 1 without support
        !          1810: 
        !          1811:  * from the device won't be very efficient
        !          1812: 
        !          1813:  */
        !          1814: 
        !          1815:        case TIOCGVMIN:
        !          1816: 
        !          1817:                ((unsigned short *)arg)[0] = 1;                 /* VMIN */
        !          1818: 
        !          1819:                ((unsigned short *)arg)[1] = tty->vtime;        /* VTIME */
        !          1820: 
        !          1821:                return 0;
        !          1822: 
        !          1823:        case TIOCSVMIN:
        !          1824: 
        !          1825:                tty->vmin = 1;
        !          1826: 
        !          1827:                tty->vtime = ((unsigned short *)arg)[1];
        !          1828: 
        !          1829:                return 0;
        !          1830: 
        !          1831: /* devices that don't know about carrier are always online... */
        !          1832: 
        !          1833:        case TIOCWONLINE:
        !          1834: 
        !          1835:                return 0;
        !          1836: 
        !          1837: /* if the device didn't do TIOC[GS]FLAGS try transforming into TIOCSFLAGSB */
        !          1838: 
        !          1839:        case TIOCGFLAGS:
        !          1840: 
        !          1841:        case TIOCSFLAGS:
        !          1842: 
        !          1843:            {
        !          1844: 
        !          1845:                unsigned long bits[2] = {-1, (unsigned short)-1};
        !          1846: 
        !          1847:                long r;
        !          1848: 
        !          1849: 
        !          1850: 
        !          1851:                if (mode == TIOCSFLAGS)
        !          1852: 
        !          1853:                        bits[0] = *(unsigned short *)arg;
        !          1854: 
        !          1855:                r = (*f->dev->ioctl)(f, TIOCSFLAGSB, &bits);
        !          1856: 
        !          1857:                if (!r && mode == TIOCGFLAGS)
        !          1858: 
        !          1859:                        *((unsigned short *)arg) = *bits;
        !          1860: 
        !          1861:                return r;
        !          1862: 
        !          1863:            }
        !          1864: 
        !          1865: #ifdef MDM0_IOCTLS
        !          1866: 
        !          1867: /*
        !          1868: 
        !          1869:  * transform mdm0 ioctls, to allow old binaries run on new devices
        !          1870: 
        !          1871:  * note this does nothing for the other way around i.e. transform the
        !          1872: 
        !          1873:  * BSD ones (TIOCCAR/HPCL etc.) for mdm0...
        !          1874: 
        !          1875:  */
        !          1876: 
        !          1877:        case TIOCGHUPCL:
        !          1878: 
        !          1879:                *(short *)arg = tty->state & TS_HPCL ? 1 : 0;
        !          1880: 
        !          1881:                return 0;
        !          1882: 
        !          1883:        case TIOCSHUPCL:
        !          1884: 
        !          1885:                flags = *(short *)arg;
        !          1886: 
        !          1887:                *(short *)arg = tty->state & TS_HPCL ? 1 : 0;
        !          1888: 
        !          1889:                if (flags)
        !          1890: 
        !          1891:                        tty->state |= TS_HPCL;
        !          1892: 
        !          1893:                else
        !          1894: 
        !          1895:                        tty->state &= ~TS_HPCL;
        !          1896: 
        !          1897:                return 0;
        !          1898: 
        !          1899:        case TIOCGSOFTCAR:
        !          1900: 
        !          1901:            {
        !          1902: 
        !          1903:                long bits[2];
        !          1904: 
        !          1905:                flags = 1;
        !          1906: 
        !          1907:                bits[0] = -1; bits[1] = TF_CAR;
        !          1908: 
        !          1909:                if ((*f->dev->ioctl)(f, TIOCSFLAGSB, &bits) >= 0)
        !          1910: 
        !          1911:                        flags = bits[0] & TF_CAR ? 0 : 1;
        !          1912: 
        !          1913:                *(short *)arg = flags;
        !          1914: 
        !          1915:                return 0;
        !          1916: 
        !          1917:            }
        !          1918: 
        !          1919:        case TIOCSSOFTCAR:
        !          1920: 
        !          1921:            {
        !          1922: 
        !          1923:                long bits[2];
        !          1924: 
        !          1925:                flags = 1;
        !          1926: 
        !          1927:                bits[0] = *(short *)arg ? 0 : TF_CAR; bits[1] = TF_CAR;
        !          1928: 
        !          1929:                if ((*f->dev->ioctl)(f, TIOCSFLAGSB, &bits) >= 0)
        !          1930: 
        !          1931:                        flags = bits[0] & TF_CAR ? 0 : 1;
        !          1932: 
        !          1933:                *(short *)arg = flags;
        !          1934: 
        !          1935:                return 0;
        !          1936: 
        !          1937:            }
        !          1938: 
        !          1939: #endif /* MDM0_IOCTLS */
        !          1940: 
1.1       root     1941:        default:
                   1942: 
1.1.1.2   root     1943:                DEBUG(("tty_ioctl: bad function call"));
1.1       root     1944: 
                   1945:                return EINVFN;
                   1946: 
                   1947:        }
                   1948: 
                   1949: }
                   1950: 
                   1951: 
                   1952: 
                   1953: /*
                   1954: 
                   1955:  * function for translating extended characters (e.g. cursor keys, or
                   1956: 
                   1957:  * ALT+key sequences) into either escape sequences or meta characters.
                   1958: 
                   1959:  * for escape sequences, we return the the first character of the
                   1960: 
                   1961:  * sequence (normally ESC) and set the tty's state so that subsequent
                   1962: 
                   1963:  * calls to tty_getchar will pick up the remaining characters.
                   1964: 
                   1965:  * Note that escape sequences are limited to 7 characters at most.
                   1966: 
                   1967:  */
                   1968: 
                   1969: 
                   1970: 
                   1971: static int
                   1972: 
                   1973: escseq(tty, scan)
                   1974: 
                   1975:        struct tty *tty;
                   1976: 
                   1977:        int scan;
                   1978: 
                   1979: {
                   1980: 
                   1981:        char *tab;
                   1982: 
                   1983:        int i;
                   1984: 
                   1985: 
                   1986: 
                   1987:        switch(scan) {
                   1988: 
                   1989:        case CURS_UP: i = 20; break;
                   1990: 
                   1991:        case CURS_DN: i = 21; break;
                   1992: 
                   1993:        case CURS_RT: i = 22; break;
                   1994: 
                   1995:        case CURS_LF: i = 23; break;
                   1996: 
                   1997:        case K_HELP:  i = 24; break;
                   1998: 
                   1999:        case K_UNDO:  i = 25; break;
                   2000: 
                   2001:        case K_INSERT:i = 26; break;
                   2002: 
                   2003:        case K_HOME:  i = 27; break;
                   2004: 
                   2005:        case CURS_UP+0x100: i = 28; break;
                   2006: 
                   2007:        case CURS_DN+0x100: i = 29; break;
                   2008: 
                   2009:        case CURS_RT+0x100: i = 30; break;
                   2010: 
                   2011:        case CURS_LF+0x100: i = 31; break;
                   2012: 
                   2013:        default:
                   2014: 
                   2015:                if (scan >= F_1 && scan <= F_10) {
                   2016: 
                   2017:                        i = scan - F_1;
                   2018: 
                   2019:                } else if (scan >= F_11 && scan <= F_20) {
                   2020: 
                   2021:                        i = 10 + scan - F_11;
                   2022: 
                   2023:                } else
                   2024: 
                   2025:                        i = -1;
                   2026: 
                   2027:        }
                   2028: 
                   2029: 
                   2030: 
                   2031:        if (i >= 0) {           /* an extended escape sequence */
                   2032: 
                   2033:                tab = tty->xkey;
                   2034: 
                   2035:                if (!tab) tab = vt52xkey;
                   2036: 
                   2037:                i *= 8;
                   2038: 
                   2039:                scan = tab[i++];
                   2040: 
                   2041:                if (scan) {
                   2042: 
                   2043:                        if (tab[i] == 0) i = 0;
                   2044: 
                   2045:                        tty->state = (tty->state & ~TS_ESC) | i;
                   2046: 
                   2047:                }
                   2048: 
                   2049:                return scan;
                   2050: 
                   2051:        }
                   2052: 
                   2053: 
                   2054: 
                   2055:        if (scan >= ALT_1 && scan <= ALT_0) {
                   2056: 
                   2057:                scan -= (ALT_1-1);
                   2058: 
                   2059:                if (scan == 10) scan = 0;
                   2060: 
                   2061:                return (scan + '0') | 0x80;
                   2062: 
                   2063:        }
                   2064: 
                   2065: 
                   2066: 
1.1.1.2   root     2067:        tab = *( ((char **)Keytbl((void *)-1UL, (void *)-1UL, (void *)-1UL)) + 2 );     /* gratuitous (void *) for Lattice */
1.1       root     2068: 
                   2069:        scan = tab[scan];
                   2070: 
                   2071:        if (scan >= 'A' && scan <= 'Z') return scan | 0x80;
                   2072: 
                   2073:        return 0;
                   2074: 
                   2075: }
                   2076: 
                   2077: 
                   2078: 
                   2079: long
                   2080: 
                   2081: tty_getchar(f, mode)
                   2082: 
                   2083:        FILEPTR *f;
                   2084: 
                   2085:        int mode;
                   2086: 
                   2087: {
                   2088: 
                   2089:        struct tty *tty = (struct tty *)f->devinfo;
                   2090: 
                   2091:        char c, *tab;
                   2092: 
                   2093:        long r, ret;
                   2094: 
                   2095:        int scan;
                   2096: 
                   2097:        int master = f->flags & O_HEAD;
                   2098: 
                   2099: 
                   2100: 
                   2101:        assert(tty);
                   2102: 
                   2103: 
                   2104: 
                   2105: /* pty masters never worry about job control and always read in raw mode */
                   2106: 
                   2107:        if (master) {
                   2108: 
                   2109:                ret = (*f->dev->read)(f, (char *)&r, 4L);
                   2110: 
                   2111:                return (ret != 4L) ? MiNTEOF : r;
                   2112: 
                   2113:        }
                   2114: 
                   2115: 
                   2116: 
                   2117: /* job control check */
                   2118: 
1.1.1.3   root     2119: 
                   2120: 
1.1.1.6 ! root     2121: /*
        !          2122: 
        !          2123: entropy: only do the job control if SIGTTIN is neither blocked nor ignored,
        !          2124: 
        !          2125: and only for the controlling tty (IEEE 1003.1-1990 7.1.1.4 70-78).
        !          2126: 
        !          2127: BUG:  if the process group is orphaned or SIGTTIN *is* blocked or ignored,
        !          2128: 
        !          2129: we should return EIO instead of signalling.
        !          2130: 
        !          2131: */
        !          2132: 
        !          2133: 
        !          2134: 
        !          2135:        if ((tty->pgrp && tty->pgrp != curproc->pgrp) &&
        !          2136: 
        !          2137:             (f->fc.dev == curproc->control->fc.dev) &&
        !          2138: 
        !          2139:             (f->fc.index == curproc->control->fc.index)) {
1.1       root     2140: 
1.1.1.2   root     2141:                TRACE(("job control: tty pgrp is %d proc pgrp is %d",
1.1       root     2142: 
1.1.1.2   root     2143:                        tty->pgrp, curproc->pgrp));
1.1       root     2144: 
1.1.1.6 ! root     2145:                killgroup(curproc->pgrp, SIGTTIN, 1);
        !          2146: 
        !          2147:                check_sigs();
1.1       root     2148: 
                   2149:        }
                   2150: 
                   2151: 
                   2152: 
                   2153:        if (mode & COOKED)
                   2154: 
                   2155:                tty->state |= TS_COOKED;
                   2156: 
                   2157:        else
                   2158: 
                   2159:                tty->state &= ~TS_COOKED;
                   2160: 
                   2161: 
                   2162: 
                   2163:        c = UNDEF+1;    /* set to UNDEF when we successfully read a character */
                   2164: 
                   2165: 
                   2166: 
                   2167: /* we may be in the middle of an escape sequence */
                   2168: 
1.1.1.2   root     2169:        scan = (tty->state & TS_ESC);
                   2170: 
                   2171:        if (scan != 0) {
1.1       root     2172: 
                   2173:                if (mode & ESCSEQ) {
                   2174: 
                   2175:                        tab = tty->xkey ? tty->xkey : vt52xkey;
                   2176: 
                   2177:                        r = (unsigned char) tab[scan++];
                   2178: 
                   2179:                        if (r) {
                   2180: 
                   2181:                                c = UNDEF;
                   2182: 
                   2183:                                if (tab[scan] == 0) scan = 0;
                   2184: 
                   2185:                        }
                   2186: 
                   2187:                        else
                   2188: 
                   2189:                                scan = 0;
                   2190: 
                   2191:                        tty->state = (tty->state & ~TS_ESC) | scan;
                   2192: 
                   2193:                }
                   2194: 
                   2195:                else
                   2196: 
                   2197:                        tty->state &= ~TS_ESC;
                   2198: 
                   2199:        }
                   2200: 
                   2201: 
                   2202: 
                   2203:        while (c != UNDEF) {
                   2204: 
1.1.1.6 ! root     2205:                if (tty->state & TS_BLIND) {
        !          2206: 
        !          2207:                        TRACE(("tty_getchar: offline"));
        !          2208: 
        !          2209:                        return MiNTEOF;
        !          2210: 
        !          2211:                }
        !          2212: 
1.1       root     2213:                ret = (*f->dev->read)(f, (char *)&r, 4L);
                   2214: 
                   2215:                if (ret != 4L) {
                   2216: 
1.1.1.2   root     2217:                        DEBUG(("EOF on tty device"));
1.1       root     2218: 
                   2219:                        return MiNTEOF;
                   2220: 
                   2221:                }
                   2222: 
                   2223:                c = r & 0x00ff;
                   2224: 
1.1.1.2   root     2225:                scan = (int)((r & 0x00ff0000L) >> 16);
1.1       root     2226: 
                   2227:                if ( (c == 0) && (mode & ESCSEQ) && scan) {
                   2228: 
                   2229:                        c = UNDEF;
                   2230: 
                   2231:        /* translate cursor keys, etc. into escape sequences or
                   2232: 
                   2233:         * META characters
                   2234: 
                   2235:         */
                   2236: 
                   2237:                        r = escseq(tty, scan);
                   2238: 
                   2239:                } else if ((mode & ESCSEQ) && ((scan == CURS_UP && c == '8') ||
                   2240: 
                   2241:                           (scan == CURS_DN && c == '2') ||
                   2242: 
                   2243:                           (scan == CURS_RT && c == '6') ||
                   2244: 
                   2245:                           (scan == CURS_LF && c == '4'))) {
                   2246: 
                   2247:                        c = UNDEF;
                   2248: 
                   2249:                        r = escseq(tty, scan+0x100);
                   2250: 
                   2251:                } else if (mode & COOKED) {
                   2252: 
                   2253:                        if (c == UNDEF)
                   2254: 
                   2255:                                ;       /* do nothing */
                   2256: 
1.1.1.6 ! root     2257:                        else if (c == tty->ltc.t_dsuspc) {
        !          2258: 
        !          2259:                                killgroup(curproc->pgrp, SIGTSTP, 1);
1.1       root     2260: 
1.1.1.6 ! root     2261:                                check_sigs();
1.1       root     2262: 
1.1.1.6 ! root     2263:                        } else if (c == tty->tc.t_intrc) {
1.1       root     2264: 
1.1.1.6 ! root     2265:                                killgroup(curproc->pgrp, SIGINT, 1);
1.1       root     2266: 
1.1.1.6 ! root     2267:                                check_sigs();
1.1.1.5   root     2268: 
1.1.1.6 ! root     2269:                        } else if (c == tty->tc.t_quitc) {
1.1.1.5   root     2270: 
1.1.1.6 ! root     2271:                                killgroup(curproc->pgrp, SIGQUIT, 1);
1.1       root     2272: 
1.1.1.6 ! root     2273:                                check_sigs();
        !          2274: 
        !          2275:                        } else if (c == tty->tc.t_stopc)
        !          2276: 
        !          2277:                                tty_ioctl(f, TIOCSTOP, 0);
1.1       root     2278: 
1.1.1.3   root     2279:                        else if (c == tty->tc.t_startc)
1.1       root     2280: 
1.1.1.6 ! root     2281:                                tty_ioctl(f, TIOCSTART, 0);
1.1       root     2282: 
                   2283:                        else
                   2284: 
                   2285:                                c = UNDEF;
                   2286: 
                   2287:                }
                   2288: 
                   2289:                else
                   2290: 
                   2291:                                c = UNDEF;
                   2292: 
                   2293:        }
                   2294: 
                   2295: 
                   2296: 
                   2297:        if (mode & ECHO)
                   2298: 
                   2299:                tty_putchar(f, r, mode);
                   2300: 
                   2301: 
                   2302: 
                   2303:        return r;
                   2304: 
                   2305: }
                   2306: 
                   2307: 
                   2308: 
                   2309: /*
                   2310: 
                   2311:  * tty_putchar: returns number of bytes successfully written
                   2312: 
                   2313:  */
                   2314: 
                   2315: 
                   2316: 
                   2317: long
                   2318: 
                   2319: tty_putchar(f, data, mode)
                   2320: 
                   2321:        FILEPTR *f;
                   2322: 
                   2323:        long data;
                   2324: 
                   2325:        int mode;
                   2326: 
                   2327: {
                   2328: 
                   2329:        struct tty *tty;
                   2330: 
                   2331:        int master;             /* file is pty master side */
                   2332: 
                   2333:        char ch;
                   2334: 
                   2335: 
                   2336: 
                   2337:        tty = (struct tty *)f->devinfo;
                   2338: 
                   2339: 
                   2340: 
                   2341:        master = f->flags & O_HEAD;
                   2342: 
                   2343: 
                   2344: 
                   2345: /* pty masters don't need to worry about job control */
                   2346: 
                   2347:        if (master) {
                   2348: 
                   2349:                ch = data & 0xff;
                   2350: 
                   2351: 
                   2352: 
                   2353:                if ( (tty->state & TS_COOKED) && ch != UNDEF) {
                   2354: 
1.1.1.6 ! root     2355:                        long r = 1;
        !          2356: 
        !          2357: 
        !          2358: 
1.1       root     2359: /* see if we're putting control characters into the buffer */
                   2360: 
                   2361:                        if (ch == tty->tc.t_intrc) {
                   2362: 
1.1.1.6 ! root     2363:                                killgroup(tty->pgrp, SIGINT, 1);
        !          2364: 
        !          2365:                                if (!(tty->sg.sg_flags & T_NOFLSH))
        !          2366: 
        !          2367:                                        tty_ioctl(f, TIOCFLUSH, &r);
1.1       root     2368: 
1.1.1.6 ! root     2369:                                tty_ioctl (f, TIOCSTART, 0);
1.1       root     2370: 
                   2371:                                return 4L;
                   2372: 
                   2373:                        }
                   2374: 
                   2375:                        else if (ch == tty->tc.t_quitc) {
                   2376: 
1.1.1.6 ! root     2377:                                killgroup(tty->pgrp, SIGQUIT, 1);
1.1       root     2378: 
1.1.1.6 ! root     2379:                                if (!(tty->sg.sg_flags & T_NOFLSH))
        !          2380: 
        !          2381:                                        tty_ioctl(f, TIOCFLUSH, &r);
        !          2382: 
        !          2383:                                tty_ioctl (f, TIOCSTART, 0);
1.1       root     2384: 
                   2385:                                return 4L;
                   2386: 
                   2387:                        }
                   2388: 
                   2389:                        else if (ch == tty->ltc.t_suspc) {
                   2390: 
1.1.1.6 ! root     2391:                                killgroup(tty->pgrp, SIGTSTP, 1);
        !          2392: 
        !          2393:                                if (!(tty->sg.sg_flags & T_NOFLSH))
        !          2394: 
        !          2395:                                        tty_ioctl(f, TIOCFLUSH, &r);
1.1       root     2396: 
1.1.1.6 ! root     2397:                                tty_ioctl (f, TIOCSTART, 0);
1.1       root     2398: 
                   2399:                                return 4L;
                   2400: 
                   2401:                        }
                   2402: 
                   2403:                        else if (ch == tty->tc.t_stopc) {
                   2404: 
1.1.1.6 ! root     2405:                                tty_ioctl (f, TIOCSTOP, 0);
1.1       root     2406: 
                   2407:                                return 4L;
                   2408: 
                   2409:                        }
                   2410: 
                   2411:                        else if (ch == tty->tc.t_startc) {
                   2412: 
1.1.1.6 ! root     2413:                                tty_ioctl (f, TIOCSTART, 0);
        !          2414: 
        !          2415:                                return 4L;
        !          2416: 
        !          2417:                        }
        !          2418: 
        !          2419:                        else if (ch == tty->ltc.t_flushc) {
        !          2420: 
        !          2421:                                long r = 2;
        !          2422: 
        !          2423:                                tty_ioctl (f, TIOCFLUSH, &r);
1.1       root     2424: 
                   2425:                                return 4L;
                   2426: 
                   2427:                        }
                   2428: 
                   2429:                        else if (tty->state & TS_HOLD) {
                   2430: 
                   2431:                                return 0;
                   2432: 
                   2433:                        }
                   2434: 
                   2435:                }
                   2436: 
                   2437:                goto do_putchar;
                   2438: 
                   2439:        }
                   2440: 
1.1.1.6 ! root     2441: #if 1
        !          2442: 
        !          2443:        tty_checkttou(f, tty);
        !          2444: 
        !          2445: #else
        !          2446: 
1.1       root     2447: /* job control checks */
                   2448: 
                   2449: /* AKP: added T_TOSTOP; don't stop BG output if T_TOSTOP is clear */
                   2450: 
1.1.1.6 ! root     2451: /*
        !          2452: 
        !          2453: entropy: only do the job control if SIGTTOU is neither blocked nor ignored,
        !          2454: 
        !          2455: and only for the controlling tty (IEEE 1003.1-1990 7.1.1.4 79-87).
        !          2456: 
        !          2457: BUG:  if the process group is orphaned and SIGTTOU *is not* blocked
        !          2458: 
        !          2459: or ignored, we should return EIO instead of signalling.
        !          2460: 
        !          2461: */
        !          2462: 
1.1.1.3   root     2463:        if (tty->pgrp && tty->pgrp != curproc->pgrp &&
1.1       root     2464: 
1.1.1.6 ! root     2465:                 (tty->sg.sg_flags & T_TOSTOP) &&
        !          2466: 
        !          2467:                  (curproc->sighandle[SIGTTOU] != SIG_IGN) &&
        !          2468: 
        !          2469:                  ((curproc->sigmask & (1L << SIGTTOU)) == 0L) &&
        !          2470: 
        !          2471:                  (f->fc.dev == curproc->control->fc.dev) &&
        !          2472: 
        !          2473:                  (f->fc.index == curproc->control->fc.index)) {
1.1       root     2474: 
1.1.1.2   root     2475:                TRACE(("job control: tty pgrp is %d proc pgrp is %d",
1.1       root     2476: 
1.1.1.2   root     2477:                        tty->pgrp, curproc->pgrp));
1.1       root     2478: 
1.1.1.6 ! root     2479:                killgroup(curproc->pgrp, SIGTTOU, 1);
1.1       root     2480: 
                   2481:        }
                   2482: 
1.1.1.6 ! root     2483: #endif
        !          2484: 
1.1       root     2485: 
                   2486: 
                   2487:        if (mode & COOKED) {
                   2488: 
                   2489:                tty->state |= TS_COOKED;
                   2490: 
1.1.1.6 ! root     2491:                while (tty->state & (TS_HOLD|TS_BLIND)) {
        !          2492: 
        !          2493:                        short bdev;
        !          2494: 
        !          2495:                        extern DEVDRV bios_tdevice;
        !          2496: 
        !          2497: 
        !          2498: 
        !          2499:                        if (tty->state & TS_BLIND) {
        !          2500: 
        !          2501:                                TRACE(("tty_putchar: offline"));
        !          2502: 
        !          2503:                                return 0;
        !          2504: 
        !          2505:                        }
1.1.1.5   root     2506: 
                   2507: #if 1
                   2508: 
                   2509:        /* hack: BIOS devices != console never reset TS_HOLD themselves
                   2510: 
                   2511:           unless another process happens to call tty_getchar on them while
                   2512: 
                   2513:           we're here.  someone has a better fix? :-(  -nox
                   2514: 
                   2515:        */
                   2516: 
                   2517: /* BIOS device definitions */
                   2518: 
                   2519: #define CONSDEV 2
                   2520: 
                   2521:                        if (f->dev == &bios_tdevice &&
                   2522: 
1.1.1.6 ! root     2523:                            (bdev=f->fc.aux) != CONSDEV) {
        !          2524: 
        !          2525:                                long c;
1.1.1.5   root     2526: 
                   2527: 
                   2528: 
1.1.1.6 ! root     2529:                                if (!bconstat(bdev) ||
1.1.1.5   root     2530: 
1.1.1.6 ! root     2531:                                    (c = bconin(bdev) & 0x7fffffffL) == UNDEF)
1.1.1.5   root     2532: 
                   2533:                                        ;       /* do nothing */
                   2534: 
                   2535:                                else if (c == tty->ltc.t_suspc) {
                   2536: 
1.1.1.6 ! root     2537:                                        tty_ioctl(f, TIOCSTART, 0);
1.1.1.5   root     2538: 
1.1.1.6 ! root     2539:                                        killgroup(tty->pgrp, SIGTSTP, 1);
1.1.1.5   root     2540: 
                   2541:                                } else if (c == tty->tc.t_intrc) {
                   2542: 
1.1.1.6 ! root     2543:                                        tty_ioctl(f, TIOCSTART, 0);
1.1.1.5   root     2544: 
1.1.1.6 ! root     2545:                                        killgroup(tty->pgrp, SIGINT, 1);
1.1.1.5   root     2546: 
                   2547:                                } else if (c == tty->tc.t_quitc) {
                   2548: 
1.1.1.6 ! root     2549:                                        tty_ioctl(f, TIOCSTART, 0);
1.1.1.5   root     2550: 
1.1.1.6 ! root     2551:                                        killgroup(tty->pgrp, SIGQUIT, 1);
1.1.1.5   root     2552: 
                   2553:                                } else if (c == tty->tc.t_startc)
                   2554: 
1.1.1.6 ! root     2555:                                        tty_ioctl(f, TIOCSTART, 0);
        !          2556: 
        !          2557:                                else if (c == tty->ltc.t_flushc) {
        !          2558: 
        !          2559:                                        long r = 2;
        !          2560: 
        !          2561:                                        tty_ioctl(f, TIOCFLUSH, &r);
        !          2562: 
        !          2563:                                }
1.1.1.5   root     2564: 
                   2565:                        }
                   2566: 
1.1.1.6 ! root     2567:                        else
        !          2568: 
1.1.1.5   root     2569: #endif
1.1       root     2570: 
1.1.1.6 ! root     2571:                        if (HAS_WRITEB(f)) {
        !          2572: 
        !          2573: /* if the device has writeb assume it wakes us when TS_HOLD resets */
        !          2574: 
        !          2575:                                sleep (IO_Q, (long)&tty->state);
        !          2576: 
        !          2577:                                continue;
        !          2578: 
        !          2579:                        }
        !          2580: 
1.1       root     2581:                        nap(60);        /* sleep for 60 milliseconds */
                   2582: 
1.1.1.5   root     2583:                }
                   2584: 
1.1       root     2585:        }
                   2586: 
                   2587:        else
                   2588: 
                   2589:                tty->state &= ~TS_COOKED;
                   2590: 
                   2591: 
                   2592: 
                   2593: do_putchar:
                   2594: 
                   2595:        return (*f->dev->write)(f, (char *)&data, 4L);
                   2596: 
                   2597: }
                   2598: 
1.1.1.6 ! root     2599: 
        !          2600: 
        !          2601: /*
        !          2602: 
        !          2603:  * special select() function that takes T_XKEY into account
        !          2604: 
        !          2605:  */
        !          2606: 
        !          2607: long
        !          2608: 
        !          2609: tty_select(FILEPTR *f, long proc, int mode)
        !          2610: 
        !          2611: {
        !          2612: 
        !          2613:        struct tty *tty;
        !          2614: 
        !          2615: 
        !          2616: 
        !          2617:        tty = (struct tty *)f->devinfo;
        !          2618: 
        !          2619:        if (mode == O_RDONLY && (tty->sg.sg_flags & T_XKEY) &&
        !          2620: 
        !          2621:            (tty->state & TS_ESC))
        !          2622: 
        !          2623:                return 1;
        !          2624: 
        !          2625:        return (*f->dev->select)(f, proc, mode);
        !          2626: 
        !          2627: }
        !          2628: 
        !          2629: 
        !          2630: 

unix.superglobalmegacorp.com

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