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