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