xref: /csrg-svn/sys/kern/tty_compat.c (revision 49594)
1*49594Sbostic /*-
2*49594Sbostic  * Copyright (c) 1982, 1986, 1991 The Regents of the University of California.
3*49594Sbostic  * All rights reserved.
435763Smarc  *
5*49594Sbostic  * %sccs.include.redist.c%
6*49594Sbostic  *
7*49594Sbostic  *	@(#)tty_compat.c	7.10 (Berkeley) 05/09/91
835763Smarc  */
935763Smarc 
1035763Smarc /*
1135811Smarc  * mapping routines for old line discipline (yuck)
1235763Smarc  */
1335763Smarc #ifdef COMPAT_43
1435763Smarc 
1535763Smarc #include "param.h"
1635763Smarc #include "systm.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 "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;
5635763Smarc 	caddr_t data;
5735763Smarc {
5846426Smarc 
5946426Smarc 	switch (com) {
6035763Smarc 	case TIOCGETP: {
6135763Smarc 		register struct sgttyb *sg = (struct sgttyb *)data;
6235763Smarc 		register u_char *cc = tp->t_cc;
6335763Smarc 		register speed;
6435763Smarc 
6535763Smarc 		speed = ttspeedtab(tp->t_ospeed, compatspeeds);
6635763Smarc 		sg->sg_ospeed = (speed == -1) ? 15 : speed;
6735763Smarc 		if (tp->t_ispeed == 0)
6835763Smarc 			sg->sg_ispeed = sg->sg_ospeed;
6935763Smarc 		else {
7035763Smarc 			speed = ttspeedtab(tp->t_ispeed, compatspeeds);
7135763Smarc 			sg->sg_ispeed = (speed == -1) ? 15 : speed;
7235763Smarc 		}
7335763Smarc 		sg->sg_erase = cc[VERASE];
7435763Smarc 		sg->sg_kill = cc[VKILL];
7535811Smarc 		sg->sg_flags = ttcompatgetflags(tp);
7635763Smarc 		break;
7735763Smarc 	}
7835763Smarc 
7935763Smarc 	case TIOCSETP:
8035763Smarc 	case TIOCSETN: {
8135763Smarc 		register struct sgttyb *sg = (struct sgttyb *)data;
8235763Smarc 		struct termios term;
8335763Smarc 		int speed;
8435763Smarc 
8535763Smarc 		term = tp->t_termios;
8635763Smarc 		if ((speed = sg->sg_ispeed) > 15 || speed < 0)
8735763Smarc 			term.c_ispeed = speed;
8835763Smarc 		else
8935763Smarc 			term.c_ispeed = compatspcodes[speed];
9035763Smarc 		if ((speed = sg->sg_ospeed) > 15 || speed < 0)
9135763Smarc 			term.c_ospeed = speed;
9235763Smarc 		else
9335763Smarc 			term.c_ospeed = compatspcodes[speed];
9435763Smarc 		term.c_cc[VERASE] = sg->sg_erase;
9535763Smarc 		term.c_cc[VKILL] = sg->sg_kill;
9646426Smarc 		tp->t_flags = tp->t_flags&0xffff0000 | sg->sg_flags&0xffff;
9735763Smarc 		ttcompatsetflags(tp, &term);
9835763Smarc 		return (ttioctl(tp, com == TIOCSETP ? TIOCSETAF : TIOCSETA,
9935763Smarc 			&term, flag));
10035763Smarc 	}
10135763Smarc 
10235763Smarc 	case TIOCGETC: {
10335763Smarc 		struct tchars *tc = (struct tchars *)data;
10435763Smarc 		register u_char *cc = tp->t_cc;
10535763Smarc 
10635763Smarc 		tc->t_intrc = cc[VINTR];
10735763Smarc 		tc->t_quitc = cc[VQUIT];
10835763Smarc 		tc->t_startc = cc[VSTART];
10935763Smarc 		tc->t_stopc = cc[VSTOP];
11035763Smarc 		tc->t_eofc = cc[VEOF];
11135763Smarc 		tc->t_brkc = cc[VEOL];
11235763Smarc 		break;
11335763Smarc 	}
11435763Smarc 	case TIOCSETC: {
11535763Smarc 		struct tchars *tc = (struct tchars *)data;
11635763Smarc 		register u_char *cc = tp->t_cc;
11735763Smarc 
11835763Smarc 		cc[VINTR] = tc->t_intrc;
11935763Smarc 		cc[VQUIT] = tc->t_quitc;
12035763Smarc 		cc[VSTART] = tc->t_startc;
12135763Smarc 		cc[VSTOP] = tc->t_stopc;
12235763Smarc 		cc[VEOF] = tc->t_eofc;
12335763Smarc 		cc[VEOL] = tc->t_brkc;
12435763Smarc 		if (tc->t_brkc == -1)
12535811Smarc 			cc[VEOL2] = _POSIX_VDISABLE;
12635763Smarc 		break;
12735763Smarc 	}
12835763Smarc 	case TIOCSLTC: {
12935763Smarc 		struct ltchars *ltc = (struct ltchars *)data;
13035763Smarc 		register u_char *cc = tp->t_cc;
13135763Smarc 
13235763Smarc 		cc[VSUSP] = ltc->t_suspc;
13335763Smarc 		cc[VDSUSP] = ltc->t_dsuspc;
13435763Smarc 		cc[VREPRINT] = ltc->t_rprntc;
13543091Smarc 		cc[VDISCARD] = ltc->t_flushc;
13635763Smarc 		cc[VWERASE] = ltc->t_werasc;
13735763Smarc 		cc[VLNEXT] = ltc->t_lnextc;
13835763Smarc 		break;
13935763Smarc 	}
14035763Smarc 	case TIOCGLTC: {
14135763Smarc 		struct ltchars *ltc = (struct ltchars *)data;
14235763Smarc 		register u_char *cc = tp->t_cc;
14335763Smarc 
14435763Smarc 		ltc->t_suspc = cc[VSUSP];
14535763Smarc 		ltc->t_dsuspc = cc[VDSUSP];
14635763Smarc 		ltc->t_rprntc = cc[VREPRINT];
14743091Smarc 		ltc->t_flushc = cc[VDISCARD];
14835763Smarc 		ltc->t_werasc = cc[VWERASE];
14935763Smarc 		ltc->t_lnextc = cc[VLNEXT];
15035763Smarc 		break;
15135763Smarc 	}
15235763Smarc 	case TIOCLBIS:
15335763Smarc 	case TIOCLBIC:
15435763Smarc 	case TIOCLSET: {
15535763Smarc 		struct termios term;
15635763Smarc 
15735763Smarc 		term = tp->t_termios;
15835763Smarc 		if (com == TIOCLSET)
15935811Smarc 			tp->t_flags = (tp->t_flags&0xffff) | *(int *)data<<16;
16035763Smarc 		else {
16135763Smarc 			tp->t_flags =
16235763Smarc 			 (ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff);
16335763Smarc 			if (com == TIOCLBIS)
16435811Smarc 				tp->t_flags |= *(int *)data<<16;
16535763Smarc 			else
16635811Smarc 				tp->t_flags &= ~(*(int *)data<<16);
16735763Smarc 		}
16835763Smarc 		ttcompatsetlflags(tp, &term);
16935763Smarc 		return (ttioctl(tp, TIOCSETA, &term, flag));
17035763Smarc 	}
17135763Smarc 	case TIOCLGET:
17235811Smarc 		*(int *)data = ttcompatgetflags(tp)>>16;
17335811Smarc 		if (ttydebug)
17435811Smarc 			printf("CLGET: returning %x\n", *(int *)data);
17535763Smarc 		break;
17635811Smarc 
17739567Smarc 	case OTIOCGETD:
17835811Smarc 		*(int *)data = tp->t_line ? tp->t_line : 2;
17935811Smarc 		break;
18035811Smarc 
18139567Smarc 	case OTIOCSETD: {
18235811Smarc 		int ldisczero = 0;
18335811Smarc 
18446426Smarc 		return (ttioctl(tp, TIOCSETD,
18535811Smarc 			*(int *)data == 2 ? (caddr_t)&ldisczero : data, flag));
18646426Smarc 	    }
18741994Smckusick 
18841994Smckusick 	case OTIOCCONS:
18941994Smckusick 		*(int *)data = 1;
19046426Smarc 		return (ttioctl(tp, TIOCCONS, data, flag));
19135811Smarc 
19235763Smarc 	default:
19335763Smarc 		return (-1);
19435763Smarc 	}
19546426Smarc 	return (0);
19635763Smarc }
19735763Smarc 
19835763Smarc ttcompatgetflags(tp)
19935763Smarc 	register struct tty *tp;
20035763Smarc {
20135763Smarc 	register long iflag = tp->t_iflag;
20235763Smarc 	register long lflag = tp->t_lflag;
20335763Smarc 	register long oflag = tp->t_oflag;
20435763Smarc 	register long cflag = tp->t_cflag;
20535763Smarc 	register flags = 0;
20635763Smarc 
20735763Smarc 	if (iflag&IXOFF)
20835763Smarc 		flags |= TANDEM;
20935763Smarc 	if (iflag&ICRNL || oflag&ONLCR)
21035763Smarc 		flags |= CRMOD;
21135763Smarc 	if (cflag&PARENB) {
21235763Smarc 		if (iflag&INPCK) {
21335763Smarc 			if (cflag&PARODD)
21435763Smarc 				flags |= ODDP;
21535763Smarc 			else
21635763Smarc 				flags |= EVENP;
21735763Smarc 		} else
21835763Smarc 			flags |= EVENP | ODDP;
21935763Smarc 	} else {
22035763Smarc 		if ((tp->t_flags&LITOUT) && !(oflag&OPOST))
22135763Smarc 			flags |= LITOUT;
22235763Smarc 		if (tp->t_flags&PASS8)
22335763Smarc 			flags |= PASS8;
22435763Smarc 	}
22535763Smarc 
22635763Smarc 	if ((lflag&ICANON) == 0) {
22735763Smarc 		/* fudge */
22835763Smarc 		if (iflag&IXON || lflag&ISIG || lflag&IEXTEN || cflag&PARENB)
22935763Smarc 			flags |= CBREAK;
23035763Smarc 		else
23135763Smarc 			flags |= RAW;
23235763Smarc 	}
23335763Smarc 	if (oflag&OXTABS)
23435763Smarc 		flags |= XTABS;
23535763Smarc 	if (lflag&ECHOE)
23635811Smarc 		flags |= CRTERA|CRTBS;
23735763Smarc 	if (lflag&ECHOKE)
23835811Smarc 		flags |= CRTKIL|CRTBS;
23935763Smarc 	if (lflag&ECHOPRT)
24035763Smarc 		flags |= PRTERA;
24135763Smarc 	if (lflag&ECHOCTL)
24235763Smarc 		flags |= CTLECH;
24335763Smarc 	if ((iflag&IXANY) == 0)
24435763Smarc 		flags |= DECCTQ;
24535763Smarc 	flags |= lflag&(ECHO|MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH);
24635811Smarc if (ttydebug)
24735811Smarc 	printf("getflags: %x\n", flags);
24835763Smarc 	return (flags);
24935763Smarc }
25035763Smarc 
25135763Smarc ttcompatsetflags(tp, t)
25235763Smarc 	register struct tty *tp;
25335763Smarc 	register struct termios *t;
25435763Smarc {
25535763Smarc 	register flags = tp->t_flags;
25635763Smarc 	register long iflag = t->c_iflag;
25735763Smarc 	register long oflag = t->c_oflag;
25835763Smarc 	register long lflag = t->c_lflag;
25935763Smarc 	register long cflag = t->c_cflag;
26035763Smarc 
26135763Smarc 	if (flags & RAW) {
26235763Smarc 		iflag &= IXOFF;
26335763Smarc 		oflag &= ~OPOST;
26438925Skarels 		lflag &= ~(ECHOCTL|ISIG|ICANON|IEXTEN);
26535763Smarc 	} else {
26638925Skarels 		iflag |= BRKINT|IXON|IMAXBEL;
26735763Smarc 		oflag |= OPOST;
26846426Smarc 		lflag |= ISIG|IEXTEN|ECHOCTL;	/* XXX was echoctl on ? */
26935763Smarc 		if (flags & XTABS)
27035763Smarc 			oflag |= OXTABS;
27135763Smarc 		else
27235763Smarc 			oflag &= ~OXTABS;
27335763Smarc 		if (flags & CBREAK)
27435763Smarc 			lflag &= ~ICANON;
27535763Smarc 		else
27635763Smarc 			lflag |= ICANON;
27735763Smarc 		if (flags&CRMOD) {
27835763Smarc 			iflag |= ICRNL;
27935763Smarc 			oflag |= ONLCR;
28035763Smarc 		} else {
28135763Smarc 			iflag &= ~ICRNL;
28235763Smarc 			oflag &= ~ONLCR;
28335763Smarc 		}
28435763Smarc 	}
28535763Smarc 	if (flags&ECHO)
28635763Smarc 		lflag |= ECHO;
28735763Smarc 	else
28835763Smarc 		lflag &= ~ECHO;
28935763Smarc 
29035763Smarc 	if (flags&(RAW|LITOUT|PASS8)) {
29135763Smarc 		cflag &= ~(CSIZE|PARENB);
29235763Smarc 		cflag |= CS8;
29335763Smarc 		if ((flags&(RAW|PASS8)) == 0)
29435763Smarc 			iflag |= ISTRIP;
29546426Smarc 		else
29646426Smarc 			iflag &= ~ISTRIP;
29735763Smarc 	} else {
29835763Smarc 		cflag &= ~CSIZE;
29935763Smarc 		cflag |= CS7|PARENB;
30046426Smarc 		iflag |= ISTRIP;
30135763Smarc 	}
30235763Smarc 	if ((flags&(EVENP|ODDP)) == EVENP) {
30335763Smarc 		iflag |= INPCK;
30435763Smarc 		cflag &= ~PARODD;
30535763Smarc 	} else if ((flags&(EVENP|ODDP)) == ODDP) {
30635763Smarc 		iflag |= INPCK;
30735763Smarc 		cflag |= PARODD;
30835763Smarc 	} else
30935763Smarc 		iflag &= ~INPCK;
31035763Smarc 	if (flags&LITOUT)
31135763Smarc 		oflag &= ~OPOST;	/* move earlier ? */
31235763Smarc 	if (flags&TANDEM)
31335763Smarc 		iflag |= IXOFF;
31435763Smarc 	else
31535763Smarc 		iflag &= ~IXOFF;
31635763Smarc 	t->c_iflag = iflag;
31735763Smarc 	t->c_oflag = oflag;
31835763Smarc 	t->c_lflag = lflag;
31935763Smarc 	t->c_cflag = cflag;
32035763Smarc }
32135763Smarc 
32235763Smarc ttcompatsetlflags(tp, t)
32335763Smarc 	register struct tty *tp;
32435763Smarc 	register struct termios *t;
32535763Smarc {
32635763Smarc 	register flags = tp->t_flags;
32735763Smarc 	register long iflag = t->c_iflag;
32835763Smarc 	register long oflag = t->c_oflag;
32935763Smarc 	register long lflag = t->c_lflag;
33035763Smarc 	register long cflag = t->c_cflag;
33135811Smarc 
33235763Smarc 	if (flags&CRTERA)
33335763Smarc 		lflag |= ECHOE;
33435763Smarc 	else
33535811Smarc 		lflag &= ~ECHOE;
33635763Smarc 	if (flags&CRTKIL)
33735763Smarc 		lflag |= ECHOKE;
33835763Smarc 	else
33935763Smarc 		lflag &= ~ECHOKE;
34035763Smarc 	if (flags&PRTERA)
34135763Smarc 		lflag |= ECHOPRT;
34235763Smarc 	else
34335763Smarc 		lflag &= ~ECHOPRT;
34435763Smarc 	if (flags&CTLECH)
34535763Smarc 		lflag |= ECHOCTL;
34635763Smarc 	else
34735763Smarc 		lflag &= ~ECHOCTL;
34835763Smarc 	if ((flags&DECCTQ) == 0)
34935763Smarc 		lflag |= IXANY;
35035763Smarc 	else
35135763Smarc 		lflag &= ~IXANY;
35235763Smarc 	lflag &= ~(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH);
35335763Smarc 	lflag |= flags&(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH);
35435763Smarc 	if (flags&(LITOUT|PASS8)) {
35535763Smarc 		iflag &= ~ISTRIP;
35635763Smarc 		cflag &= ~(CSIZE|PARENB);
35735763Smarc 		cflag |= CS8;
35835763Smarc 		if (flags&LITOUT)
35935763Smarc 			oflag &= ~OPOST;
36035763Smarc 		if ((flags&(PASS8|RAW)) == 0)
36135763Smarc 			iflag |= ISTRIP;
36235763Smarc 	} else if ((flags&RAW) == 0) {
36335763Smarc 		cflag &= ~CSIZE;
36435763Smarc 		cflag |= CS7|PARENB;
36535763Smarc 		oflag |= OPOST;
36635763Smarc 	}
36735763Smarc 	t->c_iflag = iflag;
36835763Smarc 	t->c_oflag = oflag;
36935763Smarc 	t->c_lflag = lflag;
37035763Smarc 	t->c_cflag = cflag;
37135763Smarc }
37235763Smarc #endif	/* COMPAT_43 */
373