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