authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-03 18:07:02-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-04 00:27:09-08:00
log2c22c3dabf08156eee00b927baf7d6a845a4c98d
treec7740be5cdb39255144a58c20a1fa81290bd2eec
parent08d8b412e9217018d760666094b89918de02f10e

std.Io.Threaded: make processReplace cancelable

In between each attempt to call execve() on a particular file path, it will check cancelation before trying the next PATH.

1 files changed, 5 insertions(+), 3 deletions(-)

lib/std/Io/Threaded.zig+5-3
...@@ -1428,7 +1428,7 @@ pub fn io(t: *Threaded) Io {...@@ -1428,7 +1428,7 @@ pub fn io(t: *Threaded) Io {
1428 .tryLockStderr = tryLockStderr,1428 .tryLockStderr = tryLockStderr,
1429 .unlockStderr = unlockStderr,1429 .unlockStderr = unlockStderr,
1430 .processSetCurrentDir = processSetCurrentDir,1430 .processSetCurrentDir = processSetCurrentDir,
1431 .processReplace = processReplace, // TODO audit for cancelation and unreachable1431 .processReplace = processReplace,
1432 .processReplacePath = processReplacePath, // TODO audit for cancelation and unreachable1432 .processReplacePath = processReplacePath, // TODO audit for cancelation and unreachable
1433 .processSpawn = processSpawn, // TODO audit for cancelation and unreachable1433 .processSpawn = processSpawn, // TODO audit for cancelation and unreachable
1434 .processSpawnPath = processSpawnPath, // TODO audit for cancelation and unreachable1434 .processSpawnPath = processSpawnPath, // TODO audit for cancelation and unreachable
...@@ -12946,7 +12946,9 @@ fn spawnPosix(t: *Threaded, options: process.SpawnOptions) process.SpawnError!Sp...@@ -12946,7 +12946,9 @@ fn spawnPosix(t: *Threaded, options: process.SpawnOptions) process.SpawnError!Sp
1294612946
12947 const pid_result = try posix.fork();12947 const pid_result = try posix.fork();
12948 if (pid_result == 0) {12948 if (pid_result == 0) {
12949 // we are the child12949 // We are the child.
12950 if (Thread.current) |current_thread| current_thread.cancel_protection = .blocked;
12951
12950 setUpChildIo(options.stdin, stdin_pipe[0], posix.STDIN_FILENO, dev_null_fd) catch |err| forkBail(err_pipe[1], err);12952 setUpChildIo(options.stdin, stdin_pipe[0], posix.STDIN_FILENO, dev_null_fd) catch |err| forkBail(err_pipe[1], err);
12951 setUpChildIo(options.stdout, stdout_pipe[1], posix.STDOUT_FILENO, dev_null_fd) catch |err| forkBail(err_pipe[1], err);12953 setUpChildIo(options.stdout, stdout_pipe[1], posix.STDOUT_FILENO, dev_null_fd) catch |err| forkBail(err_pipe[1], err);
12952 setUpChildIo(options.stderr, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) catch |err| forkBail(err_pipe[1], err);12954 setUpChildIo(options.stderr, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) catch |err| forkBail(err_pipe[1], err);
...@@ -14585,8 +14587,8 @@ pub fn posixExecvPath(...@@ -14585,8 +14587,8 @@ pub fn posixExecvPath(
14585 child_argv: [*:null]const ?[*:0]const u8,14587 child_argv: [*:null]const ?[*:0]const u8,
14586 envp: [*:null]const ?[*:0]const u8,14588 envp: [*:null]const ?[*:0]const u8,
14587) process.ReplaceError {14589) process.ReplaceError {
14590 try Thread.checkCancel();
14588 switch (posix.errno(posix.system.execve(path, child_argv, envp))) {14591 switch (posix.errno(posix.system.execve(path, child_argv, envp))) {
14589 .SUCCESS => unreachable,
14590 .FAULT => |err| return errnoBug(err), // Bad pointer parameter.14592 .FAULT => |err| return errnoBug(err), // Bad pointer parameter.
14591 .@"2BIG" => return error.SystemResources,14593 .@"2BIG" => return error.SystemResources,
14592 .MFILE => return error.ProcessFdQuotaExceeded,14594 .MFILE => return error.ProcessFdQuotaExceeded,