From 268ac381c8ccd9ed620e14beb646e4a77d7e15d9 Mon Sep 17 00:00:00 2001 From: Oscar Falk Date: Mon, 23 Mar 2026 16:20:49 +0100 Subject: [PATCH] Forward termination signals to child process Commit d2a3a16763ee8a62125d9c57b7a12bf5d9ae0789, "On Linux, relaunch the current process when running as PID 1 (#311)", relaunches the command in a child process and then waits for it to exit, if the parent process has PID 1. If the command is ran in a container, any termination signal sent to the container is forwarded to the parent process. This unfortunately prevents the persistent state files from being saved to disk if the container is killed, as the child process never receives the shutdown signal. This commit forwards `SIGINT` and `SIGTERM` signals to the child process, which then saves the state files to disk, exits, and triggers a graceful exit in PID 1. Co-authored-by: Fredrik Medley --- pkg/program/run_main_linux.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pkg/program/run_main_linux.go b/pkg/program/run_main_linux.go index d50e3490..3d4d7aae 100644 --- a/pkg/program/run_main_linux.go +++ b/pkg/program/run_main_linux.go @@ -38,6 +38,18 @@ func relaunchIfPID1(currentPID int) { log.Fatal("Failed to relaunch current process: ", err) } + // Forward incoming termination signals to child process. + signalChan := make(chan os.Signal, 1) + signal.Notify(signalChan, terminationSignals...) + go func() { + for { + receivedSignal := <-signalChan + if err := syscall.Kill(childPID, receivedSignal.(syscall.Signal)); err != nil { + log.Printf("Failed to forward signal %#v to child process: %s", receivedSignal.String(), err) + } + } + }() + for { var status syscall.WaitStatus waitedPID, err := syscall.Wait4(-1, &status, 0, nil)