authorgravatar for johnnymarler@gmail.comJonathan Marler <johnnymarler@gmail.com> 2019-06-18 01:40:37-06:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-18 13:19:06-04:00
logc7bcf1a447de08a18f5113c97744233a54bb9af7
tree437c2c87b5763b12d69ed23bbcf999a98e5e17e6
parent3ca4925709ac6369391eb40616de33051e0bb1f1

Fix windows create process retry/path search


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

std/child_process.zig+22-15
......@@ -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
......@@ -632,6 +632,7 @@ pub fn GetEnvironmentVariableW(lpName: LPWSTR, lpBuffer: LPWSTR, nSize: DWORD) G
632632
633633pub 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),