149594Sbostic /*- 2*63178Sbostic * Copyright (c) 1982, 1986, 1991, 1993 3*63178Sbostic * The Regents of the University of California. All rights reserved. 435763Smarc * 549594Sbostic * %sccs.include.redist.c% 649594Sbostic * 7*63178Sbostic * @(#)tty_compat.c 8.1 (Berkeley) 06/10/93 835763Smarc */ 935763Smarc 1035763Smarc /* 1135811Smarc * mapping routines for old line discipline (yuck) 1235763Smarc */ 1352500Storek #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 1435763Smarc 1556517Sbostic #include <sys/param.h> 1656517Sbostic #include <sys/systm.h> 1756517Sbostic #include <sys/ioctl.h> 1856517Sbostic #include <sys/proc.h> 1956517Sbostic #include <sys/tty.h> 2056517Sbostic #include <sys/termios.h> 2156517Sbostic #include <sys/file.h> 2256517Sbostic #include <sys/conf.h> 2356517Sbostic #include <sys/kernel.h> 2456517Sbostic #include <sys/syslog.h> 2535763Smarc 2635811Smarc int ttydebug = 0; 2735763Smarc 2835763Smarc static struct speedtab compatspeeds[] = { 2960513Storek { 38400, 15 }, 3060513Storek { 19200, 14 }, 3160513Storek { 9600, 13 }, 3260513Storek { 4800, 12 }, 3360513Storek { 2400, 11 }, 3460513Storek { 1800, 10 }, 3560513Storek { 1200, 9 }, 3660513Storek { 600, 8 }, 3760513Storek { 300, 7 }, 3860513Storek { 200, 6 }, 3960513Storek { 150, 5 }, 4060513Storek { 134, 4 }, 4160513Storek { 110, 3 }, 4260513Storek { 75, 2 }, 4360513Storek { 50, 1 }, 4460513Storek { 0, 0 }, 4560513Storek { -1, -1 }, 4635763Smarc }; 4735763Smarc static int compatspcodes[16] = { 4835763Smarc 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 4935763Smarc 1800, 2400, 4800, 9600, 19200, 38400, 5035763Smarc }; 5135763Smarc 5235763Smarc /*ARGSUSED*/ 5335763Smarc ttcompat(tp, com, data, flag) 5435763Smarc register struct tty *tp; 5552878Storek int com; 5635763Smarc caddr_t data; 5752878Storek int flag; 5835763Smarc { 5946426Smarc 6046426Smarc switch (com) { 6135763Smarc case TIOCGETP: { 6235763Smarc register struct sgttyb *sg = (struct sgttyb *)data; 6335763Smarc register u_char *cc = tp->t_cc; 6435763Smarc register speed; 6535763Smarc 6635763Smarc speed = ttspeedtab(tp->t_ospeed, compatspeeds); 6735763Smarc sg->sg_ospeed = (speed == -1) ? 15 : speed; 6835763Smarc if (tp->t_ispeed == 0) 6935763Smarc sg->sg_ispeed = sg->sg_ospeed; 7035763Smarc else { 7135763Smarc speed = ttspeedtab(tp->t_ispeed, compatspeeds); 7235763Smarc sg->sg_ispeed = (speed == -1) ? 15 : speed; 7335763Smarc } 7435763Smarc sg->sg_erase = cc[VERASE]; 7535763Smarc sg->sg_kill = cc[VKILL]; 7635811Smarc sg->sg_flags = ttcompatgetflags(tp); 7735763Smarc break; 7835763Smarc } 7935763Smarc 8035763Smarc case TIOCSETP: 8135763Smarc case TIOCSETN: { 8235763Smarc register struct sgttyb *sg = (struct sgttyb *)data; 8335763Smarc struct termios term; 8435763Smarc int speed; 8535763Smarc 8635763Smarc term = tp->t_termios; 8735763Smarc if ((speed = sg->sg_ispeed) > 15 || speed < 0) 8835763Smarc term.c_ispeed = speed; 8935763Smarc else 9035763Smarc term.c_ispeed = compatspcodes[speed]; 9135763Smarc if ((speed = sg->sg_ospeed) > 15 || speed < 0) 9235763Smarc term.c_ospeed = speed; 9335763Smarc else 9435763Smarc term.c_ospeed = compatspcodes[speed]; 9535763Smarc term.c_cc[VERASE] = sg->sg_erase; 9635763Smarc term.c_cc[VKILL] = sg->sg_kill; 9746426Smarc tp->t_flags = tp->t_flags&0xffff0000 | sg->sg_flags&0xffff; 9835763Smarc ttcompatsetflags(tp, &term); 9935763Smarc return (ttioctl(tp, com == TIOCSETP ? TIOCSETAF : TIOCSETA, 10035763Smarc &term, flag)); 10135763Smarc } 10235763Smarc 10335763Smarc case TIOCGETC: { 10435763Smarc struct tchars *tc = (struct tchars *)data; 10535763Smarc register u_char *cc = tp->t_cc; 10635763Smarc 10735763Smarc tc->t_intrc = cc[VINTR]; 10835763Smarc tc->t_quitc = cc[VQUIT]; 10935763Smarc tc->t_startc = cc[VSTART]; 11035763Smarc tc->t_stopc = cc[VSTOP]; 11135763Smarc tc->t_eofc = cc[VEOF]; 11235763Smarc tc->t_brkc = cc[VEOL]; 11335763Smarc break; 11435763Smarc } 11535763Smarc case TIOCSETC: { 11635763Smarc struct tchars *tc = (struct tchars *)data; 11735763Smarc register u_char *cc = tp->t_cc; 11835763Smarc 11935763Smarc cc[VINTR] = tc->t_intrc; 12035763Smarc cc[VQUIT] = tc->t_quitc; 12135763Smarc cc[VSTART] = tc->t_startc; 12235763Smarc cc[VSTOP] = tc->t_stopc; 12335763Smarc cc[VEOF] = tc->t_eofc; 12435763Smarc cc[VEOL] = tc->t_brkc; 12535763Smarc if (tc->t_brkc == -1) 12635811Smarc cc[VEOL2] = _POSIX_VDISABLE; 12735763Smarc break; 12835763Smarc } 12935763Smarc case TIOCSLTC: { 13035763Smarc struct ltchars *ltc = (struct ltchars *)data; 13135763Smarc register u_char *cc = tp->t_cc; 13235763Smarc 13335763Smarc cc[VSUSP] = ltc->t_suspc; 13435763Smarc cc[VDSUSP] = ltc->t_dsuspc; 13535763Smarc cc[VREPRINT] = ltc->t_rprntc; 13643091Smarc cc[VDISCARD] = ltc->t_flushc; 13735763Smarc cc[VWERASE] = ltc->t_werasc; 13835763Smarc cc[VLNEXT] = ltc->t_lnextc; 13935763Smarc break; 14035763Smarc } 14135763Smarc case TIOCGLTC: { 14235763Smarc struct ltchars *ltc = (struct ltchars *)data; 14335763Smarc register u_char *cc = tp->t_cc; 14435763Smarc 14535763Smarc ltc->t_suspc = cc[VSUSP]; 14635763Smarc ltc->t_dsuspc = cc[VDSUSP]; 14735763Smarc ltc->t_rprntc = cc[VREPRINT]; 14843091Smarc ltc->t_flushc = cc[VDISCARD]; 14935763Smarc ltc->t_werasc = cc[VWERASE]; 15035763Smarc ltc->t_lnextc = cc[VLNEXT]; 15135763Smarc break; 15235763Smarc } 15335763Smarc case TIOCLBIS: 15435763Smarc case TIOCLBIC: 15535763Smarc case TIOCLSET: { 15635763Smarc struct termios term; 15735763Smarc 15835763Smarc term = tp->t_termios; 15935763Smarc if (com == TIOCLSET) 16035811Smarc tp->t_flags = (tp->t_flags&0xffff) | *(int *)data<<16; 16135763Smarc else { 16235763Smarc tp->t_flags = 16335763Smarc (ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff); 16435763Smarc if (com == TIOCLBIS) 16535811Smarc tp->t_flags |= *(int *)data<<16; 16635763Smarc else 16735811Smarc tp->t_flags &= ~(*(int *)data<<16); 16835763Smarc } 16935763Smarc ttcompatsetlflags(tp, &term); 17035763Smarc return (ttioctl(tp, TIOCSETA, &term, flag)); 17135763Smarc } 17235763Smarc case TIOCLGET: 17335811Smarc *(int *)data = ttcompatgetflags(tp)>>16; 17435811Smarc if (ttydebug) 17535811Smarc printf("CLGET: returning %x\n", *(int *)data); 17635763Smarc break; 17735811Smarc 17839567Smarc case OTIOCGETD: 17935811Smarc *(int *)data = tp->t_line ? tp->t_line : 2; 18035811Smarc break; 18135811Smarc 18239567Smarc case OTIOCSETD: { 18335811Smarc int ldisczero = 0; 18435811Smarc 18546426Smarc return (ttioctl(tp, TIOCSETD, 18635811Smarc *(int *)data == 2 ? (caddr_t)&ldisczero : data, flag)); 18746426Smarc } 18841994Smckusick 18941994Smckusick case OTIOCCONS: 19041994Smckusick *(int *)data = 1; 19146426Smarc return (ttioctl(tp, TIOCCONS, data, flag)); 19235811Smarc 19335763Smarc default: 19435763Smarc return (-1); 19535763Smarc } 19646426Smarc return (0); 19735763Smarc } 19835763Smarc 19935763Smarc ttcompatgetflags(tp) 20035763Smarc register struct tty *tp; 20135763Smarc { 20235763Smarc register long iflag = tp->t_iflag; 20335763Smarc register long lflag = tp->t_lflag; 20435763Smarc register long oflag = tp->t_oflag; 20535763Smarc register long cflag = tp->t_cflag; 20635763Smarc register flags = 0; 20735763Smarc 20835763Smarc if (iflag&IXOFF) 20935763Smarc flags |= TANDEM; 21035763Smarc if (iflag&ICRNL || oflag&ONLCR) 21135763Smarc flags |= CRMOD; 21235763Smarc if (cflag&PARENB) { 21335763Smarc if (iflag&INPCK) { 21435763Smarc if (cflag&PARODD) 21535763Smarc flags |= ODDP; 21635763Smarc else 21735763Smarc flags |= EVENP; 21835763Smarc } else 21935763Smarc flags |= EVENP | ODDP; 22035763Smarc } else { 22135763Smarc if ((tp->t_flags&LITOUT) && !(oflag&OPOST)) 22235763Smarc flags |= LITOUT; 22335763Smarc if (tp->t_flags&PASS8) 22435763Smarc flags |= PASS8; 22535763Smarc } 22635763Smarc 22735763Smarc if ((lflag&ICANON) == 0) { 22835763Smarc /* fudge */ 22935763Smarc if (iflag&IXON || lflag&ISIG || lflag&IEXTEN || cflag&PARENB) 23035763Smarc flags |= CBREAK; 23135763Smarc else 23235763Smarc flags |= RAW; 23335763Smarc } 23456012Smarc if (cflag&MDMBUF) 23556012Smarc flags |= MDMBUF; 23656012Smarc if ((cflag&HUPCL) == 0) 23756012Smarc flags |= NOHANG; 23835763Smarc if (oflag&OXTABS) 23935763Smarc flags |= XTABS; 24035763Smarc if (lflag&ECHOE) 24135811Smarc flags |= CRTERA|CRTBS; 24235763Smarc if (lflag&ECHOKE) 24335811Smarc flags |= CRTKIL|CRTBS; 24435763Smarc if (lflag&ECHOPRT) 24535763Smarc flags |= PRTERA; 24635763Smarc if (lflag&ECHOCTL) 24735763Smarc flags |= CTLECH; 24835763Smarc if ((iflag&IXANY) == 0) 24935763Smarc flags |= DECCTQ; 25056012Smarc flags |= lflag&(ECHO|TOSTOP|FLUSHO|PENDIN|NOFLSH); 25135811Smarc if (ttydebug) 25235811Smarc printf("getflags: %x\n", flags); 25335763Smarc return (flags); 25435763Smarc } 25535763Smarc 25635763Smarc ttcompatsetflags(tp, t) 25735763Smarc register struct tty *tp; 25835763Smarc register struct termios *t; 25935763Smarc { 26035763Smarc register flags = tp->t_flags; 26135763Smarc register long iflag = t->c_iflag; 26235763Smarc register long oflag = t->c_oflag; 26335763Smarc register long lflag = t->c_lflag; 26435763Smarc register long cflag = t->c_cflag; 26535763Smarc 26635763Smarc if (flags & RAW) { 26735763Smarc iflag &= IXOFF; 26835763Smarc oflag &= ~OPOST; 26938925Skarels lflag &= ~(ECHOCTL|ISIG|ICANON|IEXTEN); 27035763Smarc } else { 27138925Skarels iflag |= BRKINT|IXON|IMAXBEL; 27235763Smarc oflag |= OPOST; 27346426Smarc lflag |= ISIG|IEXTEN|ECHOCTL; /* XXX was echoctl on ? */ 27435763Smarc if (flags & XTABS) 27535763Smarc oflag |= OXTABS; 27635763Smarc else 27735763Smarc oflag &= ~OXTABS; 27835763Smarc if (flags & CBREAK) 27935763Smarc lflag &= ~ICANON; 28035763Smarc else 28135763Smarc lflag |= ICANON; 28235763Smarc if (flags&CRMOD) { 28335763Smarc iflag |= ICRNL; 28435763Smarc oflag |= ONLCR; 28535763Smarc } else { 28635763Smarc iflag &= ~ICRNL; 28735763Smarc oflag &= ~ONLCR; 28835763Smarc } 28935763Smarc } 29035763Smarc if (flags&ECHO) 29135763Smarc lflag |= ECHO; 29235763Smarc else 29335763Smarc lflag &= ~ECHO; 29435763Smarc 29535763Smarc if (flags&(RAW|LITOUT|PASS8)) { 29635763Smarc cflag &= ~(CSIZE|PARENB); 29735763Smarc cflag |= CS8; 29835763Smarc if ((flags&(RAW|PASS8)) == 0) 29935763Smarc iflag |= ISTRIP; 30046426Smarc else 30146426Smarc iflag &= ~ISTRIP; 30235763Smarc } else { 30335763Smarc cflag &= ~CSIZE; 30435763Smarc cflag |= CS7|PARENB; 30546426Smarc iflag |= ISTRIP; 30635763Smarc } 30735763Smarc if ((flags&(EVENP|ODDP)) == EVENP) { 30835763Smarc iflag |= INPCK; 30935763Smarc cflag &= ~PARODD; 31035763Smarc } else if ((flags&(EVENP|ODDP)) == ODDP) { 31135763Smarc iflag |= INPCK; 31235763Smarc cflag |= PARODD; 31335763Smarc } else 31435763Smarc iflag &= ~INPCK; 31535763Smarc if (flags&LITOUT) 31635763Smarc oflag &= ~OPOST; /* move earlier ? */ 31735763Smarc if (flags&TANDEM) 31835763Smarc iflag |= IXOFF; 31935763Smarc else 32035763Smarc iflag &= ~IXOFF; 32135763Smarc t->c_iflag = iflag; 32235763Smarc t->c_oflag = oflag; 32335763Smarc t->c_lflag = lflag; 32435763Smarc t->c_cflag = cflag; 32535763Smarc } 32635763Smarc 32735763Smarc ttcompatsetlflags(tp, t) 32835763Smarc register struct tty *tp; 32935763Smarc register struct termios *t; 33035763Smarc { 33135763Smarc register flags = tp->t_flags; 33235763Smarc register long iflag = t->c_iflag; 33335763Smarc register long oflag = t->c_oflag; 33435763Smarc register long lflag = t->c_lflag; 33535763Smarc register long cflag = t->c_cflag; 33635811Smarc 33735763Smarc if (flags&CRTERA) 33835763Smarc lflag |= ECHOE; 33935763Smarc else 34035811Smarc lflag &= ~ECHOE; 34135763Smarc if (flags&CRTKIL) 34235763Smarc lflag |= ECHOKE; 34335763Smarc else 34435763Smarc lflag &= ~ECHOKE; 34535763Smarc if (flags&PRTERA) 34635763Smarc lflag |= ECHOPRT; 34735763Smarc else 34835763Smarc lflag &= ~ECHOPRT; 34935763Smarc if (flags&CTLECH) 35035763Smarc lflag |= ECHOCTL; 35135763Smarc else 35235763Smarc lflag &= ~ECHOCTL; 35335763Smarc if ((flags&DECCTQ) == 0) 35456012Smarc iflag |= IXANY; 35535763Smarc else 35656012Smarc iflag &= ~IXANY; 35756012Smarc if (flags & MDMBUF) 35856012Smarc cflag |= MDMBUF; 35956012Smarc else 36056012Smarc cflag &= ~MDMBUF; 36156012Smarc if (flags&NOHANG) 36256012Smarc cflag &= ~HUPCL; 36356012Smarc else 36456012Smarc cflag |= HUPCL; 36556012Smarc lflag &= ~(TOSTOP|FLUSHO|PENDIN|NOFLSH); 36656012Smarc lflag |= flags&(TOSTOP|FLUSHO|PENDIN|NOFLSH); 36735763Smarc if (flags&(LITOUT|PASS8)) { 36835763Smarc iflag &= ~ISTRIP; 36935763Smarc cflag &= ~(CSIZE|PARENB); 37035763Smarc cflag |= CS8; 37135763Smarc if (flags&LITOUT) 37235763Smarc oflag &= ~OPOST; 37335763Smarc if ((flags&(PASS8|RAW)) == 0) 37435763Smarc iflag |= ISTRIP; 37535763Smarc } else if ((flags&RAW) == 0) { 37635763Smarc cflag &= ~CSIZE; 37735763Smarc cflag |= CS7|PARENB; 37835763Smarc oflag |= OPOST; 37935763Smarc } 38035763Smarc t->c_iflag = iflag; 38135763Smarc t->c_oflag = oflag; 38235763Smarc t->c_lflag = lflag; 38335763Smarc t->c_cflag = cflag; 38435763Smarc } 38552500Storek #endif /* COMPAT_43 || COMPAT_SUNOS */ 386