blob: 205d6423dfa4d9f6a6b5539f39778753ffdb4fd7 [file] [edit]
/*
* Copyright 2021 The Emscripten Authors. All rights reserved.
* Emscripten is available under two separate licenses, the MIT license and the
* University of Illinois/NCSA Open Source License. Both these licenses can be
* found in the LICENSE file.
*/
#define _GNU_SOURCE // for sighandler_t
#include <stdbool.h>
#include <stddef.h>
#include <signal.h>
#include "emscripten_internal.h"
extern struct sigaction __sig_actions[_NSIG];
extern sigset_t __sig_pending;
bool __sig_is_blocked(int sig);
// Default handler actions ~auto-generated from https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html.
// Note that stop and continue actions are not supported and treated as ignored.
typedef enum {
ACTION_IGNORE = 0,
ACTION_TERMINATE,
ACTION_ABORT,
} default_action_t;
static default_action_t default_actions[_NSIG] = {
[SIGABRT] = ACTION_ABORT,
[SIGALRM] = ACTION_TERMINATE,
[SIGBUS] = ACTION_ABORT,
[SIGFPE] = ACTION_ABORT,
[SIGHUP] = ACTION_TERMINATE,
[SIGILL] = ACTION_ABORT,
[SIGINT] = ACTION_TERMINATE,
[SIGKILL] = ACTION_TERMINATE,
[SIGPIPE] = ACTION_TERMINATE,
[SIGQUIT] = ACTION_ABORT,
[SIGSEGV] = ACTION_ABORT,
[SIGTERM] = ACTION_TERMINATE,
[SIGUSR1] = ACTION_TERMINATE,
[SIGUSR2] = ACTION_TERMINATE,
[SIGPOLL] = ACTION_TERMINATE,
[SIGPROF] = ACTION_TERMINATE,
[SIGSYS] = ACTION_ABORT,
[SIGTRAP] = ACTION_ABORT,
[SIGVTALRM] = ACTION_TERMINATE,
[SIGXCPU] = ACTION_ABORT,
[SIGXFSZ] = ACTION_ABORT,
};
int raise(int sig) {
if (__sig_is_blocked(sig)) {
sigaddset(&__sig_pending, sig);
return 0;
}
if (__sig_actions[sig].sa_flags & SA_SIGINFO) {
siginfo_t t = {0};
__sig_actions[sig].sa_sigaction(sig, &t, NULL);
} else {
void (*handler)(int) = __sig_actions[sig].sa_handler;
if (handler == SIG_DFL) {
switch (default_actions[sig]) {
case ACTION_IGNORE:
break;
case ACTION_TERMINATE:
// Intentionally exiting via a function that doesn't call atexit handlers.
_Exit(128 + sig);
case ACTION_ABORT:
// TODO: should this integrate with `Module['onAbort'] once `abort` is migrated
// to raise SIGABRT as per spec?
__builtin_trap();
}
} else if (handler != SIG_IGN) {
// Avoid a direct call to the handler, and instead call via JS so we can
// avoid strict signature checking.
// https://github.com/emscripten-core/posixtestsuite/issues/6
__call_sighandler(__sig_actions[sig].sa_handler, sig);
}
}
return 0;
}