| ... | @@ -543,25 +543,32 @@ pub const ChildProcess = struct { | ... | @@ -543,25 +543,32 @@ pub const ChildProcess = struct { |
| 543 | | 543 | |
| 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); |
| 546 | | 548 | |
| 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| { |
| 551 | | 553 | 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 | |
| 554 | | 556 | 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 | }; |
| 567 | | 574 | |