mirror of
https://github.com/apple/container.git
synced 2026-09-12 10:45:42 +00:00
Implement pdeathSignal handling in Runc (#431)
Add support for parent death signal (pdeathSignal) to ensure child processes receive a signal when the parent process dies. This addresses the FIXME comment in Runc.execute(). ## Changes - Add pdeathSignal field to exec_command_attrs C struct - Implement prctl(PR_SET_PDEATHSIG) in child process handler (Linux only) - Expose pdeathSignal through Command.Attrs Swift API - Wire up pdeathSignal in Runc.execute() to remove FIXME ## Implementation Details The implementation uses Linux-specific prctl() to set the parent death signal, ensuring proper cleanup when parent processes terminate. The feature is conditionally compiled for Linux only, maintaining compatibility with other platforms.
This commit is contained in:
@@ -32,6 +32,9 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#if defined(__linux__)
|
||||
#include <sys/prctl.h>
|
||||
#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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user