Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 364214
b: refs/heads/master
c: f91e259
h: refs/heads/master
v: v3
  • Loading branch information
Peter Hurley authored and Greg Kroah-Hartman committed Mar 15, 2013
1 parent 219e0a7 commit 9c46eaa
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 18 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bc30c3b23bb953fc6eb59e7ac6ecb48d92962bb0
refs/heads/master: f91e2590410bd992e3f065d17c55329bdaa51b1d
65 changes: 48 additions & 17 deletions trunk/drivers/tty/tty_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -534,18 +534,21 @@ EXPORT_SYMBOL_GPL(tty_wakeup);

/**
* tty_signal_session_leader - sends SIGHUP to session leader
* @tty controlling tty
* @exit_session if non-zero, signal all foreground group processes
*
* Send SIGHUP and SIGCONT to the session leader and its
* process group.
* Send SIGHUP and SIGCONT to the session leader and its process group.
* Optionally, signal all processes in the foreground process group.
*
* Returns the number of processes in the session with this tty
* as their controlling terminal. This value is used to drop
* tty references for those processes.
*/
static int tty_signal_session_leader(struct tty_struct *tty)
static int tty_signal_session_leader(struct tty_struct *tty, int exit_session)
{
struct task_struct *p;
int refs = 0;
struct pid *tty_pgrp = NULL;

read_lock(&tasklist_lock);
if (tty->session) {
Expand All @@ -565,6 +568,7 @@ static int tty_signal_session_leader(struct tty_struct *tty)
__group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p);
put_pid(p->signal->tty_old_pgrp); /* A noop */
spin_lock(&tty->ctrl_lock);
tty_pgrp = get_pid(tty->pgrp);
if (tty->pgrp)
p->signal->tty_old_pgrp = get_pid(tty->pgrp);
spin_unlock(&tty->ctrl_lock);
Expand All @@ -573,6 +577,12 @@ static int tty_signal_session_leader(struct tty_struct *tty)
}
read_unlock(&tasklist_lock);

if (tty_pgrp) {
if (exit_session)
kill_pgrp(tty_pgrp, SIGHUP, exit_session);
put_pid(tty_pgrp);
}

return refs;
}

Expand All @@ -598,7 +608,7 @@ static int tty_signal_session_leader(struct tty_struct *tty)
* tasklist_lock to walk task list for hangup event
* ->siglock to protect ->signal/->sighand
*/
static void __tty_hangup(struct tty_struct *tty)
static void __tty_hangup(struct tty_struct *tty, int exit_session)
{
struct file *cons_filp = NULL;
struct file *filp, *f = NULL;
Expand Down Expand Up @@ -647,7 +657,7 @@ static void __tty_hangup(struct tty_struct *tty)
*/
tty_ldisc_hangup(tty);

refs = tty_signal_session_leader(tty);
refs = tty_signal_session_leader(tty, exit_session);
/* Account for the p->signal references we killed */
while (refs--)
tty_kref_put(tty);
Expand Down Expand Up @@ -696,7 +706,7 @@ static void do_tty_hangup(struct work_struct *work)
struct tty_struct *tty =
container_of(work, struct tty_struct, hangup_work);

__tty_hangup(tty);
__tty_hangup(tty, 0);
}

/**
Expand Down Expand Up @@ -734,7 +744,7 @@ void tty_vhangup(struct tty_struct *tty)

printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty, buf));
#endif
__tty_hangup(tty);
__tty_hangup(tty, 0);
}

EXPORT_SYMBOL(tty_vhangup);
Expand All @@ -757,6 +767,27 @@ void tty_vhangup_self(void)
}
}

/**
* tty_vhangup_session - hangup session leader exit
* @tty: tty to hangup
*
* The session leader is exiting and hanging up its controlling terminal.
* Every process in the foreground process group is signalled SIGHUP.
*
* We do this synchronously so that when the syscall returns the process
* is complete. That guarantee is necessary for security reasons.
*/

void tty_vhangup_session(struct tty_struct *tty)
{
#ifdef TTY_DEBUG_HANGUP
char buf[64];

printk(KERN_DEBUG "%s vhangup session...\n", tty_name(tty, buf));
#endif
__tty_hangup(tty, 1);
}

/**
* tty_hung_up_p - was tty hung up
* @filp: file pointer of tty
Expand Down Expand Up @@ -814,18 +845,18 @@ void disassociate_ctty(int on_exit)

tty = get_current_tty();
if (tty) {
struct pid *tty_pgrp = get_pid(tty->pgrp);
if (on_exit) {
if (tty->driver->type != TTY_DRIVER_TYPE_PTY)
tty_vhangup(tty);
}
tty_kref_put(tty);
if (tty_pgrp) {
kill_pgrp(tty_pgrp, SIGHUP, on_exit);
if (!on_exit)
if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) {
tty_vhangup_session(tty);
} else {
struct pid *tty_pgrp = tty_get_pgrp(tty);
if (tty_pgrp) {
kill_pgrp(tty_pgrp, SIGHUP, on_exit);
kill_pgrp(tty_pgrp, SIGCONT, on_exit);
put_pid(tty_pgrp);
put_pid(tty_pgrp);
}
}
tty_kref_put(tty);

} else if (on_exit) {
struct pid *old_pgrp;
spin_lock_irq(&current->sighand->siglock);
Expand Down

0 comments on commit 9c46eaa

Please sign in to comment.