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