diff options
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r-- | drivers/char/tty_io.c | 40 |
1 files changed, 16 insertions, 24 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 1412a8d1e58d..d33e5ab06177 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -1111,9 +1111,7 @@ void tty_write_message(struct tty_struct *tty, char *msg) | |||
1111 | * Locks the line discipline as required | 1111 | * Locks the line discipline as required |
1112 | * Writes to the tty driver are serialized by the atomic_write_lock | 1112 | * Writes to the tty driver are serialized by the atomic_write_lock |
1113 | * and are then processed in chunks to the device. The line discipline | 1113 | * and are then processed in chunks to the device. The line discipline |
1114 | * write method will not be involked in parallel for each device | 1114 | * write method will not be invoked in parallel for each device. |
1115 | * The line discipline write method is called under the big | ||
1116 | * kernel lock for historical reasons. New code should not rely on this. | ||
1117 | */ | 1115 | */ |
1118 | 1116 | ||
1119 | static ssize_t tty_write(struct file *file, const char __user *buf, | 1117 | static ssize_t tty_write(struct file *file, const char __user *buf, |
@@ -1213,7 +1211,7 @@ static void tty_line_name(struct tty_driver *driver, int index, char *p) | |||
1213 | * be held until the 'fast-open' is also done. Will change once we | 1211 | * be held until the 'fast-open' is also done. Will change once we |
1214 | * have refcounting in the driver and per driver locking | 1212 | * have refcounting in the driver and per driver locking |
1215 | */ | 1213 | */ |
1216 | struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, | 1214 | static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, |
1217 | struct inode *inode, int idx) | 1215 | struct inode *inode, int idx) |
1218 | { | 1216 | { |
1219 | struct tty_struct *tty; | 1217 | struct tty_struct *tty; |
@@ -2018,6 +2016,7 @@ static int tiocsti(struct tty_struct *tty, char __user *p) | |||
2018 | return -EPERM; | 2016 | return -EPERM; |
2019 | if (get_user(ch, p)) | 2017 | if (get_user(ch, p)) |
2020 | return -EFAULT; | 2018 | return -EFAULT; |
2019 | tty_audit_tiocsti(tty, ch); | ||
2021 | ld = tty_ldisc_ref_wait(tty); | 2020 | ld = tty_ldisc_ref_wait(tty); |
2022 | ld->ops->receive_buf(tty, &ch, &mbz, 1); | 2021 | ld->ops->receive_buf(tty, &ch, &mbz, 1); |
2023 | tty_ldisc_deref(ld); | 2022 | tty_ldisc_deref(ld); |
@@ -2049,7 +2048,6 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg) | |||
2049 | /** | 2048 | /** |
2050 | * tty_do_resize - resize event | 2049 | * tty_do_resize - resize event |
2051 | * @tty: tty being resized | 2050 | * @tty: tty being resized |
2052 | * @real_tty: real tty (not the same as tty if using a pty/tty pair) | ||
2053 | * @rows: rows (character) | 2051 | * @rows: rows (character) |
2054 | * @cols: cols (character) | 2052 | * @cols: cols (character) |
2055 | * | 2053 | * |
@@ -2057,41 +2055,34 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg) | |||
2057 | * peform a terminal resize correctly | 2055 | * peform a terminal resize correctly |
2058 | */ | 2056 | */ |
2059 | 2057 | ||
2060 | int tty_do_resize(struct tty_struct *tty, struct tty_struct *real_tty, | 2058 | int tty_do_resize(struct tty_struct *tty, struct winsize *ws) |
2061 | struct winsize *ws) | ||
2062 | { | 2059 | { |
2063 | struct pid *pgrp, *rpgrp; | 2060 | struct pid *pgrp; |
2064 | unsigned long flags; | 2061 | unsigned long flags; |
2065 | 2062 | ||
2066 | /* For a PTY we need to lock the tty side */ | 2063 | /* Lock the tty */ |
2067 | mutex_lock(&real_tty->termios_mutex); | 2064 | mutex_lock(&tty->termios_mutex); |
2068 | if (!memcmp(ws, &real_tty->winsize, sizeof(*ws))) | 2065 | if (!memcmp(ws, &tty->winsize, sizeof(*ws))) |
2069 | goto done; | 2066 | goto done; |
2070 | /* Get the PID values and reference them so we can | 2067 | /* Get the PID values and reference them so we can |
2071 | avoid holding the tty ctrl lock while sending signals */ | 2068 | avoid holding the tty ctrl lock while sending signals */ |
2072 | spin_lock_irqsave(&tty->ctrl_lock, flags); | 2069 | spin_lock_irqsave(&tty->ctrl_lock, flags); |
2073 | pgrp = get_pid(tty->pgrp); | 2070 | pgrp = get_pid(tty->pgrp); |
2074 | rpgrp = get_pid(real_tty->pgrp); | ||
2075 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 2071 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
2076 | 2072 | ||
2077 | if (pgrp) | 2073 | if (pgrp) |
2078 | kill_pgrp(pgrp, SIGWINCH, 1); | 2074 | kill_pgrp(pgrp, SIGWINCH, 1); |
2079 | if (rpgrp != pgrp && rpgrp) | ||
2080 | kill_pgrp(rpgrp, SIGWINCH, 1); | ||
2081 | |||
2082 | put_pid(pgrp); | 2075 | put_pid(pgrp); |
2083 | put_pid(rpgrp); | ||
2084 | 2076 | ||
2085 | tty->winsize = *ws; | 2077 | tty->winsize = *ws; |
2086 | real_tty->winsize = *ws; | ||
2087 | done: | 2078 | done: |
2088 | mutex_unlock(&real_tty->termios_mutex); | 2079 | mutex_unlock(&tty->termios_mutex); |
2089 | return 0; | 2080 | return 0; |
2090 | } | 2081 | } |
2091 | 2082 | ||
2092 | /** | 2083 | /** |
2093 | * tiocswinsz - implement window size set ioctl | 2084 | * tiocswinsz - implement window size set ioctl |
2094 | * @tty; tty | 2085 | * @tty; tty side of tty |
2095 | * @arg: user buffer for result | 2086 | * @arg: user buffer for result |
2096 | * | 2087 | * |
2097 | * Copies the user idea of the window size to the kernel. Traditionally | 2088 | * Copies the user idea of the window size to the kernel. Traditionally |
@@ -2104,17 +2095,16 @@ done: | |||
2104 | * then calls into the default method. | 2095 | * then calls into the default method. |
2105 | */ | 2096 | */ |
2106 | 2097 | ||
2107 | static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, | 2098 | static int tiocswinsz(struct tty_struct *tty, struct winsize __user *arg) |
2108 | struct winsize __user *arg) | ||
2109 | { | 2099 | { |
2110 | struct winsize tmp_ws; | 2100 | struct winsize tmp_ws; |
2111 | if (copy_from_user(&tmp_ws, arg, sizeof(*arg))) | 2101 | if (copy_from_user(&tmp_ws, arg, sizeof(*arg))) |
2112 | return -EFAULT; | 2102 | return -EFAULT; |
2113 | 2103 | ||
2114 | if (tty->ops->resize) | 2104 | if (tty->ops->resize) |
2115 | return tty->ops->resize(tty, real_tty, &tmp_ws); | 2105 | return tty->ops->resize(tty, &tmp_ws); |
2116 | else | 2106 | else |
2117 | return tty_do_resize(tty, real_tty, &tmp_ws); | 2107 | return tty_do_resize(tty, &tmp_ws); |
2118 | } | 2108 | } |
2119 | 2109 | ||
2120 | /** | 2110 | /** |
@@ -2539,7 +2529,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
2539 | case TIOCGWINSZ: | 2529 | case TIOCGWINSZ: |
2540 | return tiocgwinsz(real_tty, p); | 2530 | return tiocgwinsz(real_tty, p); |
2541 | case TIOCSWINSZ: | 2531 | case TIOCSWINSZ: |
2542 | return tiocswinsz(tty, real_tty, p); | 2532 | return tiocswinsz(real_tty, p); |
2543 | case TIOCCONS: | 2533 | case TIOCCONS: |
2544 | return real_tty != tty ? -EINVAL : tioccons(file); | 2534 | return real_tty != tty ? -EINVAL : tioccons(file); |
2545 | case FIONBIO: | 2535 | case FIONBIO: |
@@ -2784,6 +2774,8 @@ void initialize_tty_struct(struct tty_struct *tty, | |||
2784 | INIT_WORK(&tty->hangup_work, do_tty_hangup); | 2774 | INIT_WORK(&tty->hangup_work, do_tty_hangup); |
2785 | mutex_init(&tty->atomic_read_lock); | 2775 | mutex_init(&tty->atomic_read_lock); |
2786 | mutex_init(&tty->atomic_write_lock); | 2776 | mutex_init(&tty->atomic_write_lock); |
2777 | mutex_init(&tty->output_lock); | ||
2778 | mutex_init(&tty->echo_lock); | ||
2787 | spin_lock_init(&tty->read_lock); | 2779 | spin_lock_init(&tty->read_lock); |
2788 | spin_lock_init(&tty->ctrl_lock); | 2780 | spin_lock_init(&tty->ctrl_lock); |
2789 | INIT_LIST_HEAD(&tty->tty_files); | 2781 | INIT_LIST_HEAD(&tty->tty_files); |