I'm seeing aborts of the test-sigdelay1 and test-sigdelay2 tests on
OpenBSD and on 32-bit Cygwin.
The cause is the use of signal numbers >= NSIG, together with an
incorrect use of the sigismember() function. sigismember() does not
return a boolean value; it returns a negative value for invalid
signal numbers.
To fix this, here are two patches:
- Change sigismember() invocations to treat invalid signal numbers
like signals that are not in the set.
- Avoid iterating over invalid signal numbers in the first place.
2026-04-16 Bruno Haible <[email protected]>
sigdelay: Don't use out-of-range signal numbers.
* lib/sigdelay.c (states): Change number of elements to NSIG.
sigdelay, posix-spawn-internal: Ignore out-of-range signal numbers.
* lib/sigdelay.c (sigdelay): Do nothing when sigismember() returns -1.
* lib/spawni.c (__spawni): Likewise.
>From 9bb54c2fe5d2ffe5fc44085f32e7d2cde31c18f8 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Thu, 16 Apr 2026 14:14:38 +0200
Subject: [PATCH 1/2] sigdelay, posix-spawn-internal: Ignore out-of-range
signal numbers.
* lib/sigdelay.c (sigdelay): Do nothing when sigismember() returns -1.
* lib/spawni.c (__spawni): Likewise.
---
ChangeLog | 6 ++++++
lib/sigdelay.c | 2 +-
lib/spawni.c | 2 +-
3 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 67e90f524b..55f69d5198 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2026-04-16 Bruno Haible <[email protected]>
+
+ sigdelay, posix-spawn-internal: Ignore out-of-range signal numbers.
+ * lib/sigdelay.c (sigdelay): Do nothing when sigismember() returns -1.
+ * lib/spawni.c (__spawni): Likewise.
+
2026-04-16 Bruno Haible <[email protected]>
sigprocmask: Fix sigismember function.
diff --git a/lib/sigdelay.c b/lib/sigdelay.c
index d69fa6126b..ea0292ff90 100644
--- a/lib/sigdelay.c
+++ b/lib/sigdelay.c
@@ -76,7 +76,7 @@ sigdelay (int how, const sigset_t *restrict set, sigset_t *restrict old_set)
sigaddset (old_set, sig);
for (int sig = 1; sig < countof (states); sig++)
- if (sigismember (set, sig))
+ if (sigismember (set, sig) > 0)
{
switch (how)
{
diff --git a/lib/spawni.c b/lib/spawni.c
index 9e34e95c11..2ed0c69652 100644
--- a/lib/spawni.c
+++ b/lib/spawni.c
@@ -956,7 +956,7 @@ __spawni (pid_t *pid, const char *file,
sa.sa_handler = SIG_DFL;
for (int sig = 1; sig < NSIG; ++sig)
- if (sigismember (&attrp->_sd, sig) != 0
+ if (sigismember (&attrp->_sd, sig) > 0
&& sigaction (sig, &sa, NULL) != 0)
_exit (SPAWN_ERROR);
--
2.52.0
>From 0d791d4881ab315c4a30454cb574ac16cb2d4749 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Thu, 16 Apr 2026 14:15:52 +0200
Subject: [PATCH 2/2] sigdelay: Don't use out-of-range signal numbers.
* lib/sigdelay.c (states): Change number of elements to NSIG.
---
ChangeLog | 3 +++
lib/sigdelay.c | 4 ++--
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 55f69d5198..899ef72c2a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
2026-04-16 Bruno Haible <[email protected]>
+ sigdelay: Don't use out-of-range signal numbers.
+ * lib/sigdelay.c (states): Change number of elements to NSIG.
+
sigdelay, posix-spawn-internal: Ignore out-of-range signal numbers.
* lib/sigdelay.c (sigdelay): Do nothing when sigismember() returns -1.
* lib/spawni.c (__spawni): Likewise.
diff --git a/lib/sigdelay.c b/lib/sigdelay.c
index ea0292ff90..b85e816247 100644
--- a/lib/sigdelay.c
+++ b/lib/sigdelay.c
@@ -41,8 +41,8 @@ struct state
};
/* The state for all signals.
- Size 32 would not be sufficient: On HP-UX, SIGXCPU = 33, SIGXFSZ = 34. */
-static struct state states[64];
+ NSIG is the maximum signal number + 1. */
+static struct state states[NSIG];
static _GL_ASYNC_SAFE void
delaying_handler (int sig)
--
2.52.0