xref: /csrg-svn/sys/kern/tty_compat.c (revision 52878)
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*52878Storek  *	@(#)tty_compat.c	7.13 (Berkeley) 03/09/92
835763Smarc  */
935763Smarc 
1035763Smarc /*
1135811Smarc  * mapping routines for old line discipline (yuck)
1235763Smarc  */
1352500Storek #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
1435763Smarc 
1535763Smarc #include "param.h"
1635763Smarc #include "systm.h"
1735763Smarc #include "ioctl.h"
1852512Smckusick #include "proc.h"
1935763Smarc #include "tty.h"
2035763Smarc #include "termios.h"
2135763Smarc #include "file.h"
2235763Smarc #include "conf.h"
2335763Smarc #include "dkstat.h"
2435763Smarc #include "kernel.h"
2535763Smarc #include "syslog.h"
2635763Smarc 
2735811Smarc int ttydebug = 0;
2835763Smarc 
2935763Smarc static struct speedtab compatspeeds[] = {
3035763Smarc 	38400,	15,
3135763Smarc 	19200,	14,
3235763Smarc 	9600,	13,
3335763Smarc 	4800,	12,
3435763Smarc 	2400,	11,
3535763Smarc 	1800,	10,
3635763Smarc 	1200,	9,
3735763Smarc 	600,	8,
3835763Smarc 	300,	7,
3935763Smarc 	200,	6,
4035763Smarc 	150,	5,
4135763Smarc 	134,	4,
4235763Smarc 	110,	3,
4335763Smarc 	75,	2,
4435763Smarc 	50,	1,
4535763Smarc 	0,	0,
4635763Smarc 	-1,	-1,
4735763Smarc };
4835763Smarc static int compatspcodes[16] = {
4935763Smarc 	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
5035763Smarc 	1800, 2400, 4800, 9600, 19200, 38400,
5135763Smarc };
5235763Smarc 
5335763Smarc /*ARGSUSED*/
5435763Smarc ttcompat(tp, com, data, flag)
5535763Smarc 	register struct tty *tp;
56*52878Storek 	int com;
5735763Smarc 	caddr_t data;
58*52878Storek 	int flag;
5935763Smarc {
6046426Smarc 
6146426Smarc 	switch (com) {
6235763Smarc 	case TIOCGETP: {
6335763Smarc 		register struct sgttyb *sg = (struct sgttyb *)data;
6435763Smarc 		register u_char *cc = tp->t_cc;
6535763Smarc 		register speed;
6635763Smarc 
6735763Smarc 		speed = ttspeedtab(tp->t_ospeed, compatspeeds);
6835763Smarc 		sg->sg_ospeed = (speed == -1) ? 15 : speed;
6935763Smarc 		if (tp->t_ispeed == 0)
7035763Smarc 			sg->sg_ispeed = sg->sg_ospeed;
7135763Smarc 		else {
7235763Smarc 			speed = ttspeedtab(tp->t_ispeed, compatspeeds);
7335763Smarc 			sg->sg_ispeed = (speed == -1) ? 15 : speed;
7435763Smarc 		}
7535763Smarc 		sg->sg_erase = cc[VERASE];
7635763Smarc 		sg->sg_kill = cc[VKILL];
7735811Smarc 		sg->sg_flags = ttcompatgetflags(tp);
7835763Smarc 		break;
7935763Smarc 	}
8035763Smarc 
8135763Smarc 	case TIOCSETP:
8235763Smarc 	case TIOCSETN: {
8335763Smarc 		register struct sgttyb *sg = (struct sgttyb *)data;
8435763Smarc 		struct termios term;
8535763Smarc 		int speed;
8635763Smarc 
8735763Smarc 		term = tp->t_termios;
8835763Smarc 		if ((speed = sg->sg_ispeed) > 15 || speed < 0)
8935763Smarc 			term.c_ispeed = speed;
9035763Smarc 		else
9135763Smarc 			term.c_ispeed = compatspcodes[speed];
9235763Smarc 		if ((speed = sg->sg_ospeed) > 15 || speed < 0)
9335763Smarc 			term.c_ospeed = speed;
9435763Smarc 		else
9535763Smarc 			term.c_ospeed = compatspcodes[speed];
9635763Smarc 		term.c_cc[VERASE] = sg->sg_erase;
9735763Smarc 		term.c_cc[VKILL] = sg->sg_kill;
9846426Smarc 		tp->t_flags = tp->t_flags&0xffff0000 | sg->sg_flags&0xffff;
9935763Smarc 		ttcompatsetflags(tp, &term);
10035763Smarc 		return (ttioctl(tp, com == TIOCSETP ? TIOCSETAF : TIOCSETA,
10135763Smarc 			&term, flag));
10235763Smarc 	}
10335763Smarc 
10435763Smarc 	case TIOCGETC: {
10535763Smarc 		struct tchars *tc = (struct tchars *)data;
10635763Smarc 		register u_char *cc = tp->t_cc;
10735763Smarc 
10835763Smarc 		tc->t_intrc = cc[VINTR];
10935763Smarc 		tc->t_quitc = cc[VQUIT];
11035763Smarc 		tc->t_startc = cc[VSTART];
11135763Smarc 		tc->t_stopc = cc[VSTOP];
11235763Smarc 		tc->t_eofc = cc[VEOF];
11335763Smarc 		tc->t_brkc = cc[VEOL];
11435763Smarc 		break;
11535763Smarc 	}
11635763Smarc 	case TIOCSETC: {
11735763Smarc 		struct tchars *tc = (struct tchars *)data;
11835763Smarc 		register u_char *cc = tp->t_cc;
11935763Smarc 
12035763Smarc 		cc[VINTR] = tc->t_intrc;
12135763Smarc 		cc[VQUIT] = tc->t_quitc;
12235763Smarc 		cc[VSTART] = tc->t_startc;
12335763Smarc 		cc[VSTOP] = tc->t_stopc;
12435763Smarc 		cc[VEOF] = tc->t_eofc;
12535763Smarc 		cc[VEOL] = tc->t_brkc;
12635763Smarc 		if (tc->t_brkc == -1)
12735811Smarc 			cc[VEOL2] = _POSIX_VDISABLE;
12835763Smarc 		break;
12935763Smarc 	}
13035763Smarc 	case TIOCSLTC: {
13135763Smarc 		struct ltchars *ltc = (struct ltchars *)data;
13235763Smarc 		register u_char *cc = tp->t_cc;
13335763Smarc 
13435763Smarc 		cc[VSUSP] = ltc->t_suspc;
13535763Smarc 		cc[VDSUSP] = ltc->t_dsuspc;
13635763Smarc 		cc[VREPRINT] = ltc->t_rprntc;
13743091Smarc 		cc[VDISCARD] = ltc->t_flushc;
13835763Smarc 		cc[VWERASE] = ltc->t_werasc;
13935763Smarc 		cc[VLNEXT] = ltc->t_lnextc;
14035763Smarc 		break;
14135763Smarc 	}
14235763Smarc 	case TIOCGLTC: {
14335763Smarc 		struct ltchars *ltc = (struct ltchars *)data;
14435763Smarc 		register u_char *cc = tp->t_cc;
14535763Smarc 
14635763Smarc 		ltc->t_suspc = cc[VSUSP];
14735763Smarc 		ltc->t_dsuspc = cc[VDSUSP];
14835763Smarc 		ltc->t_rprntc = cc[VREPRINT];
14943091Smarc 		ltc->t_flushc = cc[VDISCARD];
15035763Smarc 		ltc->t_werasc = cc[VWERASE];
15135763Smarc 		ltc->t_lnextc = cc[VLNEXT];
15235763Smarc 		break;
15335763Smarc 	}
15435763Smarc 	case TIOCLBIS:
15535763Smarc 	case TIOCLBIC:
15635763Smarc 	case TIOCLSET: {
15735763Smarc 		struct termios term;
15835763Smarc 
15935763Smarc 		term = tp->t_termios;
16035763Smarc 		if (com == TIOCLSET)
16135811Smarc 			tp->t_flags = (tp->t_flags&0xffff) | *(int *)data<<16;
16235763Smarc 		else {
16335763Smarc 			tp->t_flags =
16435763Smarc 			 (ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff);
16535763Smarc 			if (com == TIOCLBIS)
16635811Smarc 				tp->t_flags |= *(int *)data<<16;
16735763Smarc 			else
16835811Smarc 				tp->t_flags &= ~(*(int *)data<<16);
16935763Smarc 		}
17035763Smarc 		ttcompatsetlflags(tp, &term);
17135763Smarc 		return (ttioctl(tp, TIOCSETA, &term, flag));
17235763Smarc 	}
17335763Smarc 	case TIOCLGET:
17435811Smarc 		*(int *)data = ttcompatgetflags(tp)>>16;
17535811Smarc 		if (ttydebug)
17635811Smarc 			printf("CLGET: returning %x\n", *(int *)data);
17735763Smarc 		break;
17835811Smarc 
17939567Smarc 	case OTIOCGETD:
18035811Smarc 		*(int *)data = tp->t_line ? tp->t_line : 2;
18135811Smarc 		break;
18235811Smarc 
18339567Smarc 	case OTIOCSETD: {
18435811Smarc 		int ldisczero = 0;
18535811Smarc 
18646426Smarc 		return (ttioctl(tp, TIOCSETD,
18735811Smarc 			*(int *)data == 2 ? (caddr_t)&ldisczero : data, flag));
18846426Smarc 	    }
18941994Smckusick 
19041994Smckusick 	case OTIOCCONS:
19141994Smckusick 		*(int *)data = 1;
19246426Smarc 		return (ttioctl(tp, TIOCCONS, data, flag));
19335811Smarc 
19435763Smarc 	default:
19535763Smarc 		return (-1);
19635763Smarc 	}
19746426Smarc 	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)
23835811Smarc 		flags |= CRTERA|CRTBS;
23935763Smarc 	if (lflag&ECHOKE)
24035811Smarc 		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);
24835811Smarc if (ttydebug)
24935811Smarc 	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;
26638925Skarels 		lflag &= ~(ECHOCTL|ISIG|ICANON|IEXTEN);
26735763Smarc 	} else {
26838925Skarels 		iflag |= BRKINT|IXON|IMAXBEL;
26935763Smarc 		oflag |= OPOST;
27046426Smarc 		lflag |= ISIG|IEXTEN|ECHOCTL;	/* XXX was echoctl on ? */
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;
29746426Smarc 		else
29846426Smarc 			iflag &= ~ISTRIP;
29935763Smarc 	} else {
30035763Smarc 		cflag &= ~CSIZE;
30135763Smarc 		cflag |= CS7|PARENB;
30246426Smarc 		iflag |= ISTRIP;
30335763Smarc 	}
30435763Smarc 	if ((flags&(EVENP|ODDP)) == EVENP) {
30535763Smarc 		iflag |= INPCK;
30635763Smarc 		cflag &= ~PARODD;
30735763Smarc 	} else if ((flags&(EVENP|ODDP)) == ODDP) {
30835763Smarc 		iflag |= INPCK;
30935763Smarc 		cflag |= PARODD;
31035763Smarc 	} else
31135763Smarc 		iflag &= ~INPCK;
31235763Smarc 	if (flags&LITOUT)
31335763Smarc 		oflag &= ~OPOST;	/* move earlier ? */
31435763Smarc 	if (flags&TANDEM)
31535763Smarc 		iflag |= IXOFF;
31635763Smarc 	else
31735763Smarc 		iflag &= ~IXOFF;
31835763Smarc 	t->c_iflag = iflag;
31935763Smarc 	t->c_oflag = oflag;
32035763Smarc 	t->c_lflag = lflag;
32135763Smarc 	t->c_cflag = cflag;
32235763Smarc }
32335763Smarc 
32435763Smarc ttcompatsetlflags(tp, t)
32535763Smarc 	register struct tty *tp;
32635763Smarc 	register struct termios *t;
32735763Smarc {
32835763Smarc 	register flags = tp->t_flags;
32935763Smarc 	register long iflag = t->c_iflag;
33035763Smarc 	register long oflag = t->c_oflag;
33135763Smarc 	register long lflag = t->c_lflag;
33235763Smarc 	register long cflag = t->c_cflag;
33335811Smarc 
33435763Smarc 	if (flags&CRTERA)
33535763Smarc 		lflag |= ECHOE;
33635763Smarc 	else
33735811Smarc 		lflag &= ~ECHOE;
33835763Smarc 	if (flags&CRTKIL)
33935763Smarc 		lflag |= ECHOKE;
34035763Smarc 	else
34135763Smarc 		lflag &= ~ECHOKE;
34235763Smarc 	if (flags&PRTERA)
34335763Smarc 		lflag |= ECHOPRT;
34435763Smarc 	else
34535763Smarc 		lflag &= ~ECHOPRT;
34635763Smarc 	if (flags&CTLECH)
34735763Smarc 		lflag |= ECHOCTL;
34835763Smarc 	else
34935763Smarc 		lflag &= ~ECHOCTL;
35035763Smarc 	if ((flags&DECCTQ) == 0)
35135763Smarc 		lflag |= IXANY;
35235763Smarc 	else
35335763Smarc 		lflag &= ~IXANY;
35435763Smarc 	lflag &= ~(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH);
35535763Smarc 	lflag |= flags&(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH);
35635763Smarc 	if (flags&(LITOUT|PASS8)) {
35735763Smarc 		iflag &= ~ISTRIP;
35835763Smarc 		cflag &= ~(CSIZE|PARENB);
35935763Smarc 		cflag |= CS8;
36035763Smarc 		if (flags&LITOUT)
36135763Smarc 			oflag &= ~OPOST;
36235763Smarc 		if ((flags&(PASS8|RAW)) == 0)
36335763Smarc 			iflag |= ISTRIP;
36435763Smarc 	} else if ((flags&RAW) == 0) {
36535763Smarc 		cflag &= ~CSIZE;
36635763Smarc 		cflag |= CS7|PARENB;
36735763Smarc 		oflag |= OPOST;
36835763Smarc 	}
36935763Smarc 	t->c_iflag = iflag;
37035763Smarc 	t->c_oflag = oflag;
37135763Smarc 	t->c_lflag = lflag;
37235763Smarc 	t->c_cflag = cflag;
37335763Smarc }
37452500Storek #endif	/* COMPAT_43 || COMPAT_SUNOS */
375