aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-10-23 08:02:03 +0900
committerOphestra <cat@gensokyo.uk>2025-10-23 08:02:03 +0900
commit57231d4acf41ac01aa96a558c8d3017054b15269 (patch)
tree433e514e4bca7dd901d001260ef46bf90089f5e6
parentc5aefe5e9d28a8d4dad68bc06b38e42101656fe9 (diff)
container/init: improve signal handling
The SIGTERM signal is delivered in many other cases and can lead to strange behaviour. The unconditional resume of the logger also causes strange behaviour in the cancellation forwarding path. This change also passes through additional signals. Signed-off-by: Ophestra <cat@gensokyo.uk>
-rw-r--r--container/container.go2
-rw-r--r--container/init.go23
-rw-r--r--container/init_test.go206
3 files changed, 217 insertions, 14 deletions
diff --git a/container/container.go b/container/container.go
index fb031c38..55e4c441 100644
--- a/container/container.go
+++ b/container/container.go
@@ -24,7 +24,7 @@ import (
const (
// CancelSignal is the signal expected by container init on context cancel.
// A custom [Container.Cancel] function must eventually deliver this signal.
- CancelSignal = SIGTERM
+ CancelSignal = SIGUSR2
)
type (
diff --git a/container/init.go b/container/init.go
index 4e2345b3..0f5edb19 100644
--- a/container/init.go
+++ b/container/init.go
@@ -390,7 +390,8 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
// handle signals to dump withheld messages
sig := make(chan os.Signal, 2)
- k.notify(sig, os.Interrupt, CancelSignal)
+ k.notify(sig, CancelSignal,
+ os.Interrupt, SIGTERM, SIGQUIT)
// closed after residualProcessTimeout has elapsed after initial process death
timeout := make(chan struct{})
@@ -399,18 +400,28 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
for {
select {
case s := <-sig:
- if msg.Resume() {
- msg.Verbosef("%s after process start", s.String())
- } else {
- msg.Verbosef("got %s", s.String())
- }
if s == CancelSignal && params.ForwardCancel && cmd.Process != nil {
+ msg.Resume()
msg.Verbose("forwarding context cancellation")
if err := k.signal(cmd, os.Interrupt); err != nil {
k.printf(msg, "cannot forward cancellation: %v", err)
}
continue
}
+
+ if s == SIGTERM || s == SIGQUIT {
+ msg.Verbosef("got %s, forwarding to initial process", s.String())
+ if err := k.signal(cmd, s); err != nil {
+ k.printf(msg, "cannot forward signal: %v", err)
+ }
+ continue
+ }
+
+ if msg.Resume() {
+ msg.Verbosef("%s after process start", s.String())
+ } else {
+ msg.Verbosef("got %s", s.String())
+ }
msg.BeforeExit()
k.exit(0)
diff --git a/container/init_test.go b/container/init_test.go
index 27f41a4a..3497fc6d 100644
--- a/container/init_test.go
+++ b/container/init_test.go
@@ -2065,9 +2065,8 @@ func TestInitEntrypoint(t *testing.T) {
call("suspend", stub.ExpectArgs{}, true, nil),
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(10)}}, nil, nil),
call("New", stub.ExpectArgs{}, nil, nil),
- call("notify", stub.ExpectArgs{func(c chan<- os.Signal) { c <- CancelSignal }, []os.Signal{syscall.SIGINT, syscall.SIGTERM}}, nil, nil),
+ call("notify", stub.ExpectArgs{func(c chan<- os.Signal) { c <- CancelSignal }, []os.Signal{CancelSignal, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}}, nil, nil),
call("resume", stub.ExpectArgs{}, true, nil),
- call("verbosef", stub.ExpectArgs{"%s after process start", []any{"terminated"}}, nil, nil),
call("verbose", stub.ExpectArgs{[]any{"forwarding context cancellation"}}, nil, nil),
// magicWait4Signal as ret causes wait4 stub to unblock
call("signal", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent", os.Interrupt}, magicWait4Signal, stub.UniqueError(9)),
@@ -2090,6 +2089,199 @@ func TestInitEntrypoint(t *testing.T) {
}}},
}, nil},
+ {"lowlastcap signaled cancel passthrough", func(k *kstub) error { initEntrypoint(k, k); return nil }, stub.Expect{
+ /* entrypoint */
+ Calls: []stub.Call{
+ call("lockOSThread", stub.ExpectArgs{}, nil, nil),
+ call("getpid", stub.ExpectArgs{}, 1, nil),
+ call("setPtracer", stub.ExpectArgs{uintptr(0)}, 0, stub.UniqueError(8)),
+ call("verbosef", stub.ExpectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{stub.UniqueError(8)}}, nil, nil),
+ call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
+ Dir: check.MustAbs("/.hakurei/nonexistent"),
+ Path: check.MustAbs("/run/current-system/sw/bin/bash"),
+ Args: []string{"bash", "-c", "false"},
+ ForwardCancel: true,
+ AdoptWaitDelay: 5 * time.Nanosecond,
+ Uid: 1 << 24,
+ Gid: 1 << 47,
+ Hostname: "hakurei-check",
+ Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), comp.BindDevice).Proc(check.MustAbs("/proc/")),
+ SeccompRules: make([]seccomp.NativeRule, 0),
+ SeccompDisable: true,
+ ParentPerm: 0750,
+ }, 1971, 127, 2, false}, uintptr(0x39)}, stub.UniqueError(7), nil),
+ call("swapVerbose", stub.ExpectArgs{false}, false, nil),
+ call("verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil),
+ call("setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil),
+ call("writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("16777216 1971 1\n"), os.FileMode(0)}, nil, nil),
+ call("writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil),
+ call("writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("140737488355328 127 1\n"), os.FileMode(0)}, nil, nil),
+ call("setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil),
+ call("umask", stub.ExpectArgs{0}, 022, nil),
+ call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
+ call("lastcap", stub.ExpectArgs{}, uintptr(4), nil),
+ call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
+ /* begin early */
+ call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
+ /* end early */
+ call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
+ call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
+ call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
+ call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
+ call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
+ call("pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil),
+ call("chdir", stub.ExpectArgs{"/"}, nil, nil),
+ /* begin apply */
+ call("stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil),
+ call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
+ call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
+ call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
+ call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
+ call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil),
+ call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
+ /* end apply */
+ call("mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil),
+ call("unmount", stub.ExpectArgs{"host", 2}, nil, nil),
+ call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, syscall.EINTR),
+ call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, nil),
+ call("chdir", stub.ExpectArgs{"/sysroot"}, nil, nil),
+ call("pivotRoot", stub.ExpectArgs{".", "."}, nil, nil),
+ call("fchdir", stub.ExpectArgs{1 << 35}, nil, nil),
+ call("unmount", stub.ExpectArgs{".", 2}, nil, nil),
+ call("chdir", stub.ExpectArgs{"/"}, nil, nil),
+ call("close", stub.ExpectArgs{1 << 35}, nil, nil),
+ call("capAmbientClearAll", stub.ExpectArgs{}, nil, nil),
+ call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x0)}, nil, nil),
+ call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1)}, nil, nil),
+ call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x2)}, nil, nil),
+ call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x3)}, nil, nil),
+ call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x4)}, nil, nil),
+ call("capset", stub.ExpectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, new([2]capData)}, nil, nil),
+ call("verbose", stub.ExpectArgs{[]any{"syscall filter not configured"}}, nil, nil),
+ call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
+ call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
+ call("umask", stub.ExpectArgs{022}, 0, nil),
+ call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
+ call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil),
+ call("suspend", stub.ExpectArgs{}, true, nil),
+ call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(7)}}, nil, nil),
+ call("New", stub.ExpectArgs{}, nil, nil),
+ call("notify", stub.ExpectArgs{func(c chan<- os.Signal) { c <- syscall.SIGQUIT }, []os.Signal{CancelSignal, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}}, nil, nil),
+ call("verbosef", stub.ExpectArgs{"got %s, forwarding to initial process", []any{"quit"}}, nil, nil),
+ // magicWait4Signal as ret causes wait4 stub to unblock
+ call("signal", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent", syscall.SIGQUIT}, magicWait4Signal, stub.UniqueError(0xfe)),
+ call("printf", stub.ExpectArgs{"cannot forward signal: %v", []any{stub.UniqueError(0xfe)}}, nil, nil),
+ call("resume", stub.ExpectArgs{}, true, nil),
+ call("verbosef", stub.ExpectArgs{"initial process exited with signal %s", []any{syscall.Signal(0x4e)}}, nil, nil),
+ call("printf", stub.ExpectArgs{"timeout exceeded waiting for lingering processes", []any(nil)}, nil, nil),
+ call("beforeExit", stub.ExpectArgs{}, nil, nil),
+ call("exit", stub.ExpectArgs{206}, nil, nil),
+ },
+
+ /* wait4 */
+ Tracks: []stub.Expect{{Calls: []stub.Call{
+ call("lockOSThread", stub.ExpectArgs{}, nil, nil),
+
+ // magicWait4Signal as args[4] causes this to block until simulated signal is delivered
+ call("wait4", stub.ExpectArgs{-1, syscall.WaitStatus(0xfade01ce), 0, nil, magicWait4Signal}, 0xbad, nil),
+ // this terminates the goroutine at the call, preventing it from leaking while preserving behaviour
+ call("wait4", stub.ExpectArgs{-1, nil, 0, nil, stub.PanicExit}, 0, syscall.ECHILD),
+ }}},
+ }, nil},
+
+ {"lowlastcap signaled cancel resumed", func(k *kstub) error { initEntrypoint(k, k); return nil }, stub.Expect{
+ /* entrypoint */
+ Calls: []stub.Call{
+ call("lockOSThread", stub.ExpectArgs{}, nil, nil),
+ call("getpid", stub.ExpectArgs{}, 1, nil),
+ call("setPtracer", stub.ExpectArgs{uintptr(0)}, 0, stub.UniqueError(8)),
+ call("verbosef", stub.ExpectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{stub.UniqueError(8)}}, nil, nil),
+ call("receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{
+ Dir: check.MustAbs("/.hakurei/nonexistent"),
+ Path: check.MustAbs("/run/current-system/sw/bin/bash"),
+ Args: []string{"bash", "-c", "false"},
+ ForwardCancel: true,
+ AdoptWaitDelay: 5 * time.Nanosecond,
+ Uid: 1 << 24,
+ Gid: 1 << 47,
+ Hostname: "hakurei-check",
+ Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), comp.BindDevice).Proc(check.MustAbs("/proc/")),
+ SeccompRules: make([]seccomp.NativeRule, 0),
+ SeccompDisable: true,
+ ParentPerm: 0750,
+ }, 1971, 127, 2, false}, uintptr(0x39)}, stub.UniqueError(7), nil),
+ call("swapVerbose", stub.ExpectArgs{false}, false, nil),
+ call("verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil),
+ call("setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil),
+ call("writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("16777216 1971 1\n"), os.FileMode(0)}, nil, nil),
+ call("writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil),
+ call("writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("140737488355328 127 1\n"), os.FileMode(0)}, nil, nil),
+ call("setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil),
+ call("umask", stub.ExpectArgs{0}, 022, nil),
+ call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
+ call("lastcap", stub.ExpectArgs{}, uintptr(4), nil),
+ call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
+ /* begin early */
+ call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
+ /* end early */
+ call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
+ call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
+ call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
+ call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
+ call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
+ call("pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil),
+ call("chdir", stub.ExpectArgs{"/"}, nil, nil),
+ /* begin apply */
+ call("stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil),
+ call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil),
+ call("verbosef", stub.ExpectArgs{"mounting %q flags %#x", []any{"/sysroot", uintptr(0x4001)}}, nil, nil),
+ call("bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil),
+ call("verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: check.MustAbs("/proc/")}}}, nil, nil),
+ call("mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil),
+ call("mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil),
+ /* end apply */
+ call("mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil),
+ call("unmount", stub.ExpectArgs{"host", 2}, nil, nil),
+ call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, syscall.EINTR),
+ call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, nil),
+ call("chdir", stub.ExpectArgs{"/sysroot"}, nil, nil),
+ call("pivotRoot", stub.ExpectArgs{".", "."}, nil, nil),
+ call("fchdir", stub.ExpectArgs{1 << 35}, nil, nil),
+ call("unmount", stub.ExpectArgs{".", 2}, nil, nil),
+ call("chdir", stub.ExpectArgs{"/"}, nil, nil),
+ call("close", stub.ExpectArgs{1 << 35}, nil, nil),
+ call("capAmbientClearAll", stub.ExpectArgs{}, nil, nil),
+ call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x0)}, nil, nil),
+ call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1)}, nil, nil),
+ call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x2)}, nil, nil),
+ call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x3)}, nil, nil),
+ call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x4)}, nil, nil),
+ call("capset", stub.ExpectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, new([2]capData)}, nil, nil),
+ call("verbose", stub.ExpectArgs{[]any{"syscall filter not configured"}}, nil, nil),
+ call("newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil),
+ call("newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil),
+ call("umask", stub.ExpectArgs{022}, 0, nil),
+ call("verbosef", stub.ExpectArgs{"starting initial program %s", []any{check.MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil),
+ call("start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil),
+ call("suspend", stub.ExpectArgs{}, true, nil),
+ call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(7)}}, nil, nil),
+ call("New", stub.ExpectArgs{}, nil, nil),
+ call("notify", stub.ExpectArgs{func(c chan<- os.Signal) { c <- os.Interrupt }, []os.Signal{CancelSignal, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}}, nil, nil),
+ call("resume", stub.ExpectArgs{}, true, nil),
+ call("verbosef", stub.ExpectArgs{"%s after process start", []any{"interrupt"}}, nil, nil),
+ call("beforeExit", stub.ExpectArgs{}, nil, nil),
+ call("exit", stub.ExpectArgs{0}, nil, nil),
+ },
+
+ /* wait4 */
+ Tracks: []stub.Expect{{Calls: []stub.Call{
+ call("lockOSThread", stub.ExpectArgs{}, nil, nil),
+
+ // this terminates the goroutine at the call, preventing it from leaking while preserving behaviour
+ call("wait4", stub.ExpectArgs{-1, nil, 0, nil, stub.PanicExit}, 0, syscall.ECHILD),
+ }}},
+ }, nil},
+
{"lowlastcap signaled cancel", func(k *kstub) error { initEntrypoint(k, k); return nil }, stub.Expect{
/* entrypoint */
Calls: []stub.Call{
@@ -2167,7 +2359,7 @@ func TestInitEntrypoint(t *testing.T) {
call("suspend", stub.ExpectArgs{}, true, nil),
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(7)}}, nil, nil),
call("New", stub.ExpectArgs{}, nil, nil),
- call("notify", stub.ExpectArgs{func(c chan<- os.Signal) { c <- os.Interrupt }, []os.Signal{syscall.SIGINT, syscall.SIGTERM}}, nil, nil),
+ call("notify", stub.ExpectArgs{func(c chan<- os.Signal) { c <- os.Interrupt }, []os.Signal{CancelSignal, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}}, nil, nil),
call("resume", stub.ExpectArgs{}, false, nil),
call("verbosef", stub.ExpectArgs{"got %s", []any{"interrupt"}}, nil, nil),
call("beforeExit", stub.ExpectArgs{}, nil, nil),
@@ -2260,7 +2452,7 @@ func TestInitEntrypoint(t *testing.T) {
call("suspend", stub.ExpectArgs{}, true, nil),
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(5)}}, nil, nil),
call("New", stub.ExpectArgs{}, nil, nil),
- call("notify", stub.ExpectArgs{nil, []os.Signal{syscall.SIGINT, syscall.SIGTERM}}, nil, nil),
+ call("notify", stub.ExpectArgs{nil, []os.Signal{CancelSignal, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}}, nil, nil),
call("resume", stub.ExpectArgs{}, true, nil),
call("verbosef", stub.ExpectArgs{"initial process exited with signal %s", []any{syscall.Signal(0x4e)}}, nil, nil),
call("printf", stub.ExpectArgs{"timeout exceeded waiting for lingering processes", ([]any)(nil)}, nil, nil),
@@ -2355,7 +2547,7 @@ func TestInitEntrypoint(t *testing.T) {
call("suspend", stub.ExpectArgs{}, true, nil),
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(3)}}, nil, nil),
call("New", stub.ExpectArgs{}, nil, nil),
- call("notify", stub.ExpectArgs{nil, []os.Signal{syscall.SIGINT, syscall.SIGTERM}}, nil, nil),
+ call("notify", stub.ExpectArgs{nil, []os.Signal{CancelSignal, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}}, nil, nil),
call("resume", stub.ExpectArgs{}, true, nil),
call("verbosef", stub.ExpectArgs{"initial process exited with signal %s", []any{syscall.Signal(0x4e)}}, nil, nil),
call("beforeExit", stub.ExpectArgs{}, nil, nil),
@@ -2493,7 +2685,7 @@ func TestInitEntrypoint(t *testing.T) {
call("suspend", stub.ExpectArgs{}, true, nil),
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(1)}}, nil, nil),
call("New", stub.ExpectArgs{}, nil, nil),
- call("notify", stub.ExpectArgs{nil, []os.Signal{syscall.SIGINT, syscall.SIGTERM}}, nil, nil),
+ call("notify", stub.ExpectArgs{nil, []os.Signal{CancelSignal, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}}, nil, nil),
call("resume", stub.ExpectArgs{}, true, nil),
call("verbosef", stub.ExpectArgs{"initial process exited with code %d", []any{1}}, nil, nil),
call("beforeExit", stub.ExpectArgs{}, nil, nil),
@@ -2635,7 +2827,7 @@ func TestInitEntrypoint(t *testing.T) {
call("suspend", stub.ExpectArgs{}, true, nil),
call("printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(0)}}, nil, nil),
call("New", stub.ExpectArgs{}, nil, nil),
- call("notify", stub.ExpectArgs{nil, []os.Signal{syscall.SIGINT, syscall.SIGTERM}}, nil, nil),
+ call("notify", stub.ExpectArgs{nil, []os.Signal{CancelSignal, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}}, nil, nil),
call("resume", stub.ExpectArgs{}, true, nil),
call("verbosef", stub.ExpectArgs{"initial process exited with status %#x", []any{syscall.WaitStatus(0xfade007f)}}, nil, nil),
call("beforeExit", stub.ExpectArgs{}, nil, nil),