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