149594Sbostic /*-
263178Sbostic * Copyright (c) 1982, 1986, 1991, 1993
363178Sbostic * The Regents of the University of California. All rights reserved.
435763Smarc *
549594Sbostic * %sccs.include.redist.c%
649594Sbostic *
7*68171Scgd * @(#)tty_compat.c 8.2 (Berkeley) 01/09/95
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*/
ttcompat(tp,com,data,flag)5335763Smarc ttcompat(tp, com, data, flag)
5435763Smarc register struct tty *tp;
55*68171Scgd u_long 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
ttcompatgetflags(tp)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
ttcompatsetflags(tp,t)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
ttcompatsetlflags(tp,t)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