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 {...@@ -543,25 +543,32 @@ pub const ChildProcess = struct {
543543
544 const PATH = try process.getEnvVarOwned(self.allocator, "PATH");544 const PATH = try process.getEnvVarOwned(self.allocator, "PATH");
545 defer self.allocator.free(PATH);545 defer self.allocator.free(PATH);
546 const PATHEXT = try process.getEnvVarOwned(self.allocator, "PATHEXT");
547 defer self.allocator.free(PATHEXT);
546548
547 var it = mem.tokenize(PATH, ";");549 var it = mem.tokenize(PATH, ";");
548 while (it.next()) |search_path| {550 retry: while (it.next()) |search_path| {
549 const joined_path = try fs.path.join(self.allocator, [_][]const u8{ search_path, app_name });551 var ext_it = mem.tokenize(PATHEXT, ";");
550 defer self.allocator.free(joined_path);552 while (ext_it.next()) |app_ext| {
551553 const app_basename = try mem.concat(self.allocator, u8, [_][]const u8{app_name[0..app_name.len - 1], app_ext});
552 const joined_path_w = try unicode.utf8ToUtf16LeWithNull(self.allocator, joined_path);554 defer self.allocator.free(app_basename);
553 defer self.allocator.free(joined_path_w);555
554556 const joined_path = try fs.path.join(self.allocator, [_][]const u8{ search_path, app_basename });
555 if (windowsCreateProcess(joined_path_w.ptr, cmd_line_w.ptr, envp_ptr, cwd_w_ptr, &siStartInfo, &piProcInfo)) |_| {557 defer self.allocator.free(joined_path);
556 break;558
557 } else |err| if (err == error.FileNotFound) {559 const joined_path_w = try unicode.utf8ToUtf16LeWithNull(self.allocator, joined_path);
558 continue;560 defer self.allocator.free(joined_path_w);
559 } else {561
560 return err;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 }
561 }569 }
562 } else {570 } else {
563 // Every other error would have been returned earlier.571 return no_path_err; // return the original error
564 return error.FileNotFound;
565 }572 }
566 };573 };
567574
std/os/windows.zig+2
...@@ -632,6 +632,7 @@ pub fn GetEnvironmentVariableW(lpName: LPWSTR, lpBuffer: LPWSTR, nSize: DWORD) G...@@ -632,6 +632,7 @@ pub fn GetEnvironmentVariableW(lpName: LPWSTR, lpBuffer: LPWSTR, nSize: DWORD) G
632632
633pub const CreateProcessError = error{633pub const CreateProcessError = error{
634 FileNotFound,634 FileNotFound,
635 AccessDenied,
635 InvalidName,636 InvalidName,
636 Unexpected,637 Unexpected,
637};638};
...@@ -663,6 +664,7 @@ pub fn CreateProcessW(...@@ -663,6 +664,7 @@ pub fn CreateProcessW(
663 switch (kernel32.GetLastError()) {664 switch (kernel32.GetLastError()) {
664 ERROR.FILE_NOT_FOUND => return error.FileNotFound,665 ERROR.FILE_NOT_FOUND => return error.FileNotFound,
665 ERROR.PATH_NOT_FOUND => return error.FileNotFound,666 ERROR.PATH_NOT_FOUND => return error.FileNotFound,
667 ERROR.ACCESS_DENIED => return error.AccessDenied,
666 ERROR.INVALID_PARAMETER => unreachable,668 ERROR.INVALID_PARAMETER => unreachable,
667 ERROR.INVALID_NAME => return error.InvalidName,669 ERROR.INVALID_NAME => return error.InvalidName,
668 else => |err| return unexpectedError(err),670 else => |err| return unexpectedError(err),