xref: /csrg-svn/sys/kern/tty_compat.c (revision 46426)
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*46426Smarc  *	@(#)tty_compat.c	7.7 (Berkeley) 02/15/91
735763Smarc  */
835763Smarc 
935763Smarc /*
1035811Smarc  * mapping routines for old line discipline (yuck)
1135763Smarc  */
1235763Smarc #ifdef COMPAT_43
1335763Smarc 
1435763Smarc #include "param.h"
1535763Smarc #include "systm.h"
1635763Smarc #include "user.h"
1735763Smarc #include "ioctl.h"
1835763Smarc #include "tty.h"
1935763Smarc #include "termios.h"
2035763Smarc #include "proc.h"
2135763Smarc #include "file.h"
2235763Smarc #include "conf.h"
2335763Smarc #include "dkstat.h"
2435763Smarc #include "uio.h"
2535763Smarc #include "kernel.h"
2635763Smarc #include "syslog.h"
2735763Smarc 
2837526Smckusick #include "machine/reg.h"
2937526Smckusick 
3035811Smarc int ttydebug = 0;
3135763Smarc 
3235763Smarc static struct speedtab compatspeeds[] = {
3335763Smarc 	38400,	15,
3435763Smarc 	19200,	14,
3535763Smarc 	9600,	13,
3635763Smarc 	4800,	12,
3735763Smarc 	2400,	11,
3835763Smarc 	1800,	10,
3935763Smarc 	1200,	9,
4035763Smarc 	600,	8,
4135763Smarc 	300,	7,
4235763Smarc 	200,	6,
4335763Smarc 	150,	5,
4435763Smarc 	134,	4,
4535763Smarc 	110,	3,
4635763Smarc 	75,	2,
4735763Smarc 	50,	1,
4835763Smarc 	0,	0,
4935763Smarc 	-1,	-1,
5035763Smarc };
5135763Smarc static int compatspcodes[16] = {
5235763Smarc 	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
5335763Smarc 	1800, 2400, 4800, 9600, 19200, 38400,
5435763Smarc };
5535763Smarc 
56*46426Smarc ttspeedtab(speed, table)
57*46426Smarc 	register struct speedtab *table;
58*46426Smarc {
59*46426Smarc 
60*46426Smarc 	for ( ; table->sp_speed != -1; table++)
61*46426Smarc 		if (table->sp_speed == speed)
62*46426Smarc 			return (table->sp_code);
63*46426Smarc 	return (-1);
64*46426Smarc }
65*46426Smarc 
6635763Smarc /*ARGSUSED*/
6735763Smarc ttcompat(tp, com, data, flag)
6835763Smarc 	register struct tty *tp;
6935763Smarc 	caddr_t data;
7035763Smarc {
71*46426Smarc 
72*46426Smarc 	switch (com) {
7335763Smarc 	case TIOCGETP: {
7435763Smarc 		register struct sgttyb *sg = (struct sgttyb *)data;
7535763Smarc 		register u_char *cc = tp->t_cc;
7635763Smarc 		register speed;
7735763Smarc 
7835763Smarc 		speed = ttspeedtab(tp->t_ospeed, compatspeeds);
7935763Smarc 		sg->sg_ospeed = (speed == -1) ? 15 : speed;
8035763Smarc 		if (tp->t_ispeed == 0)
8135763Smarc 			sg->sg_ispeed = sg->sg_ospeed;
8235763Smarc 		else {
8335763Smarc 			speed = ttspeedtab(tp->t_ispeed, compatspeeds);
8435763Smarc 			sg->sg_ispeed = (speed == -1) ? 15 : speed;
8535763Smarc 		}
8635763Smarc 		sg->sg_erase = cc[VERASE];
8735763Smarc 		sg->sg_kill = cc[VKILL];
8835811Smarc 		sg->sg_flags = ttcompatgetflags(tp);
8935763Smarc 		break;
9035763Smarc 	}
9135763Smarc 
9235763Smarc 	case TIOCSETP:
9335763Smarc 	case TIOCSETN: {
9435763Smarc 		register struct sgttyb *sg = (struct sgttyb *)data;
9535763Smarc 		struct termios term;
9635763Smarc 		int speed;
9735763Smarc 
9835763Smarc 		term = tp->t_termios;
9935763Smarc 		if ((speed = sg->sg_ispeed) > 15 || speed < 0)
10035763Smarc 			term.c_ispeed = speed;
10135763Smarc 		else
10235763Smarc 			term.c_ispeed = compatspcodes[speed];
10335763Smarc 		if ((speed = sg->sg_ospeed) > 15 || speed < 0)
10435763Smarc 			term.c_ospeed = speed;
10535763Smarc 		else
10635763Smarc 			term.c_ospeed = compatspcodes[speed];
10735763Smarc 		term.c_cc[VERASE] = sg->sg_erase;
10835763Smarc 		term.c_cc[VKILL] = sg->sg_kill;
109*46426Smarc 		tp->t_flags = tp->t_flags&0xffff0000 | sg->sg_flags&0xffff;
11035763Smarc 		ttcompatsetflags(tp, &term);
11135763Smarc 		return (ttioctl(tp, com == TIOCSETP ? TIOCSETAF : TIOCSETA,
11235763Smarc 			&term, flag));
11335763Smarc 	}
11435763Smarc 
11535763Smarc 	case TIOCGETC: {
11635763Smarc 		struct tchars *tc = (struct tchars *)data;
11735763Smarc 		register u_char *cc = tp->t_cc;
11835763Smarc 
11935763Smarc 		tc->t_intrc = cc[VINTR];
12035763Smarc 		tc->t_quitc = cc[VQUIT];
12135763Smarc 		tc->t_startc = cc[VSTART];
12235763Smarc 		tc->t_stopc = cc[VSTOP];
12335763Smarc 		tc->t_eofc = cc[VEOF];
12435763Smarc 		tc->t_brkc = cc[VEOL];
12535763Smarc 		break;
12635763Smarc 	}
12735763Smarc 	case TIOCSETC: {
12835763Smarc 		struct tchars *tc = (struct tchars *)data;
12935763Smarc 		register u_char *cc = tp->t_cc;
13035763Smarc 
13135763Smarc 		cc[VINTR] = tc->t_intrc;
13235763Smarc 		cc[VQUIT] = tc->t_quitc;
13335763Smarc 		cc[VSTART] = tc->t_startc;
13435763Smarc 		cc[VSTOP] = tc->t_stopc;
13535763Smarc 		cc[VEOF] = tc->t_eofc;
13635763Smarc 		cc[VEOL] = tc->t_brkc;
13735763Smarc 		if (tc->t_brkc == -1)
13835811Smarc 			cc[VEOL2] = _POSIX_VDISABLE;
13935763Smarc 		break;
14035763Smarc 	}
14135763Smarc 	case TIOCSLTC: {
14235763Smarc 		struct ltchars *ltc = (struct ltchars *)data;
14335763Smarc 		register u_char *cc = tp->t_cc;
14435763Smarc 
14535763Smarc 		cc[VSUSP] = ltc->t_suspc;
14635763Smarc 		cc[VDSUSP] = ltc->t_dsuspc;
14735763Smarc 		cc[VREPRINT] = ltc->t_rprntc;
14843091Smarc 		cc[VDISCARD] = ltc->t_flushc;
14935763Smarc 		cc[VWERASE] = ltc->t_werasc;
15035763Smarc 		cc[VLNEXT] = ltc->t_lnextc;
15135763Smarc 		break;
15235763Smarc 	}
15335763Smarc 	case TIOCGLTC: {
15435763Smarc 		struct ltchars *ltc = (struct ltchars *)data;
15535763Smarc 		register u_char *cc = tp->t_cc;
15635763Smarc 
15735763Smarc 		ltc->t_suspc = cc[VSUSP];
15835763Smarc 		ltc->t_dsuspc = cc[VDSUSP];
15935763Smarc 		ltc->t_rprntc = cc[VREPRINT];
16043091Smarc 		ltc->t_flushc = cc[VDISCARD];
16135763Smarc 		ltc->t_werasc = cc[VWERASE];
16235763Smarc 		ltc->t_lnextc = cc[VLNEXT];
16335763Smarc 		break;
16435763Smarc 	}
16535763Smarc 	case TIOCLBIS:
16635763Smarc 	case TIOCLBIC:
16735763Smarc 	case TIOCLSET: {
16835763Smarc 		struct termios term;
16935763Smarc 
17035763Smarc 		term = tp->t_termios;
17135763Smarc 		if (com == TIOCLSET)
17235811Smarc 			tp->t_flags = (tp->t_flags&0xffff) | *(int *)data<<16;
17335763Smarc 		else {
17435763Smarc 			tp->t_flags =
17535763Smarc 			 (ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff);
17635763Smarc 			if (com == TIOCLBIS)
17735811Smarc 				tp->t_flags |= *(int *)data<<16;
17835763Smarc 			else
17935811Smarc 				tp->t_flags &= ~(*(int *)data<<16);
18035763Smarc 		}
18135763Smarc 		ttcompatsetlflags(tp, &term);
18235763Smarc 		return (ttioctl(tp, TIOCSETA, &term, flag));
18335763Smarc 	}
18435763Smarc 	case TIOCLGET:
18535811Smarc 		*(int *)data = ttcompatgetflags(tp)>>16;
18635811Smarc 		if (ttydebug)
18735811Smarc 			printf("CLGET: returning %x\n", *(int *)data);
18835763Smarc 		break;
18935811Smarc 
19039567Smarc 	case OTIOCGETD:
19135811Smarc 		*(int *)data = tp->t_line ? tp->t_line : 2;
19235811Smarc 		break;
19335811Smarc 
19439567Smarc 	case OTIOCSETD: {
19535811Smarc 		int ldisczero = 0;
19635811Smarc 
197*46426Smarc 		return (ttioctl(tp, TIOCSETD,
19835811Smarc 			*(int *)data == 2 ? (caddr_t)&ldisczero : data, flag));
199*46426Smarc 	    }
20041994Smckusick 
20141994Smckusick 	case OTIOCCONS:
20241994Smckusick 		*(int *)data = 1;
203*46426Smarc 		return (ttioctl(tp, TIOCCONS, data, flag));
20435811Smarc 
20535763Smarc 	default:
20635763Smarc 		return (-1);
20735763Smarc 	}
208*46426Smarc 	return (0);
20935763Smarc }
21035763Smarc 
21135763Smarc ttcompatgetflags(tp)
21235763Smarc 	register struct tty *tp;
21335763Smarc {
21435763Smarc 	register long iflag = tp->t_iflag;
21535763Smarc 	register long lflag = tp->t_lflag;
21635763Smarc 	register long oflag = tp->t_oflag;
21735763Smarc 	register long cflag = tp->t_cflag;
21835763Smarc 	register flags = 0;
21935763Smarc 
22035763Smarc 	if (iflag&IXOFF)
22135763Smarc 		flags |= TANDEM;
22235763Smarc 	if (iflag&ICRNL || oflag&ONLCR)
22335763Smarc 		flags |= CRMOD;
22435763Smarc 	if (cflag&PARENB) {
22535763Smarc 		if (iflag&INPCK) {
22635763Smarc 			if (cflag&PARODD)
22735763Smarc 				flags |= ODDP;
22835763Smarc 			else
22935763Smarc 				flags |= EVENP;
23035763Smarc 		} else
23135763Smarc 			flags |= EVENP | ODDP;
23235763Smarc 	} else {
23335763Smarc 		if ((tp->t_flags&LITOUT) && !(oflag&OPOST))
23435763Smarc 			flags |= LITOUT;
23535763Smarc 		if (tp->t_flags&PASS8)
23635763Smarc 			flags |= PASS8;
23735763Smarc 	}
23835763Smarc 
23935763Smarc 	if ((lflag&ICANON) == 0) {
24035763Smarc 		/* fudge */
24135763Smarc 		if (iflag&IXON || lflag&ISIG || lflag&IEXTEN || cflag&PARENB)
24235763Smarc 			flags |= CBREAK;
24335763Smarc 		else
24435763Smarc 			flags |= RAW;
24535763Smarc 	}
24635763Smarc 	if (oflag&OXTABS)
24735763Smarc 		flags |= XTABS;
24835763Smarc 	if (lflag&ECHOE)
24935811Smarc 		flags |= CRTERA|CRTBS;
25035763Smarc 	if (lflag&ECHOKE)
25135811Smarc 		flags |= CRTKIL|CRTBS;
25235763Smarc 	if (lflag&ECHOPRT)
25335763Smarc 		flags |= PRTERA;
25435763Smarc 	if (lflag&ECHOCTL)
25535763Smarc 		flags |= CTLECH;
25635763Smarc 	if ((iflag&IXANY) == 0)
25735763Smarc 		flags |= DECCTQ;
25835763Smarc 	flags |= lflag&(ECHO|MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH);
25935811Smarc if (ttydebug)
26035811Smarc 	printf("getflags: %x\n", flags);
26135763Smarc 	return (flags);
26235763Smarc }
26335763Smarc 
26435763Smarc ttcompatsetflags(tp, t)
26535763Smarc 	register struct tty *tp;
26635763Smarc 	register struct termios *t;
26735763Smarc {
26835763Smarc 	register flags = tp->t_flags;
26935763Smarc 	register long iflag = t->c_iflag;
27035763Smarc 	register long oflag = t->c_oflag;
27135763Smarc 	register long lflag = t->c_lflag;
27235763Smarc 	register long cflag = t->c_cflag;
27335763Smarc 
27435763Smarc 	if (flags & RAW) {
27535763Smarc 		iflag &= IXOFF;
27635763Smarc 		oflag &= ~OPOST;
27738925Skarels 		lflag &= ~(ECHOCTL|ISIG|ICANON|IEXTEN);
27835763Smarc 	} else {
27938925Skarels 		iflag |= BRKINT|IXON|IMAXBEL;
28035763Smarc 		oflag |= OPOST;
281*46426Smarc 		lflag |= ISIG|IEXTEN|ECHOCTL;	/* XXX was echoctl on ? */
28235763Smarc 		if (flags & XTABS)
28335763Smarc 			oflag |= OXTABS;
28435763Smarc 		else
28535763Smarc 			oflag &= ~OXTABS;
28635763Smarc 		if (flags & CBREAK)
28735763Smarc 			lflag &= ~ICANON;
28835763Smarc 		else
28935763Smarc 			lflag |= ICANON;
29035763Smarc 		if (flags&CRMOD) {
29135763Smarc 			iflag |= ICRNL;
29235763Smarc 			oflag |= ONLCR;
29335763Smarc 		} else {
29435763Smarc 			iflag &= ~ICRNL;
29535763Smarc 			oflag &= ~ONLCR;
29635763Smarc 		}
29735763Smarc 	}
29835763Smarc 	if (flags&ECHO)
29935763Smarc 		lflag |= ECHO;
30035763Smarc 	else
30135763Smarc 		lflag &= ~ECHO;
30235763Smarc 
30335763Smarc 	if (flags&(RAW|LITOUT|PASS8)) {
30435763Smarc 		cflag &= ~(CSIZE|PARENB);
30535763Smarc 		cflag |= CS8;
30635763Smarc 		if ((flags&(RAW|PASS8)) == 0)
30735763Smarc 			iflag |= ISTRIP;
308*46426Smarc 		else
309*46426Smarc 			iflag &= ~ISTRIP;
31035763Smarc 	} else {
31135763Smarc 		cflag &= ~CSIZE;
31235763Smarc 		cflag |= CS7|PARENB;
313*46426Smarc 		iflag |= ISTRIP;
31435763Smarc 	}
31535763Smarc 	if ((flags&(EVENP|ODDP)) == EVENP) {
31635763Smarc 		iflag |= INPCK;
31735763Smarc 		cflag &= ~PARODD;
31835763Smarc 	} else if ((flags&(EVENP|ODDP)) == ODDP) {
31935763Smarc 		iflag |= INPCK;
32035763Smarc 		cflag |= PARODD;
32135763Smarc 	} else
32235763Smarc 		iflag &= ~INPCK;
32335763Smarc 	if (flags&LITOUT)
32435763Smarc 		oflag &= ~OPOST;	/* move earlier ? */
32535763Smarc 	if (flags&TANDEM)
32635763Smarc 		iflag |= IXOFF;
32735763Smarc 	else
32835763Smarc 		iflag &= ~IXOFF;
32935763Smarc 	t->c_iflag = iflag;
33035763Smarc 	t->c_oflag = oflag;
33135763Smarc 	t->c_lflag = lflag;
33235763Smarc 	t->c_cflag = cflag;
33335763Smarc }
33435763Smarc 
33535763Smarc ttcompatsetlflags(tp, t)
33635763Smarc 	register struct tty *tp;
33735763Smarc 	register struct termios *t;
33835763Smarc {
33935763Smarc 	register flags = tp->t_flags;
34035763Smarc 	register long iflag = t->c_iflag;
34135763Smarc 	register long oflag = t->c_oflag;
34235763Smarc 	register long lflag = t->c_lflag;
34335763Smarc 	register long cflag = t->c_cflag;
34435811Smarc 
34535763Smarc 	if (flags&CRTERA)
34635763Smarc 		lflag |= ECHOE;
34735763Smarc 	else
34835811Smarc 		lflag &= ~ECHOE;
34935763Smarc 	if (flags&CRTKIL)
35035763Smarc 		lflag |= ECHOKE;
35135763Smarc 	else
35235763Smarc 		lflag &= ~ECHOKE;
35335763Smarc 	if (flags&PRTERA)
35435763Smarc 		lflag |= ECHOPRT;
35535763Smarc 	else
35635763Smarc 		lflag &= ~ECHOPRT;
35735763Smarc 	if (flags&CTLECH)
35835763Smarc 		lflag |= ECHOCTL;
35935763Smarc 	else
36035763Smarc 		lflag &= ~ECHOCTL;
36135763Smarc 	if ((flags&DECCTQ) == 0)
36235763Smarc 		lflag |= IXANY;
36335763Smarc 	else
36435763Smarc 		lflag &= ~IXANY;
36535763Smarc 	lflag &= ~(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH);
36635763Smarc 	lflag |= flags&(MDMBUF|TOSTOP|FLUSHO|NOHANG|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 }
38535763Smarc #endif	/* COMPAT_43 */
386