xref: /csrg-svn/sys/kern/tty_compat.c (revision 68171)
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