xref: /csrg-svn/sys/kern/tty_compat.c (revision 56517)
149594Sbostic /*-
249594Sbostic  * Copyright (c) 1982, 1986, 1991 The Regents of the University of California.
349594Sbostic  * All rights reserved.
435763Smarc  *
549594Sbostic  * %sccs.include.redist.c%
649594Sbostic  *
7*56517Sbostic  *	@(#)tty_compat.c	7.16 (Berkeley) 10/11/92
835763Smarc  */
935763Smarc 
1035763Smarc /*
1135811Smarc  * mapping routines for old line discipline (yuck)
1235763Smarc  */
1352500Storek #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
1435763Smarc 
15*56517Sbostic #include <sys/param.h>
16*56517Sbostic #include <sys/systm.h>
17*56517Sbostic #include <sys/ioctl.h>
18*56517Sbostic #include <sys/proc.h>
19*56517Sbostic #include <sys/tty.h>
20*56517Sbostic #include <sys/termios.h>
21*56517Sbostic #include <sys/file.h>
22*56517Sbostic #include <sys/conf.h>
23*56517Sbostic #include <sys/kernel.h>
24*56517Sbostic #include <sys/syslog.h>
2535763Smarc 
2635811Smarc int ttydebug = 0;
2735763Smarc 
2835763Smarc static struct speedtab compatspeeds[] = {
2935763Smarc 	38400,	15,
3035763Smarc 	19200,	14,
3135763Smarc 	9600,	13,
3235763Smarc 	4800,	12,
3335763Smarc 	2400,	11,
3435763Smarc 	1800,	10,
3535763Smarc 	1200,	9,
3635763Smarc 	600,	8,
3735763Smarc 	300,	7,
3835763Smarc 	200,	6,
3935763Smarc 	150,	5,
4035763Smarc 	134,	4,
4135763Smarc 	110,	3,
4235763Smarc 	75,	2,
4335763Smarc 	50,	1,
4435763Smarc 	0,	0,
4535763Smarc 	-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