|
|
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 */ ! 78: #if defined(COMPAT_43) || defined(COMPAT_SUNOS) ! 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.