tty_43.c revision 1.10 1 /* $NetBSD: tty_43.c,v 1.10 2000/03/30 11:27:14 augustss Exp $ */
2
3 /*-
4 * Copyright (c) 1982, 1986, 1991, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 * @(#)tty_compat.c 8.2 (Berkeley) 1/9/95
36 */
37
38 /*
39 * mapping routines for old line discipline (yuck)
40 */
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/ioctl.h>
44 #include <sys/proc.h>
45 #include <sys/tty.h>
46 #include <sys/termios.h>
47 #include <sys/file.h>
48 #include <sys/kernel.h>
49 #include <sys/syslog.h>
50 #include <sys/ioctl_compat.h>
51
52 /*
53 * XXX libcompat files should be included with config attributes
54 */
55 #ifdef COMPAT_OLDTTY
56
57 int ttydebug = 0;
58
59 static struct speedtab compatspeeds[] = {
60 #define MAX_SPEED 17
61 { 115200, 17 },
62 { 57600, 16 },
63 { 38400, 15 },
64 { 19200, 14 },
65 { 9600, 13 },
66 { 4800, 12 },
67 { 2400, 11 },
68 { 1800, 10 },
69 { 1200, 9 },
70 { 600, 8 },
71 { 300, 7 },
72 { 200, 6 },
73 { 150, 5 },
74 { 134, 4 },
75 { 110, 3 },
76 { 75, 2 },
77 { 50, 1 },
78 { 0, 0 },
79 { -1, -1 },
80 };
81 static int compatspcodes[] = {
82 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
83 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200
84 };
85
86 /* Macros to clear/set/test flags. */
87 #define SET(t, f) (t) |= (f)
88 #define CLR(t, f) (t) &= ~(f)
89 #define ISSET(t, f) ((t) & (f))
90
91 int ttcompatgetflags __P((struct tty *));
92 void ttcompatsetflags __P((struct tty *, struct termios *));
93 void ttcompatsetlflags __P((struct tty *, struct termios *));
94
95 /*ARGSUSED*/
96 int
97 ttcompat(tp, com, data, flag, p)
98 struct tty *tp;
99 u_long com;
100 caddr_t data;
101 int flag;
102 struct proc *p;
103 {
104
105 switch (com) {
106 case TIOCGETP: {
107 struct sgttyb *sg = (struct sgttyb *)data;
108 u_char *cc = tp->t_cc;
109 int speed;
110
111 speed = ttspeedtab(tp->t_ospeed, compatspeeds);
112 sg->sg_ospeed = (speed == -1) ? MAX_SPEED : speed;
113 if (tp->t_ispeed == 0)
114 sg->sg_ispeed = sg->sg_ospeed;
115 else {
116 speed = ttspeedtab(tp->t_ispeed, compatspeeds);
117 sg->sg_ispeed = (speed == -1) ? MAX_SPEED : speed;
118 }
119 sg->sg_erase = cc[VERASE];
120 sg->sg_kill = cc[VKILL];
121 sg->sg_flags = ttcompatgetflags(tp);
122 break;
123 }
124
125 case TIOCSETP:
126 case TIOCSETN: {
127 struct sgttyb *sg = (struct sgttyb *)data;
128 struct termios term;
129 int speed;
130
131 term = tp->t_termios;
132 if ((speed = sg->sg_ispeed) > MAX_SPEED || speed < 0)
133 term.c_ispeed = speed;
134 else
135 term.c_ispeed = compatspcodes[speed];
136 if ((speed = sg->sg_ospeed) > MAX_SPEED || speed < 0)
137 term.c_ospeed = speed;
138 else
139 term.c_ospeed = compatspcodes[speed];
140 term.c_cc[VERASE] = sg->sg_erase;
141 term.c_cc[VKILL] = sg->sg_kill;
142 tp->t_flags = (ttcompatgetflags(tp)&0xffff0000) | (sg->sg_flags&0xffff);
143 ttcompatsetflags(tp, &term);
144 return (ttioctl(tp, com == TIOCSETP ? TIOCSETAF : TIOCSETA,
145 (caddr_t)&term, flag, p));
146 }
147
148 case TIOCGETC: {
149 struct tchars *tc = (struct tchars *)data;
150 u_char *cc = tp->t_cc;
151
152 tc->t_intrc = cc[VINTR];
153 tc->t_quitc = cc[VQUIT];
154 tc->t_startc = cc[VSTART];
155 tc->t_stopc = cc[VSTOP];
156 tc->t_eofc = cc[VEOF];
157 tc->t_brkc = cc[VEOL];
158 break;
159 }
160 case TIOCSETC: {
161 struct tchars *tc = (struct tchars *)data;
162 u_char *cc = tp->t_cc;
163
164 cc[VINTR] = tc->t_intrc;
165 cc[VQUIT] = tc->t_quitc;
166 cc[VSTART] = tc->t_startc;
167 cc[VSTOP] = tc->t_stopc;
168 cc[VEOF] = tc->t_eofc;
169 cc[VEOL] = tc->t_brkc;
170 if (tc->t_brkc == (char)-1)
171 cc[VEOL2] = _POSIX_VDISABLE;
172 break;
173 }
174 case TIOCSLTC: {
175 struct ltchars *ltc = (struct ltchars *)data;
176 u_char *cc = tp->t_cc;
177
178 cc[VSUSP] = ltc->t_suspc;
179 cc[VDSUSP] = ltc->t_dsuspc;
180 cc[VREPRINT] = ltc->t_rprntc;
181 cc[VDISCARD] = ltc->t_flushc;
182 cc[VWERASE] = ltc->t_werasc;
183 cc[VLNEXT] = ltc->t_lnextc;
184 break;
185 }
186 case TIOCGLTC: {
187 struct ltchars *ltc = (struct ltchars *)data;
188 u_char *cc = tp->t_cc;
189
190 ltc->t_suspc = cc[VSUSP];
191 ltc->t_dsuspc = cc[VDSUSP];
192 ltc->t_rprntc = cc[VREPRINT];
193 ltc->t_flushc = cc[VDISCARD];
194 ltc->t_werasc = cc[VWERASE];
195 ltc->t_lnextc = cc[VLNEXT];
196 break;
197 }
198 case TIOCLBIS:
199 case TIOCLBIC:
200 case TIOCLSET: {
201 struct termios term;
202 int flags;
203
204 term = tp->t_termios;
205 flags = ttcompatgetflags(tp);
206 switch (com) {
207 case TIOCLSET:
208 tp->t_flags = (flags&0xffff) | (*(int *)data<<16);
209 break;
210 case TIOCLBIS:
211 tp->t_flags = flags | (*(int *)data<<16);
212 break;
213 case TIOCLBIC:
214 tp->t_flags = flags & ~(*(int *)data<<16);
215 break;
216 }
217 ttcompatsetlflags(tp, &term);
218 return (ttioctl(tp, TIOCSETA, (caddr_t)&term, flag, p));
219 }
220 case TIOCLGET:
221 *(int *)data = ttcompatgetflags(tp)>>16;
222 if (ttydebug)
223 printf("CLGET: returning %x\n", *(int *)data);
224 break;
225
226 case OTIOCGETD:
227 *(int *)data = tp->t_line ? tp->t_line : 2;
228 break;
229
230 case OTIOCSETD: {
231 int ldisczero = 0;
232
233 return (ttioctl(tp, TIOCSETD,
234 *(int *)data == 2 ? (caddr_t)&ldisczero : data, flag,
235 p));
236 }
237
238 case OTIOCCONS:
239 *(int *)data = 1;
240 return (ttioctl(tp, TIOCCONS, data, flag, p));
241
242 case TIOCHPCL:
243 SET(tp->t_cflag, HUPCL);
244 break;
245
246 case TIOCGSID:
247 if (tp->t_session == NULL)
248 return ENOTTY;
249
250 if (tp->t_session->s_leader == NULL)
251 return ENOTTY;
252
253 *(int *) data = tp->t_session->s_leader->p_pid;
254 break;
255
256 default:
257 return (-1);
258 }
259 return (0);
260 }
261
262 int
263 ttcompatgetflags(tp)
264 struct tty *tp;
265 {
266 tcflag_t iflag = tp->t_iflag;
267 tcflag_t lflag = tp->t_lflag;
268 tcflag_t oflag = tp->t_oflag;
269 tcflag_t cflag = tp->t_cflag;
270 int flags = 0;
271
272 if (ISSET(iflag, IXOFF))
273 SET(flags, TANDEM);
274 if (ISSET(iflag, ICRNL) || ISSET(oflag, ONLCR))
275 SET(flags, CRMOD);
276 if (ISSET(cflag, PARENB)) {
277 if (ISSET(iflag, INPCK)) {
278 if (ISSET(cflag, PARODD))
279 SET(flags, ODDP);
280 else
281 SET(flags, EVENP);
282 } else
283 SET(flags, ANYP);
284 }
285
286 if (!ISSET(lflag, ICANON)) {
287 /* fudge */
288 if (ISSET(iflag, IXON) || ISSET(lflag, ISIG|IEXTEN) ||
289 ISSET(cflag, PARENB))
290 SET(flags, CBREAK);
291 else
292 SET(flags, RAW);
293 }
294
295 if (ISSET(flags, RAW))
296 SET(flags, ISSET(tp->t_flags, LITOUT|PASS8));
297 else if (ISSET(cflag, CSIZE) == CS8) {
298 if (!ISSET(oflag, OPOST))
299 SET(flags, LITOUT);
300 if (!ISSET(iflag, ISTRIP))
301 SET(flags, PASS8);
302 }
303
304 if (ISSET(cflag, MDMBUF))
305 SET(flags, MDMBUF);
306 if (!ISSET(cflag, HUPCL))
307 SET(flags, NOHANG);
308 if (ISSET(oflag, OXTABS))
309 SET(flags, XTABS);
310 if (ISSET(lflag, ECHOE))
311 SET(flags, CRTERA|CRTBS);
312 if (ISSET(lflag, ECHOKE))
313 SET(flags, CRTKIL|CRTBS);
314 if (ISSET(lflag, ECHOPRT))
315 SET(flags, PRTERA);
316 if (ISSET(lflag, ECHOCTL))
317 SET(flags, CTLECH);
318 if (!ISSET(iflag, IXANY))
319 SET(flags, DECCTQ);
320 SET(flags, ISSET(lflag, ECHO|TOSTOP|FLUSHO|PENDIN|NOFLSH));
321 if (ttydebug)
322 printf("getflags: %x\n", flags);
323 return (flags);
324 }
325
326 void
327 ttcompatsetflags(tp, t)
328 struct tty *tp;
329 struct termios *t;
330 {
331 int flags = tp->t_flags;
332 tcflag_t iflag = t->c_iflag;
333 tcflag_t oflag = t->c_oflag;
334 tcflag_t lflag = t->c_lflag;
335 tcflag_t cflag = t->c_cflag;
336
337 if (ISSET(flags, TANDEM))
338 SET(iflag, IXOFF);
339 else
340 CLR(iflag, IXOFF);
341 if (ISSET(flags, ECHO))
342 SET(lflag, ECHO);
343 else
344 CLR(lflag, ECHO);
345 if (ISSET(flags, CRMOD)) {
346 SET(iflag, ICRNL);
347 SET(oflag, ONLCR);
348 } else {
349 CLR(iflag, ICRNL);
350 CLR(oflag, ONLCR);
351 }
352 if (ISSET(flags, XTABS))
353 SET(oflag, OXTABS);
354 else
355 CLR(oflag, OXTABS);
356
357
358 if (ISSET(flags, RAW)) {
359 iflag &= IXOFF;
360 CLR(lflag, ISIG|ICANON|IEXTEN);
361 CLR(cflag, PARENB);
362 } else {
363 SET(iflag, BRKINT|IXON|IMAXBEL);
364 SET(lflag, ISIG|IEXTEN);
365 if (ISSET(flags, CBREAK))
366 CLR(lflag, ICANON);
367 else
368 SET(lflag, ICANON);
369 switch (ISSET(flags, ANYP)) {
370 case 0:
371 CLR(cflag, PARENB);
372 break;
373 case ANYP:
374 SET(cflag, PARENB);
375 CLR(iflag, INPCK);
376 break;
377 case EVENP:
378 SET(cflag, PARENB);
379 SET(iflag, INPCK);
380 CLR(cflag, PARODD);
381 break;
382 case ODDP:
383 SET(cflag, PARENB);
384 SET(iflag, INPCK);
385 SET(cflag, PARODD);
386 break;
387 }
388 }
389
390 if (ISSET(flags, RAW|LITOUT|PASS8)) {
391 CLR(cflag, CSIZE);
392 SET(cflag, CS8);
393 if (!ISSET(flags, RAW|PASS8))
394 SET(iflag, ISTRIP);
395 else
396 CLR(iflag, ISTRIP);
397 if (!ISSET(flags, RAW|LITOUT))
398 SET(oflag, OPOST);
399 else
400 CLR(oflag, OPOST);
401 } else {
402 CLR(cflag, CSIZE);
403 SET(cflag, CS7);
404 SET(iflag, ISTRIP);
405 SET(oflag, OPOST);
406 }
407
408 t->c_iflag = iflag;
409 t->c_oflag = oflag;
410 t->c_lflag = lflag;
411 t->c_cflag = cflag;
412 }
413
414 void
415 ttcompatsetlflags(tp, t)
416 struct tty *tp;
417 struct termios *t;
418 {
419 int flags = tp->t_flags;
420 tcflag_t iflag = t->c_iflag;
421 tcflag_t oflag = t->c_oflag;
422 tcflag_t lflag = t->c_lflag;
423 tcflag_t cflag = t->c_cflag;
424
425 /* Nothing we can do with CRTBS. */
426 if (ISSET(flags, PRTERA))
427 SET(lflag, ECHOPRT);
428 else
429 CLR(lflag, ECHOPRT);
430 if (ISSET(flags, CRTERA))
431 SET(lflag, ECHOE);
432 else
433 CLR(lflag, ECHOE);
434 /* Nothing we can do with TILDE. */
435 if (ISSET(flags, MDMBUF))
436 SET(cflag, MDMBUF);
437 else
438 CLR(cflag, MDMBUF);
439 if (ISSET(flags, NOHANG))
440 CLR(cflag, HUPCL);
441 else
442 SET(cflag, HUPCL);
443 if (ISSET(flags, CRTKIL))
444 SET(lflag, ECHOKE);
445 else
446 CLR(lflag, ECHOKE);
447 if (ISSET(flags, CTLECH))
448 SET(lflag, ECHOCTL);
449 else
450 CLR(lflag, ECHOCTL);
451 if (!ISSET(flags, DECCTQ))
452 SET(iflag, IXANY);
453 else
454 CLR(iflag, IXANY);
455 CLR(lflag, TOSTOP|FLUSHO|PENDIN|NOFLSH);
456 SET(lflag, ISSET(flags, TOSTOP|FLUSHO|PENDIN|NOFLSH));
457
458 if (ISSET(flags, RAW|LITOUT|PASS8)) {
459 CLR(cflag, CSIZE);
460 SET(cflag, CS8);
461 if (!ISSET(flags, RAW|PASS8))
462 SET(iflag, ISTRIP);
463 else
464 CLR(iflag, ISTRIP);
465 if (!ISSET(flags, RAW|LITOUT))
466 SET(oflag, OPOST);
467 else
468 CLR(oflag, OPOST);
469 } else {
470 CLR(cflag, CSIZE);
471 SET(cflag, CS7);
472 SET(iflag, ISTRIP);
473 SET(oflag, OPOST);
474 }
475
476 t->c_iflag = iflag;
477 t->c_oflag = oflag;
478 t->c_lflag = lflag;
479 t->c_cflag = cflag;
480 }
481
482 #endif /* COMPAT_OLDTTY */
483