diff options
author | Alan Cox <alan@redhat.com> | 2008-10-13 05:44:17 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-13 12:51:44 -0400 |
commit | 47afa7a5a8a8fb9e60cdb6a3bd612e07c37e9d90 (patch) | |
tree | 4f07d3aed0a08516162e529df75a014bd0798f8f /drivers/char/tty_ioctl.c | |
parent | fe6e29fdb1a7b94891bbdd3c67358fe4ed14639d (diff) |
tty: some ICANON magic is in the wrong places
Move the set up on ldisc change into the ldisc
Move the INQ/OUTQ cases into the driver not in shared ioctl code where it
gives bogus answers for other ldisc values
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/tty_ioctl.c')
-rw-r--r-- | drivers/char/tty_ioctl.c | 42 |
1 files changed, 2 insertions, 40 deletions
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index 14cc19c344cc..a408c8e487ec 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c | |||
@@ -489,7 +489,6 @@ EXPORT_SYMBOL(tty_termios_hw_change); | |||
489 | 489 | ||
490 | static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) | 490 | static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) |
491 | { | 491 | { |
492 | int canon_change; | ||
493 | struct ktermios old_termios; | 492 | struct ktermios old_termios; |
494 | struct tty_ldisc *ld; | 493 | struct tty_ldisc *ld; |
495 | unsigned long flags; | 494 | unsigned long flags; |
@@ -505,18 +504,6 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) | |||
505 | old_termios = *tty->termios; | 504 | old_termios = *tty->termios; |
506 | *tty->termios = *new_termios; | 505 | *tty->termios = *new_termios; |
507 | unset_locked_termios(tty->termios, &old_termios, tty->termios_locked); | 506 | unset_locked_termios(tty->termios, &old_termios, tty->termios_locked); |
508 | canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON; | ||
509 | if (canon_change) { | ||
510 | memset(&tty->read_flags, 0, sizeof tty->read_flags); | ||
511 | tty->canon_head = tty->read_tail; | ||
512 | tty->canon_data = 0; | ||
513 | tty->erasing = 0; | ||
514 | } | ||
515 | |||
516 | /* This bit should be in the ldisc code */ | ||
517 | if (canon_change && !L_ICANON(tty) && tty->read_cnt) | ||
518 | /* Get characters left over from canonical mode. */ | ||
519 | wake_up_interruptible(&tty->read_wait); | ||
520 | 507 | ||
521 | /* See if packet mode change of state. */ | 508 | /* See if packet mode change of state. */ |
522 | if (tty->link && tty->link->packet) { | 509 | if (tty->link && tty->link->packet) { |
@@ -677,24 +664,6 @@ static int set_termiox(struct tty_struct *tty, void __user *arg, int opt) | |||
677 | 664 | ||
678 | #endif | 665 | #endif |
679 | 666 | ||
680 | static unsigned long inq_canon(struct tty_struct *tty) | ||
681 | { | ||
682 | int nr, head, tail; | ||
683 | |||
684 | if (!tty->canon_data || !tty->read_buf) | ||
685 | return 0; | ||
686 | head = tty->canon_head; | ||
687 | tail = tty->read_tail; | ||
688 | nr = (head - tail) & (N_TTY_BUF_SIZE-1); | ||
689 | /* Skip EOF-chars.. */ | ||
690 | while (head != tail) { | ||
691 | if (test_bit(tail, tty->read_flags) && | ||
692 | tty->read_buf[tail] == __DISABLED_CHAR) | ||
693 | nr--; | ||
694 | tail = (tail+1) & (N_TTY_BUF_SIZE-1); | ||
695 | } | ||
696 | return nr; | ||
697 | } | ||
698 | 667 | ||
699 | #ifdef TIOCGETP | 668 | #ifdef TIOCGETP |
700 | /* | 669 | /* |
@@ -1110,7 +1079,7 @@ int tty_perform_flush(struct tty_struct *tty, unsigned long arg) | |||
1110 | } | 1079 | } |
1111 | EXPORT_SYMBOL_GPL(tty_perform_flush); | 1080 | EXPORT_SYMBOL_GPL(tty_perform_flush); |
1112 | 1081 | ||
1113 | int n_tty_ioctl(struct tty_struct *tty, struct file *file, | 1082 | int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, |
1114 | unsigned int cmd, unsigned long arg) | 1083 | unsigned int cmd, unsigned long arg) |
1115 | { | 1084 | { |
1116 | unsigned long flags; | 1085 | unsigned long flags; |
@@ -1148,13 +1117,6 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file, | |||
1148 | return 0; | 1117 | return 0; |
1149 | case TCFLSH: | 1118 | case TCFLSH: |
1150 | return tty_perform_flush(tty, arg); | 1119 | return tty_perform_flush(tty, arg); |
1151 | case TIOCOUTQ: | ||
1152 | return put_user(tty_chars_in_buffer(tty), (int __user *) arg); | ||
1153 | case TIOCINQ: | ||
1154 | retval = tty->read_cnt; | ||
1155 | if (L_ICANON(tty)) | ||
1156 | retval = inq_canon(tty); | ||
1157 | return put_user(retval, (unsigned int __user *) arg); | ||
1158 | case TIOCPKT: | 1120 | case TIOCPKT: |
1159 | { | 1121 | { |
1160 | int pktmode; | 1122 | int pktmode; |
@@ -1180,4 +1142,4 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file, | |||
1180 | return tty_mode_ioctl(tty, file, cmd, arg); | 1142 | return tty_mode_ioctl(tty, file, cmd, arg); |
1181 | } | 1143 | } |
1182 | } | 1144 | } |
1183 | EXPORT_SYMBOL(n_tty_ioctl); | 1145 | EXPORT_SYMBOL(n_tty_ioctl_helper); |