xref: /original-bsd/sys/kern/tty_compat.c (revision 7b081c7c)
1 /*
2  * Copyright (c) 1982, 1986 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)tty_compat.c	7.4 (Berkeley) 02/17/90
7  */
8 
9 /*
10  * mapping routines for old line discipline (yuck)
11  */
12 #ifdef COMPAT_43
13 
14 #include "param.h"
15 #include "systm.h"
16 #include "user.h"
17 #include "ioctl.h"
18 #include "tty.h"
19 #include "termios.h"
20 #include "proc.h"
21 #include "file.h"
22 #include "conf.h"
23 #include "dkstat.h"
24 #include "uio.h"
25 #include "kernel.h"
26 #include "syslog.h"
27 
28 #include "machine/reg.h"
29 
30 int ttydebug = 0;
31 
32 /* XXX - fold these two tables into one */
33 static struct speedtab compatspeeds[] = {
34 	38400,	15,
35 	19200,	14,
36 	9600,	13,
37 	4800,	12,
38 	2400,	11,
39 	1800,	10,
40 	1200,	9,
41 	600,	8,
42 	300,	7,
43 	200,	6,
44 	150,	5,
45 	134,	4,
46 	110,	3,
47 	75,	2,
48 	50,	1,
49 	0,	0,
50 	-1,	-1,
51 };
52 static int compatspcodes[16] = {
53 	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
54 	1800, 2400, 4800, 9600, 19200, 38400,
55 };
56 
57 /*ARGSUSED*/
58 ttcompat(tp, com, data, flag)
59 	register struct tty *tp;
60 	caddr_t data;
61 {
62 	switch(com) {
63 	case TIOCGETP: {
64 		register struct sgttyb *sg = (struct sgttyb *)data;
65 		register u_char *cc = tp->t_cc;
66 		register speed;
67 
68 		speed = ttspeedtab(tp->t_ospeed, compatspeeds);
69 		sg->sg_ospeed = (speed == -1) ? 15 : speed;
70 		if (tp->t_ispeed == 0)
71 			sg->sg_ispeed = sg->sg_ospeed;
72 		else {
73 			speed = ttspeedtab(tp->t_ispeed, compatspeeds);
74 			sg->sg_ispeed = (speed == -1) ? 15 : speed;
75 		}
76 		sg->sg_erase = cc[VERASE];
77 		sg->sg_kill = cc[VKILL];
78 		sg->sg_flags = ttcompatgetflags(tp);
79 		break;
80 	}
81 
82 	case TIOCSETP:
83 	case TIOCSETN: {
84 		register struct sgttyb *sg = (struct sgttyb *)data;
85 		struct termios term;
86 		int speed;
87 
88 		term = tp->t_termios;
89 		if ((speed = sg->sg_ispeed) > 15 || speed < 0)
90 			term.c_ispeed = speed;
91 		else
92 			term.c_ispeed = compatspcodes[speed];
93 		if ((speed = sg->sg_ospeed) > 15 || speed < 0)
94 			term.c_ospeed = speed;
95 		else
96 			term.c_ospeed = compatspcodes[speed];
97 		term.c_cc[VERASE] = sg->sg_erase;
98 		term.c_cc[VKILL] = sg->sg_kill;
99 		tp->t_flags = (tp->t_flags&0xffff0000) | sg->sg_flags;
100 		ttcompatsetflags(tp, &term);
101 		return (ttioctl(tp, com == TIOCSETP ? TIOCSETAF : TIOCSETA,
102 			&term, flag));
103 	}
104 
105 	case TIOCGETC: {
106 		struct tchars *tc = (struct tchars *)data;
107 		register u_char *cc = tp->t_cc;
108 
109 		tc->t_intrc = cc[VINTR];
110 		tc->t_quitc = cc[VQUIT];
111 		tc->t_startc = cc[VSTART];
112 		tc->t_stopc = cc[VSTOP];
113 		tc->t_eofc = cc[VEOF];
114 		tc->t_brkc = cc[VEOL];
115 		break;
116 	}
117 	case TIOCSETC: {
118 		struct tchars *tc = (struct tchars *)data;
119 		register u_char *cc = tp->t_cc;
120 
121 		cc[VINTR] = tc->t_intrc;
122 		cc[VQUIT] = tc->t_quitc;
123 		cc[VSTART] = tc->t_startc;
124 		cc[VSTOP] = tc->t_stopc;
125 		cc[VEOF] = tc->t_eofc;
126 		cc[VEOL] = tc->t_brkc;
127 		if (tc->t_brkc == -1)
128 			cc[VEOL2] = _POSIX_VDISABLE;
129 		break;
130 	}
131 	case TIOCSLTC: {
132 		struct ltchars *ltc = (struct ltchars *)data;
133 		register u_char *cc = tp->t_cc;
134 
135 		cc[VSUSP] = ltc->t_suspc;
136 		cc[VDSUSP] = ltc->t_dsuspc;
137 		cc[VREPRINT] = ltc->t_rprntc;
138 		cc[VFLUSHO] = ltc->t_flushc;
139 		cc[VWERASE] = ltc->t_werasc;
140 		cc[VLNEXT] = ltc->t_lnextc;
141 		break;
142 	}
143 	case TIOCGLTC: {
144 		struct ltchars *ltc = (struct ltchars *)data;
145 		register u_char *cc = tp->t_cc;
146 
147 		ltc->t_suspc = cc[VSUSP];
148 		ltc->t_dsuspc = cc[VDSUSP];
149 		ltc->t_rprntc = cc[VREPRINT];
150 		ltc->t_flushc = cc[VFLUSHO];
151 		ltc->t_werasc = cc[VWERASE];
152 		ltc->t_lnextc = cc[VLNEXT];
153 		break;
154 	}
155 	case TIOCLBIS:
156 	case TIOCLBIC:
157 	case TIOCLSET: {
158 		struct termios term;
159 
160 		term = tp->t_termios;
161 		if (com == TIOCLSET)
162 			tp->t_flags = (tp->t_flags&0xffff) | *(int *)data<<16;
163 		else {
164 			tp->t_flags =
165 			 (ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff);
166 			if (com == TIOCLBIS)
167 				tp->t_flags |= *(int *)data<<16;
168 			else
169 				tp->t_flags &= ~(*(int *)data<<16);
170 		}
171 		ttcompatsetlflags(tp, &term);
172 		return (ttioctl(tp, TIOCSETA, &term, flag));
173 	}
174 	case TIOCLGET:
175 		*(int *)data = ttcompatgetflags(tp)>>16;
176 		if (ttydebug)
177 			printf("CLGET: returning %x\n", *(int *)data);
178 		break;
179 
180 	case OTIOCGETD:
181 		*(int *)data = tp->t_line ? tp->t_line : 2;
182 		break;
183 
184 	case OTIOCSETD: {
185 		int ldisczero = 0;
186 
187 		return(ttioctl(tp, TIOCSETD,
188 			*(int *)data == 2 ? (caddr_t)&ldisczero : data, flag));
189 	}
190 
191 	default:
192 		return (-1);
193 	}
194 	return(0);
195 }
196 
197 ttcompatgetflags(tp)
198 	register struct tty *tp;
199 {
200 	register long iflag = tp->t_iflag;
201 	register long lflag = tp->t_lflag;
202 	register long oflag = tp->t_oflag;
203 	register long cflag = tp->t_cflag;
204 	register flags = 0;
205 
206 	if (iflag&IXOFF)
207 		flags |= TANDEM;
208 	if (iflag&ICRNL || oflag&ONLCR)
209 		flags |= CRMOD;
210 	if (cflag&PARENB) {
211 		if (iflag&INPCK) {
212 			if (cflag&PARODD)
213 				flags |= ODDP;
214 			else
215 				flags |= EVENP;
216 		} else
217 			flags |= EVENP | ODDP;
218 	} else {
219 		if ((tp->t_flags&LITOUT) && !(oflag&OPOST))
220 			flags |= LITOUT;
221 		if (tp->t_flags&PASS8)
222 			flags |= PASS8;
223 	}
224 
225 	if ((lflag&ICANON) == 0) {
226 		/* fudge */
227 		if (iflag&IXON || lflag&ISIG || lflag&IEXTEN || cflag&PARENB)
228 			flags |= CBREAK;
229 		else
230 			flags |= RAW;
231 	}
232 	if (oflag&OXTABS)
233 		flags |= XTABS;
234 	if (lflag&ECHOE)
235 		flags |= CRTERA|CRTBS;
236 	if (lflag&ECHOKE)
237 		flags |= CRTKIL|CRTBS;
238 	if (lflag&ECHOPRT)
239 		flags |= PRTERA;
240 	if (lflag&ECHOCTL)
241 		flags |= CTLECH;
242 	if ((iflag&IXANY) == 0)
243 		flags |= DECCTQ;
244 	flags |= lflag&(ECHO|MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH);
245 if (ttydebug)
246 	printf("getflags: %x\n", flags);
247 	return (flags);
248 }
249 
250 ttcompatsetflags(tp, t)
251 	register struct tty *tp;
252 	register struct termios *t;
253 {
254 	register flags = tp->t_flags;
255 	register long iflag = t->c_iflag;
256 	register long oflag = t->c_oflag;
257 	register long lflag = t->c_lflag;
258 	register long cflag = t->c_cflag;
259 
260 	if (flags & RAW) {
261 		iflag &= IXOFF;
262 		oflag &= ~OPOST;
263 		lflag &= ~(ECHOCTL|ISIG|ICANON|IEXTEN);
264 	} else {
265 		iflag |= BRKINT|IXON|IMAXBEL;
266 		oflag |= OPOST;
267 		lflag |= ISIG|IEXTEN;
268 		if (flags & XTABS)
269 			oflag |= OXTABS;
270 		else
271 			oflag &= ~OXTABS;
272 		if (flags & CBREAK)
273 			lflag &= ~ICANON;
274 		else
275 			lflag |= ICANON;
276 		if (flags&CRMOD) {
277 			iflag |= ICRNL;
278 			oflag |= ONLCR;
279 		} else {
280 			iflag &= ~ICRNL;
281 			oflag &= ~ONLCR;
282 		}
283 	}
284 	if (flags&ECHO)
285 		lflag |= ECHO;
286 	else
287 		lflag &= ~ECHO;
288 
289 	if (flags&(RAW|LITOUT|PASS8)) {
290 		cflag &= ~(CSIZE|PARENB);
291 		cflag |= CS8;
292 		if ((flags&(RAW|PASS8)) == 0)
293 			iflag |= ISTRIP;
294 	} else {
295 		cflag &= ~CSIZE;
296 		cflag |= CS7|PARENB;
297 	}
298 	if ((flags&(EVENP|ODDP)) == EVENP) {
299 		iflag |= INPCK;
300 		cflag &= ~PARODD;
301 	} else if ((flags&(EVENP|ODDP)) == ODDP) {
302 		iflag |= INPCK;
303 		cflag |= PARODD;
304 	} else
305 		iflag &= ~INPCK;
306 	if (flags&LITOUT)
307 		oflag &= ~OPOST;	/* move earlier ? */
308 	if (flags&TANDEM)
309 		iflag |= IXOFF;
310 	else
311 		iflag &= ~IXOFF;
312 	t->c_iflag = iflag;
313 	t->c_oflag = oflag;
314 	t->c_lflag = lflag;
315 	t->c_cflag = cflag;
316 }
317 
318 ttcompatsetlflags(tp, t)
319 	register struct tty *tp;
320 	register struct termios *t;
321 {
322 	register flags = tp->t_flags;
323 	register long iflag = t->c_iflag;
324 	register long oflag = t->c_oflag;
325 	register long lflag = t->c_lflag;
326 	register long cflag = t->c_cflag;
327 
328 	if (flags&CRTERA)
329 		lflag |= ECHOE;
330 	else
331 		lflag &= ~ECHOE;
332 	if (flags&CRTKIL)
333 		lflag |= ECHOKE;
334 	else
335 		lflag &= ~ECHOKE;
336 	if (flags&PRTERA)
337 		lflag |= ECHOPRT;
338 	else
339 		lflag &= ~ECHOPRT;
340 	if (flags&CTLECH)
341 		lflag |= ECHOCTL;
342 	else
343 		lflag &= ~ECHOCTL;
344 	if ((flags&DECCTQ) == 0)
345 		lflag |= IXANY;
346 	else
347 		lflag &= ~IXANY;
348 	lflag &= ~(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH);
349 	lflag |= flags&(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH);
350 	if (flags&(LITOUT|PASS8)) {
351 		iflag &= ~ISTRIP;
352 		cflag &= ~(CSIZE|PARENB);
353 		cflag |= CS8;
354 		if (flags&LITOUT)
355 			oflag &= ~OPOST;
356 		if ((flags&(PASS8|RAW)) == 0)
357 			iflag |= ISTRIP;
358 	} else if ((flags&RAW) == 0) {
359 		cflag &= ~CSIZE;
360 		cflag |= CS7|PARENB;
361 		oflag |= OPOST;
362 	}
363 	t->c_iflag = iflag;
364 	t->c_oflag = oflag;
365 	t->c_lflag = lflag;
366 	t->c_cflag = cflag;
367 }
368 #endif	/* COMPAT_43 */
369