diff options
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 32 |
1 files changed, 11 insertions, 21 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 24d5059ab0a9..0528a959daa9 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -591,9 +591,7 @@ static int check_kill_permission(int sig, struct siginfo *info, | |||
591 | } | 591 | } |
592 | 592 | ||
593 | /* forward decl */ | 593 | /* forward decl */ |
594 | static void do_notify_parent_cldstop(struct task_struct *tsk, | 594 | static void do_notify_parent_cldstop(struct task_struct *tsk, int why); |
595 | int to_self, | ||
596 | int why); | ||
597 | 595 | ||
598 | /* | 596 | /* |
599 | * Handle magic process-wide effects of stop/continue signals. | 597 | * Handle magic process-wide effects of stop/continue signals. |
@@ -643,7 +641,7 @@ static void handle_stop_signal(int sig, struct task_struct *p) | |||
643 | p->signal->group_stop_count = 0; | 641 | p->signal->group_stop_count = 0; |
644 | p->signal->flags = SIGNAL_STOP_CONTINUED; | 642 | p->signal->flags = SIGNAL_STOP_CONTINUED; |
645 | spin_unlock(&p->sighand->siglock); | 643 | spin_unlock(&p->sighand->siglock); |
646 | do_notify_parent_cldstop(p, (p->ptrace & PT_PTRACED), CLD_STOPPED); | 644 | do_notify_parent_cldstop(p, CLD_STOPPED); |
647 | spin_lock(&p->sighand->siglock); | 645 | spin_lock(&p->sighand->siglock); |
648 | } | 646 | } |
649 | rm_from_queue(SIG_KERNEL_STOP_MASK, &p->signal->shared_pending); | 647 | rm_from_queue(SIG_KERNEL_STOP_MASK, &p->signal->shared_pending); |
@@ -684,7 +682,7 @@ static void handle_stop_signal(int sig, struct task_struct *p) | |||
684 | p->signal->flags = SIGNAL_STOP_CONTINUED; | 682 | p->signal->flags = SIGNAL_STOP_CONTINUED; |
685 | p->signal->group_exit_code = 0; | 683 | p->signal->group_exit_code = 0; |
686 | spin_unlock(&p->sighand->siglock); | 684 | spin_unlock(&p->sighand->siglock); |
687 | do_notify_parent_cldstop(p, (p->ptrace & PT_PTRACED), CLD_CONTINUED); | 685 | do_notify_parent_cldstop(p, CLD_CONTINUED); |
688 | spin_lock(&p->sighand->siglock); | 686 | spin_lock(&p->sighand->siglock); |
689 | } else { | 687 | } else { |
690 | /* | 688 | /* |
@@ -1519,14 +1517,14 @@ void do_notify_parent(struct task_struct *tsk, int sig) | |||
1519 | spin_unlock_irqrestore(&psig->siglock, flags); | 1517 | spin_unlock_irqrestore(&psig->siglock, flags); |
1520 | } | 1518 | } |
1521 | 1519 | ||
1522 | static void do_notify_parent_cldstop(struct task_struct *tsk, int to_self, int why) | 1520 | static void do_notify_parent_cldstop(struct task_struct *tsk, int why) |
1523 | { | 1521 | { |
1524 | struct siginfo info; | 1522 | struct siginfo info; |
1525 | unsigned long flags; | 1523 | unsigned long flags; |
1526 | struct task_struct *parent; | 1524 | struct task_struct *parent; |
1527 | struct sighand_struct *sighand; | 1525 | struct sighand_struct *sighand; |
1528 | 1526 | ||
1529 | if (to_self) | 1527 | if (tsk->ptrace & PT_PTRACED) |
1530 | parent = tsk->parent; | 1528 | parent = tsk->parent; |
1531 | else { | 1529 | else { |
1532 | tsk = tsk->group_leader; | 1530 | tsk = tsk->group_leader; |
@@ -1601,7 +1599,7 @@ static void ptrace_stop(int exit_code, int nostop_code, siginfo_t *info) | |||
1601 | !(current->ptrace & PT_ATTACHED)) && | 1599 | !(current->ptrace & PT_ATTACHED)) && |
1602 | (likely(current->parent->signal != current->signal) || | 1600 | (likely(current->parent->signal != current->signal) || |
1603 | !unlikely(current->signal->flags & SIGNAL_GROUP_EXIT))) { | 1601 | !unlikely(current->signal->flags & SIGNAL_GROUP_EXIT))) { |
1604 | do_notify_parent_cldstop(current, 1, CLD_TRAPPED); | 1602 | do_notify_parent_cldstop(current, CLD_TRAPPED); |
1605 | read_unlock(&tasklist_lock); | 1603 | read_unlock(&tasklist_lock); |
1606 | schedule(); | 1604 | schedule(); |
1607 | } else { | 1605 | } else { |
@@ -1650,25 +1648,17 @@ void ptrace_notify(int exit_code) | |||
1650 | static void | 1648 | static void |
1651 | finish_stop(int stop_count) | 1649 | finish_stop(int stop_count) |
1652 | { | 1650 | { |
1653 | int to_self; | ||
1654 | |||
1655 | /* | 1651 | /* |
1656 | * If there are no other threads in the group, or if there is | 1652 | * If there are no other threads in the group, or if there is |
1657 | * a group stop in progress and we are the last to stop, | 1653 | * a group stop in progress and we are the last to stop, |
1658 | * report to the parent. When ptraced, every thread reports itself. | 1654 | * report to the parent. When ptraced, every thread reports itself. |
1659 | */ | 1655 | */ |
1660 | if (current->ptrace & PT_PTRACED) | 1656 | if (stop_count == 0 || (current->ptrace & PT_PTRACED)) { |
1661 | to_self = 1; | 1657 | read_lock(&tasklist_lock); |
1662 | else if (stop_count == 0) | 1658 | do_notify_parent_cldstop(current, CLD_STOPPED); |
1663 | to_self = 0; | 1659 | read_unlock(&tasklist_lock); |
1664 | else | 1660 | } |
1665 | goto out; | ||
1666 | |||
1667 | read_lock(&tasklist_lock); | ||
1668 | do_notify_parent_cldstop(current, to_self, CLD_STOPPED); | ||
1669 | read_unlock(&tasklist_lock); | ||
1670 | 1661 | ||
1671 | out: | ||
1672 | schedule(); | 1662 | schedule(); |
1673 | /* | 1663 | /* |
1674 | * Now we don't run again until continued. | 1664 | * Now we don't run again until continued. |