#include "shim-signal.h" #include #include #include #include #include static pid_t hakurei_shim_param_ppid = -1; static int hakurei_shim_fd = -1; /* see shim.go for handling of the message */ static inline ssize_t hakurei_shim_write(hakurei_shim_msg msg) { int savedErrno = errno; unsigned char buf = (unsigned char)msg; ssize_t ret = write(hakurei_shim_fd, &buf, 1); if (ret == -1 && errno != EAGAIN) exit(EXIT_FAILURE); errno = savedErrno; return ret; } static void hakurei_shim_sigaction(int sig, siginfo_t *si, void *ucontext) { if (sig != SIGCONT || si == NULL) { hakurei_shim_write(HAKUREI_SHIM_INVALID); return; } if (si->si_pid == hakurei_shim_param_ppid) { hakurei_shim_write(HAKUREI_SHIM_EXIT_REQUESTED); return; } hakurei_shim_write(HAKUREI_SHIM_BAD_PID); if (getppid() != hakurei_shim_param_ppid) hakurei_shim_write(HAKUREI_SHIM_ORPHAN); } void hakurei_shim_setup_cont_signal(pid_t ppid, int fd) { if (hakurei_shim_param_ppid != -1 || hakurei_shim_fd != -1) *(int *)NULL = 0; /* unreachable */ 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; hakurei_shim_fd = fd; }