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