aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/signal.c42
1 files changed, 17 insertions, 25 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index 772aa011dad8..fb8ffd468854 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -668,6 +668,14 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
668 struct sigqueue * q = NULL; 668 struct sigqueue * q = NULL;
669 669
670 /* 670 /*
671 * Short-circuit ignored signals and support queuing
672 * exactly one non-rt signal, so that we can get more
673 * detailed information about the cause of the signal.
674 */
675 if (sig_ignored(t, sig) || legacy_queue(signals, sig))
676 return 0;
677
678 /*
671 * Deliver the signal to listening signalfds. This must be called 679 * Deliver the signal to listening signalfds. This must be called
672 * with the sighand lock held. 680 * with the sighand lock held.
673 */ 681 */
@@ -723,7 +731,7 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
723 731
724out_set: 732out_set:
725 sigaddset(&signals->signal, sig); 733 sigaddset(&signals->signal, sig);
726 return 0; 734 return 1;
727} 735}
728 736
729int print_fatal_signals; 737int print_fatal_signals;
@@ -761,26 +769,18 @@ __setup("print-fatal-signals=", setup_print_fatal_signals);
761static int 769static int
762specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t) 770specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
763{ 771{
764 int ret = 0; 772 int ret;
765 773
766 BUG_ON(!irqs_disabled()); 774 BUG_ON(!irqs_disabled());
767 assert_spin_locked(&t->sighand->siglock); 775 assert_spin_locked(&t->sighand->siglock);
768 776
769 /* Short-circuit ignored signals. */
770 if (sig_ignored(t, sig))
771 goto out;
772
773 /* Support queueing exactly one non-rt signal, so that we
774 can get more detailed information about the cause of
775 the signal. */
776 if (legacy_queue(&t->pending, sig))
777 goto out;
778
779 ret = send_signal(sig, info, t, &t->pending); 777 ret = send_signal(sig, info, t, &t->pending);
780 if (!ret && !sigismember(&t->blocked, sig)) 778 if (ret <= 0)
779 return ret;
780
781 if (!sigismember(&t->blocked, sig))
781 signal_wake_up(t, sig == SIGKILL); 782 signal_wake_up(t, sig == SIGKILL);
782out: 783 return 0;
783 return ret;
784} 784}
785 785
786/* 786/*
@@ -925,26 +925,18 @@ __group_complete_signal(int sig, struct task_struct *p)
925int 925int
926__group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p) 926__group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
927{ 927{
928 int ret = 0; 928 int ret;
929 929
930 assert_spin_locked(&p->sighand->siglock); 930 assert_spin_locked(&p->sighand->siglock);
931 handle_stop_signal(sig, p); 931 handle_stop_signal(sig, p);
932 932
933 /* Short-circuit ignored signals. */
934 if (sig_ignored(p, sig))
935 return ret;
936
937 if (legacy_queue(&p->signal->shared_pending, sig))
938 /* This is a non-RT signal and we already have one queued. */
939 return ret;
940
941 /* 933 /*
942 * Put this signal on the shared-pending queue, or fail with EAGAIN. 934 * Put this signal on the shared-pending queue, or fail with EAGAIN.
943 * We always use the shared queue for process-wide signals, 935 * We always use the shared queue for process-wide signals,
944 * to avoid several races. 936 * to avoid several races.
945 */ 937 */
946 ret = send_signal(sig, info, p, &p->signal->shared_pending); 938 ret = send_signal(sig, info, p, &p->signal->shared_pending);
947 if (unlikely(ret)) 939 if (ret <= 0)
948 return ret; 940 return ret;
949 941
950 __group_complete_signal(sig, p); 942 __group_complete_signal(sig, p);