aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Hurley <peter@hurleysoftware.com>2015-10-10 20:28:42 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-10-18 00:30:49 -0400
commit2812d9e9fd94c54b0482215f579e6aa04452a322 (patch)
tree04be4bb895b4bbde79538de1e61550fcae6d9dbe
parent71a5cd8a4a2602a6e9010b557a23af0a54df87b6 (diff)
tty: Combine SIGTTOU/SIGTTIN handling
The job_control() check in n_tty_read() has nearly identical purpose and results as tty_check_change(). Both functions' purpose is to determine if the current task's pgrp is the foreground pgrp for the tty, and if not, to signal the current pgrp. Introduce __tty_check_change() which takes the signal to send and performs the shared operations for job control() and tty_check_change(). Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/tty/n_tty.c26
-rw-r--r--drivers/tty/tty_io.c46
-rw-r--r--include/linux/tty.h1
3 files changed, 27 insertions, 46 deletions
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index ff728d32cb53..fb8ccbfdbb30 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -2138,37 +2138,15 @@ extern ssize_t redirected_tty_write(struct file *, const char __user *,
2138 2138
2139static int job_control(struct tty_struct *tty, struct file *file) 2139static int job_control(struct tty_struct *tty, struct file *file)
2140{ 2140{
2141 struct pid *pgrp;
2142
2143 /* Job control check -- must be done at start and after 2141 /* Job control check -- must be done at start and after
2144 every sleep (POSIX.1 7.1.1.4). */ 2142 every sleep (POSIX.1 7.1.1.4). */
2145 /* NOTE: not yet done after every sleep pending a thorough 2143 /* NOTE: not yet done after every sleep pending a thorough
2146 check of the logic of this change. -- jlc */ 2144 check of the logic of this change. -- jlc */
2147 /* don't stop on /dev/console */ 2145 /* don't stop on /dev/console */
2148 if (file->f_op->write == redirected_tty_write || 2146 if (file->f_op->write == redirected_tty_write)
2149 current->signal->tty != tty)
2150 return 0; 2147 return 0;
2151 2148
2152 rcu_read_lock(); 2149 return __tty_check_change(tty, SIGTTIN);
2153 pgrp = task_pgrp(current);
2154
2155 spin_lock_irq(&tty->ctrl_lock);
2156 if (!tty->pgrp)
2157 printk(KERN_ERR "n_tty_read: no tty->pgrp!\n");
2158 else if (pgrp != tty->pgrp) {
2159 spin_unlock_irq(&tty->ctrl_lock);
2160 if (is_ignored(SIGTTIN) || is_current_pgrp_orphaned()) {
2161 rcu_read_unlock();
2162 return -EIO;
2163 }
2164 kill_pgrp(pgrp, SIGTTIN, 1);
2165 rcu_read_unlock();
2166 set_thread_flag(TIF_SIGPENDING);
2167 return -ERESTARTSYS;
2168 }
2169 spin_unlock_irq(&tty->ctrl_lock);
2170 rcu_read_unlock();
2171 return 0;
2172} 2150}
2173 2151
2174 2152
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 2eefaa6e3e3a..aa48367a0c79 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -390,10 +390,10 @@ EXPORT_SYMBOL_GPL(tty_find_polling_driver);
390 * Locking: ctrl_lock 390 * Locking: ctrl_lock
391 */ 391 */
392 392
393int tty_check_change(struct tty_struct *tty) 393int __tty_check_change(struct tty_struct *tty, int sig)
394{ 394{
395 unsigned long flags; 395 unsigned long flags;
396 struct pid *pgrp; 396 struct pid *pgrp, *tty_pgrp;
397 int ret = 0; 397 int ret = 0;
398 398
399 if (current->signal->tty != tty) 399 if (current->signal->tty != tty)
@@ -403,33 +403,35 @@ int tty_check_change(struct tty_struct *tty)
403 pgrp = task_pgrp(current); 403 pgrp = task_pgrp(current);
404 404
405 spin_lock_irqsave(&tty->ctrl_lock, flags); 405 spin_lock_irqsave(&tty->ctrl_lock, flags);
406 406 tty_pgrp = tty->pgrp;
407 if (!tty->pgrp) {
408 printk(KERN_WARNING "tty_check_change: tty->pgrp == NULL!\n");
409 goto out_unlock;
410 }
411 if (pgrp == tty->pgrp)
412 goto out_unlock;
413 spin_unlock_irqrestore(&tty->ctrl_lock, flags); 407 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
414 408
415 if (is_ignored(SIGTTOU)) 409 if (tty_pgrp && pgrp != tty->pgrp) {
416 goto out_rcuunlock; 410 if (is_ignored(sig)) {
417 if (is_current_pgrp_orphaned()) { 411 if (sig == SIGTTIN)
418 ret = -EIO; 412 ret = -EIO;
419 goto out_rcuunlock; 413 } else if (is_current_pgrp_orphaned())
414 ret = -EIO;
415 else {
416 kill_pgrp(pgrp, sig, 1);
417 set_thread_flag(TIF_SIGPENDING);
418 ret = -ERESTARTSYS;
419 }
420 } 420 }
421 kill_pgrp(pgrp, SIGTTOU, 1);
422 rcu_read_unlock();
423 set_thread_flag(TIF_SIGPENDING);
424 ret = -ERESTARTSYS;
425 return ret;
426out_unlock:
427 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
428out_rcuunlock:
429 rcu_read_unlock(); 421 rcu_read_unlock();
422
423 if (!tty_pgrp) {
424 pr_warn("%s: tty_check_change: sig=%d, tty->pgrp == NULL!\n",
425 tty_name(tty), sig);
426 }
427
430 return ret; 428 return ret;
431} 429}
432 430
431int tty_check_change(struct tty_struct *tty)
432{
433 return __tty_check_change(tty, SIGTTOU);
434}
433EXPORT_SYMBOL(tty_check_change); 435EXPORT_SYMBOL(tty_check_change);
434 436
435static ssize_t hung_up_tty_read(struct file *file, char __user *buf, 437static ssize_t hung_up_tty_read(struct file *file, char __user *buf,
diff --git a/include/linux/tty.h b/include/linux/tty.h
index c2889f4331e1..533d7f6e2481 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -423,6 +423,7 @@ extern int tty_paranoia_check(struct tty_struct *tty, struct inode *inode,
423 const char *routine); 423 const char *routine);
424extern const char *tty_name(const struct tty_struct *tty); 424extern const char *tty_name(const struct tty_struct *tty);
425extern void tty_wait_until_sent(struct tty_struct *tty, long timeout); 425extern void tty_wait_until_sent(struct tty_struct *tty, long timeout);
426extern int __tty_check_change(struct tty_struct *tty, int sig);
426extern int tty_check_change(struct tty_struct *tty); 427extern int tty_check_change(struct tty_struct *tty);
427extern void __stop_tty(struct tty_struct *tty); 428extern void __stop_tty(struct tty_struct *tty);
428extern void stop_tty(struct tty_struct *tty); 429extern void stop_tty(struct tty_struct *tty);