spawnWindows: Fix PATH searching when cwd is absolute

Fixes a regression caused by https://github.com/ziglang/zig/pull/13983

From the added comment:

We still search the path if the cwd is absolute because of the
"cwd set in ChildProcess is in effect when choosing the executable path
to match posix semantics" behavior--we don't want to skip searching
the PATH just because we were trying to set the cwd of the child process.
This commit is contained in:
Ryan Liptak 2022-12-18 06:30:21 -08:00 committed by Andrew Kelley
parent 3bfae2a0d9
commit 3db8cffa3b
2 changed files with 15 additions and 2 deletions

View File

@ -1022,8 +1022,12 @@ pub const ChildProcess = struct {
};
// If the app name had path separators, that disallows PATH searching,
// and there's no need to search the PATH if the cwd path is absolute.
if (app_dirname_w != null or fs.path.isAbsoluteWindowsWTF16(cwd_path_w)) {
// and there's no need to search the PATH if the app name is absolute.
// We still search the path if the cwd is absolute because of the
// "cwd set in ChildProcess is in effect when choosing the executable path
// to match posix semantics" behavior--we don't want to skip searching
// the PATH just because we were trying to set the cwd of the child process.
if (app_dirname_w != null or app_name_is_absolute) {
return original_err;
}

View File

@ -142,6 +142,10 @@ pub fn main() anyerror!void {
defer allocator.free(goodbye_abs_path);
// then the PATH should not be searched and we should get InvalidExe
try testExecError(error.InvalidExe, allocator, goodbye_abs_path);
// If we try to exec but provide a cwd that is an absolute path, the PATH
// should still be searched and the goodbye.exe in something should be found.
try testExecWithCwd(allocator, "goodbye", tmp_absolute_path, "hello from exe\n");
}
fn testExecError(err: anyerror, allocator: std.mem.Allocator, command: []const u8) !void {
@ -149,9 +153,14 @@ fn testExecError(err: anyerror, allocator: std.mem.Allocator, command: []const u
}
fn testExec(allocator: std.mem.Allocator, command: []const u8, expected_stdout: []const u8) !void {
return testExecWithCwd(allocator, command, null, expected_stdout);
}
fn testExecWithCwd(allocator: std.mem.Allocator, command: []const u8, cwd: ?[]const u8, expected_stdout: []const u8) !void {
var result = try std.ChildProcess.exec(.{
.allocator = allocator,
.argv = &[_][]const u8{command},
.cwd = cwd,
});
defer allocator.free(result.stdout);
defer allocator.free(result.stderr);