aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/app/shim-signal.c
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-07-28 23:38:28 +0900
committerOphestra <cat@gensokyo.uk>2025-07-28 23:39:30 +0900
commitddf48a6c22d4387ff2ca2e45afbcc86fa7d81968 (patch)
tree22a7701de9435edfe8077696ec4357400bb56077 /internal/app/shim-signal.c
parenta0f499e30a2f2a43b7a86ad081fc6703d67a6e36 (diff)
app/shim: implement signal handler outcome in Go
This needs to be done from the Go side eventually anyway to integrate the signal forwarding behaviour now supported by the container package. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/app/shim-signal.c')
-rw-r--r--internal/app/shim-signal.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/internal/app/shim-signal.c b/internal/app/shim-signal.c
index b6120f1a..fc005347 100644
--- a/internal/app/shim-signal.c
+++ b/internal/app/shim-signal.c
@@ -6,27 +6,43 @@
#include <unistd.h>
static pid_t hakurei_shim_param_ppid = -1;
+static int hakurei_shim_fd = -1;
-// this cannot unblock hlog since Go code is not async-signal-safe
+static ssize_t hakurei_shim_write(const void *buf, size_t count) {
+ int savedErrno = errno;
+ ssize_t ret = write(hakurei_shim_fd, buf, count);
+ if (ret == -1 && errno != EAGAIN)
+ exit(EXIT_FAILURE);
+ errno = savedErrno;
+ return ret;
+}
+
+/* see shim_linux.go for handling of the value */
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");
+ /* unreachable */
+ hakurei_shim_write("\2", 1);
return;
}
- // monitor requests shim exit
- if (si->si_pid == hakurei_shim_param_ppid)
- exit(254);
+ if (si->si_pid == hakurei_shim_param_ppid) {
+ /* monitor requests shim exit */
+ hakurei_shim_write("\0", 1);
+ return;
+ }
- fprintf(stderr, "sigaction: got SIGCONT from process %d\n", si->si_pid);
+ /* unexpected si_pid */
+ hakurei_shim_write("\3", 1);
- // shim orphaned before monitor delivers a signal
if (getppid() != hakurei_shim_param_ppid)
- exit(3);
+ /* shim orphaned before monitor delivers a signal */
+ hakurei_shim_write("\1", 1);
}
-void hakurei_shim_setup_cont_signal(pid_t ppid) {
+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;
@@ -45,4 +61,5 @@ void hakurei_shim_setup_cont_signal(pid_t ppid) {
errno = 0;
hakurei_shim_param_ppid = ppid;
+ hakurei_shim_fd = fd;
}