Skip to content

spawnWindows: Fix PATH searching when cwd is absolute #13994

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions lib/std/child_process.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
9 changes: 9 additions & 0 deletions test/standalone/windows_spawn/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -142,16 +142,25 @@ 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 {
return std.testing.expectError(err, testExec(allocator, command, ""));
}

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);
Expand Down