Skip to content
Merged
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
7 changes: 3 additions & 4 deletions frankenphp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1276,13 +1276,12 @@ static int frankenphp_startup(sapi_module_struct *sapi_module) {
int result = php_module_startup(sapi_module, &frankenphp_module);
#ifndef PHP_WIN32
if (result == SUCCESS) {
const int signals[] = {SIGSEGV, SIGBUS, SIGFPE};
for (size_t i = 0; i < sizeof(signals) / sizeof(signals[0]); i++) {
for (int sig = 1; sig < NSIG; sig++) {
struct sigaction sa;
if (sigaction(signals[i], NULL, &sa) == 0 && sa.sa_handler != SIG_DFL &&
if (sigaction(sig, NULL, &sa) == 0 && sa.sa_handler != SIG_DFL &&
sa.sa_handler != SIG_IGN && !(sa.sa_flags & SA_ONSTACK)) {
sa.sa_flags |= SA_ONSTACK;
sigaction(signals[i], &sa, NULL);
sigaction(sig, &sa, NULL);
}
}
}
Expand Down
64 changes: 40 additions & 24 deletions internal/testext/extensions.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,47 +7,63 @@
#ifndef PHP_WIN32
#include <signal.h>

static struct sigaction original_sigsegv_action;
static struct sigaction installed_sigsegv_action;
static const int test_signals[] = {SIGSEGV, SIGVTALRM};
#define TEST_SIGNALS_COUNT (sizeof(test_signals) / sizeof(test_signals[0]))

static void test_sigsegv_handler(int sig, siginfo_t *info, void *context) {
original_sigsegv_action.sa_sigaction(sig, info, context);
static struct sigaction original_actions[TEST_SIGNALS_COUNT];
static struct sigaction installed_actions[TEST_SIGNALS_COUNT];

static void test_handler(int sig, siginfo_t *info, void *context) {
for (size_t i = 0; i < TEST_SIGNALS_COUNT; i++) {
if (test_signals[i] == sig) {
original_actions[i].sa_sigaction(sig, info, context);
}
}
}

static PHP_MINIT_FUNCTION(test_signals) {
struct sigaction sa = {0};
sa.sa_sigaction = test_sigsegv_handler;
sa.sa_flags = SA_SIGINFO | SA_RESTART;
sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGUSR2);
if (sigaction(SIGSEGV, &sa, &original_sigsegv_action) != 0 ||
sigaction(SIGSEGV, NULL, &installed_sigsegv_action) != 0) {
return FAILURE;
for (size_t i = 0; i < TEST_SIGNALS_COUNT; i++) {
struct sigaction sa = {0};
sa.sa_sigaction = test_handler;
sa.sa_flags = SA_SIGINFO | SA_RESTART;
sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGUSR2);
if (sigaction(test_signals[i], &sa, &original_actions[i]) != 0 ||
sigaction(test_signals[i], NULL, &installed_actions[i]) != 0) {
return FAILURE;
}
}

return SUCCESS;
}

static PHP_MSHUTDOWN_FUNCTION(test_signals) {
return sigaction(SIGSEGV, &original_sigsegv_action, NULL) == 0 ? SUCCESS
: FAILURE;
for (size_t i = 0; i < TEST_SIGNALS_COUNT; i++) {
if (sigaction(test_signals[i], &original_actions[i], NULL) != 0) {
return FAILURE;
}
}

return SUCCESS;
}
#endif

int test_signal_handler(void) {
#ifndef PHP_WIN32
struct sigaction sa;
if (sigaction(SIGSEGV, NULL, &sa) != 0 ||
sa.sa_sigaction != installed_sigsegv_action.sa_sigaction ||
sa.sa_flags != (installed_sigsegv_action.sa_flags | SA_ONSTACK)) {
return FAILURE;
}

for (int sig = 1; sig < NSIG; sig++) {
if (sigismember(&sa.sa_mask, sig) !=
sigismember(&installed_sigsegv_action.sa_mask, sig)) {
for (size_t i = 0; i < TEST_SIGNALS_COUNT; i++) {
struct sigaction sa;
if (sigaction(test_signals[i], NULL, &sa) != 0 ||
sa.sa_sigaction != installed_actions[i].sa_sigaction ||
sa.sa_flags != (installed_actions[i].sa_flags | SA_ONSTACK)) {
return FAILURE;
}

for (int sig = 1; sig < NSIG; sig++) {
if (sigismember(&sa.sa_mask, sig) !=
sigismember(&installed_actions[i].sa_mask, sig)) {
return FAILURE;
}
}
}
#endif

Expand Down
Loading