xref: /csrg-svn/sys/kern/tty_compat.c (revision 39567)
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*39567Smarc  *	@(#)tty_compat.c	7.3 (Berkeley) 11/20/89
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"
1638952Skarels #include "dir.h"
1735763Smarc #include "user.h"
1835763Smarc #include "ioctl.h"
1935763Smarc #include "tty.h"
2035763Smarc #include "termios.h"
2135763Smarc #include "proc.h"
2235763Smarc #include "file.h"
2335763Smarc #include "conf.h"
2435763Smarc #include "dkstat.h"
2535763Smarc #include "uio.h"
2635763Smarc #include "kernel.h"
2735763Smarc #include "syslog.h"
2835763Smarc 
2937526Smckusick #include "machine/reg.h"
3037526Smckusick 
3135811Smarc int ttydebug = 0;
3235763Smarc 
3335811Smarc /* 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];
7935811Smarc 		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 		tp->t_flags = (tp->t_flags&0xffff0000) | sg->sg_flags;
10135763Smarc 		ttcompatsetflags(tp, &term);
10235763Smarc 		return (ttioctl(tp, com == TIOCSETP ? TIOCSETAF : TIOCSETA,
10335763Smarc 			&term, flag));
10435763Smarc 	}
10535763Smarc 
10635763Smarc 	case TIOCGETC: {
10735763Smarc 		struct tchars *tc = (struct tchars *)data;
10835763Smarc 		register u_char *cc = tp->t_cc;
10935763Smarc 
11035763Smarc 		tc->t_intrc = cc[VINTR];
11135763Smarc 		tc->t_quitc = cc[VQUIT];
11235763Smarc 		tc->t_startc = cc[VSTART];
11335763Smarc 		tc->t_stopc = cc[VSTOP];
11435763Smarc 		tc->t_eofc = cc[VEOF];
11535763Smarc 		tc->t_brkc = cc[VEOL];
11635763Smarc 		break;
11735763Smarc 	}
11835763Smarc 	case TIOCSETC: {
11935763Smarc 		struct tchars *tc = (struct tchars *)data;
12035763Smarc 		register u_char *cc = tp->t_cc;
12135763Smarc 
12235763Smarc 		cc[VINTR] = tc->t_intrc;
12335763Smarc 		cc[VQUIT] = tc->t_quitc;
12435763Smarc 		cc[VSTART] = tc->t_startc;
12535763Smarc 		cc[VSTOP] = tc->t_stopc;
12635763Smarc 		cc[VEOF] = tc->t_eofc;
12735763Smarc 		cc[VEOL] = tc->t_brkc;
12835763Smarc 		if (tc->t_brkc == -1)
12935811Smarc 			cc[VEOL2] = _POSIX_VDISABLE;
13035763Smarc 		break;
13135763Smarc 	}
13235763Smarc 	case TIOCSLTC: {
13335763Smarc 		struct ltchars *ltc = (struct ltchars *)data;
13435763Smarc 		register u_char *cc = tp->t_cc;
13535763Smarc 
13635763Smarc 		cc[VSUSP] = ltc->t_suspc;
13735763Smarc 		cc[VDSUSP] = ltc->t_dsuspc;
13835763Smarc 		cc[VREPRINT] = ltc->t_rprntc;
13935763Smarc 		cc[VFLUSHO] = ltc->t_flushc;
14035763Smarc 		cc[VWERASE] = ltc->t_werasc;
14135763Smarc 		cc[VLNEXT] = ltc->t_lnextc;
14235763Smarc 		break;
14335763Smarc 	}
14435763Smarc 	case TIOCGLTC: {
14535763Smarc 		struct ltchars *ltc = (struct ltchars *)data;
14635763Smarc 		register u_char *cc = tp->t_cc;
14735763Smarc 
14835763Smarc 		ltc->t_suspc = cc[VSUSP];
14935763Smarc 		ltc->t_dsuspc = cc[VDSUSP];
15035763Smarc 		ltc->t_rprntc = cc[VREPRINT];
15135763Smarc 		ltc->t_flushc = cc[VFLUSHO];
15235763Smarc 		ltc->t_werasc = cc[VWERASE];
15335763Smarc 		ltc->t_lnextc = cc[VLNEXT];
15435763Smarc 		break;
15535763Smarc 	}
15635763Smarc 	case TIOCLBIS:
15735763Smarc 	case TIOCLBIC:
15835763Smarc 	case TIOCLSET: {
15935763Smarc 		struct termios term;
16035763Smarc 
16135763Smarc 		term = tp->t_termios;
16235763Smarc 		if (com == TIOCLSET)
16335811Smarc 			tp->t_flags = (tp->t_flags&0xffff) | *(int *)data<<16;
16435763Smarc 		else {
16535763Smarc 			tp->t_flags =
16635763Smarc 			 (ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff);
16735763Smarc 			if (com == TIOCLBIS)
16835811Smarc 				tp->t_flags |= *(int *)data<<16;
16935763Smarc 			else
17035811Smarc 				tp->t_flags &= ~(*(int *)data<<16);
17135763Smarc 		}
17235763Smarc 		ttcompatsetlflags(tp, &term);
17335763Smarc 		return (ttioctl(tp, TIOCSETA, &term, flag));
17435763Smarc 	}
17535763Smarc 	case TIOCLGET:
17635811Smarc 		*(int *)data = ttcompatgetflags(tp)>>16;
17735811Smarc 		if (ttydebug)
17835811Smarc 			printf("CLGET: returning %x\n", *(int *)data);
17935763Smarc 		break;
18035811Smarc 
181*39567Smarc 	case OTIOCGETD:
18235811Smarc 		*(int *)data = tp->t_line ? tp->t_line : 2;
18335811Smarc 		break;
18435811Smarc 
185*39567Smarc 	case OTIOCSETD: {
18635811Smarc 		int ldisczero = 0;
18735811Smarc 
18835811Smarc 		return(ttioctl(tp, TIOCSETD,
18935811Smarc 			*(int *)data == 2 ? (caddr_t)&ldisczero : data, flag));
19035811Smarc 	}
19135811Smarc 
19235763Smarc 	default:
19335763Smarc 		return (-1);
19435763Smarc 	}
19535763Smarc 	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;
26838925Skarels 		lflag |= ISIG|IEXTEN;
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;
29535763Smarc 	} else {
29635763Smarc 		cflag &= ~CSIZE;
29735763Smarc 		cflag |= CS7|PARENB;
29835763Smarc 	}
29935763Smarc 	if ((flags&(EVENP|ODDP)) == EVENP) {
30035763Smarc 		iflag |= INPCK;
30135763Smarc 		cflag &= ~PARODD;
30235763Smarc 	} else if ((flags&(EVENP|ODDP)) == ODDP) {
30335763Smarc 		iflag |= INPCK;
30435763Smarc 		cflag |= PARODD;
30535763Smarc 	} else
30635763Smarc 		iflag &= ~INPCK;
30735763Smarc 	if (flags&LITOUT)
30835763Smarc 		oflag &= ~OPOST;	/* move earlier ? */
30935763Smarc 	if (flags&TANDEM)
31035763Smarc 		iflag |= IXOFF;
31135763Smarc 	else
31235763Smarc 		iflag &= ~IXOFF;
31335763Smarc 	t->c_iflag = iflag;
31435763Smarc 	t->c_oflag = oflag;
31535763Smarc 	t->c_lflag = lflag;
31635763Smarc 	t->c_cflag = cflag;
31735763Smarc }
31835763Smarc 
31935763Smarc ttcompatsetlflags(tp, t)
32035763Smarc 	register struct tty *tp;
32135763Smarc 	register struct termios *t;
32235763Smarc {
32335763Smarc 	register flags = tp->t_flags;
32435763Smarc 	register long iflag = t->c_iflag;
32535763Smarc 	register long oflag = t->c_oflag;
32635763Smarc 	register long lflag = t->c_lflag;
32735763Smarc 	register long cflag = t->c_cflag;
32835811Smarc 
32935763Smarc 	if (flags&CRTERA)
33035763Smarc 		lflag |= ECHOE;
33135763Smarc 	else
33235811Smarc 		lflag &= ~ECHOE;
33335763Smarc 	if (flags&CRTKIL)
33435763Smarc 		lflag |= ECHOKE;
33535763Smarc 	else
33635763Smarc 		lflag &= ~ECHOKE;
33735763Smarc 	if (flags&PRTERA)
33835763Smarc 		lflag |= ECHOPRT;
33935763Smarc 	else
34035763Smarc 		lflag &= ~ECHOPRT;
34135763Smarc 	if (flags&CTLECH)
34235763Smarc 		lflag |= ECHOCTL;
34335763Smarc 	else
34435763Smarc 		lflag &= ~ECHOCTL;
34535763Smarc 	if ((flags&DECCTQ) == 0)
34635763Smarc 		lflag |= IXANY;
34735763Smarc 	else
34835763Smarc 		lflag &= ~IXANY;
34935763Smarc 	lflag &= ~(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH);
35035763Smarc 	lflag |= flags&(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH);
35135763Smarc 	if (flags&(LITOUT|PASS8)) {
35235763Smarc 		iflag &= ~ISTRIP;
35335763Smarc 		cflag &= ~(CSIZE|PARENB);
35435763Smarc 		cflag |= CS8;
35535763Smarc 		if (flags&LITOUT)
35635763Smarc 			oflag &= ~OPOST;
35735763Smarc 		if ((flags&(PASS8|RAW)) == 0)
35835763Smarc 			iflag |= ISTRIP;
35935763Smarc 	} else if ((flags&RAW) == 0) {
36035763Smarc 		cflag &= ~CSIZE;
36135763Smarc 		cflag |= CS7|PARENB;
36235763Smarc 		oflag |= OPOST;
36335763Smarc 	}
36435763Smarc 	t->c_iflag = iflag;
36535763Smarc 	t->c_oflag = oflag;
36635763Smarc 	t->c_lflag = lflag;
36735763Smarc 	t->c_cflag = cflag;
36835763Smarc }
36935763Smarc #endif	/* COMPAT_43 */
370