Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions libc-top-half/musl/src/signal/sigaction.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <signal.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include "syscall.h"
Expand Down Expand Up @@ -31,8 +32,12 @@ static void core_handler(int sig) {

_Noreturn
static void terminate_handler(int sig) {
fprintf(stderr, "Program recieved termination signal: %s\n", strsignal(sig));
abort();
/* A terminating signal is not an abort. Calling abort() here raises
* SIGABRT while the original signal is still being dispatched, which can
* recursively re-enter the default signal path on runtimes that deliver
* the nested signal immediately. POSIX termination is silent; report it
* through the conventional shell status instead. */
_Exit(128 + sig);
}

_Noreturn
Expand Down
4 changes: 4 additions & 0 deletions test/wasix/c_signals/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
cmake_minimum_required(VERSION 3.5.0)
project(c_signals C)

add_executable(main main.c)
54 changes: 54 additions & 0 deletions test/wasix/c_signals/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include <signal.h>
#include <stdio.h>
#include <string.h>

static volatile sig_atomic_t handled;

static void siginfo_handler(int sig, siginfo_t *info, void *context)
{
if (sig == SIGUSR1 && info != NULL && info->si_signo == SIGUSR1 &&
context == NULL) {
handled++;
}
}

static int install_siginfo_handler(int flags)
{
struct sigaction action;
memset(&action, 0, sizeof(action));
action.sa_sigaction = siginfo_handler;
action.sa_flags = SA_SIGINFO | flags;
sigemptyset(&action.sa_mask);
return sigaction(SIGUSR1, &action, NULL);
}

int main(int argc, char **argv)
{
if (argc != 2) return 2;

if (strcmp(argv[1], "siginfo") == 0) {
if (install_siginfo_handler(0) != 0) return 3;
if (raise(SIGUSR1) != 0) return 4;
return handled == 1 ? 0 : 5;
}

if (strcmp(argv[1], "reset") == 0) {
if (install_siginfo_handler(SA_RESETHAND) != 0) return 6;
if (raise(SIGUSR1) != 0) return 7;
if (handled != 1) return 8;
raise(SIGUSR1);
return 9;
}

if (strcmp(argv[1], "terminate") == 0) {
struct sigaction action;
memset(&action, 0, sizeof(action));
action.sa_handler = SIG_DFL;
sigemptyset(&action.sa_mask);
if (sigaction(SIGTERM, &action, NULL) != 0) return 10;
raise(SIGTERM);
return 12;
}

return 11;
}
41 changes: 41 additions & 0 deletions test/wasix/c_signals/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env bash

set -u

stderr_file=$(mktemp)
trap 'rm -f "$stderr_file"' EXIT

wasmer run --enable-all ./main siginfo
RESULT=$?
if [ "$RESULT" != "0" ]; then
echo "SA_SIGINFO test failed: different exit code ($RESULT vs. 0)" >&2
exit 1
fi

wasmer run --enable-all ./main reset 2>"$stderr_file"
RESULT=$?
if [ "$RESULT" != "138" ]; then
echo "SA_RESETHAND test failed: different exit code ($RESULT vs. 138)" >&2
cat "$stderr_file" >&2
exit 1
fi
if grep -q "fatal signal: Aborted" "$stderr_file"; then
echo "SA_RESETHAND test failed: default termination recursed into SIGABRT" >&2
cat "$stderr_file" >&2
exit 1
fi

wasmer run --enable-all ./main terminate 2>"$stderr_file"
RESULT=$?
if [ "$RESULT" != "143" ]; then
echo "default SIGTERM test failed: different exit code ($RESULT vs. 143)" >&2
cat "$stderr_file" >&2
exit 1
fi
if [ -s "$stderr_file" ]; then
echo "default SIGTERM test failed: default termination wrote to stderr" >&2
cat "$stderr_file" >&2
exit 1
fi

echo "c_signals test passed"
Loading