diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/signal.c | 42 |
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 | ||
724 | out_set: | 732 | out_set: |
725 | sigaddset(&signals->signal, sig); | 733 | sigaddset(&signals->signal, sig); |
726 | return 0; | 734 | return 1; |
727 | } | 735 | } |
728 | 736 | ||
729 | int print_fatal_signals; | 737 | int print_fatal_signals; |
@@ -761,26 +769,18 @@ __setup("print-fatal-signals=", setup_print_fatal_signals); | |||
761 | static int | 769 | static int |
762 | specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t) | 770 | specific_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); |
782 | out: | 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) | |||
925 | int | 925 | int |
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); |