Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 106220
b: refs/heads/master
c: 2b2a1ff
h: refs/heads/master
v: v3
  • Loading branch information
Roland McGrath authored and Linus Torvalds committed Jul 26, 2008
1 parent 4678044 commit 142878a
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 22 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: fa00b80b3c41a845b3d56f866fb40a2e98754c51
refs/heads/master: 2b2a1ff64afbadac842bbc58c5166962cf4f7664
2 changes: 1 addition & 1 deletion trunk/include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -1796,7 +1796,7 @@ extern int kill_pid_info_as_uid(int, struct siginfo *, struct pid *, uid_t, uid_
extern int kill_pgrp(struct pid *pid, int sig, int priv);
extern int kill_pid(struct pid *pid, int sig, int priv);
extern int kill_proc_info(int, struct siginfo *, pid_t);
extern void do_notify_parent(struct task_struct *, int);
extern int do_notify_parent(struct task_struct *, int);
extern void force_sig(int, struct task_struct *);
extern void force_sig_specific(int, struct task_struct *);
extern int send_sig(int, struct task_struct *, int);
Expand Down
52 changes: 52 additions & 0 deletions trunk/include/linux/tracehook.h
Original file line number Diff line number Diff line change
Expand Up @@ -471,4 +471,56 @@ static inline int tracehook_notify_jctl(int notify, int why)
return notify || (current->ptrace & PT_PTRACED);
}

/**
* tracehook_notify_death - task is dead, ready to notify parent
* @task: @current task now exiting
* @death_cookie: value to pass to tracehook_report_death()
* @group_dead: nonzero if this was the last thread in the group to die
*
* Return the signal number to send our parent with do_notify_parent(), or
* zero to send no signal and leave a zombie, or -1 to self-reap right now.
*
* Called with write_lock_irq(&tasklist_lock) held.
*/
static inline int tracehook_notify_death(struct task_struct *task,
void **death_cookie, int group_dead)
{
if (task->exit_signal == -1)
return task->ptrace ? SIGCHLD : -1;

/*
* If something other than our normal parent is ptracing us, then
* send it a SIGCHLD instead of honoring exit_signal. exit_signal
* only has special meaning to our real parent.
*/
if (thread_group_empty(task) && !ptrace_reparented(task))
return task->exit_signal;

return task->ptrace ? SIGCHLD : 0;
}

/**
* tracehook_report_death - task is dead and ready to be reaped
* @task: @current task now exiting
* @signal: signal number sent to parent, or 0 or -1
* @death_cookie: value passed back from tracehook_notify_death()
* @group_dead: nonzero if this was the last thread in the group to die
*
* Thread has just become a zombie or is about to self-reap. If positive,
* @signal is the signal number just sent to the parent (usually %SIGCHLD).
* If @signal is -1, this thread will self-reap. If @signal is 0, this is
* a delayed_group_leader() zombie. The @death_cookie was passed back by
* tracehook_notify_death().
*
* If normal reaping is not inhibited, @task->exit_state might be changing
* in parallel.
*
* Called without locks.
*/
static inline void tracehook_report_death(struct task_struct *task,
int signal, void *death_cookie,
int group_dead)
{
}

#endif /* <linux/tracehook.h> */
26 changes: 9 additions & 17 deletions trunk/kernel/exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -885,7 +885,8 @@ static void forget_original_parent(struct task_struct *father)
*/
static void exit_notify(struct task_struct *tsk, int group_dead)
{
int state;
int signal;
void *cookie;

/*
* This does two things:
Expand Down Expand Up @@ -922,22 +923,11 @@ static void exit_notify(struct task_struct *tsk, int group_dead)
!capable(CAP_KILL))
tsk->exit_signal = SIGCHLD;

/* If something other than our normal parent is ptracing us, then
* send it a SIGCHLD instead of honoring exit_signal. exit_signal
* only has special meaning to our real parent.
*/
if (!task_detached(tsk) && thread_group_empty(tsk)) {
int signal = ptrace_reparented(tsk) ?
SIGCHLD : tsk->exit_signal;
do_notify_parent(tsk, signal);
} else if (tsk->ptrace) {
do_notify_parent(tsk, SIGCHLD);
}
signal = tracehook_notify_death(tsk, &cookie, group_dead);
if (signal > 0)
signal = do_notify_parent(tsk, signal);

state = EXIT_ZOMBIE;
if (task_detached(tsk) && likely(!tsk->ptrace))
state = EXIT_DEAD;
tsk->exit_state = state;
tsk->exit_state = signal < 0 ? EXIT_DEAD : EXIT_ZOMBIE;

/* mt-exec, de_thread() is waiting for us */
if (thread_group_leader(tsk) &&
Expand All @@ -947,8 +937,10 @@ static void exit_notify(struct task_struct *tsk, int group_dead)

write_unlock_irq(&tasklist_lock);

tracehook_report_death(tsk, signal, cookie, group_dead);

/* If the process is dead, release it - nobody will wait for it */
if (state == EXIT_DEAD)
if (signal < 0)
release_task(tsk);
}

Expand Down
10 changes: 7 additions & 3 deletions trunk/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -1326,9 +1326,11 @@ static inline void __wake_up_parent(struct task_struct *p,
/*
* Let a parent know about the death of a child.
* For a stopped/continued status change, use do_notify_parent_cldstop instead.
*
* Returns -1 if our parent ignored us and so we've switched to
* self-reaping, or else @sig.
*/

void do_notify_parent(struct task_struct *tsk, int sig)
int do_notify_parent(struct task_struct *tsk, int sig)
{
struct siginfo info;
unsigned long flags;
Expand Down Expand Up @@ -1399,12 +1401,14 @@ void do_notify_parent(struct task_struct *tsk, int sig)
*/
tsk->exit_signal = -1;
if (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN)
sig = 0;
sig = -1;
}
if (valid_signal(sig) && sig > 0)
__group_send_sig_info(sig, &info, tsk->parent);
__wake_up_parent(tsk, tsk->parent);
spin_unlock_irqrestore(&psig->siglock, flags);

return sig;
}

static void do_notify_parent_cldstop(struct task_struct *tsk, int why)
Expand Down

0 comments on commit 142878a

Please sign in to comment.