summaryrefslogtreecommitdiff
path: root/drivers/tty/tty_jobctrl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/tty_jobctrl.c')
-rw-r--r--drivers/tty/tty_jobctrl.c30
1 files changed, 20 insertions, 10 deletions
diff --git a/drivers/tty/tty_jobctrl.c b/drivers/tty/tty_jobctrl.c
index 4b751b9285ad..7813dc910a19 100644
--- a/drivers/tty/tty_jobctrl.c
+++ b/drivers/tty/tty_jobctrl.c
@@ -11,6 +11,7 @@
#include <linux/tty.h>
#include <linux/fcntl.h>
#include <linux/uaccess.h>
+#include "tty.h"
static int is_ignored(int sig)
{
@@ -75,6 +76,7 @@ void proc_clear_tty(struct task_struct *p)
{
unsigned long flags;
struct tty_struct *tty;
+
spin_lock_irqsave(&p->sighand->siglock, flags);
tty = p->signal->tty;
p->signal->tty = NULL;
@@ -173,6 +175,7 @@ EXPORT_SYMBOL_GPL(get_current_tty);
void session_clear_tty(struct pid *session)
{
struct task_struct *p;
+
do_each_pid_task(session, PIDTYPE_SID, p) {
proc_clear_tty(p);
} while_each_pid_task(session, PIDTYPE_SID, p);
@@ -202,8 +205,10 @@ int tty_signal_session_leader(struct tty_struct *tty, int exit_session)
spin_lock_irq(&p->sighand->siglock);
if (p->signal->tty == tty) {
p->signal->tty = NULL;
- /* We defer the dereferences outside fo
- the tasklist lock */
+ /*
+ * We defer the dereferences outside of
+ * the tasklist lock.
+ */
refs++;
}
if (!p->signal->leader) {
@@ -240,10 +245,10 @@ int tty_signal_session_leader(struct tty_struct *tty, int exit_session)
* it wants to disassociate itself from its controlling tty.
*
* It performs the following functions:
- * (1) Sends a SIGHUP and SIGCONT to the foreground process group
- * (2) Clears the tty from being controlling the session
- * (3) Clears the controlling tty for all processes in the
- * session group.
+ * (1) Sends a SIGHUP and SIGCONT to the foreground process group
+ * (2) Clears the tty from being controlling the session
+ * (3) Clears the controlling tty for all processes in the
+ * session group.
*
* The argument on_exit is set to 1 if called when a process is
* exiting; it is 0 if called by the ioctl TIOCNOTTY.
@@ -269,6 +274,7 @@ void disassociate_ctty(int on_exit)
tty_vhangup_session(tty);
} else {
struct pid *tty_pgrp = tty_get_pgrp(tty);
+
if (tty_pgrp) {
kill_pgrp(tty_pgrp, SIGHUP, on_exit);
if (!on_exit)
@@ -280,6 +286,7 @@ void disassociate_ctty(int on_exit)
} else if (on_exit) {
struct pid *old_pgrp;
+
spin_lock_irq(&current->sighand->siglock);
old_pgrp = current->signal->tty_old_pgrp;
current->signal->tty_old_pgrp = NULL;
@@ -324,10 +331,13 @@ void disassociate_ctty(int on_exit)
*/
void no_tty(void)
{
- /* FIXME: Review locking here. The tty_lock never covered any race
- between a new association and proc_clear_tty but possible we need
- to protect against this anyway */
+ /*
+ * FIXME: Review locking here. The tty_lock never covered any race
+ * between a new association and proc_clear_tty but possibly we need
+ * to protect against this anyway.
+ */
struct task_struct *tsk = current;
+
disassociate_ctty(0);
proc_clear_tty(tsk);
}
@@ -531,7 +541,7 @@ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t _
/*
* (tty == real_tty) is a cheap way of
* testing if the tty is NOT a master pty.
- */
+ */
if (tty == real_tty && current->signal->tty != real_tty)
return -ENOTTY;