introduce kill_orphaned_pgrp() helper
Factor out the common code in reparent_thread() and exit_notify(). No functional changes. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Родитель
5ce2087ed0
Коммит
f49ee505b1
|
@ -255,6 +255,37 @@ static int has_stopped_jobs(struct pid *pgrp)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check to see if any process groups have become orphaned as
|
||||
* a result of our exiting, and if they have any stopped jobs,
|
||||
* send them a SIGHUP and then a SIGCONT. (POSIX 3.2.2.2)
|
||||
*/
|
||||
static void
|
||||
kill_orphaned_pgrp(struct task_struct *tsk, struct task_struct *parent)
|
||||
{
|
||||
struct pid *pgrp = task_pgrp(tsk);
|
||||
struct task_struct *ignored_task = tsk;
|
||||
|
||||
if (!parent)
|
||||
/* exit: our father is in a different pgrp than
|
||||
* we are and we were the only connection outside.
|
||||
*/
|
||||
parent = tsk->real_parent;
|
||||
else
|
||||
/* reparent: our child is in a different pgrp than
|
||||
* we are, and it was the only connection outside.
|
||||
*/
|
||||
ignored_task = NULL;
|
||||
|
||||
if (task_pgrp(parent) != pgrp &&
|
||||
task_session(parent) == task_session(tsk) &&
|
||||
will_become_orphaned_pgrp(pgrp, ignored_task) &&
|
||||
has_stopped_jobs(pgrp)) {
|
||||
__kill_pgrp_info(SIGHUP, SEND_SIG_PRIV, pgrp);
|
||||
__kill_pgrp_info(SIGCONT, SEND_SIG_PRIV, pgrp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* reparent_to_kthreadd - Reparent the calling kernel thread to kthreadd
|
||||
*
|
||||
|
@ -635,22 +666,7 @@ reparent_thread(struct task_struct *p, struct task_struct *father, int traced)
|
|||
p->exit_signal != -1 && thread_group_empty(p))
|
||||
do_notify_parent(p, p->exit_signal);
|
||||
|
||||
/*
|
||||
* process group orphan check
|
||||
* Case ii: Our child is in a different pgrp
|
||||
* than we are, and it was the only connection
|
||||
* outside, so the child pgrp is now orphaned.
|
||||
*/
|
||||
if ((task_pgrp(p) != task_pgrp(father)) &&
|
||||
(task_session(p) == task_session(father))) {
|
||||
struct pid *pgrp = task_pgrp(p);
|
||||
|
||||
if (will_become_orphaned_pgrp(pgrp, NULL) &&
|
||||
has_stopped_jobs(pgrp)) {
|
||||
__kill_pgrp_info(SIGHUP, SEND_SIG_PRIV, pgrp);
|
||||
__kill_pgrp_info(SIGCONT, SEND_SIG_PRIV, pgrp);
|
||||
}
|
||||
}
|
||||
kill_orphaned_pgrp(p, father);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -738,8 +754,6 @@ static void forget_original_parent(struct task_struct *father)
|
|||
static void exit_notify(struct task_struct *tsk)
|
||||
{
|
||||
int state;
|
||||
struct task_struct *t;
|
||||
struct pid *pgrp;
|
||||
|
||||
/*
|
||||
* This does two things:
|
||||
|
@ -753,25 +767,7 @@ static void exit_notify(struct task_struct *tsk)
|
|||
exit_task_namespaces(tsk);
|
||||
|
||||
write_lock_irq(&tasklist_lock);
|
||||
/*
|
||||
* Check to see if any process groups have become orphaned
|
||||
* as a result of our exiting, and if they have any stopped
|
||||
* jobs, send them a SIGHUP and then a SIGCONT. (POSIX 3.2.2.2)
|
||||
*
|
||||
* Case i: Our father is in a different pgrp than we are
|
||||
* and we were the only connection outside, so our pgrp
|
||||
* is about to become orphaned.
|
||||
*/
|
||||
t = tsk->real_parent;
|
||||
|
||||
pgrp = task_pgrp(tsk);
|
||||
if ((task_pgrp(t) != pgrp) &&
|
||||
(task_session(t) == task_session(tsk)) &&
|
||||
will_become_orphaned_pgrp(pgrp, tsk) &&
|
||||
has_stopped_jobs(pgrp)) {
|
||||
__kill_pgrp_info(SIGHUP, SEND_SIG_PRIV, pgrp);
|
||||
__kill_pgrp_info(SIGCONT, SEND_SIG_PRIV, pgrp);
|
||||
}
|
||||
kill_orphaned_pgrp(tsk, NULL);
|
||||
|
||||
/* Let father know we died
|
||||
*
|
||||
|
@ -788,8 +784,8 @@ static void exit_notify(struct task_struct *tsk)
|
|||
* the same after a fork.
|
||||
*/
|
||||
if (tsk->exit_signal != SIGCHLD && tsk->exit_signal != -1 &&
|
||||
( tsk->parent_exec_id != t->self_exec_id ||
|
||||
tsk->self_exec_id != tsk->parent_exec_id)
|
||||
(tsk->parent_exec_id != tsk->real_parent->self_exec_id ||
|
||||
tsk->self_exec_id != tsk->parent_exec_id)
|
||||
&& !capable(CAP_KILL))
|
||||
tsk->exit_signal = SIGCHLD;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче