tty: Combine SIGTTOU/SIGTTIN handling
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
@@ -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
@@ -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
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
@@ -2548,7 +2548,6 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_tstruct 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_tif (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
PATCH 3/3 tty: Prevent tty teardown during tty_write_message()
In reply to Peter Hurleytty_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
@@ -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