diff options
| author | Ophestra <cat@gensokyo.uk> | 2025-07-28 21:52:53 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2025-07-28 21:52:53 +0900 |
| commit | a0f499e30a2f2a43b7a86ad081fc6703d67a6e36 (patch) | |
| tree | 806fe784dee6cd36e1e0f5e3c10a17adf4b1ad0a | |
| parent | d6b07f12ff5064682b722f77bbb4436451bfcdab (diff) | |
app/shim: separate signal handler implementation
Signed-off-by: Ophestra <cat@gensokyo.uk>
| -rw-r--r-- | internal/app/shim-signal.c | 48 | ||||
| -rw-r--r-- | internal/app/shim-signal.h | 3 | ||||
| -rw-r--r-- | internal/app/shim_linux.go | 50 |
3 files changed, 52 insertions, 49 deletions
diff --git a/internal/app/shim-signal.c b/internal/app/shim-signal.c new file mode 100644 index 00000000..b6120f1a --- /dev/null +++ b/internal/app/shim-signal.c @@ -0,0 +1,48 @@ +#include "shim-signal.h" +#include <errno.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +static pid_t hakurei_shim_param_ppid = -1; + +// this cannot unblock hlog since Go code is not async-signal-safe +static void hakurei_shim_sigaction(int sig, siginfo_t *si, void *ucontext) { + if (sig != SIGCONT || si == NULL) { + // unreachable + fprintf(stderr, "sigaction: sa_sigaction got invalid siginfo\n"); + return; + } + + // monitor requests shim exit + if (si->si_pid == hakurei_shim_param_ppid) + exit(254); + + fprintf(stderr, "sigaction: got SIGCONT from process %d\n", si->si_pid); + + // shim orphaned before monitor delivers a signal + if (getppid() != hakurei_shim_param_ppid) + exit(3); +} + +void hakurei_shim_setup_cont_signal(pid_t ppid) { + struct sigaction new_action = {0}, old_action = {0}; + if (sigaction(SIGCONT, NULL, &old_action) != 0) + return; + if (old_action.sa_handler != SIG_DFL) { + errno = ENOTRECOVERABLE; + return; + } + + new_action.sa_sigaction = hakurei_shim_sigaction; + if (sigemptyset(&new_action.sa_mask) != 0) + return; + new_action.sa_flags = SA_ONSTACK | SA_SIGINFO; + + if (sigaction(SIGCONT, &new_action, NULL) != 0) + return; + + errno = 0; + hakurei_shim_param_ppid = ppid; +} diff --git a/internal/app/shim-signal.h b/internal/app/shim-signal.h new file mode 100644 index 00000000..28b80ed8 --- /dev/null +++ b/internal/app/shim-signal.h @@ -0,0 +1,3 @@ +#include <signal.h> + +void hakurei_shim_setup_cont_signal(pid_t ppid); diff --git a/internal/app/shim_linux.go b/internal/app/shim_linux.go index 876c3e81..67e5fdbe 100644 --- a/internal/app/shim_linux.go +++ b/internal/app/shim_linux.go @@ -16,55 +16,7 @@ import ( "hakurei.app/internal/hlog" ) -/* -#include <stdlib.h> -#include <unistd.h> -#include <stdio.h> -#include <errno.h> -#include <signal.h> - -static pid_t hakurei_shim_param_ppid = -1; - -// this cannot unblock hlog since Go code is not async-signal-safe -static void hakurei_shim_sigaction(int sig, siginfo_t *si, void *ucontext) { - if (sig != SIGCONT || si == NULL) { - // unreachable - fprintf(stderr, "sigaction: sa_sigaction got invalid siginfo\n"); - return; - } - - // monitor requests shim exit - if (si->si_pid == hakurei_shim_param_ppid) - exit(254); - - fprintf(stderr, "sigaction: got SIGCONT from process %d\n", si->si_pid); - - // shim orphaned before monitor delivers a signal - if (getppid() != hakurei_shim_param_ppid) - exit(3); -} - -void hakurei_shim_setup_cont_signal(pid_t ppid) { - struct sigaction new_action = {0}, old_action = {0}; - if (sigaction(SIGCONT, NULL, &old_action) != 0) - return; - if (old_action.sa_handler != SIG_DFL) { - errno = ENOTRECOVERABLE; - return; - } - - new_action.sa_sigaction = hakurei_shim_sigaction; - if (sigemptyset(&new_action.sa_mask) != 0) - return; - new_action.sa_flags = SA_ONSTACK | SA_SIGINFO; - - if (sigaction(SIGCONT, &new_action, NULL) != 0) - return; - - errno = 0; - hakurei_shim_param_ppid = ppid; -} -*/ +//#include "shim-signal.h" import "C" const shimEnv = "HAKUREI_SHIM" |
