Skip to contentSkip to conversation

tty: Combine SIGTTOU/SIGTTIN handling

PATCH New Peter Hurley 1 participant 3 messages Oct 11, 2015 TTY layer and serial drivers

lore
Share & tools
lore
#0 lore raw

PATCH 1/3 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().

---
 drivers/tty/n_tty.c  | 26 ++------------------------
 drivers/tty/tty_io.c | 46 ++++++++++++++++++++++++----------------------
 include/linux/tty.h  |  1 +
 3 files changed, 27 insertions(+), 46 deletions(-)
drivers/tty/n_tty.c +2 -24
index 20932cc..bd383c4 100644
@@ -2147,37 +2147,15 @@ extern ssize_t redirected_tty_write(struct file *, const char __user *,
 
 static int job_control(struct tty_struct *tty, struct file *file)
 {
-	struct pid *pgrp;
-
 	/* Job control check -- must be done at start and after
 	   every sleep (POSIX.1 7.1.1.4). */
 	/* NOTE: not yet done after every sleep pending a thorough
 	   check of the logic of this change. -- jlc */
 	/* don't stop on /dev/console */
-	if (file->f_op->write == redirected_tty_write ||
-	    current->signal->tty != tty)
+	if (file->f_op->write == redirected_tty_write)
 		return 0;
 
-	rcu_read_lock();
-	pgrp = task_pgrp(current);
-
-	spin_lock_irq(&tty->ctrl_lock);
-	if (!tty->pgrp)
-		printk(KERN_ERR "n_tty_read: no tty->pgrp!\n");
-	else if (pgrp != tty->pgrp) {
-		spin_unlock_irq(&tty->ctrl_lock);
-		if (is_ignored(SIGTTIN) || is_current_pgrp_orphaned()) {
-			rcu_read_unlock();
-			return -EIO;
-		}
-		kill_pgrp(pgrp, SIGTTIN, 1);
-		rcu_read_unlock();
-		set_thread_flag(TIF_SIGPENDING);
-		return -ERESTARTSYS;
-	}
-	spin_unlock_irq(&tty->ctrl_lock);
-	rcu_read_unlock();
-	return 0;
+	return __tty_check_change(tty, SIGTTIN);
 }
 
 
drivers/tty/tty_io.c +24 -22

67 lines not on this page · raw message

include/linux/tty.h +1 -0
index c2889f4..533d7f6 100644
@@ -423,6 +423,7 @@ extern int tty_paranoia_check(struct tty_struct *tty, struct inode *inode,
 			      const char *routine);
 extern const char *tty_name(const struct tty_struct *tty);
 extern void tty_wait_until_sent(struct tty_struct *tty, long timeout);
+extern int __tty_check_change(struct tty_struct *tty, int sig);
 extern int tty_check_change(struct tty_struct *tty);
 extern void __stop_tty(struct tty_struct *tty);
 extern void stop_tty(struct tty_struct *tty);
Signature · 1 line
2.6.1
#1 lore raw

PATCH 2/3 tty: core: Use correct spinlock flavor in tiocspgrp()

tiocspgrp() is the ioctl handler for TIOCSPGRP, which runs in non-atomic context; use spin_lock/unlock_irq (since interrupt state is on).

---
 drivers/tty/tty_io.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/tty/tty_io.c +2 -3
index eb210d7..bf404cd 100644
@@ -2548,7 +2548,6 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
 	struct pid *pgrp;
 	pid_t pgrp_nr;
 	int retval = tty_check_change(real_tty);
-	unsigned long flags;
 
 	if (retval == -EIO)
 		return -ENOTTY;
@@ -2571,10 +2570,10 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
 	if (session_of_pgrp(pgrp) != task_session(current))
 		goto out_unlock;
 	retval = 0;
-	spin_lock_irqsave(&tty->ctrl_lock, flags);
+	spin_lock_irq(&tty->ctrl_lock);
 	put_pid(real_tty->pgrp);
 	real_tty->pgrp = get_pid(pgrp);
-	spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+	spin_unlock_irq(&tty->ctrl_lock);
 out_unlock:
 	rcu_read_unlock();
 	return retval;
Signature · 1 line
2.6.1
#2 lore raw

PATCH 3/3 tty: Prevent tty teardown during tty_write_message()

In reply to Peter Hurley

tty_write_message() allows the caller to directly write to a specific tty. Since the line discipline is bypassed for the direct write, nothing prevents the tty from being torn down after the tty count is checked.

Hold the tty lock for the duration of the direct write.

---
 drivers/tty/tty_io.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/tty/tty_io.c +2 -4
index bf404cd..4530993 100644
@@ -1200,11 +1200,9 @@ void tty_write_message(struct tty_struct *tty, char *msg)
 	if (tty) {
 		mutex_lock(&tty->atomic_write_lock);
 		tty_lock(tty);
-		if (tty->ops->write && tty->count > 0) {
-			tty_unlock(tty);
+		if (tty->ops->write && tty->count > 0)
 			tty->ops->write(tty, msg, strlen(msg));
-		} else
-			tty_unlock(tty);
+		tty_unlock(tty);
 		tty_write_unlock(tty);
 	}
 	return;
Signature · 1 line
2.6.1