Skip to content

Commit e8756e6

Browse files
marler8997Jonathan Marler
authored and
Jonathan Marler
committed
Fix windows create process retry/path search
1 parent 3ca4925 commit e8756e6

File tree

2 files changed

+24
-15
lines changed

2 files changed

+24
-15
lines changed

std/child_process.zig

+22-15
Original file line numberDiff line numberDiff line change
@@ -543,25 +543,32 @@ pub const ChildProcess = struct {
543543

544544
const PATH = try process.getEnvVarOwned(self.allocator, "PATH");
545545
defer self.allocator.free(PATH);
546+
const PATHEXT = try process.getEnvVarOwned(self.allocator, "PATHEXT");
547+
defer self.allocator.free(PATHEXT);
546548

547549
var it = mem.tokenize(PATH, ";");
548-
while (it.next()) |search_path| {
549-
const joined_path = try fs.path.join(self.allocator, [_][]const u8{ search_path, app_name });
550-
defer self.allocator.free(joined_path);
551-
552-
const joined_path_w = try unicode.utf8ToUtf16LeWithNull(self.allocator, joined_path);
553-
defer self.allocator.free(joined_path_w);
554-
555-
if (windowsCreateProcess(joined_path_w.ptr, cmd_line_w.ptr, envp_ptr, cwd_w_ptr, &siStartInfo, &piProcInfo)) |_| {
556-
break;
557-
} else |err| if (err == error.FileNotFound) {
558-
continue;
559-
} else {
560-
return err;
550+
retry: while (it.next()) |search_path| {
551+
var ext_it = mem.tokenize(PATHEXT, ";");
552+
while (ext_it.next()) |app_ext| {
553+
const app_basename = try mem.concat(self.allocator, u8, [_][]const u8{app_name[0..app_name.len - 1], app_ext});
554+
defer self.allocator.free(app_basename);
555+
556+
const joined_path = try fs.path.join(self.allocator, [_][]const u8{ search_path, app_basename });
557+
defer self.allocator.free(joined_path);
558+
559+
const joined_path_w = try unicode.utf8ToUtf16LeWithNull(self.allocator, joined_path);
560+
defer self.allocator.free(joined_path_w);
561+
562+
if (windowsCreateProcess(joined_path_w.ptr, cmd_line_w.ptr, envp_ptr, cwd_w_ptr, &siStartInfo, &piProcInfo)) |_| {
563+
break :retry;
564+
} else |err| switch (err) {
565+
error.FileNotFound => { continue; },
566+
error.AccessDenied => { continue; },
567+
else => { return err; },
568+
}
561569
}
562570
} else {
563-
// Every other error would have been returned earlier.
564-
return error.FileNotFound;
571+
return no_path_err; // return the original error
565572
}
566573
};
567574

std/os/windows.zig

+2
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,7 @@ pub fn GetEnvironmentVariableW(lpName: LPWSTR, lpBuffer: LPWSTR, nSize: DWORD) G
632632

633633
pub const CreateProcessError = error{
634634
FileNotFound,
635+
AccessDenied,
635636
InvalidName,
636637
Unexpected,
637638
};
@@ -663,6 +664,7 @@ pub fn CreateProcessW(
663664
switch (kernel32.GetLastError()) {
664665
ERROR.FILE_NOT_FOUND => return error.FileNotFound,
665666
ERROR.PATH_NOT_FOUND => return error.FileNotFound,
667+
ERROR.ACCESS_DENIED => return error.AccessDenied,
666668
ERROR.INVALID_PARAMETER => unreachable,
667669
ERROR.INVALID_NAME => return error.InvalidName,
668670
else => |err| return unexpectedError(err),

0 commit comments

Comments
 (0)