aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r--drivers/char/tty_io.c40
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
1119static ssize_t tty_write(struct file *file, const char __user *buf, 1117static 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 */
1216struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, 1214static 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
2060int tty_do_resize(struct tty_struct *tty, struct tty_struct *real_tty, 2058int 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;
2087done: 2078done:
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
2107static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, 2098static 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);