https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=d33a13e5c167b4758c0d09807d84012b58269af3
commit d33a13e5c167b4758c0d09807d84012b58269af3 Author: Jeremy Drake <cyg...@jdrake.com> Date: Thu Jun 19 10:22:52 2025 -0700 Cygwin: testsuite: test signal mask and ignore options. Test both that SIG_IGN and sigprocmask are inherited by default, and that posix_spawnattr options can prevent this. Signed-off-by: Jeremy Drake <cyg...@jdrake.com> Diff: --- winsup/testsuite/Makefile.am | 1 + winsup/testsuite/winsup.api/posix_spawn/signals.c | 82 +++++++++++++++++++++++ winsup/testsuite/winsup.api/posix_spawn/test.h | 10 +++ 3 files changed, 93 insertions(+) diff --git a/winsup/testsuite/Makefile.am b/winsup/testsuite/Makefile.am index 1cda72905..b92532e4f 100644 --- a/winsup/testsuite/Makefile.am +++ b/winsup/testsuite/Makefile.am @@ -312,6 +312,7 @@ check_PROGRAMS = \ winsup.api/pthread/threadidafterfork \ winsup.api/pthread/tsd1 \ winsup.api/posix_spawn/errors \ + winsup.api/posix_spawn/signals \ winsup.api/posix_spawn/spawnp \ winsup.api/samples/sample-fail \ winsup.api/samples/sample-pass diff --git a/winsup/testsuite/winsup.api/posix_spawn/signals.c b/winsup/testsuite/winsup.api/posix_spawn/signals.c new file mode 100644 index 000000000..f64404ddc --- /dev/null +++ b/winsup/testsuite/winsup.api/posix_spawn/signals.c @@ -0,0 +1,82 @@ +#include "test.h" +#include <signal.h> +#include <spawn.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +int handle_child (char *arg) +{ + struct sigaction sa; + sigset_t mask; + int ret; + + negError (sigaction (SIGUSR1, NULL, &sa)); + negError (sigprocmask (SIG_SETMASK, NULL, &mask)); + negError (ret = sigismember (&mask, SIGUSR2)); + + if (!strcmp (arg, "inherited")) + { + testAssert (sa.sa_handler == SIG_IGN); + testAssertMsg (ret, "SIGUSR2 not masked"); + } + else + { + testAssert (sa.sa_handler == SIG_DFL); + testAssertMsg (!ret, "SIGUSR2 masked"); + } + + return 0; +} + +int main (int argc, char **argv) +{ + posix_spawnattr_t sa; + pid_t pid; + int status; + sigset_t sigusr1mask, sigusr2mask, emptymask; + char *childargv[] = {"signal", "--child", "inherited", NULL}; + + /* unbuffer stdout */ + setvbuf(stdout, NULL, _IONBF, 0); + + if (argc == 3 && !strcmp (argv[1], "--child")) + return handle_child (argv[2]); + + negError (sigemptyset (&sigusr1mask)); + negError (sigaddset (&sigusr1mask, SIGUSR1)); + negError (sigemptyset (&sigusr2mask)); + negError (sigaddset (&sigusr2mask, SIGUSR2)); + negError (sigemptyset (&emptymask)); + + /* set all signals to default */ + for (int i = 1; i < NSIG; ++i) + if (i != SIGKILL && i != SIGSTOP) + signal (i, SIG_DFL); + + /* change some signal states to test signal-related posix_spawn flags */ + sigError (signal (SIGUSR1, SIG_IGN)); + negError (sigprocmask (SIG_SETMASK, &sigusr2mask, NULL)); + + /* ensure ignored and blocked signals are inherited by default */ + errCode (posix_spawn (&pid, MYSELF, NULL, NULL, childargv, environ)); + negError (waitpid (pid, &status, 0)); + exitStatus (status, 0); + + errCode (posix_spawnattr_init (&sa)); + errCode (posix_spawnattr_setsigmask (&sa, &emptymask)); + errCode (posix_spawnattr_setsigdefault (&sa, &sigusr1mask)); + errCode (posix_spawnattr_setflags (&sa, + POSIX_SPAWN_SETSIGDEF|POSIX_SPAWN_SETSIGMASK)); + + /* ensure setsigmask and setsigdefault work */ + childargv[2] = "spawnattr"; + errCode (posix_spawn (&pid, MYSELF, NULL, &sa, childargv, environ)); + negError (waitpid (pid, &status, 0)); + exitStatus (status, 0); + + errCode (posix_spawnattr_destroy (&sa)); + + return 0; +} diff --git a/winsup/testsuite/winsup.api/posix_spawn/test.h b/winsup/testsuite/winsup.api/posix_spawn/test.h index e10b6ce5e..531d11c4d 100644 --- a/winsup/testsuite/winsup.api/posix_spawn/test.h +++ b/winsup/testsuite/winsup.api/posix_spawn/test.h @@ -34,5 +34,15 @@ "child exited with code %d", WEXITSTATUS ((status))); \ } while (0) +/* first vararg to testAssertMsg must be string msg */ +#define testAssertMsg(cond, ...) do { \ + if (!(cond)) \ + error_at_line (1, 0, __FILE__, __LINE__, __VA_ARGS__); \ +} while (0); + +#define testAssert(cond) testAssertMsg(cond, "%s", #cond) + +#define MYSELF "/proc/self/exe" + #endif /* _POSIX_SPAWN_TEST_H_ */