tty_ioctl.c (23181B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds 4 * 5 * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines 6 * which can be dynamically activated and de-activated by the line 7 * discipline handling modules (like SLIP). 8 */ 9 10#include <linux/types.h> 11#include <linux/termios.h> 12#include <linux/errno.h> 13#include <linux/sched/signal.h> 14#include <linux/kernel.h> 15#include <linux/major.h> 16#include <linux/tty.h> 17#include <linux/fcntl.h> 18#include <linux/string.h> 19#include <linux/mm.h> 20#include <linux/module.h> 21#include <linux/bitops.h> 22#include <linux/mutex.h> 23#include <linux/compat.h> 24#include "tty.h" 25 26#include <asm/io.h> 27#include <linux/uaccess.h> 28 29#undef TTY_DEBUG_WAIT_UNTIL_SENT 30 31#ifdef TTY_DEBUG_WAIT_UNTIL_SENT 32# define tty_debug_wait_until_sent(tty, f, args...) tty_debug(tty, f, ##args) 33#else 34# define tty_debug_wait_until_sent(tty, f, args...) do {} while (0) 35#endif 36 37#undef DEBUG 38 39/* 40 * Internal flag options for termios setting behavior 41 */ 42#define TERMIOS_FLUSH 1 43#define TERMIOS_WAIT 2 44#define TERMIOS_TERMIO 4 45#define TERMIOS_OLD 8 46 47 48/** 49 * tty_chars_in_buffer - characters pending 50 * @tty: terminal 51 * 52 * Return the number of bytes of data in the device private 53 * output queue. If no private method is supplied there is assumed 54 * to be no queue on the device. 55 */ 56 57unsigned int tty_chars_in_buffer(struct tty_struct *tty) 58{ 59 if (tty->ops->chars_in_buffer) 60 return tty->ops->chars_in_buffer(tty); 61 return 0; 62} 63EXPORT_SYMBOL(tty_chars_in_buffer); 64 65/** 66 * tty_write_room - write queue space 67 * @tty: terminal 68 * 69 * Return the number of bytes that can be queued to this device 70 * at the present time. The result should be treated as a guarantee 71 * and the driver cannot offer a value it later shrinks by more than 72 * the number of bytes written. If no method is provided 2K is always 73 * returned and data may be lost as there will be no flow control. 74 */ 75 76unsigned int tty_write_room(struct tty_struct *tty) 77{ 78 if (tty->ops->write_room) 79 return tty->ops->write_room(tty); 80 return 2048; 81} 82EXPORT_SYMBOL(tty_write_room); 83 84/** 85 * tty_driver_flush_buffer - discard internal buffer 86 * @tty: terminal 87 * 88 * Discard the internal output buffer for this device. If no method 89 * is provided then either the buffer cannot be hardware flushed or 90 * there is no buffer driver side. 91 */ 92void tty_driver_flush_buffer(struct tty_struct *tty) 93{ 94 if (tty->ops->flush_buffer) 95 tty->ops->flush_buffer(tty); 96} 97EXPORT_SYMBOL(tty_driver_flush_buffer); 98 99/** 100 * tty_unthrottle - flow control 101 * @tty: terminal 102 * 103 * Indicate that a tty may continue transmitting data down the stack. 104 * Takes the termios rwsem to protect against parallel throttle/unthrottle 105 * and also to ensure the driver can consistently reference its own 106 * termios data at this point when implementing software flow control. 107 * 108 * Drivers should however remember that the stack can issue a throttle, 109 * then change flow control method, then unthrottle. 110 */ 111 112void tty_unthrottle(struct tty_struct *tty) 113{ 114 down_write(&tty->termios_rwsem); 115 if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && 116 tty->ops->unthrottle) 117 tty->ops->unthrottle(tty); 118 tty->flow_change = 0; 119 up_write(&tty->termios_rwsem); 120} 121EXPORT_SYMBOL(tty_unthrottle); 122 123/** 124 * tty_throttle_safe - flow control 125 * @tty: terminal 126 * 127 * Indicate that a tty should stop transmitting data down the stack. 128 * tty_throttle_safe will only attempt throttle if tty->flow_change is 129 * TTY_THROTTLE_SAFE. Prevents an accidental throttle due to race 130 * conditions when throttling is conditional on factors evaluated prior to 131 * throttling. 132 * 133 * Returns 0 if tty is throttled (or was already throttled) 134 */ 135 136int tty_throttle_safe(struct tty_struct *tty) 137{ 138 int ret = 0; 139 140 mutex_lock(&tty->throttle_mutex); 141 if (!tty_throttled(tty)) { 142 if (tty->flow_change != TTY_THROTTLE_SAFE) 143 ret = 1; 144 else { 145 set_bit(TTY_THROTTLED, &tty->flags); 146 if (tty->ops->throttle) 147 tty->ops->throttle(tty); 148 } 149 } 150 mutex_unlock(&tty->throttle_mutex); 151 152 return ret; 153} 154 155/** 156 * tty_unthrottle_safe - flow control 157 * @tty: terminal 158 * 159 * Similar to tty_unthrottle() but will only attempt unthrottle 160 * if tty->flow_change is TTY_UNTHROTTLE_SAFE. Prevents an accidental 161 * unthrottle due to race conditions when unthrottling is conditional 162 * on factors evaluated prior to unthrottling. 163 * 164 * Returns 0 if tty is unthrottled (or was already unthrottled) 165 */ 166 167int tty_unthrottle_safe(struct tty_struct *tty) 168{ 169 int ret = 0; 170 171 mutex_lock(&tty->throttle_mutex); 172 if (tty_throttled(tty)) { 173 if (tty->flow_change != TTY_UNTHROTTLE_SAFE) 174 ret = 1; 175 else { 176 clear_bit(TTY_THROTTLED, &tty->flags); 177 if (tty->ops->unthrottle) 178 tty->ops->unthrottle(tty); 179 } 180 } 181 mutex_unlock(&tty->throttle_mutex); 182 183 return ret; 184} 185 186/** 187 * tty_wait_until_sent - wait for I/O to finish 188 * @tty: tty we are waiting for 189 * @timeout: how long we will wait 190 * 191 * Wait for characters pending in a tty driver to hit the wire, or 192 * for a timeout to occur (eg due to flow control) 193 * 194 * Locking: none 195 */ 196 197void tty_wait_until_sent(struct tty_struct *tty, long timeout) 198{ 199 tty_debug_wait_until_sent(tty, "wait until sent, timeout=%ld\n", timeout); 200 201 if (!timeout) 202 timeout = MAX_SCHEDULE_TIMEOUT; 203 204 timeout = wait_event_interruptible_timeout(tty->write_wait, 205 !tty_chars_in_buffer(tty), timeout); 206 if (timeout <= 0) 207 return; 208 209 if (timeout == MAX_SCHEDULE_TIMEOUT) 210 timeout = 0; 211 212 if (tty->ops->wait_until_sent) 213 tty->ops->wait_until_sent(tty, timeout); 214} 215EXPORT_SYMBOL(tty_wait_until_sent); 216 217 218/* 219 * Termios Helper Methods 220 */ 221 222static void unset_locked_termios(struct tty_struct *tty, struct ktermios *old) 223{ 224 struct ktermios *termios = &tty->termios; 225 struct ktermios *locked = &tty->termios_locked; 226 int i; 227 228#define NOSET_MASK(x, y, z) (x = ((x) & ~(z)) | ((y) & (z))) 229 230 NOSET_MASK(termios->c_iflag, old->c_iflag, locked->c_iflag); 231 NOSET_MASK(termios->c_oflag, old->c_oflag, locked->c_oflag); 232 NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag); 233 NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag); 234 termios->c_line = locked->c_line ? old->c_line : termios->c_line; 235 for (i = 0; i < NCCS; i++) 236 termios->c_cc[i] = locked->c_cc[i] ? 237 old->c_cc[i] : termios->c_cc[i]; 238 /* FIXME: What should we do for i/ospeed */ 239} 240 241/** 242 * tty_termios_copy_hw - copy hardware settings 243 * @new: New termios 244 * @old: Old termios 245 * 246 * Propagate the hardware specific terminal setting bits from 247 * the old termios structure to the new one. This is used in cases 248 * where the hardware does not support reconfiguration or as a helper 249 * in some cases where only minimal reconfiguration is supported 250 */ 251 252void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old) 253{ 254 /* The bits a dumb device handles in software. Smart devices need 255 to always provide a set_termios method */ 256 new->c_cflag &= HUPCL | CREAD | CLOCAL; 257 new->c_cflag |= old->c_cflag & ~(HUPCL | CREAD | CLOCAL); 258 new->c_ispeed = old->c_ispeed; 259 new->c_ospeed = old->c_ospeed; 260} 261EXPORT_SYMBOL(tty_termios_copy_hw); 262 263/** 264 * tty_termios_hw_change - check for setting change 265 * @a: termios 266 * @b: termios to compare 267 * 268 * Check if any of the bits that affect a dumb device have changed 269 * between the two termios structures, or a speed change is needed. 270 */ 271 272int tty_termios_hw_change(const struct ktermios *a, const struct ktermios *b) 273{ 274 if (a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed) 275 return 1; 276 if ((a->c_cflag ^ b->c_cflag) & ~(HUPCL | CREAD | CLOCAL)) 277 return 1; 278 return 0; 279} 280EXPORT_SYMBOL(tty_termios_hw_change); 281 282/** 283 * tty_get_char_size - get size of a character 284 * @cflag: termios cflag value 285 * 286 * Get the size (in bits) of a character depending on @cflag's %CSIZE 287 * setting. 288 */ 289unsigned char tty_get_char_size(unsigned int cflag) 290{ 291 switch (cflag & CSIZE) { 292 case CS5: 293 return 5; 294 case CS6: 295 return 6; 296 case CS7: 297 return 7; 298 case CS8: 299 default: 300 return 8; 301 } 302} 303EXPORT_SYMBOL_GPL(tty_get_char_size); 304 305/** 306 * tty_get_frame_size - get size of a frame 307 * @cflag: termios cflag value 308 * 309 * Get the size (in bits) of a frame depending on @cflag's %CSIZE, %CSTOPB, 310 * and %PARENB setting. The result is a sum of character size, start and 311 * stop bits -- one bit each -- second stop bit (if set), and parity bit 312 * (if set). 313 */ 314unsigned char tty_get_frame_size(unsigned int cflag) 315{ 316 unsigned char bits = 2 + tty_get_char_size(cflag); 317 318 if (cflag & CSTOPB) 319 bits++; 320 if (cflag & PARENB) 321 bits++; 322 323 return bits; 324} 325EXPORT_SYMBOL_GPL(tty_get_frame_size); 326 327/** 328 * tty_set_termios - update termios values 329 * @tty: tty to update 330 * @new_termios: desired new value 331 * 332 * Perform updates to the termios values set on this terminal. 333 * A master pty's termios should never be set. 334 * 335 * Locking: termios_rwsem 336 */ 337 338int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios) 339{ 340 struct ktermios old_termios; 341 struct tty_ldisc *ld; 342 343 WARN_ON(tty->driver->type == TTY_DRIVER_TYPE_PTY && 344 tty->driver->subtype == PTY_TYPE_MASTER); 345 /* 346 * Perform the actual termios internal changes under lock. 347 */ 348 349 350 /* FIXME: we need to decide on some locking/ordering semantics 351 for the set_termios notification eventually */ 352 down_write(&tty->termios_rwsem); 353 old_termios = tty->termios; 354 tty->termios = *new_termios; 355 unset_locked_termios(tty, &old_termios); 356 357 if (tty->ops->set_termios) 358 tty->ops->set_termios(tty, &old_termios); 359 else 360 tty_termios_copy_hw(&tty->termios, &old_termios); 361 362 ld = tty_ldisc_ref(tty); 363 if (ld != NULL) { 364 if (ld->ops->set_termios) 365 ld->ops->set_termios(tty, &old_termios); 366 tty_ldisc_deref(ld); 367 } 368 up_write(&tty->termios_rwsem); 369 return 0; 370} 371EXPORT_SYMBOL_GPL(tty_set_termios); 372 373/** 374 * set_termios - set termios values for a tty 375 * @tty: terminal device 376 * @arg: user data 377 * @opt: option information 378 * 379 * Helper function to prepare termios data and run necessary other 380 * functions before using tty_set_termios to do the actual changes. 381 * 382 * Locking: 383 * Called functions take ldisc and termios_rwsem locks 384 */ 385 386static int set_termios(struct tty_struct *tty, void __user *arg, int opt) 387{ 388 struct ktermios tmp_termios; 389 struct tty_ldisc *ld; 390 int retval = tty_check_change(tty); 391 392 if (retval) 393 return retval; 394 395 down_read(&tty->termios_rwsem); 396 tmp_termios = tty->termios; 397 up_read(&tty->termios_rwsem); 398 399 if (opt & TERMIOS_TERMIO) { 400 if (user_termio_to_kernel_termios(&tmp_termios, 401 (struct termio __user *)arg)) 402 return -EFAULT; 403#ifdef TCGETS2 404 } else if (opt & TERMIOS_OLD) { 405 if (user_termios_to_kernel_termios_1(&tmp_termios, 406 (struct termios __user *)arg)) 407 return -EFAULT; 408 } else { 409 if (user_termios_to_kernel_termios(&tmp_termios, 410 (struct termios2 __user *)arg)) 411 return -EFAULT; 412 } 413#else 414 } else if (user_termios_to_kernel_termios(&tmp_termios, 415 (struct termios __user *)arg)) 416 return -EFAULT; 417#endif 418 419 /* If old style Bfoo values are used then load c_ispeed/c_ospeed 420 * with the real speed so its unconditionally usable */ 421 tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios); 422 tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios); 423 424 ld = tty_ldisc_ref(tty); 425 426 if (ld != NULL) { 427 if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer) 428 ld->ops->flush_buffer(tty); 429 tty_ldisc_deref(ld); 430 } 431 432 if (opt & TERMIOS_WAIT) { 433 tty_wait_until_sent(tty, 0); 434 if (signal_pending(current)) 435 return -ERESTARTSYS; 436 } 437 438 tty_set_termios(tty, &tmp_termios); 439 440 /* FIXME: Arguably if tmp_termios == tty->termios AND the 441 actual requested termios was not tmp_termios then we may 442 want to return an error as no user requested change has 443 succeeded */ 444 return 0; 445} 446 447static void copy_termios(struct tty_struct *tty, struct ktermios *kterm) 448{ 449 down_read(&tty->termios_rwsem); 450 *kterm = tty->termios; 451 up_read(&tty->termios_rwsem); 452} 453 454static void copy_termios_locked(struct tty_struct *tty, struct ktermios *kterm) 455{ 456 down_read(&tty->termios_rwsem); 457 *kterm = tty->termios_locked; 458 up_read(&tty->termios_rwsem); 459} 460 461static int get_termio(struct tty_struct *tty, struct termio __user *termio) 462{ 463 struct ktermios kterm; 464 copy_termios(tty, &kterm); 465 if (kernel_termios_to_user_termio(termio, &kterm)) 466 return -EFAULT; 467 return 0; 468} 469 470#ifdef TIOCGETP 471/* 472 * These are deprecated, but there is limited support.. 473 * 474 * The "sg_flags" translation is a joke.. 475 */ 476static int get_sgflags(struct tty_struct *tty) 477{ 478 int flags = 0; 479 480 if (!L_ICANON(tty)) { 481 if (L_ISIG(tty)) 482 flags |= 0x02; /* cbreak */ 483 else 484 flags |= 0x20; /* raw */ 485 } 486 if (L_ECHO(tty)) 487 flags |= 0x08; /* echo */ 488 if (O_OPOST(tty)) 489 if (O_ONLCR(tty)) 490 flags |= 0x10; /* crmod */ 491 return flags; 492} 493 494static int get_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb) 495{ 496 struct sgttyb tmp; 497 498 down_read(&tty->termios_rwsem); 499 tmp.sg_ispeed = tty->termios.c_ispeed; 500 tmp.sg_ospeed = tty->termios.c_ospeed; 501 tmp.sg_erase = tty->termios.c_cc[VERASE]; 502 tmp.sg_kill = tty->termios.c_cc[VKILL]; 503 tmp.sg_flags = get_sgflags(tty); 504 up_read(&tty->termios_rwsem); 505 506 return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0; 507} 508 509static void set_sgflags(struct ktermios *termios, int flags) 510{ 511 termios->c_iflag = ICRNL | IXON; 512 termios->c_oflag = 0; 513 termios->c_lflag = ISIG | ICANON; 514 if (flags & 0x02) { /* cbreak */ 515 termios->c_iflag = 0; 516 termios->c_lflag &= ~ICANON; 517 } 518 if (flags & 0x08) { /* echo */ 519 termios->c_lflag |= ECHO | ECHOE | ECHOK | 520 ECHOCTL | ECHOKE | IEXTEN; 521 } 522 if (flags & 0x10) { /* crmod */ 523 termios->c_oflag |= OPOST | ONLCR; 524 } 525 if (flags & 0x20) { /* raw */ 526 termios->c_iflag = 0; 527 termios->c_lflag &= ~(ISIG | ICANON); 528 } 529 if (!(termios->c_lflag & ICANON)) { 530 termios->c_cc[VMIN] = 1; 531 termios->c_cc[VTIME] = 0; 532 } 533} 534 535/** 536 * set_sgttyb - set legacy terminal values 537 * @tty: tty structure 538 * @sgttyb: pointer to old style terminal structure 539 * 540 * Updates a terminal from the legacy BSD style terminal information 541 * structure. 542 * 543 * Locking: termios_rwsem 544 */ 545 546static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb) 547{ 548 int retval; 549 struct sgttyb tmp; 550 struct ktermios termios; 551 552 retval = tty_check_change(tty); 553 if (retval) 554 return retval; 555 556 if (copy_from_user(&tmp, sgttyb, sizeof(tmp))) 557 return -EFAULT; 558 559 down_write(&tty->termios_rwsem); 560 termios = tty->termios; 561 termios.c_cc[VERASE] = tmp.sg_erase; 562 termios.c_cc[VKILL] = tmp.sg_kill; 563 set_sgflags(&termios, tmp.sg_flags); 564 /* Try and encode into Bfoo format */ 565 tty_termios_encode_baud_rate(&termios, termios.c_ispeed, 566 termios.c_ospeed); 567 up_write(&tty->termios_rwsem); 568 tty_set_termios(tty, &termios); 569 return 0; 570} 571#endif 572 573#ifdef TIOCGETC 574static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars) 575{ 576 struct tchars tmp; 577 578 down_read(&tty->termios_rwsem); 579 tmp.t_intrc = tty->termios.c_cc[VINTR]; 580 tmp.t_quitc = tty->termios.c_cc[VQUIT]; 581 tmp.t_startc = tty->termios.c_cc[VSTART]; 582 tmp.t_stopc = tty->termios.c_cc[VSTOP]; 583 tmp.t_eofc = tty->termios.c_cc[VEOF]; 584 tmp.t_brkc = tty->termios.c_cc[VEOL2]; /* what is brkc anyway? */ 585 up_read(&tty->termios_rwsem); 586 return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; 587} 588 589static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars) 590{ 591 struct tchars tmp; 592 593 if (copy_from_user(&tmp, tchars, sizeof(tmp))) 594 return -EFAULT; 595 down_write(&tty->termios_rwsem); 596 tty->termios.c_cc[VINTR] = tmp.t_intrc; 597 tty->termios.c_cc[VQUIT] = tmp.t_quitc; 598 tty->termios.c_cc[VSTART] = tmp.t_startc; 599 tty->termios.c_cc[VSTOP] = tmp.t_stopc; 600 tty->termios.c_cc[VEOF] = tmp.t_eofc; 601 tty->termios.c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */ 602 up_write(&tty->termios_rwsem); 603 return 0; 604} 605#endif 606 607#ifdef TIOCGLTC 608static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars) 609{ 610 struct ltchars tmp; 611 612 down_read(&tty->termios_rwsem); 613 tmp.t_suspc = tty->termios.c_cc[VSUSP]; 614 /* what is dsuspc anyway? */ 615 tmp.t_dsuspc = tty->termios.c_cc[VSUSP]; 616 tmp.t_rprntc = tty->termios.c_cc[VREPRINT]; 617 /* what is flushc anyway? */ 618 tmp.t_flushc = tty->termios.c_cc[VEOL2]; 619 tmp.t_werasc = tty->termios.c_cc[VWERASE]; 620 tmp.t_lnextc = tty->termios.c_cc[VLNEXT]; 621 up_read(&tty->termios_rwsem); 622 return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; 623} 624 625static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars) 626{ 627 struct ltchars tmp; 628 629 if (copy_from_user(&tmp, ltchars, sizeof(tmp))) 630 return -EFAULT; 631 632 down_write(&tty->termios_rwsem); 633 tty->termios.c_cc[VSUSP] = tmp.t_suspc; 634 /* what is dsuspc anyway? */ 635 tty->termios.c_cc[VEOL2] = tmp.t_dsuspc; 636 tty->termios.c_cc[VREPRINT] = tmp.t_rprntc; 637 /* what is flushc anyway? */ 638 tty->termios.c_cc[VEOL2] = tmp.t_flushc; 639 tty->termios.c_cc[VWERASE] = tmp.t_werasc; 640 tty->termios.c_cc[VLNEXT] = tmp.t_lnextc; 641 up_write(&tty->termios_rwsem); 642 return 0; 643} 644#endif 645 646/** 647 * tty_change_softcar - carrier change ioctl helper 648 * @tty: tty to update 649 * @arg: enable/disable CLOCAL 650 * 651 * Perform a change to the CLOCAL state and call into the driver 652 * layer to make it visible. All done with the termios rwsem 653 */ 654 655static int tty_change_softcar(struct tty_struct *tty, int arg) 656{ 657 int ret = 0; 658 int bit = arg ? CLOCAL : 0; 659 struct ktermios old; 660 661 down_write(&tty->termios_rwsem); 662 old = tty->termios; 663 tty->termios.c_cflag &= ~CLOCAL; 664 tty->termios.c_cflag |= bit; 665 if (tty->ops->set_termios) 666 tty->ops->set_termios(tty, &old); 667 if (C_CLOCAL(tty) != bit) 668 ret = -EINVAL; 669 up_write(&tty->termios_rwsem); 670 return ret; 671} 672 673/** 674 * tty_mode_ioctl - mode related ioctls 675 * @tty: tty for the ioctl 676 * @cmd: command 677 * @arg: ioctl argument 678 * 679 * Perform non line discipline specific mode control ioctls. This 680 * is designed to be called by line disciplines to ensure they provide 681 * consistent mode setting. 682 */ 683 684int tty_mode_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) 685{ 686 struct tty_struct *real_tty; 687 void __user *p = (void __user *)arg; 688 int ret = 0; 689 struct ktermios kterm; 690 691 if (tty->driver->type == TTY_DRIVER_TYPE_PTY && 692 tty->driver->subtype == PTY_TYPE_MASTER) 693 real_tty = tty->link; 694 else 695 real_tty = tty; 696 697 switch (cmd) { 698#ifdef TIOCGETP 699 case TIOCGETP: 700 return get_sgttyb(real_tty, (struct sgttyb __user *) arg); 701 case TIOCSETP: 702 case TIOCSETN: 703 return set_sgttyb(real_tty, (struct sgttyb __user *) arg); 704#endif 705#ifdef TIOCGETC 706 case TIOCGETC: 707 return get_tchars(real_tty, p); 708 case TIOCSETC: 709 return set_tchars(real_tty, p); 710#endif 711#ifdef TIOCGLTC 712 case TIOCGLTC: 713 return get_ltchars(real_tty, p); 714 case TIOCSLTC: 715 return set_ltchars(real_tty, p); 716#endif 717 case TCSETSF: 718 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD); 719 case TCSETSW: 720 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD); 721 case TCSETS: 722 return set_termios(real_tty, p, TERMIOS_OLD); 723#ifndef TCGETS2 724 case TCGETS: 725 copy_termios(real_tty, &kterm); 726 if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm)) 727 ret = -EFAULT; 728 return ret; 729#else 730 case TCGETS: 731 copy_termios(real_tty, &kterm); 732 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm)) 733 ret = -EFAULT; 734 return ret; 735 case TCGETS2: 736 copy_termios(real_tty, &kterm); 737 if (kernel_termios_to_user_termios((struct termios2 __user *)arg, &kterm)) 738 ret = -EFAULT; 739 return ret; 740 case TCSETSF2: 741 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT); 742 case TCSETSW2: 743 return set_termios(real_tty, p, TERMIOS_WAIT); 744 case TCSETS2: 745 return set_termios(real_tty, p, 0); 746#endif 747 case TCGETA: 748 return get_termio(real_tty, p); 749 case TCSETAF: 750 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_TERMIO); 751 case TCSETAW: 752 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO); 753 case TCSETA: 754 return set_termios(real_tty, p, TERMIOS_TERMIO); 755#ifndef TCGETS2 756 case TIOCGLCKTRMIOS: 757 copy_termios_locked(real_tty, &kterm); 758 if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm)) 759 ret = -EFAULT; 760 return ret; 761 case TIOCSLCKTRMIOS: 762 if (!capable(CAP_SYS_ADMIN)) 763 return -EPERM; 764 copy_termios_locked(real_tty, &kterm); 765 if (user_termios_to_kernel_termios(&kterm, 766 (struct termios __user *) arg)) 767 return -EFAULT; 768 down_write(&real_tty->termios_rwsem); 769 real_tty->termios_locked = kterm; 770 up_write(&real_tty->termios_rwsem); 771 return 0; 772#else 773 case TIOCGLCKTRMIOS: 774 copy_termios_locked(real_tty, &kterm); 775 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm)) 776 ret = -EFAULT; 777 return ret; 778 case TIOCSLCKTRMIOS: 779 if (!capable(CAP_SYS_ADMIN)) 780 return -EPERM; 781 copy_termios_locked(real_tty, &kterm); 782 if (user_termios_to_kernel_termios_1(&kterm, 783 (struct termios __user *) arg)) 784 return -EFAULT; 785 down_write(&real_tty->termios_rwsem); 786 real_tty->termios_locked = kterm; 787 up_write(&real_tty->termios_rwsem); 788 return ret; 789#endif 790#ifdef TCGETX 791 case TCGETX: 792 case TCSETX: 793 case TCSETXW: 794 case TCSETXF: 795 return -ENOTTY; 796#endif 797 case TIOCGSOFTCAR: 798 copy_termios(real_tty, &kterm); 799 ret = put_user((kterm.c_cflag & CLOCAL) ? 1 : 0, 800 (int __user *)arg); 801 return ret; 802 case TIOCSSOFTCAR: 803 if (get_user(arg, (unsigned int __user *) arg)) 804 return -EFAULT; 805 return tty_change_softcar(real_tty, arg); 806 default: 807 return -ENOIOCTLCMD; 808 } 809} 810EXPORT_SYMBOL_GPL(tty_mode_ioctl); 811 812 813/* Caller guarantees ldisc reference is held */ 814static int __tty_perform_flush(struct tty_struct *tty, unsigned long arg) 815{ 816 struct tty_ldisc *ld = tty->ldisc; 817 818 switch (arg) { 819 case TCIFLUSH: 820 if (ld && ld->ops->flush_buffer) { 821 ld->ops->flush_buffer(tty); 822 tty_unthrottle(tty); 823 } 824 break; 825 case TCIOFLUSH: 826 if (ld && ld->ops->flush_buffer) { 827 ld->ops->flush_buffer(tty); 828 tty_unthrottle(tty); 829 } 830 fallthrough; 831 case TCOFLUSH: 832 tty_driver_flush_buffer(tty); 833 break; 834 default: 835 return -EINVAL; 836 } 837 return 0; 838} 839 840int tty_perform_flush(struct tty_struct *tty, unsigned long arg) 841{ 842 struct tty_ldisc *ld; 843 int retval = tty_check_change(tty); 844 if (retval) 845 return retval; 846 847 ld = tty_ldisc_ref_wait(tty); 848 retval = __tty_perform_flush(tty, arg); 849 if (ld) 850 tty_ldisc_deref(ld); 851 return retval; 852} 853EXPORT_SYMBOL_GPL(tty_perform_flush); 854 855int n_tty_ioctl_helper(struct tty_struct *tty, unsigned int cmd, 856 unsigned long arg) 857{ 858 int retval; 859 860 switch (cmd) { 861 case TCXONC: 862 retval = tty_check_change(tty); 863 if (retval) 864 return retval; 865 switch (arg) { 866 case TCOOFF: 867 spin_lock_irq(&tty->flow.lock); 868 if (!tty->flow.tco_stopped) { 869 tty->flow.tco_stopped = true; 870 __stop_tty(tty); 871 } 872 spin_unlock_irq(&tty->flow.lock); 873 break; 874 case TCOON: 875 spin_lock_irq(&tty->flow.lock); 876 if (tty->flow.tco_stopped) { 877 tty->flow.tco_stopped = false; 878 __start_tty(tty); 879 } 880 spin_unlock_irq(&tty->flow.lock); 881 break; 882 case TCIOFF: 883 if (STOP_CHAR(tty) != __DISABLED_CHAR) 884 retval = tty_send_xchar(tty, STOP_CHAR(tty)); 885 break; 886 case TCION: 887 if (START_CHAR(tty) != __DISABLED_CHAR) 888 retval = tty_send_xchar(tty, START_CHAR(tty)); 889 break; 890 default: 891 return -EINVAL; 892 } 893 return retval; 894 case TCFLSH: 895 retval = tty_check_change(tty); 896 if (retval) 897 return retval; 898 return __tty_perform_flush(tty, arg); 899 default: 900 /* Try the mode commands */ 901 return tty_mode_ioctl(tty, cmd, arg); 902 } 903} 904EXPORT_SYMBOL(n_tty_ioctl_helper);