xref: /csrg-svn/sys/kern/tty_compat.c (revision 41994)
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*41994Smckusick  *	@(#)tty_compat.c	7.5 (Berkeley) 05/15/90
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 
3235811Smarc /* XXX - fold these two tables into one */
3335763Smarc static struct speedtab compatspeeds[] = {
3435763Smarc 	38400,	15,
3535763Smarc 	19200,	14,
3635763Smarc 	9600,	13,
3735763Smarc 	4800,	12,
3835763Smarc 	2400,	11,
3935763Smarc 	1800,	10,
4035763Smarc 	1200,	9,
4135763Smarc 	600,	8,
4235763Smarc 	300,	7,
4335763Smarc 	200,	6,
4435763Smarc 	150,	5,
4535763Smarc 	134,	4,
4635763Smarc 	110,	3,
4735763Smarc 	75,	2,
4835763Smarc 	50,	1,
4935763Smarc 	0,	0,
5035763Smarc 	-1,	-1,
5135763Smarc };
5235763Smarc static int compatspcodes[16] = {
5335763Smarc 	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
5435763Smarc 	1800, 2400, 4800, 9600, 19200, 38400,
5535763Smarc };
5635763Smarc 
5735763Smarc /*ARGSUSED*/
5835763Smarc ttcompat(tp, com, data, flag)
5935763Smarc 	register struct tty *tp;
6035763Smarc 	caddr_t data;
6135763Smarc {
6235763Smarc 	switch(com) {
6335763Smarc 	case TIOCGETP: {
6435763Smarc 		register struct sgttyb *sg = (struct sgttyb *)data;
6535763Smarc 		register u_char *cc = tp->t_cc;
6635763Smarc 		register speed;
6735763Smarc 
6835763Smarc 		speed = ttspeedtab(tp->t_ospeed, compatspeeds);
6935763Smarc 		sg->sg_ospeed = (speed == -1) ? 15 : speed;
7035763Smarc 		if (tp->t_ispeed == 0)
7135763Smarc 			sg->sg_ispeed = sg->sg_ospeed;
7235763Smarc 		else {
7335763Smarc 			speed = ttspeedtab(tp->t_ispeed, compatspeeds);
7435763Smarc 			sg->sg_ispeed = (speed == -1) ? 15 : speed;
7535763Smarc 		}
7635763Smarc 		sg->sg_erase = cc[VERASE];
7735763Smarc 		sg->sg_kill = cc[VKILL];
7835811Smarc 		sg->sg_flags = ttcompatgetflags(tp);
7935763Smarc 		break;
8035763Smarc 	}
8135763Smarc 
8235763Smarc 	case TIOCSETP:
8335763Smarc 	case TIOCSETN: {
8435763Smarc 		register struct sgttyb *sg = (struct sgttyb *)data;
8535763Smarc 		struct termios term;
8635763Smarc 		int speed;
8735763Smarc 
8835763Smarc 		term = tp->t_termios;
8935763Smarc 		if ((speed = sg->sg_ispeed) > 15 || speed < 0)
9035763Smarc 			term.c_ispeed = speed;
9135763Smarc 		else
9235763Smarc 			term.c_ispeed = compatspcodes[speed];
9335763Smarc 		if ((speed = sg->sg_ospeed) > 15 || speed < 0)
9435763Smarc 			term.c_ospeed = speed;
9535763Smarc 		else
9635763Smarc 			term.c_ospeed = compatspcodes[speed];
9735763Smarc 		term.c_cc[VERASE] = sg->sg_erase;
9835763Smarc 		term.c_cc[VKILL] = sg->sg_kill;
9935763Smarc 		tp->t_flags = (tp->t_flags&0xffff0000) | sg->sg_flags;
10035763Smarc 		ttcompatsetflags(tp, &term);
10135763Smarc 		return (ttioctl(tp, com == TIOCSETP ? TIOCSETAF : TIOCSETA,
10235763Smarc 			&term, flag));
10335763Smarc 	}
10435763Smarc 
10535763Smarc 	case TIOCGETC: {
10635763Smarc 		struct tchars *tc = (struct tchars *)data;
10735763Smarc 		register u_char *cc = tp->t_cc;
10835763Smarc 
10935763Smarc 		tc->t_intrc = cc[VINTR];
11035763Smarc 		tc->t_quitc = cc[VQUIT];
11135763Smarc 		tc->t_startc = cc[VSTART];
11235763Smarc 		tc->t_stopc = cc[VSTOP];
11335763Smarc 		tc->t_eofc = cc[VEOF];
11435763Smarc 		tc->t_brkc = cc[VEOL];
11535763Smarc 		break;
11635763Smarc 	}
11735763Smarc 	case TIOCSETC: {
11835763Smarc 		struct tchars *tc = (struct tchars *)data;
11935763Smarc 		register u_char *cc = tp->t_cc;
12035763Smarc 
12135763Smarc 		cc[VINTR] = tc->t_intrc;
12235763Smarc 		cc[VQUIT] = tc->t_quitc;
12335763Smarc 		cc[VSTART] = tc->t_startc;
12435763Smarc 		cc[VSTOP] = tc->t_stopc;
12535763Smarc 		cc[VEOF] = tc->t_eofc;
12635763Smarc 		cc[VEOL] = tc->t_brkc;
12735763Smarc 		if (tc->t_brkc == -1)
12835811Smarc 			cc[VEOL2] = _POSIX_VDISABLE;
12935763Smarc 		break;
13035763Smarc 	}
13135763Smarc 	case TIOCSLTC: {
13235763Smarc 		struct ltchars *ltc = (struct ltchars *)data;
13335763Smarc 		register u_char *cc = tp->t_cc;
13435763Smarc 
13535763Smarc 		cc[VSUSP] = ltc->t_suspc;
13635763Smarc 		cc[VDSUSP] = ltc->t_dsuspc;
13735763Smarc 		cc[VREPRINT] = ltc->t_rprntc;
13835763Smarc 		cc[VFLUSHO] = ltc->t_flushc;
13935763Smarc 		cc[VWERASE] = ltc->t_werasc;
14035763Smarc 		cc[VLNEXT] = ltc->t_lnextc;
14135763Smarc 		break;
14235763Smarc 	}
14335763Smarc 	case TIOCGLTC: {
14435763Smarc 		struct ltchars *ltc = (struct ltchars *)data;
14535763Smarc 		register u_char *cc = tp->t_cc;
14635763Smarc 
14735763Smarc 		ltc->t_suspc = cc[VSUSP];
14835763Smarc 		ltc->t_dsuspc = cc[VDSUSP];
14935763Smarc 		ltc->t_rprntc = cc[VREPRINT];
15035763Smarc 		ltc->t_flushc = cc[VFLUSHO];
15135763Smarc 		ltc->t_werasc = cc[VWERASE];
15235763Smarc 		ltc->t_lnextc = cc[VLNEXT];
15335763Smarc 		break;
15435763Smarc 	}
15535763Smarc 	case TIOCLBIS:
15635763Smarc 	case TIOCLBIC:
15735763Smarc 	case TIOCLSET: {
15835763Smarc 		struct termios term;
15935763Smarc 
16035763Smarc 		term = tp->t_termios;
16135763Smarc 		if (com == TIOCLSET)
16235811Smarc 			tp->t_flags = (tp->t_flags&0xffff) | *(int *)data<<16;
16335763Smarc 		else {
16435763Smarc 			tp->t_flags =
16535763Smarc 			 (ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff);
16635763Smarc 			if (com == TIOCLBIS)
16735811Smarc 				tp->t_flags |= *(int *)data<<16;
16835763Smarc 			else
16935811Smarc 				tp->t_flags &= ~(*(int *)data<<16);
17035763Smarc 		}
17135763Smarc 		ttcompatsetlflags(tp, &term);
17235763Smarc 		return (ttioctl(tp, TIOCSETA, &term, flag));
17335763Smarc 	}
17435763Smarc 	case TIOCLGET:
17535811Smarc 		*(int *)data = ttcompatgetflags(tp)>>16;
17635811Smarc 		if (ttydebug)
17735811Smarc 			printf("CLGET: returning %x\n", *(int *)data);
17835763Smarc 		break;
17935811Smarc 
18039567Smarc 	case OTIOCGETD:
18135811Smarc 		*(int *)data = tp->t_line ? tp->t_line : 2;
18235811Smarc 		break;
18335811Smarc 
18439567Smarc 	case OTIOCSETD: {
18535811Smarc 		int ldisczero = 0;
18635811Smarc 
18735811Smarc 		return(ttioctl(tp, TIOCSETD,
18835811Smarc 			*(int *)data == 2 ? (caddr_t)&ldisczero : data, flag));
189*41994Smckusick 
190*41994Smckusick 	case OTIOCCONS:
191*41994Smckusick 		*(int *)data = 1;
192*41994Smckusick 		return(ttioctl(tp, TIOCCONS, data, flag));
19335811Smarc 	}
19435811Smarc 
19535763Smarc 	default:
19635763Smarc 		return (-1);
19735763Smarc 	}
19835763Smarc 	return(0);
19935763Smarc }
20035763Smarc 
20135763Smarc ttcompatgetflags(tp)
20235763Smarc 	register struct tty *tp;
20335763Smarc {
20435763Smarc 	register long iflag = tp->t_iflag;
20535763Smarc 	register long lflag = tp->t_lflag;
20635763Smarc 	register long oflag = tp->t_oflag;
20735763Smarc 	register long cflag = tp->t_cflag;
20835763Smarc 	register flags = 0;
20935763Smarc 
21035763Smarc 	if (iflag&IXOFF)
21135763Smarc 		flags |= TANDEM;
21235763Smarc 	if (iflag&ICRNL || oflag&ONLCR)
21335763Smarc 		flags |= CRMOD;
21435763Smarc 	if (cflag&PARENB) {
21535763Smarc 		if (iflag&INPCK) {
21635763Smarc 			if (cflag&PARODD)
21735763Smarc 				flags |= ODDP;
21835763Smarc 			else
21935763Smarc 				flags |= EVENP;
22035763Smarc 		} else
22135763Smarc 			flags |= EVENP | ODDP;
22235763Smarc 	} else {
22335763Smarc 		if ((tp->t_flags&LITOUT) && !(oflag&OPOST))
22435763Smarc 			flags |= LITOUT;
22535763Smarc 		if (tp->t_flags&PASS8)
22635763Smarc 			flags |= PASS8;
22735763Smarc 	}
22835763Smarc 
22935763Smarc 	if ((lflag&ICANON) == 0) {
23035763Smarc 		/* fudge */
23135763Smarc 		if (iflag&IXON || lflag&ISIG || lflag&IEXTEN || cflag&PARENB)
23235763Smarc 			flags |= CBREAK;
23335763Smarc 		else
23435763Smarc 			flags |= RAW;
23535763Smarc 	}
23635763Smarc 	if (oflag&OXTABS)
23735763Smarc 		flags |= XTABS;
23835763Smarc 	if (lflag&ECHOE)
23935811Smarc 		flags |= CRTERA|CRTBS;
24035763Smarc 	if (lflag&ECHOKE)
24135811Smarc 		flags |= CRTKIL|CRTBS;
24235763Smarc 	if (lflag&ECHOPRT)
24335763Smarc 		flags |= PRTERA;
24435763Smarc 	if (lflag&ECHOCTL)
24535763Smarc 		flags |= CTLECH;
24635763Smarc 	if ((iflag&IXANY) == 0)
24735763Smarc 		flags |= DECCTQ;
24835763Smarc 	flags |= lflag&(ECHO|MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH);
24935811Smarc if (ttydebug)
25035811Smarc 	printf("getflags: %x\n", flags);
25135763Smarc 	return (flags);
25235763Smarc }
25335763Smarc 
25435763Smarc ttcompatsetflags(tp, t)
25535763Smarc 	register struct tty *tp;
25635763Smarc 	register struct termios *t;
25735763Smarc {
25835763Smarc 	register flags = tp->t_flags;
25935763Smarc 	register long iflag = t->c_iflag;
26035763Smarc 	register long oflag = t->c_oflag;
26135763Smarc 	register long lflag = t->c_lflag;
26235763Smarc 	register long cflag = t->c_cflag;
26335763Smarc 
26435763Smarc 	if (flags & RAW) {
26535763Smarc 		iflag &= IXOFF;
26635763Smarc 		oflag &= ~OPOST;
26738925Skarels 		lflag &= ~(ECHOCTL|ISIG|ICANON|IEXTEN);
26835763Smarc 	} else {
26938925Skarels 		iflag |= BRKINT|IXON|IMAXBEL;
27035763Smarc 		oflag |= OPOST;
27138925Skarels 		lflag |= ISIG|IEXTEN;
27235763Smarc 		if (flags & XTABS)
27335763Smarc 			oflag |= OXTABS;
27435763Smarc 		else
27535763Smarc 			oflag &= ~OXTABS;
27635763Smarc 		if (flags & CBREAK)
27735763Smarc 			lflag &= ~ICANON;
27835763Smarc 		else
27935763Smarc 			lflag |= ICANON;
28035763Smarc 		if (flags&CRMOD) {
28135763Smarc 			iflag |= ICRNL;
28235763Smarc 			oflag |= ONLCR;
28335763Smarc 		} else {
28435763Smarc 			iflag &= ~ICRNL;
28535763Smarc 			oflag &= ~ONLCR;
28635763Smarc 		}
28735763Smarc 	}
28835763Smarc 	if (flags&ECHO)
28935763Smarc 		lflag |= ECHO;
29035763Smarc 	else
29135763Smarc 		lflag &= ~ECHO;
29235763Smarc 
29335763Smarc 	if (flags&(RAW|LITOUT|PASS8)) {
29435763Smarc 		cflag &= ~(CSIZE|PARENB);
29535763Smarc 		cflag |= CS8;
29635763Smarc 		if ((flags&(RAW|PASS8)) == 0)
29735763Smarc 			iflag |= ISTRIP;
29835763Smarc 	} else {
29935763Smarc 		cflag &= ~CSIZE;
30035763Smarc 		cflag |= CS7|PARENB;
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