hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/tty/tty_ioctl.c
....@@ -21,6 +21,7 @@
2121 #include <linux/bitops.h>
2222 #include <linux/mutex.h>
2323 #include <linux/compat.h>
24
+#include "tty.h"
2425
2526 #include <asm/io.h>
2627 #include <linux/uaccess.h>
....@@ -397,21 +398,42 @@
397398 tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios);
398399 tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios);
399400
400
- ld = tty_ldisc_ref(tty);
401
+ if (opt & (TERMIOS_FLUSH|TERMIOS_WAIT)) {
402
+retry_write_wait:
403
+ retval = wait_event_interruptible(tty->write_wait, !tty_chars_in_buffer(tty));
404
+ if (retval < 0)
405
+ return retval;
401406
402
- if (ld != NULL) {
403
- if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
404
- ld->ops->flush_buffer(tty);
405
- tty_ldisc_deref(ld);
407
+ if (tty_write_lock(tty, 0) < 0)
408
+ goto retry_write_wait;
409
+
410
+ /* Racing writer? */
411
+ if (tty_chars_in_buffer(tty)) {
412
+ tty_write_unlock(tty);
413
+ goto retry_write_wait;
414
+ }
415
+
416
+ ld = tty_ldisc_ref(tty);
417
+ if (ld != NULL) {
418
+ if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
419
+ ld->ops->flush_buffer(tty);
420
+ tty_ldisc_deref(ld);
421
+ }
422
+
423
+ if ((opt & TERMIOS_WAIT) && tty->ops->wait_until_sent) {
424
+ tty->ops->wait_until_sent(tty, 0);
425
+ if (signal_pending(current)) {
426
+ tty_write_unlock(tty);
427
+ return -ERESTARTSYS;
428
+ }
429
+ }
430
+
431
+ tty_set_termios(tty, &tmp_termios);
432
+
433
+ tty_write_unlock(tty);
434
+ } else {
435
+ tty_set_termios(tty, &tmp_termios);
406436 }
407
-
408
- if (opt & TERMIOS_WAIT) {
409
- tty_wait_until_sent(tty, 0);
410
- if (signal_pending(current))
411
- return -ERESTARTSYS;
412
- }
413
-
414
- tty_set_termios(tty, &tmp_termios);
415437
416438 /* FIXME: Arguably if tmp_termios == tty->termios AND the
417439 actual requested termios was not tmp_termios then we may
....@@ -442,51 +464,6 @@
442464 return -EFAULT;
443465 return 0;
444466 }
445
-
446
-
447
-#ifdef TCGETX
448
-
449
-/**
450
- * set_termiox - set termiox fields if possible
451
- * @tty: terminal
452
- * @arg: termiox structure from user
453
- * @opt: option flags for ioctl type
454
- *
455
- * Implement the device calling points for the SYS5 termiox ioctl
456
- * interface in Linux
457
- */
458
-
459
-static int set_termiox(struct tty_struct *tty, void __user *arg, int opt)
460
-{
461
- struct termiox tnew;
462
- struct tty_ldisc *ld;
463
-
464
- if (tty->termiox == NULL)
465
- return -EINVAL;
466
- if (copy_from_user(&tnew, arg, sizeof(struct termiox)))
467
- return -EFAULT;
468
-
469
- ld = tty_ldisc_ref(tty);
470
- if (ld != NULL) {
471
- if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
472
- ld->ops->flush_buffer(tty);
473
- tty_ldisc_deref(ld);
474
- }
475
- if (opt & TERMIOS_WAIT) {
476
- tty_wait_until_sent(tty, 0);
477
- if (signal_pending(current))
478
- return -ERESTARTSYS;
479
- }
480
-
481
- down_write(&tty->termios_rwsem);
482
- if (tty->ops->set_termiox)
483
- tty->ops->set_termiox(tty, &tnew);
484
- up_write(&tty->termios_rwsem);
485
- return 0;
486
-}
487
-
488
-#endif
489
-
490467
491468 #ifdef TIOCGETP
492469 /*
....@@ -815,24 +792,12 @@
815792 return ret;
816793 #endif
817794 #ifdef TCGETX
818
- case TCGETX: {
819
- struct termiox ktermx;
820
- if (real_tty->termiox == NULL)
821
- return -EINVAL;
822
- down_read(&real_tty->termios_rwsem);
823
- memcpy(&ktermx, real_tty->termiox, sizeof(struct termiox));
824
- up_read(&real_tty->termios_rwsem);
825
- if (copy_to_user(p, &ktermx, sizeof(struct termiox)))
826
- ret = -EFAULT;
827
- return ret;
828
- }
795
+ case TCGETX:
829796 case TCSETX:
830
- return set_termiox(real_tty, p, 0);
831797 case TCSETXW:
832
- return set_termiox(real_tty, p, TERMIOS_WAIT);
833798 case TCSETXF:
834
- return set_termiox(real_tty, p, TERMIOS_FLUSH);
835
-#endif
799
+ return -ENOTTY;
800
+#endif
836801 case TIOCGSOFTCAR:
837802 copy_termios(real_tty, &kterm);
838803 ret = put_user((kterm.c_cflag & CLOCAL) ? 1 : 0,
....@@ -866,7 +831,7 @@
866831 ld->ops->flush_buffer(tty);
867832 tty_unthrottle(tty);
868833 }
869
- /* fall through */
834
+ fallthrough;
870835 case TCOFLUSH:
871836 tty_driver_flush_buffer(tty);
872837 break;
....@@ -941,19 +906,3 @@
941906 }
942907 }
943908 EXPORT_SYMBOL(n_tty_ioctl_helper);
944
-
945
-#ifdef CONFIG_COMPAT
946
-long n_tty_compat_ioctl_helper(struct tty_struct *tty, struct file *file,
947
- unsigned int cmd, unsigned long arg)
948
-{
949
- switch (cmd) {
950
- case TIOCGLCKTRMIOS:
951
- case TIOCSLCKTRMIOS:
952
- return tty_mode_ioctl(tty, file, cmd, (unsigned long) compat_ptr(arg));
953
- default:
954
- return -ENOIOCTLCMD;
955
- }
956
-}
957
-EXPORT_SYMBOL(n_tty_compat_ioctl_helper);
958
-#endif
959
-