aboutsummaryrefslogtreecommitdiff
path: root/std
diff options
context:
space:
mode:
authorJonathan Marler <johnnymarler@gmail.com>2019-06-18 01:40:37 -0600
committerAndrew Kelley <andrew@ziglang.org>2019-06-18 13:19:06 -0400
commitc7bcf1a447de08a18f5113c97744233a54bb9af7 (patch)
tree437c2c87b5763b12d69ed23bbcf999a98e5e17e6 /std
parent3ca4925709ac6369391eb40616de33051e0bb1f1 (diff)
downloadzig-c7bcf1a447de08a18f5113c97744233a54bb9af7.tar.gz
zig-c7bcf1a447de08a18f5113c97744233a54bb9af7.zip
Fix windows create process retry/path search
Diffstat (limited to 'std')
-rw-r--r--std/child_process.zig37
-rw-r--r--std/os/windows.zig2
2 files changed, 24 insertions, 15 deletions
diff --git a/std/child_process.zig b/std/child_process.zig
index 8e4c086d1d..6e6cca335a 100644
--- a/std/child_process.zig
+++ b/std/child_process.zig
@@ -543,25 +543,32 @@ pub const ChildProcess = struct {
const PATH = try process.getEnvVarOwned(self.allocator, "PATH");
defer self.allocator.free(PATH);
+ const PATHEXT = try process.getEnvVarOwned(self.allocator, "PATHEXT");
+ defer self.allocator.free(PATHEXT);
var it = mem.tokenize(PATH, ";");
- while (it.next()) |search_path| {
- const joined_path = try fs.path.join(self.allocator, [_][]const u8{ search_path, app_name });
- defer self.allocator.free(joined_path);
-
- const joined_path_w = try unicode.utf8ToUtf16LeWithNull(self.allocator, joined_path);
- defer self.allocator.free(joined_path_w);
-
- if (windowsCreateProcess(joined_path_w.ptr, cmd_line_w.ptr, envp_ptr, cwd_w_ptr, &siStartInfo, &piProcInfo)) |_| {
- break;
- } else |err| if (err == error.FileNotFound) {
- continue;
- } else {
- return err;
+ retry: while (it.next()) |search_path| {
+ var ext_it = mem.tokenize(PATHEXT, ";");
+ while (ext_it.next()) |app_ext| {
+ const app_basename = try mem.concat(self.allocator, u8, [_][]const u8{app_name[0..app_name.len - 1], app_ext});
+ defer self.allocator.free(app_basename);
+
+ const joined_path = try fs.path.join(self.allocator, [_][]const u8{ search_path, app_basename });
+ defer self.allocator.free(joined_path);
+
+ const joined_path_w = try unicode.utf8ToUtf16LeWithNull(self.allocator, joined_path);
+ defer self.allocator.free(joined_path_w);
+
+ if (windowsCreateProcess(joined_path_w.ptr, cmd_line_w.ptr, envp_ptr, cwd_w_ptr, &siStartInfo, &piProcInfo)) |_| {
+ break :retry;
+ } else |err| switch (err) {
+ error.FileNotFound => { continue; },
+ error.AccessDenied => { continue; },
+ else => { return err; },
+ }
}
} else {
- // Every other error would have been returned earlier.
- return error.FileNotFound;
+ return no_path_err; // return the original error
}
};
diff --git a/std/os/windows.zig b/std/os/windows.zig
index 7b9feb7b15..d10ab695db 100644
--- a/std/os/windows.zig
+++ b/std/os/windows.zig
@@ -632,6 +632,7 @@ pub fn GetEnvironmentVariableW(lpName: LPWSTR, lpBuffer: LPWSTR, nSize: DWORD) G
pub const CreateProcessError = error{
FileNotFound,
+ AccessDenied,
InvalidName,
Unexpected,
};
@@ -663,6 +664,7 @@ pub fn CreateProcessW(
switch (kernel32.GetLastError()) {
ERROR.FILE_NOT_FOUND => return error.FileNotFound,
ERROR.PATH_NOT_FOUND => return error.FileNotFound,
+ ERROR.ACCESS_DENIED => return error.AccessDenied,
ERROR.INVALID_PARAMETER => unreachable,
ERROR.INVALID_NAME => return error.InvalidName,
else => |err| return unexpectedError(err),