From 446b8a0e5d4994ed7c149c8e5d8ddab475177965 Mon Sep 17 00:00:00 2001 From: Arshia Ghafoori Date: Thu, 30 Jul 2026 07:45:17 +0000 Subject: [PATCH 1/5] test(wasix): cover sa_handler and SA_SIGINFO signal dispatch Handlers installed through `sa_sigaction` with `SA_SIGINFO` take three arguments, while `sa_handler` handlers take one. On wasm the arity is part of the function type, so dispatching the three-argument form through the one-argument signature traps with "indirect call type mismatch" and exits with `Errno::Intr`. Exercise both dispatch forms. Requires the wasix-libc fix in wasix-org/wasix-libc; gated with `MinimalLibc` so pinned older sysroots skip rather than fail. Co-Authored-By: Claude Opus 5 (1M context) --- .../signal/sigaction-siginfo/main.c | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 lib/wasix/tests/wasm_tests/signal/sigaction-siginfo/main.c diff --git a/lib/wasix/tests/wasm_tests/signal/sigaction-siginfo/main.c b/lib/wasix/tests/wasm_tests/signal/sigaction-siginfo/main.c new file mode 100644 index 000000000000..bebe378017fe --- /dev/null +++ b/lib/wasix/tests/wasm_tests/signal/sigaction-siginfo/main.c @@ -0,0 +1,58 @@ +//#MinimalLibc: v2026-07-30.1 +//#ExpectedStdout: plain handler ok +//#ExpectedStdout: siginfo handler ok + +#include +#include +#include +#include + +// A handler installed through `sa_sigaction` with `SA_SIGINFO` takes three +// arguments, while one installed through `sa_handler` takes a single one. On +// wasm these are distinct function types, so dispatching a three-argument +// handler through a one-argument `call_indirect` traps with "indirect call +// type mismatch" and kills the instance. Cover both dispatch forms. + +static volatile sig_atomic_t plain_calls = 0; +static volatile sig_atomic_t info_calls = 0; +static volatile sig_atomic_t info_signo = 0; +static volatile sig_atomic_t info_arg_ok = 0; + +static void plain_handler(int sig) { + (void)sig; + plain_calls++; +} + +static void info_handler(int sig, siginfo_t *info, void *ucontext) { + (void)ucontext; + info_calls++; + info_signo = sig; + info_arg_ok = (info != NULL && info->si_signo == sig); +} + +int main() { + struct sigaction sa; + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = plain_handler; + sigfillset(&sa.sa_mask); + assert(sigaction(SIGUSR1, &sa, NULL) == 0); + + assert(raise(SIGUSR1) == 0); + assert(plain_calls == 1 && "one-argument handler should have run"); + printf("plain handler ok\n"); + + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = info_handler; + sa.sa_flags = SA_SIGINFO; + sigfillset(&sa.sa_mask); + assert(sigaction(SIGUSR2, &sa, NULL) == 0); + + assert(raise(SIGUSR2) == 0); + assert(info_calls == 1 && "three-argument handler should have run"); + assert(info_signo == SIGUSR2 && "handler should receive the signal number"); + assert(info_arg_ok && "handler should receive a populated siginfo_t"); + printf("siginfo handler ok\n"); + + return 0; +} From 0daae54f30e2b9c998e4cbb1f05e395c7b7c9f62 Mon Sep 17 00:00:00 2001 From: Arshia Ghafoori Date: Thu, 30 Jul 2026 09:22:11 +0000 Subject: [PATCH 2/5] test(wasix): cover SA_RESETHAND disposition reset POSIX resets a handler installed with SA_RESETHAND to SIG_DFL on entry, so a signal re-raised from inside it takes the default action rather than re-entering the handler. Node's `SignalExit` relies on that; without the reset it recurses until the stack is exhausted. The reset is asserted directly instead of by re-raising: unbounded re-entry exhausts the host stack and would take the test process down rather than failing this one test. Co-Authored-By: Claude Opus 5 (1M context) --- .../signal/sigaction-resethand/main.c | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 lib/wasix/tests/wasm_tests/signal/sigaction-resethand/main.c diff --git a/lib/wasix/tests/wasm_tests/signal/sigaction-resethand/main.c b/lib/wasix/tests/wasm_tests/signal/sigaction-resethand/main.c new file mode 100644 index 000000000000..14d17dc05841 --- /dev/null +++ b/lib/wasix/tests/wasm_tests/signal/sigaction-resethand/main.c @@ -0,0 +1,47 @@ +//#MinimalLibc: v2026-07-30.1 +//#ExpectedStdout: resethand ok + +#include +#include +#include +#include + +// POSIX resets a handler installed with SA_RESETHAND to SIG_DFL on entry, so +// re-raising the same signal from inside the handler takes the default action +// instead of re-entering the handler. Node's `SignalExit` relies on exactly +// that: it re-raises to let the default disposition terminate the process. +// Without the reset it recurses until the stack is exhausted. +// +// The reset is asserted directly rather than by re-raising, because unbounded +// re-entry exhausts the host stack and would take the test process down with +// it instead of failing this one test. + +static volatile sig_atomic_t calls = 0; + +static void handler(int sig, siginfo_t *info, void *ucontext) { + (void)sig; + (void)info; + (void)ucontext; + calls++; +} + +int main() { + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = handler; + sa.sa_flags = SA_SIGINFO | SA_RESETHAND; + sigfillset(&sa.sa_mask); + assert(sigaction(SIGUSR1, &sa, NULL) == 0); + + assert(raise(SIGUSR1) == 0); + assert(calls == 1 && "handler should have run once"); + + struct sigaction old; + memset(&old, 0, sizeof(old)); + assert(sigaction(SIGUSR1, NULL, &old) == 0); + assert(old.sa_handler == SIG_DFL && + "SA_RESETHAND should reset the disposition to SIG_DFL"); + + printf("resethand ok\n"); + return 0; +} From 28db01b6c3a49a90b45f76aac1c26d3e578178a0 Mon Sep 17 00:00:00 2001 From: Arshia Ghafoori Date: Thu, 30 Jul 2026 12:28:02 +0000 Subject: [PATCH 3/5] test(wasix): cover per-thread signal mask semantics Five fixtures for sa_mask, SA_NODEFER, sigprocmask/sigpending, and mask inheritance across pthread_create. sigaction-mask-defers and sigaction-nodefer-reenters are the same program differing only in SA_NODEFER, so they pin the semantics from both sides: the handler re-raises its own signal and records how often it ran and how deep it nested. Without SA_NODEFER the delivery is deferred and the handler runs five times sequentially (max_depth 1); with it the handler re-enters and nests five deep. The re-raise is gated on a counter in guest code, so the recursion is bounded whatever libc does rather than exhausting the host stack. Note that nodefer-reenters must use an empty sa_mask: sa_mask is applied on top of SA_NODEFER, so a sigfillset() mask would block the signal anyway and defeat the opt-out being tested. Requires the mask implementation in wasix-org/wasix-libc. Co-Authored-By: Claude Opus 5 (1M context) --- .../signal/pthread-sigmask-inherit/main.c | 55 +++++++++++++++++ .../signal/sigaction-mask-blocks-other/main.c | 61 +++++++++++++++++++ .../signal/sigaction-mask-defers/main.c | 60 ++++++++++++++++++ .../signal/sigaction-nodefer-reenters/main.c | 57 +++++++++++++++++ .../sigprocmask-blocks-and-pends/main.c | 56 +++++++++++++++++ 5 files changed, 289 insertions(+) create mode 100644 lib/wasix/tests/wasm_tests/signal/pthread-sigmask-inherit/main.c create mode 100644 lib/wasix/tests/wasm_tests/signal/sigaction-mask-blocks-other/main.c create mode 100644 lib/wasix/tests/wasm_tests/signal/sigaction-mask-defers/main.c create mode 100644 lib/wasix/tests/wasm_tests/signal/sigaction-nodefer-reenters/main.c create mode 100644 lib/wasix/tests/wasm_tests/signal/sigprocmask-blocks-and-pends/main.c diff --git a/lib/wasix/tests/wasm_tests/signal/pthread-sigmask-inherit/main.c b/lib/wasix/tests/wasm_tests/signal/pthread-sigmask-inherit/main.c new file mode 100644 index 000000000000..4f05f16a62a3 --- /dev/null +++ b/lib/wasix/tests/wasm_tests/signal/pthread-sigmask-inherit/main.c @@ -0,0 +1,55 @@ +//#MinimalLibc: v2026-07-30.1 +//#ExpectedStdout: child inherited the blocked mask + +#include +#include +#include +#include +#include + +// A new thread inherits its creator's signal mask, and the mask is per-thread: +// unblocking in the child must not affect the parent. + +static volatile int child_saw_blocked = 0; +static volatile int child_query_ok = 0; + +static void *child(void *arg) { + (void)arg; + + sigset_t mask; + sigemptyset(&mask); + child_query_ok = (pthread_sigmask(SIG_BLOCK, NULL, &mask) == 0); + child_saw_blocked = sigismember(&mask, SIGUSR1); + + sigset_t unblock; + sigemptyset(&unblock); + sigaddset(&unblock, SIGUSR1); + pthread_sigmask(SIG_UNBLOCK, &unblock, NULL); + + return NULL; +} + +int main() { + sigset_t block; + sigemptyset(&block); + sigaddset(&block, SIGUSR1); + assert(pthread_sigmask(SIG_BLOCK, &block, NULL) == 0); + + pthread_t thread; + assert(pthread_create(&thread, NULL, child, NULL) == 0); + assert(pthread_join(thread, NULL) == 0); + + assert(child_query_ok && "pthread_sigmask should succeed in the child"); + assert(child_saw_blocked == 1 && + "child should inherit the creator's blocked mask"); + + // The child unblocked SIGUSR1 for itself only; ours must still be blocked. + sigset_t mine; + sigemptyset(&mine); + assert(pthread_sigmask(SIG_BLOCK, NULL, &mine) == 0); + assert(sigismember(&mine, SIGUSR1) == 1 && + "the mask should be per-thread, not shared"); + + printf("child inherited the blocked mask\n"); + return 0; +} diff --git a/lib/wasix/tests/wasm_tests/signal/sigaction-mask-blocks-other/main.c b/lib/wasix/tests/wasm_tests/signal/sigaction-mask-blocks-other/main.c new file mode 100644 index 000000000000..57bb5edfccbf --- /dev/null +++ b/lib/wasix/tests/wasm_tests/signal/sigaction-mask-blocks-other/main.c @@ -0,0 +1,61 @@ +//#MinimalLibc: v2026-07-30.1 +//#ExpectedStdout: usr2 deferred until handler returned + +#include +#include +#include +#include + +// sa_mask names *additional* signals to block while a handler runs, not just +// the one being delivered. A SIGUSR1 handler whose sa_mask contains SIGUSR2 +// must not be interrupted by SIGUSR2; that delivery is deferred until the +// handler returns. + +static volatile sig_atomic_t usr2_calls = 0; +static volatile sig_atomic_t usr2_seen_inside = -1; + +static void usr1_handler(int sig, siginfo_t *info, void *ucontext) { + (void)sig; + (void)info; + (void)ucontext; + + raise(SIGUSR2); + // Sampled before returning: SIGUSR2 is in our sa_mask, so it must still be + // pending rather than already handled. + usr2_seen_inside = usr2_calls; +} + +static void usr2_handler(int sig, siginfo_t *info, void *ucontext) { + (void)sig; + (void)info; + (void)ucontext; + + usr2_calls++; +} + +int main() { + struct sigaction sa; + + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = usr2_handler; + sa.sa_flags = SA_SIGINFO; + sigemptyset(&sa.sa_mask); + assert(sigaction(SIGUSR2, &sa, NULL) == 0); + + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = usr1_handler; + sa.sa_flags = SA_SIGINFO; + sigemptyset(&sa.sa_mask); + sigaddset(&sa.sa_mask, SIGUSR2); + assert(sigaction(SIGUSR1, &sa, NULL) == 0); + + assert(raise(SIGUSR1) == 0); + + assert(usr2_seen_inside == 0 && + "sa_mask should keep SIGUSR2 blocked inside the SIGUSR1 handler"); + assert(usr2_calls == 1 && + "SIGUSR2 should be delivered once the SIGUSR1 handler returns"); + + printf("usr2 deferred until handler returned\n"); + return 0; +} diff --git a/lib/wasix/tests/wasm_tests/signal/sigaction-mask-defers/main.c b/lib/wasix/tests/wasm_tests/signal/sigaction-mask-defers/main.c new file mode 100644 index 000000000000..14e092314439 --- /dev/null +++ b/lib/wasix/tests/wasm_tests/signal/sigaction-mask-defers/main.c @@ -0,0 +1,60 @@ +//#MinimalLibc: v2026-07-30.1 +//#ExpectedStdout: calls=5 max_depth=1 + +#include +#include +#include +#include + +// POSIX blocks the delivered signal for the duration of its handler (sa_mask +// plus the signal itself, the latter unless SA_NODEFER). So a signal re-raised +// from inside the handler is deferred and delivered once the handler returns, +// running the handler again sequentially rather than nesting it. +// +// The re-raise is gated on `calls < LIMIT` in guest code, so the recursion is +// bounded no matter how libc behaves: even with masking entirely broken this +// nests 5 deep rather than exhausting the stack. +// +// Paired with sigaction-nodefer-reenters, which is the same program with +// SA_NODEFER and therefore expects max_depth == LIMIT. + +#define LIMIT 5 + +static volatile sig_atomic_t calls = 0; +static volatile sig_atomic_t depth = 0; +static volatile sig_atomic_t max_depth = 0; + +static void handler(int sig, siginfo_t *info, void *ucontext) { + (void)info; + (void)ucontext; + + calls++; + depth++; + if (depth > max_depth) { + max_depth = depth; + } + if (calls < LIMIT) { + raise(sig); + } + depth--; +} + +int main() { + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = handler; + sa.sa_flags = SA_SIGINFO; + sigfillset(&sa.sa_mask); + assert(sigaction(SIGUSR1, &sa, NULL) == 0); + + // Every deferred delivery is drained before the raise that triggered the + // first one returns, so no further syscall is needed to observe them. + assert(raise(SIGUSR1) == 0); + + assert(calls == LIMIT && "handler should run once per raise"); + assert(max_depth == 1 && "a blocked signal must not re-enter its handler"); + assert(depth == 0 && "every invocation should have returned"); + + printf("calls=%d max_depth=%d\n", (int)calls, (int)max_depth); + return 0; +} diff --git a/lib/wasix/tests/wasm_tests/signal/sigaction-nodefer-reenters/main.c b/lib/wasix/tests/wasm_tests/signal/sigaction-nodefer-reenters/main.c new file mode 100644 index 000000000000..2fafb128ffd8 --- /dev/null +++ b/lib/wasix/tests/wasm_tests/signal/sigaction-nodefer-reenters/main.c @@ -0,0 +1,57 @@ +//#MinimalLibc: v2026-07-30.1 +//#ExpectedStdout: calls=5 max_depth=5 + +#include +#include +#include +#include + +// SA_NODEFER opts out of adding the delivered signal to the mask for the +// duration of its handler, so a signal re-raised from inside the handler +// re-enters it immediately instead of being deferred. +// +// sa_mask must be empty here: it is applied on top of SA_NODEFER, so a +// sigfillset() mask would block SIGUSR1 anyway and defeat the opt-out. +// +// The re-raise is gated on `calls < LIMIT` in guest code, bounding the nesting +// to 5 frames. Paired with sigaction-mask-defers, the same program without +// SA_NODEFER, which expects max_depth == 1. + +#define LIMIT 5 + +static volatile sig_atomic_t calls = 0; +static volatile sig_atomic_t depth = 0; +static volatile sig_atomic_t max_depth = 0; + +static void handler(int sig, siginfo_t *info, void *ucontext) { + (void)info; + (void)ucontext; + + calls++; + depth++; + if (depth > max_depth) { + max_depth = depth; + } + if (calls < LIMIT) { + raise(sig); + } + depth--; +} + +int main() { + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = handler; + sa.sa_flags = SA_SIGINFO | SA_NODEFER; + sigemptyset(&sa.sa_mask); + assert(sigaction(SIGUSR1, &sa, NULL) == 0); + + assert(raise(SIGUSR1) == 0); + + assert(calls == LIMIT && "handler should run once per raise"); + assert(max_depth == LIMIT && "SA_NODEFER should allow the handler to nest"); + assert(depth == 0 && "every invocation should have returned"); + + printf("calls=%d max_depth=%d\n", (int)calls, (int)max_depth); + return 0; +} diff --git a/lib/wasix/tests/wasm_tests/signal/sigprocmask-blocks-and-pends/main.c b/lib/wasix/tests/wasm_tests/signal/sigprocmask-blocks-and-pends/main.c new file mode 100644 index 000000000000..ce8eb7dd3465 --- /dev/null +++ b/lib/wasix/tests/wasm_tests/signal/sigprocmask-blocks-and-pends/main.c @@ -0,0 +1,56 @@ +//#MinimalLibc: v2026-07-30.1 +//#ExpectedStdout: blocked, pending, then delivered on unblock + +#include +#include +#include +#include + +// sigprocmask must actually block: a signal raised while blocked is held +// pending, reported by sigpending(), and delivered when it is unblocked. +// Delivery has to happen before sigprocmask returns, since WASIX only delivers +// signals at syscall boundaries and nothing else would come along to do it. + +static volatile sig_atomic_t calls = 0; + +static void handler(int sig, siginfo_t *info, void *ucontext) { + (void)sig; + (void)info; + (void)ucontext; + + calls++; +} + +int main() { + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = handler; + sa.sa_flags = SA_SIGINFO; + sigemptyset(&sa.sa_mask); + assert(sigaction(SIGUSR1, &sa, NULL) == 0); + + sigset_t block; + sigemptyset(&block); + sigaddset(&block, SIGUSR1); + assert(sigprocmask(SIG_BLOCK, &block, NULL) == 0); + + assert(raise(SIGUSR1) == 0); + assert(calls == 0 && "a blocked signal must not be delivered"); + + sigset_t pending; + sigemptyset(&pending); + assert(sigpending(&pending) == 0); + assert(sigismember(&pending, SIGUSR1) == 1 && + "sigpending should report the blocked signal"); + + assert(sigprocmask(SIG_UNBLOCK, &block, NULL) == 0); + assert(calls == 1 && "unblocking should deliver the pending signal"); + + sigemptyset(&pending); + assert(sigpending(&pending) == 0); + assert(sigismember(&pending, SIGUSR1) == 0 && + "the signal should no longer be pending once delivered"); + + printf("blocked, pending, then delivered on unblock\n"); + return 0; +} From 6c2d2d7e754130b8906064e8e634a642695e2e23 Mon Sep 17 00:00:00 2001 From: Arshia Ghafoori Date: Thu, 30 Jul 2026 13:35:22 +0000 Subject: [PATCH 4/5] style(wasix): clang-format the signal fixtures `make lint` runs clang-format over every .c file in the tree, and the repo style puts the pointer with the type (`siginfo_t* info`). All seven fixtures were written with the pointer on the identifier, so the Code lint job has been red since the first of them landed. Formatting only; the inline `//#Directive:` lines the harness parses are untouched and the suite still passes. Co-Authored-By: Claude Opus 5 (1M context) --- .../tests/wasm_tests/signal/pthread-sigmask-inherit/main.c | 2 +- .../wasm_tests/signal/sigaction-mask-blocks-other/main.c | 4 ++-- .../tests/wasm_tests/signal/sigaction-mask-defers/main.c | 2 +- .../tests/wasm_tests/signal/sigaction-nodefer-reenters/main.c | 2 +- lib/wasix/tests/wasm_tests/signal/sigaction-resethand/main.c | 2 +- lib/wasix/tests/wasm_tests/signal/sigaction-siginfo/main.c | 2 +- .../wasm_tests/signal/sigprocmask-blocks-and-pends/main.c | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/wasix/tests/wasm_tests/signal/pthread-sigmask-inherit/main.c b/lib/wasix/tests/wasm_tests/signal/pthread-sigmask-inherit/main.c index 4f05f16a62a3..74e3cf9e6b4b 100644 --- a/lib/wasix/tests/wasm_tests/signal/pthread-sigmask-inherit/main.c +++ b/lib/wasix/tests/wasm_tests/signal/pthread-sigmask-inherit/main.c @@ -13,7 +13,7 @@ static volatile int child_saw_blocked = 0; static volatile int child_query_ok = 0; -static void *child(void *arg) { +static void* child(void* arg) { (void)arg; sigset_t mask; diff --git a/lib/wasix/tests/wasm_tests/signal/sigaction-mask-blocks-other/main.c b/lib/wasix/tests/wasm_tests/signal/sigaction-mask-blocks-other/main.c index 57bb5edfccbf..3e0146e98812 100644 --- a/lib/wasix/tests/wasm_tests/signal/sigaction-mask-blocks-other/main.c +++ b/lib/wasix/tests/wasm_tests/signal/sigaction-mask-blocks-other/main.c @@ -14,7 +14,7 @@ static volatile sig_atomic_t usr2_calls = 0; static volatile sig_atomic_t usr2_seen_inside = -1; -static void usr1_handler(int sig, siginfo_t *info, void *ucontext) { +static void usr1_handler(int sig, siginfo_t* info, void* ucontext) { (void)sig; (void)info; (void)ucontext; @@ -25,7 +25,7 @@ static void usr1_handler(int sig, siginfo_t *info, void *ucontext) { usr2_seen_inside = usr2_calls; } -static void usr2_handler(int sig, siginfo_t *info, void *ucontext) { +static void usr2_handler(int sig, siginfo_t* info, void* ucontext) { (void)sig; (void)info; (void)ucontext; diff --git a/lib/wasix/tests/wasm_tests/signal/sigaction-mask-defers/main.c b/lib/wasix/tests/wasm_tests/signal/sigaction-mask-defers/main.c index 14e092314439..d536565a6f94 100644 --- a/lib/wasix/tests/wasm_tests/signal/sigaction-mask-defers/main.c +++ b/lib/wasix/tests/wasm_tests/signal/sigaction-mask-defers/main.c @@ -24,7 +24,7 @@ static volatile sig_atomic_t calls = 0; static volatile sig_atomic_t depth = 0; static volatile sig_atomic_t max_depth = 0; -static void handler(int sig, siginfo_t *info, void *ucontext) { +static void handler(int sig, siginfo_t* info, void* ucontext) { (void)info; (void)ucontext; diff --git a/lib/wasix/tests/wasm_tests/signal/sigaction-nodefer-reenters/main.c b/lib/wasix/tests/wasm_tests/signal/sigaction-nodefer-reenters/main.c index 2fafb128ffd8..454be080b09c 100644 --- a/lib/wasix/tests/wasm_tests/signal/sigaction-nodefer-reenters/main.c +++ b/lib/wasix/tests/wasm_tests/signal/sigaction-nodefer-reenters/main.c @@ -23,7 +23,7 @@ static volatile sig_atomic_t calls = 0; static volatile sig_atomic_t depth = 0; static volatile sig_atomic_t max_depth = 0; -static void handler(int sig, siginfo_t *info, void *ucontext) { +static void handler(int sig, siginfo_t* info, void* ucontext) { (void)info; (void)ucontext; diff --git a/lib/wasix/tests/wasm_tests/signal/sigaction-resethand/main.c b/lib/wasix/tests/wasm_tests/signal/sigaction-resethand/main.c index 14d17dc05841..61e759a7a7b2 100644 --- a/lib/wasix/tests/wasm_tests/signal/sigaction-resethand/main.c +++ b/lib/wasix/tests/wasm_tests/signal/sigaction-resethand/main.c @@ -18,7 +18,7 @@ static volatile sig_atomic_t calls = 0; -static void handler(int sig, siginfo_t *info, void *ucontext) { +static void handler(int sig, siginfo_t* info, void* ucontext) { (void)sig; (void)info; (void)ucontext; diff --git a/lib/wasix/tests/wasm_tests/signal/sigaction-siginfo/main.c b/lib/wasix/tests/wasm_tests/signal/sigaction-siginfo/main.c index bebe378017fe..de13f5b0c071 100644 --- a/lib/wasix/tests/wasm_tests/signal/sigaction-siginfo/main.c +++ b/lib/wasix/tests/wasm_tests/signal/sigaction-siginfo/main.c @@ -23,7 +23,7 @@ static void plain_handler(int sig) { plain_calls++; } -static void info_handler(int sig, siginfo_t *info, void *ucontext) { +static void info_handler(int sig, siginfo_t* info, void* ucontext) { (void)ucontext; info_calls++; info_signo = sig; diff --git a/lib/wasix/tests/wasm_tests/signal/sigprocmask-blocks-and-pends/main.c b/lib/wasix/tests/wasm_tests/signal/sigprocmask-blocks-and-pends/main.c index ce8eb7dd3465..6e957d1cb851 100644 --- a/lib/wasix/tests/wasm_tests/signal/sigprocmask-blocks-and-pends/main.c +++ b/lib/wasix/tests/wasm_tests/signal/sigprocmask-blocks-and-pends/main.c @@ -13,7 +13,7 @@ static volatile sig_atomic_t calls = 0; -static void handler(int sig, siginfo_t *info, void *ucontext) { +static void handler(int sig, siginfo_t* info, void* ucontext) { (void)sig; (void)info; (void)ucontext; From e7fc9311d76f6cd971ec5e284eeb000b11a9b0b7 Mon Sep 17 00:00:00 2001 From: Arshia Ghafoori Date: Thu, 30 Jul 2026 14:29:27 +0000 Subject: [PATCH 5/5] ci: bump the pinned wasix-libc sysroot to v2026-07-30.1 The new signal fixtures exercise SA_SIGINFO dispatch, SA_RESETHAND, and the signal mask, none of which exist in v2026-07-03.1. MinimalLibc only gates the explicitly-versioned sysroots in TESTED_LIBC_VERSIONS, so the configurations built against the pinned default run regardless and fail on the old libc -- sigaction-mask-defers exits 27 there and passes on v2026-07-30.1. Co-Authored-By: Claude Opus 5 (1M context) --- .github/ci-constants.env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ci-constants.env b/.github/ci-constants.env index 85885c2f14be..163657207d35 100644 --- a/.github/ci-constants.env +++ b/.github/ci-constants.env @@ -1,3 +1,3 @@ # Shared CI constants. Loaded into GITHUB_ENV by workflows that need them. # Pinned wasix-libc sysroot (wasix-org/wasix-libc release tag). -WASIX_LIBC_SYSROOT_TAG=v2026-07-03.1 +WASIX_LIBC_SYSROOT_TAG=v2026-07-30.1