1/* 2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28/* Copyright (c) 1997 Apple Computer, Inc. All Rights Reserved */ 29/*- 30 * Copyright (c) 1982, 1986, 1991, 1993 31 * The Regents of the University of California. All rights reserved. 32 * 33 * Redistribution and use in source and binary forms, with or without 34 * modification, are permitted provided that the following conditions 35 * are met: 36 * 1. Redistributions of source code must retain the above copyright 37 * notice, this list of conditions and the following disclaimer. 38 * 2. Redistributions in binary form must reproduce the above copyright 39 * notice, this list of conditions and the following disclaimer in the 40 * documentation and/or other materials provided with the distribution. 41 * 3. All advertising materials mentioning features or use of this software 42 * must display the following acknowledgement: 43 * This product includes software developed by the University of 44 * California, Berkeley and its contributors. 45 * 4. Neither the name of the University nor the names of its contributors 46 * may be used to endorse or promote products derived from this software 47 * without specific prior written permission. 48 * 49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 59 * SUCH DAMAGE. 60 * 61 * @(#)tty_compat.c 8.1 (Berkeley) 6/10/93 62 */ 63 64/* 65 * Compatibility routines for BSD 4.3 tty ioctl() commands 66 * 67 * The only function externalized from this file is ttcompat() and it is 68 * externalized as private extern to prevent exporting of the symbol when 69 * KEXTs link against the kernel. 70 * 71 * Locks: All functions in this file assume that the tty_lock() 72 * is held on the tty structure before these functions are 73 * called. 74 */ 75 76#include <sys/param.h> 77#include <sys/systm.h> 78#include <sys/ioctl.h> 79#include <sys/proc_internal.h> 80#include <sys/tty.h> 81#include <sys/termios.h> 82#include <sys/file_internal.h> 83#include <sys/conf.h> 84#include <sys/kernel.h> 85#include <sys/sysctl.h> 86#include <sys/syslog.h> 87 88static int ttcompatgetflags(struct tty *tp); 89static void ttcompatsetflags(struct tty *tp, struct termios *t); 90static void ttcompatsetlflags(struct tty *tp, struct termios *t); 91static int ttcompatspeedtab(int speed, struct speedtab *table); 92 93/* 94 * These two tables encode baud rate to speed code and speed code to 95 * baud rate information. They are a mapping between the <sys/termios.h> 96 * baud rate constants and the <sys/ttydev.h> baud rate constants. We 97 * cannot use those constants directly here because they occupy the same 98 * name space. 99 */ 100static struct speedtab compatspeeds[] = { 101#define MAX_SPEED 17 102 { 115200, 17 }, 103 { 57600, 16 }, 104 { 38400, 15 }, 105 { 19200, 14 }, 106 { 9600, 13 }, 107 { 4800, 12 }, 108 { 2400, 11 }, 109 { 1800, 10 }, 110 { 1200, 9 }, 111 { 600, 8 }, 112 { 300, 7 }, 113 { 200, 6 }, 114 { 150, 5 }, 115 { 134, 4 }, 116 { 110, 3 }, 117 { 75, 2 }, 118 { 50, 1 }, 119 { 0, 0 }, 120 { -1, -1 }, 121}; 122static int compatspcodes[] = { 123 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 124 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 125}; 126 127/* 128 * ttcompatspeedtab 129 * 130 * Description: Given a baud rate value as an integer, and a speed table, 131 * convert the baud rate to a speed code, according to the 132 * contents of the table. This effectively changes termios.h 133 * baud rate values into ttydev.h baud rate codes. 134 * 135 * Parameters: int speed Baud rate, as an integer 136 * struct speedtab *table Baud rate table to speed code table 137 * 138 * Returns: 1 B50 speed code; returned if we can 139 * not find an answer in the table. 140 * 0 If a 0 was requested in order to 141 * trigger a hangup (250ms of line 142 * silence, per Bell 103C standard). 143 * * A speed code matching the requested 144 * baud rate (potentially rounded down, 145 * if there is no exact match). 146 * 147 * Notes: This function is used for TIOCGETP, TIOCSETP, and TIOCSETN. 148 */ 149static int 150ttcompatspeedtab(int speed, struct speedtab *table) 151{ 152 if (speed == 0) 153 return (0); /* hangup */ 154 for ( ; table->sp_speed > 0; table++) 155 if (table->sp_speed <= speed) /* nearest one, rounded down */ 156 return (table->sp_code); 157 return (1); /* 50, min and not hangup */ 158} 159 160 161/* 162 * ttsetcompat 163 * 164 * Description: Convert backward compatability set command arguments as 165 * follows: 166 * 167 * TIOCSETP -> TIOSETAF 168 * TIOCSETN -> TIOCSETA 169 * TIOCSETC -> TIOCSETA 170 * TIOCSLTC -> TIOCSETA 171 * TIOCLBIS -> TIOCSETA 172 * TIOCLBIC -> TIOCSETA 173 * TIOCLSET -> TIOCSETA 174 * 175 * The converted command argument and potentially modified 'term' 176 * argument are returned to ttcompat(), which will then call 177 * ttioctl_locked(), if this function returns successfully. 178 * 179 * Parameters struct tty *tp The tty on which the operation is 180 * being performed. 181 * u_long *com A pointer to the terminal input/output 182 * command being requested; its contents 183 * will be modified per the table above, 184 * on a non-error return. 185 * caddr_t data Command specific parameter data; this 186 * data is read but not modified. 187 * struct termios *term A local stack termios structure from 188 * ttcompat(), whose contents are to be 189 * modified based on *com and *data. 190 * 191 * Returns: EINVAL An input speed or output speed is 192 * outside the allowable range for a 193 * TIOCSETP or TIOCSETN command. 194 * 0 All other cases return 0. 195 * 196 * Notes: This function may modify the contents of the tp->t_flags 197 * field in a successful call to TIOCSETP, TIOCSETN, TIOCLBIS, 198 * TIOCLBIC, or TIOCLSET. 199 * 200 * All other tp fields will remain unmodifed, since the struct 201 * termios is a local stack copy from ttcompat(), and not the 202 * real thing. A subsequent call to ttioctl_locked() in 203 * ttcompat(), however, may result in subsequent changes. 204 * 205 * WARNING: This compatibility code is not 6/432 clean; it will only 206 * work for 32 bit processes on 32 bit kernels or 64 bit 207 * processes on 64 bit kernels. We are not addressing this 208 * due to <rdar://6904053>. 209 */ 210static int 211ttsetcompat(struct tty *tp, u_long *com, caddr_t data, struct termios *term) 212{ 213 switch (*com) { 214 case TIOCSETP: 215 /* 216 * Wait for all characters queued for output to drain, then 217 * Discard all characters queued for input, and then set 218 * the input and output speeds and device flags, per the 219 * contents of the struct sgttyb that 'data' points to. 220 */ 221 case TIOCSETN: 222 /* 223 * Same as TIOCSETP, but the output is not drained, and any 224 * pending input is not discarded. 225 */ 226 { 227 register struct sgttyb *sg = (struct sgttyb *)data; 228 int speed; 229 230 if ((speed = sg->sg_ispeed) > MAX_SPEED || speed < 0) 231 return(EINVAL); 232 else if (speed != ttcompatspeedtab(tp->t_ispeed, compatspeeds)) 233 term->c_ispeed = compatspcodes[speed]; 234 else 235 term->c_ispeed = tp->t_ispeed; 236 if ((speed = sg->sg_ospeed) > MAX_SPEED || speed < 0) 237 return(EINVAL); 238 else if (speed != ttcompatspeedtab(tp->t_ospeed, compatspeeds)) 239 term->c_ospeed = compatspcodes[speed]; 240 else 241 term->c_ospeed = tp->t_ospeed; 242 term->c_cc[VERASE] = sg->sg_erase; 243 term->c_cc[VKILL] = sg->sg_kill; 244 tp->t_flags = (tp->t_flags&0xffff0000) | (sg->sg_flags&0xffff); 245 ttcompatsetflags(tp, term); 246 *com = (*com == TIOCSETP) ? TIOCSETAF : TIOCSETA; 247 break; 248 } 249 case TIOCSETC: 250 /* 251 * Set the terminal control characters per the contents of 252 * the struct tchars that 'data' points to. 253 */ 254 { 255 struct tchars *tc = (struct tchars *)data; 256 register cc_t *cc; 257 258 cc = term->c_cc; 259 cc[VINTR] = tc->t_intrc; 260 cc[VQUIT] = tc->t_quitc; 261 cc[VSTART] = tc->t_startc; 262 cc[VSTOP] = tc->t_stopc; 263 cc[VEOF] = tc->t_eofc; 264 cc[VEOL] = tc->t_brkc; 265 if (tc->t_brkc == -1) 266 cc[VEOL2] = _POSIX_VDISABLE; 267 *com = TIOCSETA; 268 break; 269 } 270 case TIOCSLTC: 271 /* 272 * Set the terminal control characters per the contents of 273 * the struct ltchars that 'data' points to. 274 */ 275 { 276 struct ltchars *ltc = (struct ltchars *)data; 277 register cc_t *cc; 278 279 cc = term->c_cc; 280 cc[VSUSP] = ltc->t_suspc; 281 cc[VDSUSP] = ltc->t_dsuspc; 282 cc[VREPRINT] = ltc->t_rprntc; 283 cc[VDISCARD] = ltc->t_flushc; 284 cc[VWERASE] = ltc->t_werasc; 285 cc[VLNEXT] = ltc->t_lnextc; 286 *com = TIOCSETA; 287 break; 288 } 289 case TIOCLBIS: 290 /* 291 * Set the bits in the terminal state local flags word 292 * (16 bits) for the terminal to the current bits OR 293 * those in the 16 bit value pointed to by 'data'. 294 */ 295 case TIOCLBIC: 296 /* 297 * Clear the bits in the terminal state local flags word 298 * for the terminal to the current bits AND those bits NOT 299 * in the 16 bit value pointed to by 'data'. 300 */ 301 case TIOCLSET: 302 /* 303 * Set the terminal state local flags word to exactly those 304 * bits that correspond to the 16 bit value pointed to by 305 * 'data'. 306 */ 307 if (*com == TIOCLSET) 308 tp->t_flags = (tp->t_flags&0xffff) | *(int *)data<<16; 309 else { 310 tp->t_flags = 311 (ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff); 312 if (*com == TIOCLBIS) 313 tp->t_flags |= *(int *)data<<16; 314 else 315 tp->t_flags &= ~(*(int *)data<<16); 316 } 317 ttcompatsetlflags(tp, term); 318 *com = TIOCSETA; 319 break; 320 } 321 return 0; 322} 323 324/* 325 * ttcompat 326 * 327 * Description: For 'set' commands, convert the command and arguments as 328 * necessary, and call ttioctl_locked(), returning the result 329 * as our result; for 'get' commands, obtain the requested data 330 * from the appropriate source, and return it in the expected 331 * format. If the command is not recognized, return EINVAL. 332 * 333 * Parameters struct tty *tp The tty on which the operation is 334 * being performed. 335 * u_long com The terminal input/output command 336 * being requested. 337 * caddr_t data The pointer to the user data argument 338 * provided with the command. 339 * int flag The file open flags (e.g. FREAD). 340 * struct proc *p The current process pointer for the 341 * operation. 342 * 343 * Returns: 0 Most 'get' operations can't fail, and 344 * therefore return this. 345 * ENOTTY TIOCGSID may return this when you 346 * attempt to get the session ID for a 347 * terminal with no associated session, 348 * or for which there is a session, but 349 * no session leader. 350 * ENOTTY If the command cannot be handled at 351 * this layer, this will be returned. 352 * * Any value returned by ttioctl_locked(), 353 * if a set command is requested. 354 * 355 * Notes: The process pointer may be a proxy on whose behalf we are 356 * operating, so it is not safe to simply use current_process() 357 * instead. 358 */ 359/*ARGSUSED*/ 360__private_extern__ int 361ttcompat(struct tty *tp, u_long com, caddr_t data, int flag, struct proc *p) 362{ 363 switch (com) { 364 case TIOCSETP: 365 case TIOCSETN: 366 case TIOCSETC: 367 case TIOCSLTC: 368 case TIOCLBIS: 369 case TIOCLBIC: 370 case TIOCLSET: 371 /* 372 * See ttsetcompat() for a full description of these command 373 * values and their meanings. 374 */ 375 { 376 struct termios term; 377 int error; 378 379 term = tp->t_termios; 380 if ((error = ttsetcompat(tp, &com, data, &term)) != 0) 381 return error; 382 return ttioctl_locked(tp, com, (caddr_t) &term, flag, p); 383 } 384 case TIOCGETP: 385 /* 386 * Get the current input and output speeds, and device 387 * flags, into the structure pointed to by 'data'. 388 */ 389 { 390 register struct sgttyb *sg = (struct sgttyb *)data; 391 register cc_t *cc = tp->t_cc; 392 393 sg->sg_ospeed = ttcompatspeedtab(tp->t_ospeed, compatspeeds); 394 if (tp->t_ispeed == 0) 395 sg->sg_ispeed = sg->sg_ospeed; 396 else 397 sg->sg_ispeed = ttcompatspeedtab(tp->t_ispeed, compatspeeds); 398 sg->sg_erase = cc[VERASE]; 399 sg->sg_kill = cc[VKILL]; 400 sg->sg_flags = tp->t_flags = ttcompatgetflags(tp); 401 break; 402 } 403 case TIOCGETC: 404 /* 405 * Get the terminal control characters into the struct 406 * tchars that 'data' points to. 407 */ 408 { 409 struct tchars *tc = (struct tchars *)data; 410 register cc_t *cc = tp->t_cc; 411 412 tc->t_intrc = cc[VINTR]; 413 tc->t_quitc = cc[VQUIT]; 414 tc->t_startc = cc[VSTART]; 415 tc->t_stopc = cc[VSTOP]; 416 tc->t_eofc = cc[VEOF]; 417 tc->t_brkc = cc[VEOL]; 418 break; 419 } 420 case TIOCGLTC: 421 /* 422 * Get the terminal control characters into the struct 423 * ltchars that 'data' points to. 424 */ 425 { 426 struct ltchars *ltc = (struct ltchars *)data; 427 register cc_t *cc = tp->t_cc; 428 429 ltc->t_suspc = cc[VSUSP]; 430 ltc->t_dsuspc = cc[VDSUSP]; 431 ltc->t_rprntc = cc[VREPRINT]; 432 ltc->t_flushc = cc[VDISCARD]; 433 ltc->t_werasc = cc[VWERASE]; 434 ltc->t_lnextc = cc[VLNEXT]; 435 break; 436 } 437 case TIOCLGET: 438 /* 439 * Get the terminal state local flags word into the 16 bit 440 * value pointed to by 'data'. 441 */ 442 tp->t_flags = 443 (ttcompatgetflags(tp) & 0xffff0000UL) 444 | (tp->t_flags & 0xffff); 445 *(int *)data = tp->t_flags>>16; 446 break; 447 448 case OTIOCGETD: 449 /* 450 * Get the current line discipline into the int pointed to 451 * by 'data'. 452 */ 453 *(int *)data = tp->t_line ? tp->t_line : 2; 454 break; 455 456 case OTIOCSETD: 457 /* 458 * Set the current line discipline based on the value of the 459 * int pointed to by 'data'. 460 */ 461 { 462 int ldisczero = 0; 463 464 return (ttioctl_locked(tp, TIOCSETD, 465 *(int *)data == 2 ? (caddr_t)&ldisczero : data, flag, p)); 466 } 467 468 case OTIOCCONS: 469 /* 470 * Become the console device. 471 */ 472 *(int *)data = 1; 473 return (ttioctl_locked(tp, TIOCCONS, data, flag, p)); 474 475 case TIOCGSID: 476 /* 477 * Get the current session ID (controlling process' PID). 478 */ 479 if (tp->t_session == NULL) 480 return ENOTTY; 481 482 if (tp->t_session->s_leader == NULL) 483 return ENOTTY; 484 485 *(int *) data = tp->t_session->s_leader->p_pid; 486 break; 487 488 default: 489 /* 490 * This ioctl is not handled at this layer. 491 */ 492 return (ENOTTY); 493 } 494 495 /* 496 * Successful 'get' operation. 497 */ 498 return (0); 499} 500 501/* 502 * ttcompatgetflags 503 * 504 * Description: Get the terminal state local flags, device flags, and current 505 * speed code for the device (all 32 bits are returned). 506 * 507 * Parameters struct tty *tp The tty on which the operation is 508 * being performed. 509 * 510 * Returns: * Integer value corresponding to the 511 * current terminal state local flags 512 * word. 513 * 514 * Notes: Caller is responsible for breaking these bits back out into 515 * separate 16 bit filelds, if that's what was actually desired. 516 */ 517static int 518ttcompatgetflags(struct tty *tp) 519{ 520 register tcflag_t iflag = tp->t_iflag; 521 register tcflag_t lflag = tp->t_lflag; 522 register tcflag_t oflag = tp->t_oflag; 523 register tcflag_t cflag = tp->t_cflag; 524 register int flags = 0; 525 526 if (iflag&IXOFF) 527 flags |= TANDEM; 528 if (iflag&ICRNL || oflag&ONLCR) 529 flags |= CRMOD; 530 if ((cflag&CSIZE) == CS8) { 531 flags |= PASS8; 532 if (iflag&ISTRIP) 533 flags |= ANYP; 534 } 535 else if (cflag&PARENB) { 536 if (iflag&INPCK) { 537 if (cflag&PARODD) 538 flags |= ODDP; 539 else 540 flags |= EVENP; 541 } else 542 flags |= EVENP | ODDP; 543 } 544 545 if ((lflag&ICANON) == 0) { 546 /* fudge */ 547 if (iflag&(INPCK|ISTRIP|IXON) || lflag&(IEXTEN|ISIG) 548 || (cflag&(CSIZE|PARENB)) != CS8) 549 flags |= CBREAK; 550 else 551 flags |= RAW; 552 } 553 if (!(flags&RAW) && !(oflag&OPOST) && (cflag&(CSIZE|PARENB)) == CS8) 554 flags |= LITOUT; 555 if (cflag&MDMBUF) 556 flags |= MDMBUF; 557 if ((cflag&HUPCL) == 0) 558 flags |= NOHANG; 559 if (oflag&OXTABS) 560 flags |= XTABS; 561 if (lflag&ECHOE) 562 flags |= CRTERA|CRTBS; 563 if (lflag&ECHOKE) 564 flags |= CRTKIL|CRTBS; 565 if (lflag&ECHOPRT) 566 flags |= PRTERA; 567 if (lflag&ECHOCTL) 568 flags |= CTLECH; 569 if ((iflag&IXANY) == 0) 570 flags |= DECCTQ; 571 flags |= lflag&(ECHO|TOSTOP|FLUSHO|PENDIN|NOFLSH); 572 return (flags); 573} 574 575/* 576 * ttcompatsetflags 577 * 578 * Description: Given a set of compatability flags, convert the compatability 579 * flags in the terminal flags fields into canonical flags in the 580 * provided termios struct. 581 * 582 * Parameters: struct tty *tp The tty on which the operation is 583 * being performed. 584 * struct termios *t The termios structure into which to 585 * return the converted flags. 586 * 587 * Returns: void (implicit: *t, modified) 588 */ 589static void 590ttcompatsetflags(struct tty *tp, struct termios *t) 591{ 592 register int flags = tp->t_flags; 593 register tcflag_t iflag = t->c_iflag; 594 register tcflag_t oflag = t->c_oflag; 595 register tcflag_t lflag = t->c_lflag; 596 register tcflag_t cflag = t->c_cflag; 597 598 if (flags & RAW) { 599 iflag = IGNBRK; 600 lflag &= ~(ECHOCTL|ISIG|ICANON|IEXTEN); 601 } else { 602 iflag &= ~(PARMRK|IGNPAR|IGNCR|INLCR); 603 iflag |= BRKINT|IXON|IMAXBEL; 604 lflag |= ISIG|IEXTEN|ECHOCTL; /* XXX was echoctl on ? */ 605 if (flags & XTABS) 606 oflag |= OXTABS; 607 else 608 oflag &= ~OXTABS; 609 if (flags & CBREAK) 610 lflag &= ~ICANON; 611 else 612 lflag |= ICANON; 613 if (flags&CRMOD) { 614 iflag |= ICRNL; 615 oflag |= ONLCR; 616 } else { 617 iflag &= ~ICRNL; 618 oflag &= ~ONLCR; 619 } 620 } 621 if (flags&ECHO) 622 lflag |= ECHO; 623 else 624 lflag &= ~ECHO; 625 626 cflag &= ~(CSIZE|PARENB); 627 if (flags&(RAW|LITOUT|PASS8)) { 628 cflag |= CS8; 629 if (!(flags&(RAW|PASS8)) 630 || (flags&(RAW|PASS8|ANYP)) == (PASS8|ANYP)) 631 iflag |= ISTRIP; 632 else 633 iflag &= ~ISTRIP; 634 if (flags&(RAW|LITOUT)) 635 oflag &= ~OPOST; 636 else 637 oflag |= OPOST; 638 } else { 639 cflag |= CS7|PARENB; 640 iflag |= ISTRIP; 641 oflag |= OPOST; 642 } 643 /* XXX don't set INPCK if RAW or PASS8? */ 644 if ((flags&(EVENP|ODDP)) == EVENP) { 645 iflag |= INPCK; 646 cflag &= ~PARODD; 647 } else if ((flags&(EVENP|ODDP)) == ODDP) { 648 iflag |= INPCK; 649 cflag |= PARODD; 650 } else 651 iflag &= ~INPCK; 652 if (flags&TANDEM) 653 iflag |= IXOFF; 654 else 655 iflag &= ~IXOFF; 656 if ((flags&DECCTQ) == 0) 657 iflag |= IXANY; 658 else 659 iflag &= ~IXANY; 660 t->c_iflag = iflag; 661 t->c_oflag = oflag; 662 t->c_lflag = lflag; 663 t->c_cflag = cflag; 664} 665 666/* 667 * ttcompatsetlflags 668 * 669 * Description: Given a set of compatability terminal state local flags, 670 * convert the compatability flags in the terminal flags 671 * fields into canonical flags in the provided termios struct. 672 * 673 * Parameters: struct tty *tp The tty on which the operation is 674 * being performed. 675 * struct termios *t The termios structure into which to 676 * return the converted local flags. 677 * 678 * Returns: void (implicit: *t, modified) 679 */ 680static void 681ttcompatsetlflags(struct tty *tp, struct termios *t) 682{ 683 register int flags = tp->t_flags; 684 register tcflag_t iflag = t->c_iflag; 685 register tcflag_t oflag = t->c_oflag; 686 register tcflag_t lflag = t->c_lflag; 687 register tcflag_t cflag = t->c_cflag; 688 689 iflag &= ~(PARMRK|IGNPAR|IGNCR|INLCR); 690 if (flags&CRTERA) 691 lflag |= ECHOE; 692 else 693 lflag &= ~ECHOE; 694 if (flags&CRTKIL) 695 lflag |= ECHOKE; 696 else 697 lflag &= ~ECHOKE; 698 if (flags&PRTERA) 699 lflag |= ECHOPRT; 700 else 701 lflag &= ~ECHOPRT; 702 if (flags&CTLECH) 703 lflag |= ECHOCTL; 704 else 705 lflag &= ~ECHOCTL; 706 if (flags&TANDEM) 707 iflag |= IXOFF; 708 else 709 iflag &= ~IXOFF; 710 if ((flags&DECCTQ) == 0) 711 iflag |= IXANY; 712 else 713 iflag &= ~IXANY; 714 if (flags & MDMBUF) 715 cflag |= MDMBUF; 716 else 717 cflag &= ~MDMBUF; 718 if (flags&NOHANG) 719 cflag &= ~HUPCL; 720 else 721 cflag |= HUPCL; 722 lflag &= ~(TOSTOP|FLUSHO|PENDIN|NOFLSH); 723 lflag |= flags&(TOSTOP|FLUSHO|PENDIN|NOFLSH); 724 725 /* 726 * The next if-else statement is copied from above so don't bother 727 * checking it separately. We could avoid fiddlling with the 728 * character size if the mode is already RAW or if neither the 729 * LITOUT bit or the PASS8 bit is being changed, but the delta of 730 * the change is not available here and skipping the RAW case would 731 * make the code different from above. 732 */ 733 cflag &= ~(CSIZE|PARENB); 734 if (flags&(RAW|LITOUT|PASS8)) { 735 cflag |= CS8; 736 if (!(flags&(RAW|PASS8)) 737 || (flags&(RAW|PASS8|ANYP)) == (PASS8|ANYP)) 738 iflag |= ISTRIP; 739 else 740 iflag &= ~ISTRIP; 741 if (flags&(RAW|LITOUT)) 742 oflag &= ~OPOST; 743 else 744 oflag |= OPOST; 745 } else { 746 cflag |= CS7|PARENB; 747 iflag |= ISTRIP; 748 oflag |= OPOST; 749 } 750 t->c_iflag = iflag; 751 t->c_oflag = oflag; 752 t->c_lflag = lflag; 753 t->c_cflag = cflag; 754} 755