|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /* Copyright (c) 1997 Apple Computer, Inc. All Rights Reserved */
26: /*-
27: * Copyright (c) 1982, 1986, 1991, 1993
28: * The Regents of the University of California. All rights reserved.
29: *
30: * Redistribution and use in source and binary forms, with or without
31: * modification, are permitted provided that the following conditions
32: * are met:
33: * 1. Redistributions of source code must retain the above copyright
34: * notice, this list of conditions and the following disclaimer.
35: * 2. Redistributions in binary form must reproduce the above copyright
36: * notice, this list of conditions and the following disclaimer in the
37: * documentation and/or other materials provided with the distribution.
38: * 3. All advertising materials mentioning features or use of this software
39: * must display the following acknowledgement:
40: * This product includes software developed by the University of
41: * California, Berkeley and its contributors.
42: * 4. Neither the name of the University nor the names of its contributors
43: * may be used to endorse or promote products derived from this software
44: * without specific prior written permission.
45: *
46: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
47: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
50: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56: * SUCH DAMAGE.
57: *
58: * @(#)tty_compat.c 8.1 (Berkeley) 6/10/93
59: */
60:
61: /*
62: * mapping routines for old line discipline (yuck)
63: */
64:
65: #include <sys/param.h>
66: #include <sys/systm.h>
67: #include <sys/ioctl.h>
68: #include <sys/proc.h>
69: #include <sys/tty.h>
70: #include <sys/termios.h>
71: #include <sys/file.h>
72: #include <sys/conf.h>
73: #include <sys/kernel.h>
74: #include <sys/sysctl.h>
75: #include <sys/syslog.h>
76:
77: /* NeXT Move define down here cause COMPAT_43 not valid earlier */
1.1.1.2 ! root 78: #if COMPAT_43 || defined(COMPAT_SUNOS)
1.1 root 79:
80: static int ttcompatgetflags __P((struct tty *tp));
81: static void ttcompatsetflags __P((struct tty *tp, struct termios *t));
82: static void ttcompatsetlflags __P((struct tty *tp, struct termios *t));
83: static int ttcompatspeedtab __P((int speed, struct speedtab *table));
84:
85: #ifndef NeXT
86: static int ttydebug = 0;
87: SYSCTL_INT(_debug, OID_AUTO, ttydebug, CTLFLAG_RW, &ttydebug, 0, "");
88: #endif
89:
90: static struct speedtab compatspeeds[] = {
91: #define MAX_SPEED 17
92: { 115200, 17 },
93: { 57600, 16 },
94: { 38400, 15 },
95: { 19200, 14 },
96: { 9600, 13 },
97: { 4800, 12 },
98: { 2400, 11 },
99: { 1800, 10 },
100: { 1200, 9 },
101: { 600, 8 },
102: { 300, 7 },
103: { 200, 6 },
104: { 150, 5 },
105: { 134, 4 },
106: { 110, 3 },
107: { 75, 2 },
108: { 50, 1 },
109: { 0, 0 },
110: { -1, -1 },
111: };
112: static int compatspcodes[] = {
113: 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
114: 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200,
115: };
116:
117: static int
118: ttcompatspeedtab(speed, table)
119: int speed;
120: register struct speedtab *table;
121: {
122: if (speed == 0)
123: return (0); /* hangup */
124: for ( ; table->sp_speed > 0; table++)
125: if (table->sp_speed <= speed) /* nearest one, rounded down */
126: return (table->sp_code);
127: return (1); /* 50, min and not hangup */
128: }
129:
130: #ifndef NeXT
131: int
132: ttsetcompat(tp, com, data, term)
133: register struct tty *tp;
134: int *com;
135: caddr_t data;
136: struct termios *term;
137: #else
138: __private_extern__ int
139: ttsetcompat(tp, com, data, term)
140: register struct tty *tp;
141: u_long *com;
142: caddr_t data;
143: struct termios *term;
144: #endif /* !NeXT */
145: {
146: switch (*com) {
147: case TIOCSETP:
148: case TIOCSETN: {
149: register struct sgttyb *sg = (struct sgttyb *)data;
150: int speed;
151:
152: if ((speed = sg->sg_ispeed) > MAX_SPEED || speed < 0)
153: return(EINVAL);
154: else if (speed != ttcompatspeedtab(tp->t_ispeed, compatspeeds))
155: term->c_ispeed = compatspcodes[speed];
156: else
157: term->c_ispeed = tp->t_ispeed;
158: if ((speed = sg->sg_ospeed) > MAX_SPEED || speed < 0)
159: return(EINVAL);
160: else if (speed != ttcompatspeedtab(tp->t_ospeed, compatspeeds))
161: term->c_ospeed = compatspcodes[speed];
162: else
163: term->c_ospeed = tp->t_ospeed;
164: term->c_cc[VERASE] = sg->sg_erase;
165: term->c_cc[VKILL] = sg->sg_kill;
166: tp->t_flags = (tp->t_flags&0xffff0000) | (sg->sg_flags&0xffff);
167: ttcompatsetflags(tp, term);
168: *com = (*com == TIOCSETP) ? TIOCSETAF : TIOCSETA;
169: break;
170: }
171: case TIOCSETC: {
172: struct tchars *tc = (struct tchars *)data;
173: register cc_t *cc;
174:
175: cc = term->c_cc;
176: cc[VINTR] = tc->t_intrc;
177: cc[VQUIT] = tc->t_quitc;
178: cc[VSTART] = tc->t_startc;
179: cc[VSTOP] = tc->t_stopc;
180: cc[VEOF] = tc->t_eofc;
181: cc[VEOL] = tc->t_brkc;
182: if (tc->t_brkc == -1)
183: cc[VEOL2] = _POSIX_VDISABLE;
184: *com = TIOCSETA;
185: break;
186: }
187: case TIOCSLTC: {
188: struct ltchars *ltc = (struct ltchars *)data;
189: register cc_t *cc;
190:
191: cc = term->c_cc;
192: cc[VSUSP] = ltc->t_suspc;
193: cc[VDSUSP] = ltc->t_dsuspc;
194: cc[VREPRINT] = ltc->t_rprntc;
195: cc[VDISCARD] = ltc->t_flushc;
196: cc[VWERASE] = ltc->t_werasc;
197: cc[VLNEXT] = ltc->t_lnextc;
198: *com = TIOCSETA;
199: break;
200: }
201: case TIOCLBIS:
202: case TIOCLBIC:
203: case TIOCLSET:
204: if (*com == TIOCLSET)
205: tp->t_flags = (tp->t_flags&0xffff) | *(int *)data<<16;
206: else {
207: tp->t_flags =
208: (ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff);
209: if (*com == TIOCLBIS)
210: tp->t_flags |= *(int *)data<<16;
211: else
212: tp->t_flags &= ~(*(int *)data<<16);
213: }
214: ttcompatsetlflags(tp, term);
215: *com = TIOCSETA;
216: break;
217: }
218: return 0;
219: }
220:
221: /*ARGSUSED*/
222: #ifndef NeXT
223: int
224: ttcompat(tp, com, data, flag)
225: register struct tty *tp;
226: int com;
227: caddr_t data;
228: int flag;
229: #else
230: __private_extern__ int
231: ttcompat(tp, com, data, flag, p)
232: register struct tty *tp;
233: u_long com;
234: caddr_t data;
235: int flag;
236: struct proc *p;
237: #endif /* !NeXT */
238: {
239: switch (com) {
240: case TIOCSETP:
241: case TIOCSETN:
242: case TIOCSETC:
243: case TIOCSLTC:
244: case TIOCLBIS:
245: case TIOCLBIC:
246: case TIOCLSET: {
247: struct termios term;
248: int error;
249:
250: term = tp->t_termios;
251: if ((error = ttsetcompat(tp, &com, data, &term)) != 0)
252: return error;
253: #ifdef NeXT
254: return ttioctl(tp, com, (caddr_t) &term, flag, p);
255: #else
256: return ttioctl(tp, com, &term, flag);
257: #endif
258: }
259: case TIOCGETP: {
260: register struct sgttyb *sg = (struct sgttyb *)data;
261: register cc_t *cc = tp->t_cc;
262:
263: sg->sg_ospeed = ttcompatspeedtab(tp->t_ospeed, compatspeeds);
264: if (tp->t_ispeed == 0)
265: sg->sg_ispeed = sg->sg_ospeed;
266: else
267: sg->sg_ispeed = ttcompatspeedtab(tp->t_ispeed, compatspeeds);
268: sg->sg_erase = cc[VERASE];
269: sg->sg_kill = cc[VKILL];
270: sg->sg_flags = tp->t_flags = ttcompatgetflags(tp);
271: break;
272: }
273: case TIOCGETC: {
274: struct tchars *tc = (struct tchars *)data;
275: register cc_t *cc = tp->t_cc;
276:
277: tc->t_intrc = cc[VINTR];
278: tc->t_quitc = cc[VQUIT];
279: tc->t_startc = cc[VSTART];
280: tc->t_stopc = cc[VSTOP];
281: tc->t_eofc = cc[VEOF];
282: tc->t_brkc = cc[VEOL];
283: break;
284: }
285: case TIOCGLTC: {
286: struct ltchars *ltc = (struct ltchars *)data;
287: register cc_t *cc = tp->t_cc;
288:
289: ltc->t_suspc = cc[VSUSP];
290: ltc->t_dsuspc = cc[VDSUSP];
291: ltc->t_rprntc = cc[VREPRINT];
292: ltc->t_flushc = cc[VDISCARD];
293: ltc->t_werasc = cc[VWERASE];
294: ltc->t_lnextc = cc[VLNEXT];
295: break;
296: }
297: case TIOCLGET:
298: tp->t_flags =
299: (ttcompatgetflags(tp) & 0xffff0000UL)
300: | (tp->t_flags & 0xffff);
301: *(int *)data = tp->t_flags>>16;
302: #ifndef NeXT
303: if (ttydebug)
304: printf("CLGET: returning %x\n", *(int *)data);
305: #endif
306: break;
307:
308: case OTIOCGETD:
309: *(int *)data = tp->t_line ? tp->t_line : 2;
310: break;
311:
312: #ifndef NeXT
313: case OTIOCSETD: {
314: int ldisczero = 0;
315:
316: return (ttioctl(tp, TIOCSETD,
317: *(int *)data == 2 ? (caddr_t)&ldisczero : data, flag));
318: }
319:
320: case OTIOCCONS:
321: *(int *)data = 1;
322: return (ttioctl(tp, TIOCCONS, data, flag));
323: #else
324: case OTIOCSETD: {
325: int ldisczero = 0;
326:
327: return (ttioctl(tp, TIOCSETD,
328: *(int *)data == 2 ? (caddr_t)&ldisczero : data, flag, p));
329: }
330:
331: case OTIOCCONS:
332: *(int *)data = 1;
333: return (ttioctl(tp, TIOCCONS, data, flag, p));
334:
335: case TIOCGSID:
336: if (tp->t_session == NULL)
337: return ENOTTY;
338:
339: if (tp->t_session->s_leader == NULL)
340: return ENOTTY;
341:
342: *(int *) data = tp->t_session->s_leader->p_pid;
343: break;
344: #endif /* NeXT */
345:
346: default:
347: return (-1);
348: }
349: return (0);
350: }
351:
352: static int
353: ttcompatgetflags(tp)
354: register struct tty *tp;
355: {
356: register tcflag_t iflag = tp->t_iflag;
357: register tcflag_t lflag = tp->t_lflag;
358: register tcflag_t oflag = tp->t_oflag;
359: register tcflag_t cflag = tp->t_cflag;
360: register flags = 0;
361:
362: if (iflag&IXOFF)
363: flags |= TANDEM;
364: if (iflag&ICRNL || oflag&ONLCR)
365: flags |= CRMOD;
366: if ((cflag&CSIZE) == CS8) {
367: flags |= PASS8;
368: if (iflag&ISTRIP)
369: flags |= ANYP;
370: }
371: else if (cflag&PARENB) {
372: if (iflag&INPCK) {
373: if (cflag&PARODD)
374: flags |= ODDP;
375: else
376: flags |= EVENP;
377: } else
378: flags |= EVENP | ODDP;
379: }
380:
381: if ((lflag&ICANON) == 0) {
382: /* fudge */
383: if (iflag&(INPCK|ISTRIP|IXON) || lflag&(IEXTEN|ISIG)
384: || cflag&(CSIZE|PARENB) != CS8)
385: flags |= CBREAK;
386: else
387: flags |= RAW;
388: }
389: if (!(flags&RAW) && !(oflag&OPOST) && cflag&(CSIZE|PARENB) == CS8)
390: flags |= LITOUT;
391: if (cflag&MDMBUF)
392: flags |= MDMBUF;
393: if ((cflag&HUPCL) == 0)
394: flags |= NOHANG;
395: if (oflag&OXTABS)
396: flags |= XTABS;
397: if (lflag&ECHOE)
398: flags |= CRTERA|CRTBS;
399: if (lflag&ECHOKE)
400: flags |= CRTKIL|CRTBS;
401: if (lflag&ECHOPRT)
402: flags |= PRTERA;
403: if (lflag&ECHOCTL)
404: flags |= CTLECH;
405: if ((iflag&IXANY) == 0)
406: flags |= DECCTQ;
407: flags |= lflag&(ECHO|TOSTOP|FLUSHO|PENDIN|NOFLSH);
408: #ifndef NeXT
409: if (ttydebug)
410: printf("getflags: %x\n", flags);
411: #endif
412: return (flags);
413: }
414:
415: static void
416: ttcompatsetflags(tp, t)
417: register struct tty *tp;
418: register struct termios *t;
419: {
420: register flags = tp->t_flags;
421: register tcflag_t iflag = t->c_iflag;
422: register tcflag_t oflag = t->c_oflag;
423: register tcflag_t lflag = t->c_lflag;
424: register tcflag_t cflag = t->c_cflag;
425:
426: if (flags & RAW) {
427: iflag = IGNBRK;
428: lflag &= ~(ECHOCTL|ISIG|ICANON|IEXTEN);
429: } else {
430: iflag &= ~(PARMRK|IGNPAR|IGNCR|INLCR);
431: iflag |= BRKINT|IXON|IMAXBEL;
432: lflag |= ISIG|IEXTEN|ECHOCTL; /* XXX was echoctl on ? */
433: if (flags & XTABS)
434: oflag |= OXTABS;
435: else
436: oflag &= ~OXTABS;
437: if (flags & CBREAK)
438: lflag &= ~ICANON;
439: else
440: lflag |= ICANON;
441: if (flags&CRMOD) {
442: iflag |= ICRNL;
443: oflag |= ONLCR;
444: } else {
445: iflag &= ~ICRNL;
446: oflag &= ~ONLCR;
447: }
448: }
449: if (flags&ECHO)
450: lflag |= ECHO;
451: else
452: lflag &= ~ECHO;
453:
454: cflag &= ~(CSIZE|PARENB);
455: if (flags&(RAW|LITOUT|PASS8)) {
456: cflag |= CS8;
457: if (!(flags&(RAW|PASS8))
458: || (flags&(RAW|PASS8|ANYP)) == (PASS8|ANYP))
459: iflag |= ISTRIP;
460: else
461: iflag &= ~ISTRIP;
462: if (flags&(RAW|LITOUT))
463: oflag &= ~OPOST;
464: else
465: oflag |= OPOST;
466: } else {
467: cflag |= CS7|PARENB;
468: iflag |= ISTRIP;
469: oflag |= OPOST;
470: }
471: /* XXX don't set INPCK if RAW or PASS8? */
472: if ((flags&(EVENP|ODDP)) == EVENP) {
473: iflag |= INPCK;
474: cflag &= ~PARODD;
475: } else if ((flags&(EVENP|ODDP)) == ODDP) {
476: iflag |= INPCK;
477: cflag |= PARODD;
478: } else
479: iflag &= ~INPCK;
480: if (flags&TANDEM)
481: iflag |= IXOFF;
482: else
483: iflag &= ~IXOFF;
484: if ((flags&DECCTQ) == 0)
485: iflag |= IXANY;
486: else
487: iflag &= ~IXANY;
488: t->c_iflag = iflag;
489: t->c_oflag = oflag;
490: t->c_lflag = lflag;
491: t->c_cflag = cflag;
492: }
493:
494: static void
495: ttcompatsetlflags(tp, t)
496: register struct tty *tp;
497: register struct termios *t;
498: {
499: register flags = tp->t_flags;
500: register tcflag_t iflag = t->c_iflag;
501: register tcflag_t oflag = t->c_oflag;
502: register tcflag_t lflag = t->c_lflag;
503: register tcflag_t cflag = t->c_cflag;
504:
505: iflag &= ~(PARMRK|IGNPAR|IGNCR|INLCR);
506: if (flags&CRTERA)
507: lflag |= ECHOE;
508: else
509: lflag &= ~ECHOE;
510: if (flags&CRTKIL)
511: lflag |= ECHOKE;
512: else
513: lflag &= ~ECHOKE;
514: if (flags&PRTERA)
515: lflag |= ECHOPRT;
516: else
517: lflag &= ~ECHOPRT;
518: if (flags&CTLECH)
519: lflag |= ECHOCTL;
520: else
521: lflag &= ~ECHOCTL;
522: if (flags&TANDEM)
523: iflag |= IXOFF;
524: else
525: iflag &= ~IXOFF;
526: if ((flags&DECCTQ) == 0)
527: iflag |= IXANY;
528: else
529: iflag &= ~IXANY;
530: if (flags & MDMBUF)
531: cflag |= MDMBUF;
532: else
533: cflag &= ~MDMBUF;
534: if (flags&NOHANG)
535: cflag &= ~HUPCL;
536: else
537: cflag |= HUPCL;
538: lflag &= ~(TOSTOP|FLUSHO|PENDIN|NOFLSH);
539: lflag |= flags&(TOSTOP|FLUSHO|PENDIN|NOFLSH);
540:
541: /*
542: * The next if-else statement is copied from above so don't bother
543: * checking it separately. We could avoid fiddlling with the
544: * character size if the mode is already RAW or if neither the
545: * LITOUT bit or the PASS8 bit is being changed, but the delta of
546: * the change is not available here and skipping the RAW case would
547: * make the code different from above.
548: */
549: cflag &= ~(CSIZE|PARENB);
550: if (flags&(RAW|LITOUT|PASS8)) {
551: cflag |= CS8;
552: if (!(flags&(RAW|PASS8))
553: || (flags&(RAW|PASS8|ANYP)) == (PASS8|ANYP))
554: iflag |= ISTRIP;
555: else
556: iflag &= ~ISTRIP;
557: if (flags&(RAW|LITOUT))
558: oflag &= ~OPOST;
559: else
560: oflag |= OPOST;
561: } else {
562: cflag |= CS7|PARENB;
563: iflag |= ISTRIP;
564: oflag |= OPOST;
565: }
566: t->c_iflag = iflag;
567: t->c_oflag = oflag;
568: t->c_lflag = lflag;
569: t->c_cflag = cflag;
570: }
571: #endif /* COMPAT_43 || COMPAT_SUNOS */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.