diff --git a/Sources/CShim/exec_command.c b/Sources/CShim/exec_command.c index cbb35b3d..667ebece 100644 --- a/Sources/CShim/exec_command.c +++ b/Sources/CShim/exec_command.c @@ -32,6 +32,9 @@ #include #include #include +#if defined(__linux__) +#include +#endif #include "exec_command.h" @@ -98,6 +101,7 @@ void exec_command_attrs_init(struct exec_command_attrs *attrs) { attrs->mask = 0; attrs->uid = -1; attrs->gid = -1; + attrs->pdeathSignal = 0; } static void child_handler(const int sync_pipes[2], const char *executable, @@ -253,6 +257,15 @@ static void child_handler(const int sync_pipes[2], const char *executable, } } +#if defined(__linux__) + // Set parent death signal if specified + if (attrs.pdeathSignal != 0) { + if (prctl(PR_SET_PDEATHSIG, attrs.pdeathSignal) != 0) { + goto fail; + } + } +#endif + // close exec everything outside of our child's fd_table. if (cloexec_from(file_handle_count) != 0) { goto fail; diff --git a/Sources/CShim/include/exec_command.h b/Sources/CShim/include/exec_command.h index 89919cd5..4a54879f 100644 --- a/Sources/CShim/include/exec_command.h +++ b/Sources/CShim/include/exec_command.h @@ -38,6 +38,8 @@ struct exec_command_attrs { gid_t gid; /// signal mask for the child process int mask; + /// parent death signal (Linux only, 0 to disable) + int pdeathSignal; }; void exec_command_attrs_init(struct exec_command_attrs *attrs); diff --git a/Sources/ContainerizationOS/Command.swift b/Sources/ContainerizationOS/Command.swift index 77c8c166..cb6f7f5a 100644 --- a/Sources/ContainerizationOS/Command.swift +++ b/Sources/ContainerizationOS/Command.swift @@ -68,6 +68,8 @@ public struct Command: Sendable { public var uid: UInt32? /// Set the process group ID. public var gid: UInt32? + /// Signal to send when parent process dies (Linux only). + public var pdeathSignal: Int32? public init( setPGroup: Bool = false, @@ -77,7 +79,8 @@ public struct Command: Sendable { setsid: Bool = false, setctty: Bool = false, uid: UInt32? = nil, - gid: UInt32? = nil + gid: UInt32? = nil, + pdeathSignal: Int32? = nil ) { self.setPGroup = setPGroup self.resetIDs = resetIDs @@ -87,6 +90,7 @@ public struct Command: Sendable { self.setctty = setctty self.uid = uid self.gid = gid + self.pdeathSignal = pdeathSignal } } @@ -207,6 +211,10 @@ extension Command { attrs.gid = gid } + if let pdeathSignal = self.attrs.pdeathSignal { + attrs.pdeathSignal = pdeathSignal + } + var pid: pid_t = 0 var argv = ([executable] + arguments).map { strdup($0) } + [nil] defer { diff --git a/vminitd/Sources/vminitd/Runc/Runc.swift b/vminitd/Sources/vminitd/Runc/Runc.swift index ec7e3fbd..6b582b0f 100644 --- a/vminitd/Sources/vminitd/Runc/Runc.swift +++ b/vminitd/Sources/vminitd/Runc/Runc.swift @@ -339,7 +339,9 @@ extension Runc { cmd.stdout = stdout ?? outPipe.fileHandleForWriting cmd.stderr = stderr ?? outPipe.fileHandleForWriting - // FIXME: pdeathSignal handling if Command supported it. + if let pdeathSignal = pdeathSignal { + cmd.attrs.pdeathSignal = pdeathSignal + } if setpgid { cmd.attrs.setPGroup = true