authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2022-12-18 06:30:21-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-19 04:12:46-05:00
log3db8cffa3b383011471f425983a7e98ad8a46aa5
treeca5e55fe37d770c3774112f01bdb04448abdfcd6
parent3bfae2a0d9503dbd832774c3b39a74dbd55e8b6e

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.

2 files changed, 15 insertions(+), 2 deletions(-)

lib/std/child_process.zig+6-2
...@@ -1022,8 +1022,12 @@ pub const ChildProcess = struct {...@@ -1022,8 +1022,12 @@ pub const ChildProcess = struct {
1022 };1022 };
10231023
1024 // If the app name had path separators, that disallows PATH searching,1024 // If the app name had path separators, that disallows PATH searching,
1025 // and there's no need to search the PATH if the cwd path is absolute.1025 // and there's no need to search the PATH if the app name is absolute.
1026 if (app_dirname_w != null or fs.path.isAbsoluteWindowsWTF16(cwd_path_w)) {1026 // We still search the path if the cwd is absolute because of the
1027 // "cwd set in ChildProcess is in effect when choosing the executable path
1028 // to match posix semantics" behavior--we don't want to skip searching
1029 // the PATH just because we were trying to set the cwd of the child process.
1030 if (app_dirname_w != null or app_name_is_absolute) {
1027 return original_err;1031 return original_err;
1028 }1032 }
10291033
test/standalone/windows_spawn/main.zig+9
...@@ -142,6 +142,10 @@ pub fn main() anyerror!void {...@@ -142,6 +142,10 @@ pub fn main() anyerror!void {
142 defer allocator.free(goodbye_abs_path);142 defer allocator.free(goodbye_abs_path);
143 // then the PATH should not be searched and we should get InvalidExe143 // then the PATH should not be searched and we should get InvalidExe
144 try testExecError(error.InvalidExe, allocator, goodbye_abs_path);144 try testExecError(error.InvalidExe, allocator, goodbye_abs_path);
145
146 // If we try to exec but provide a cwd that is an absolute path, the PATH
147 // should still be searched and the goodbye.exe in something should be found.
148 try testExecWithCwd(allocator, "goodbye", tmp_absolute_path, "hello from exe\n");
145}149}
146150
147fn testExecError(err: anyerror, allocator: std.mem.Allocator, command: []const u8) !void {151fn 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...@@ -149,9 +153,14 @@ fn testExecError(err: anyerror, allocator: std.mem.Allocator, command: []const u
149}153}
150154
151fn testExec(allocator: std.mem.Allocator, command: []const u8, expected_stdout: []const u8) !void {155fn testExec(allocator: std.mem.Allocator, command: []const u8, expected_stdout: []const u8) !void {
156 return testExecWithCwd(allocator, command, null, expected_stdout);
157}
158
159fn testExecWithCwd(allocator: std.mem.Allocator, command: []const u8, cwd: ?[]const u8, expected_stdout: []const u8) !void {
152 var result = try std.ChildProcess.exec(.{160 var result = try std.ChildProcess.exec(.{
153 .allocator = allocator,161 .allocator = allocator,
154 .argv = &[_][]const u8{command},162 .argv = &[_][]const u8{command},
163 .cwd = cwd,
155 });164 });
156 defer allocator.free(result.stdout);165 defer allocator.free(result.stdout);
157 defer allocator.free(result.stderr);166 defer allocator.free(result.stderr);