135763Smarc /* 235763Smarc * Copyright (c) 1982, 1986 Regents of the University of California. 335763Smarc * All rights reserved. The Berkeley software License Agreement 435763Smarc * specifies the terms and conditions for redistribution. 535763Smarc * 6*35811Smarc * @(#)tty_compat.c 1.2 (Berkeley) 10/18/88 735763Smarc */ 835763Smarc 935763Smarc /* 10*35811Smarc * mapping routines for old line discipline (yuck) 1135763Smarc */ 1235763Smarc #ifdef COMPAT_43 1335763Smarc 1435763Smarc #include "../machine/reg.h" 1535763Smarc 1635763Smarc #include "param.h" 1735763Smarc #include "systm.h" 1835763Smarc #include "dir.h" 1935763Smarc #include "user.h" 2035763Smarc #include "ioctl.h" 2135763Smarc #include "tty.h" 2235763Smarc #include "termios.h" 2335763Smarc #include "proc.h" 2435763Smarc #include "file.h" 2535763Smarc #include "conf.h" 2635763Smarc #include "dkstat.h" 2735763Smarc #include "uio.h" 2835763Smarc #include "kernel.h" 2935763Smarc #include "syslog.h" 3035763Smarc 31*35811Smarc int ttydebug = 0; 3235763Smarc 33*35811Smarc /* XXX - fold these two tables into one */ 3435763Smarc static struct speedtab compatspeeds[] = { 3535763Smarc 38400, 15, 3635763Smarc 19200, 14, 3735763Smarc 9600, 13, 3835763Smarc 4800, 12, 3935763Smarc 2400, 11, 4035763Smarc 1800, 10, 4135763Smarc 1200, 9, 4235763Smarc 600, 8, 4335763Smarc 300, 7, 4435763Smarc 200, 6, 4535763Smarc 150, 5, 4635763Smarc 134, 4, 4735763Smarc 110, 3, 4835763Smarc 75, 2, 4935763Smarc 50, 1, 5035763Smarc 0, 0, 5135763Smarc -1, -1, 5235763Smarc }; 5335763Smarc static int compatspcodes[16] = { 5435763Smarc 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 5535763Smarc 1800, 2400, 4800, 9600, 19200, 38400, 5635763Smarc }; 5735763Smarc 5835763Smarc /*ARGSUSED*/ 5935763Smarc ttcompat(tp, com, data, flag) 6035763Smarc register struct tty *tp; 6135763Smarc caddr_t data; 6235763Smarc { 6335763Smarc switch(com) { 6435763Smarc case TIOCGETP: { 6535763Smarc register struct sgttyb *sg = (struct sgttyb *)data; 6635763Smarc register u_char *cc = tp->t_cc; 6735763Smarc register speed; 6835763Smarc 6935763Smarc speed = ttspeedtab(tp->t_ospeed, compatspeeds); 7035763Smarc sg->sg_ospeed = (speed == -1) ? 15 : speed; 7135763Smarc if (tp->t_ispeed == 0) 7235763Smarc sg->sg_ispeed = sg->sg_ospeed; 7335763Smarc else { 7435763Smarc speed = ttspeedtab(tp->t_ispeed, compatspeeds); 7535763Smarc sg->sg_ispeed = (speed == -1) ? 15 : speed; 7635763Smarc } 7735763Smarc sg->sg_erase = cc[VERASE]; 7835763Smarc sg->sg_kill = cc[VKILL]; 79*35811Smarc sg->sg_flags = ttcompatgetflags(tp); 8035763Smarc break; 8135763Smarc } 8235763Smarc 8335763Smarc case TIOCSETP: 8435763Smarc case TIOCSETN: { 8535763Smarc register struct sgttyb *sg = (struct sgttyb *)data; 8635763Smarc struct termios term; 8735763Smarc int speed; 8835763Smarc 8935763Smarc term = tp->t_termios; 9035763Smarc if ((speed = sg->sg_ispeed) > 15 || speed < 0) 9135763Smarc term.c_ispeed = speed; 9235763Smarc else 9335763Smarc term.c_ispeed = compatspcodes[speed]; 9435763Smarc if ((speed = sg->sg_ospeed) > 15 || speed < 0) 9535763Smarc term.c_ospeed = speed; 9635763Smarc else 9735763Smarc term.c_ospeed = compatspcodes[speed]; 9835763Smarc term.c_cc[VERASE] = sg->sg_erase; 9935763Smarc term.c_cc[VKILL] = sg->sg_kill; 10035763Smarc if (sg->sg_erase == -1) 101*35811Smarc term.c_cc[VERASE2] = _POSIX_VDISABLE; 10235763Smarc tp->t_flags = (tp->t_flags&0xffff0000) | sg->sg_flags; 10335763Smarc ttcompatsetflags(tp, &term); 10435763Smarc return (ttioctl(tp, com == TIOCSETP ? TIOCSETAF : TIOCSETA, 10535763Smarc &term, flag)); 10635763Smarc } 10735763Smarc 10835763Smarc case TIOCGETC: { 10935763Smarc struct tchars *tc = (struct tchars *)data; 11035763Smarc register u_char *cc = tp->t_cc; 11135763Smarc 11235763Smarc tc->t_intrc = cc[VINTR]; 11335763Smarc tc->t_quitc = cc[VQUIT]; 11435763Smarc tc->t_startc = cc[VSTART]; 11535763Smarc tc->t_stopc = cc[VSTOP]; 11635763Smarc tc->t_eofc = cc[VEOF]; 11735763Smarc tc->t_brkc = cc[VEOL]; 11835763Smarc break; 11935763Smarc } 12035763Smarc case TIOCSETC: { 12135763Smarc struct tchars *tc = (struct tchars *)data; 12235763Smarc register u_char *cc = tp->t_cc; 12335763Smarc 12435763Smarc cc[VINTR] = tc->t_intrc; 12535763Smarc cc[VQUIT] = tc->t_quitc; 12635763Smarc cc[VSTART] = tc->t_startc; 12735763Smarc cc[VSTOP] = tc->t_stopc; 12835763Smarc cc[VEOF] = tc->t_eofc; 12935763Smarc cc[VEOL] = tc->t_brkc; 13035763Smarc if (tc->t_brkc == -1) 131*35811Smarc cc[VEOL2] = _POSIX_VDISABLE; 13235763Smarc break; 13335763Smarc } 13435763Smarc case TIOCSLTC: { 13535763Smarc struct ltchars *ltc = (struct ltchars *)data; 13635763Smarc register u_char *cc = tp->t_cc; 13735763Smarc 13835763Smarc cc[VSUSP] = ltc->t_suspc; 13935763Smarc cc[VDSUSP] = ltc->t_dsuspc; 14035763Smarc cc[VREPRINT] = ltc->t_rprntc; 14135763Smarc cc[VFLUSHO] = ltc->t_flushc; 14235763Smarc cc[VWERASE] = ltc->t_werasc; 14335763Smarc cc[VLNEXT] = ltc->t_lnextc; 14435763Smarc break; 14535763Smarc } 14635763Smarc case TIOCGLTC: { 14735763Smarc struct ltchars *ltc = (struct ltchars *)data; 14835763Smarc register u_char *cc = tp->t_cc; 14935763Smarc 15035763Smarc ltc->t_suspc = cc[VSUSP]; 15135763Smarc ltc->t_dsuspc = cc[VDSUSP]; 15235763Smarc ltc->t_rprntc = cc[VREPRINT]; 15335763Smarc ltc->t_flushc = cc[VFLUSHO]; 15435763Smarc ltc->t_werasc = cc[VWERASE]; 15535763Smarc ltc->t_lnextc = cc[VLNEXT]; 15635763Smarc break; 15735763Smarc } 15835763Smarc case TIOCLBIS: 15935763Smarc case TIOCLBIC: 16035763Smarc case TIOCLSET: { 16135763Smarc struct termios term; 16235763Smarc 16335763Smarc term = tp->t_termios; 16435763Smarc if (com == TIOCLSET) 165*35811Smarc tp->t_flags = (tp->t_flags&0xffff) | *(int *)data<<16; 16635763Smarc else { 16735763Smarc tp->t_flags = 16835763Smarc (ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff); 16935763Smarc if (com == TIOCLBIS) 170*35811Smarc tp->t_flags |= *(int *)data<<16; 17135763Smarc else 172*35811Smarc tp->t_flags &= ~(*(int *)data<<16); 17335763Smarc } 17435763Smarc ttcompatsetlflags(tp, &term); 17535763Smarc return (ttioctl(tp, TIOCSETA, &term, flag)); 17635763Smarc } 17735763Smarc case TIOCLGET: 178*35811Smarc *(int *)data = ttcompatgetflags(tp)>>16; 179*35811Smarc if (ttydebug) 180*35811Smarc printf("CLGET: returning %x\n", *(int *)data); 18135763Smarc break; 182*35811Smarc 183*35811Smarc case TIOCGETDCOMPAT: 184*35811Smarc *(int *)data = tp->t_line ? tp->t_line : 2; 185*35811Smarc break; 186*35811Smarc 187*35811Smarc case TIOCSETDCOMPAT: { 188*35811Smarc int ldisczero = 0; 189*35811Smarc 190*35811Smarc return(ttioctl(tp, TIOCSETD, 191*35811Smarc *(int *)data == 2 ? (caddr_t)&ldisczero : data, flag)); 192*35811Smarc } 193*35811Smarc 19435763Smarc default: 19535763Smarc return (-1); 19635763Smarc } 19735763Smarc return(0); 19835763Smarc } 19935763Smarc 20035763Smarc ttcompatgetflags(tp) 20135763Smarc register struct tty *tp; 20235763Smarc { 20335763Smarc register long iflag = tp->t_iflag; 20435763Smarc register long lflag = tp->t_lflag; 20535763Smarc register long oflag = tp->t_oflag; 20635763Smarc register long cflag = tp->t_cflag; 20735763Smarc register flags = 0; 20835763Smarc 20935763Smarc if (iflag&IXOFF) 21035763Smarc flags |= TANDEM; 21135763Smarc if (iflag&ICRNL || oflag&ONLCR) 21235763Smarc flags |= CRMOD; 21335763Smarc if (cflag&PARENB) { 21435763Smarc if (iflag&INPCK) { 21535763Smarc if (cflag&PARODD) 21635763Smarc flags |= ODDP; 21735763Smarc else 21835763Smarc flags |= EVENP; 21935763Smarc } else 22035763Smarc flags |= EVENP | ODDP; 22135763Smarc } else { 22235763Smarc if ((tp->t_flags&LITOUT) && !(oflag&OPOST)) 22335763Smarc flags |= LITOUT; 22435763Smarc if (tp->t_flags&PASS8) 22535763Smarc flags |= PASS8; 22635763Smarc } 22735763Smarc 22835763Smarc if ((lflag&ICANON) == 0) { 22935763Smarc /* fudge */ 23035763Smarc if (iflag&IXON || lflag&ISIG || lflag&IEXTEN || cflag&PARENB) 23135763Smarc flags |= CBREAK; 23235763Smarc else 23335763Smarc flags |= RAW; 23435763Smarc } 23535763Smarc if (oflag&OXTABS) 23635763Smarc flags |= XTABS; 23735763Smarc if (lflag&ECHOE) 238*35811Smarc flags |= CRTERA|CRTBS; 23935763Smarc if (lflag&ECHOKE) 240*35811Smarc flags |= CRTKIL|CRTBS; 24135763Smarc if (lflag&ECHOPRT) 24235763Smarc flags |= PRTERA; 24335763Smarc if (lflag&ECHOCTL) 24435763Smarc flags |= CTLECH; 24535763Smarc if ((iflag&IXANY) == 0) 24635763Smarc flags |= DECCTQ; 24735763Smarc flags |= lflag&(ECHO|MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH); 248*35811Smarc if (ttydebug) 249*35811Smarc printf("getflags: %x\n", flags); 25035763Smarc return (flags); 25135763Smarc } 25235763Smarc 25335763Smarc ttcompatsetflags(tp, t) 25435763Smarc register struct tty *tp; 25535763Smarc register struct termios *t; 25635763Smarc { 25735763Smarc register flags = tp->t_flags; 25835763Smarc register long iflag = t->c_iflag; 25935763Smarc register long oflag = t->c_oflag; 26035763Smarc register long lflag = t->c_lflag; 26135763Smarc register long cflag = t->c_cflag; 26235763Smarc 26335763Smarc if (flags & RAW) { 26435763Smarc iflag &= IXOFF; 26535763Smarc oflag &= ~OPOST; 26635763Smarc lflag &= ~(ECHOCTL|ISIG|ICANON); 26735763Smarc } else { 26835763Smarc iflag |= BRKINT|IXON|IEXTEN|IMAXBEL; 26935763Smarc oflag |= OPOST; 27035763Smarc lflag |= ISIG; 27135763Smarc if (flags & XTABS) 27235763Smarc oflag |= OXTABS; 27335763Smarc else 27435763Smarc oflag &= ~OXTABS; 27535763Smarc if (flags & CBREAK) 27635763Smarc lflag &= ~ICANON; 27735763Smarc else 27835763Smarc lflag |= ICANON; 27935763Smarc if (flags&CRMOD) { 28035763Smarc iflag |= ICRNL; 28135763Smarc oflag |= ONLCR; 28235763Smarc } else { 28335763Smarc iflag &= ~ICRNL; 28435763Smarc oflag &= ~ONLCR; 28535763Smarc } 28635763Smarc } 28735763Smarc if (flags&ECHO) 28835763Smarc lflag |= ECHO; 28935763Smarc else 29035763Smarc lflag &= ~ECHO; 29135763Smarc 29235763Smarc if (flags&(RAW|LITOUT|PASS8)) { 29335763Smarc cflag &= ~(CSIZE|PARENB); 29435763Smarc cflag |= CS8; 29535763Smarc if ((flags&(RAW|PASS8)) == 0) 29635763Smarc iflag |= ISTRIP; 29735763Smarc } else { 29835763Smarc cflag &= ~CSIZE; 29935763Smarc cflag |= CS7|PARENB; 30035763Smarc } 30135763Smarc if ((flags&(EVENP|ODDP)) == EVENP) { 30235763Smarc iflag |= INPCK; 30335763Smarc cflag &= ~PARODD; 30435763Smarc } else if ((flags&(EVENP|ODDP)) == ODDP) { 30535763Smarc iflag |= INPCK; 30635763Smarc cflag |= PARODD; 30735763Smarc } else 30835763Smarc iflag &= ~INPCK; 30935763Smarc if (flags&LITOUT) 31035763Smarc oflag &= ~OPOST; /* move earlier ? */ 31135763Smarc if (flags&TANDEM) 31235763Smarc iflag |= IXOFF; 31335763Smarc else 31435763Smarc iflag &= ~IXOFF; 31535763Smarc t->c_iflag = iflag; 31635763Smarc t->c_oflag = oflag; 31735763Smarc t->c_lflag = lflag; 31835763Smarc t->c_cflag = cflag; 31935763Smarc } 32035763Smarc 32135763Smarc ttcompatsetlflags(tp, t) 32235763Smarc register struct tty *tp; 32335763Smarc register struct termios *t; 32435763Smarc { 32535763Smarc register flags = tp->t_flags; 32635763Smarc register long iflag = t->c_iflag; 32735763Smarc register long oflag = t->c_oflag; 32835763Smarc register long lflag = t->c_lflag; 32935763Smarc register long cflag = t->c_cflag; 330*35811Smarc 33135763Smarc if (flags&CRTERA) 33235763Smarc lflag |= ECHOE; 33335763Smarc else 334*35811Smarc lflag &= ~ECHOE; 33535763Smarc if (flags&CRTKIL) 33635763Smarc lflag |= ECHOKE; 33735763Smarc else 33835763Smarc lflag &= ~ECHOKE; 33935763Smarc if (flags&PRTERA) 34035763Smarc lflag |= ECHOPRT; 34135763Smarc else 34235763Smarc lflag &= ~ECHOPRT; 34335763Smarc if (flags&CTLECH) 34435763Smarc lflag |= ECHOCTL; 34535763Smarc else 34635763Smarc lflag &= ~ECHOCTL; 34735763Smarc if ((flags&DECCTQ) == 0) 34835763Smarc lflag |= IXANY; 34935763Smarc else 35035763Smarc lflag &= ~IXANY; 35135763Smarc lflag &= ~(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH); 35235763Smarc lflag |= flags&(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH); 35335763Smarc if (flags&(LITOUT|PASS8)) { 35435763Smarc iflag &= ~ISTRIP; 35535763Smarc cflag &= ~(CSIZE|PARENB); 35635763Smarc cflag |= CS8; 35735763Smarc if (flags&LITOUT) 35835763Smarc oflag &= ~OPOST; 35935763Smarc if ((flags&(PASS8|RAW)) == 0) 36035763Smarc iflag |= ISTRIP; 36135763Smarc } else if ((flags&RAW) == 0) { 36235763Smarc cflag &= ~CSIZE; 36335763Smarc cflag |= CS7|PARENB; 36435763Smarc oflag |= OPOST; 36535763Smarc } 36635763Smarc t->c_iflag = iflag; 36735763Smarc t->c_oflag = oflag; 36835763Smarc t->c_lflag = lflag; 36935763Smarc t->c_cflag = cflag; 37035763Smarc } 37135763Smarc #endif /* COMPAT_43 */ 372