Fix windows create process retry/path search

This commit is contained in:
Jonathan Marler 2019-06-18 01:40:37 -06:00 committed by Andrew Kelley
parent 3ca4925709
commit c7bcf1a447
2 changed files with 22 additions and 13 deletions

View File

@ -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);
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_w = try unicode.utf8ToUtf16LeWithNull(self.allocator, joined_path);
defer self.allocator.free(joined_path_w);
const joined_path = try fs.path.join(self.allocator, [_][]const u8{ search_path, app_basename });
defer self.allocator.free(joined_path);
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;
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
}
};

View File

@ -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),