]> err.no Git - linux-2.6/blobdiff - kernel/signal.c
iwlwifi: fix printk newlines
[linux-2.6] / kernel / signal.c
index 10b31ecdd9c80df91d95fde3e78288313302ca0f..c539f60c6f41bc2b9e170b93bf66a8bca5e93ce3 100644 (file)
@@ -134,7 +134,9 @@ void recalc_sigpending_and_wake(struct task_struct *t)
 
 void recalc_sigpending(void)
 {
-       if (!recalc_sigpending_tsk(current) && !freezing(current))
+       if (unlikely(tracehook_force_sigpending()))
+               set_thread_flag(TIF_SIGPENDING);
+       else if (!recalc_sigpending_tsk(current) && !freezing(current))
                clear_thread_flag(TIF_SIGPENDING);
 
 }
@@ -596,9 +598,6 @@ static int check_kill_permission(int sig, struct siginfo *info,
        return security_task_kill(t, info, sig, 0);
 }
 
-/* forward decl */
-static void do_notify_parent_cldstop(struct task_struct *tsk, int why);
-
 /*
  * Handle magic process-wide effects of stop/continue signals. Unlike
  * the signal actions, these happen immediately at signal-generation
@@ -1305,6 +1304,7 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group)
                q->info.si_overrun++;
                goto out;
        }
+       q->info.si_overrun = 0;
 
        signalfd_notify(t, sig);
        pending = group ? &t->signal->shared_pending : &t->pending;
@@ -1329,9 +1329,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;
@@ -1402,12 +1404,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)
@@ -1605,7 +1609,7 @@ finish_stop(int stop_count)
         * a group stop in progress and we are the last to stop,
         * report to the parent.  When ptraced, every thread reports itself.
         */
-       if (stop_count == 0 || (current->ptrace & PT_PTRACED)) {
+       if (tracehook_notify_jctl(stop_count == 0, CLD_STOPPED)) {
                read_lock(&tasklist_lock);
                do_notify_parent_cldstop(current, CLD_STOPPED);
                read_unlock(&tasklist_lock);
@@ -1741,6 +1745,9 @@ relock:
                signal->flags &= ~SIGNAL_CLD_MASK;
                spin_unlock_irq(&sighand->siglock);
 
+               if (unlikely(!tracehook_notify_jctl(1, why)))
+                       goto relock;
+
                read_lock(&tasklist_lock);
                do_notify_parent_cldstop(current->group_leader, why);
                read_unlock(&tasklist_lock);
@@ -1906,7 +1913,7 @@ void exit_signals(struct task_struct *tsk)
 out:
        spin_unlock_irq(&tsk->sighand->siglock);
 
-       if (unlikely(group_stop)) {
+       if (unlikely(group_stop) && tracehook_notify_jctl(1, CLD_STOPPED)) {
                read_lock(&tasklist_lock);
                do_notify_parent_cldstop(tsk, CLD_STOPPED);
                read_unlock(&tasklist_lock);