about summary refs log tree commit diff
path: root/src/signal
diff options
context:
space:
mode:
Diffstat (limited to 'src/signal')
-rw-r--r--src/signal/sigaction.c17
1 files changed, 8 insertions, 9 deletions
diff --git a/src/signal/sigaction.c b/src/signal/sigaction.c
index a4737404..7232d4b9 100644
--- a/src/signal/sigaction.c
+++ b/src/signal/sigaction.c
@@ -21,6 +21,13 @@ int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigact
 {
 	struct k_sigaction ksa, ksa_old;
 	unsigned long set[_NSIG/(8*sizeof(long))];
+	/* Doing anything with the disposition of SIGABRT requires a lock,
+	 * so that it cannot be changed while abort is terminating the
+	 * process and so any change made by abort can't be observed. */
+	if (sig == SIGABRT) {
+		__block_all_sigs(&set);
+		LOCK(__abort_lock);
+	}
 	if (sa) {
 		if ((uintptr_t)sa->sa_handler > 1UL) {
 			a_or_l(handler_set+(sig-1)/(8*sizeof(long)),
@@ -44,21 +51,13 @@ int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigact
 				a_store(&__eintr_valid_flag, 1);
 			}
 		}
-		/* Changing the disposition of SIGABRT to anything but
-		 * SIG_DFL requires a lock, so that it cannot be changed
-		 * while abort is terminating the process after simply
-		 * calling raise(SIGABRT) failed to do so. */
-		if (sa->sa_handler != SIG_DFL && sig == SIGABRT) {
-			__block_all_sigs(&set);
-			LOCK(__abort_lock);
-		}
 		ksa.handler = sa->sa_handler;
 		ksa.flags = sa->sa_flags | SA_RESTORER;
 		ksa.restorer = (sa->sa_flags & SA_SIGINFO) ? __restore_rt : __restore;
 		memcpy(&ksa.mask, &sa->sa_mask, _NSIG/8);
 	}
 	int r = __syscall(SYS_rt_sigaction, sig, sa?&ksa:0, old?&ksa_old:0, _NSIG/8);
-	if (sig == SIGABRT && sa && sa->sa_handler != SIG_DFL) {
+	if (sig == SIGABRT) {
 		UNLOCK(__abort_lock);
 		__restore_sigs(&set);
 	}