diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/tty_ioctl.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index bf34e4597421..93bfa1d6cc92 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c | |||
@@ -579,6 +579,50 @@ static int get_termio(struct tty_struct *tty, struct termio __user *termio) | |||
579 | return 0; | 579 | return 0; |
580 | } | 580 | } |
581 | 581 | ||
582 | |||
583 | #ifdef TCGETX | ||
584 | |||
585 | /** | ||
586 | * set_termiox - set termiox fields if possible | ||
587 | * @tty: terminal | ||
588 | * @arg: termiox structure from user | ||
589 | * @opt: option flags for ioctl type | ||
590 | * | ||
591 | * Implement the device calling points for the SYS5 termiox ioctl | ||
592 | * interface in Linux | ||
593 | */ | ||
594 | |||
595 | static int set_termiox(struct tty_struct *tty, void __user *arg, int opt) | ||
596 | { | ||
597 | struct termiox tnew; | ||
598 | struct tty_ldisc *ld; | ||
599 | |||
600 | if (tty->termiox == NULL) | ||
601 | return -EINVAL; | ||
602 | if (copy_from_user(&tnew, arg, sizeof(struct termiox))) | ||
603 | return -EFAULT; | ||
604 | |||
605 | ld = tty_ldisc_ref(tty); | ||
606 | if (ld != NULL) { | ||
607 | if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer) | ||
608 | ld->ops->flush_buffer(tty); | ||
609 | tty_ldisc_deref(ld); | ||
610 | } | ||
611 | if (opt & TERMIOS_WAIT) { | ||
612 | tty_wait_until_sent(tty, 0); | ||
613 | if (signal_pending(current)) | ||
614 | return -EINTR; | ||
615 | } | ||
616 | |||
617 | mutex_lock(&tty->termios_mutex); | ||
618 | if (tty->ops->set_termiox) | ||
619 | tty->ops->set_termiox(tty, &tnew); | ||
620 | mutex_unlock(&tty->termios_mutex); | ||
621 | return 0; | ||
622 | } | ||
623 | |||
624 | #endif | ||
625 | |||
582 | static unsigned long inq_canon(struct tty_struct *tty) | 626 | static unsigned long inq_canon(struct tty_struct *tty) |
583 | { | 627 | { |
584 | int nr, head, tail; | 628 | int nr, head, tail; |
@@ -936,6 +980,20 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file, | |||
936 | return -EFAULT; | 980 | return -EFAULT; |
937 | return 0; | 981 | return 0; |
938 | #endif | 982 | #endif |
983 | #ifdef TCGETX | ||
984 | case TCGETX: | ||
985 | if (real_tty->termiox == NULL) | ||
986 | return -EINVAL; | ||
987 | if (copy_to_user(p, real_tty->termiox, sizeof(struct termiox))) | ||
988 | return -EFAULT; | ||
989 | return 0; | ||
990 | case TCSETX: | ||
991 | return set_termiox(real_tty, p, 0); | ||
992 | case TCSETXW: | ||
993 | return set_termiox(real_tty, p, TERMIOS_WAIT); | ||
994 | case TCSETXF: | ||
995 | return set_termiox(real_tty, p, TERMIOS_FLUSH); | ||
996 | #endif | ||
939 | case TIOCGSOFTCAR: | 997 | case TIOCGSOFTCAR: |
940 | /* FIXME: for correctness we may need to take the termios | 998 | /* FIXME: for correctness we may need to take the termios |
941 | lock here - review */ | 999 | lock here - review */ |