| ... | ... | @@ -142,7 +142,7 @@ pub const ChildProcess = struct { |
| 142 | 142 | if (!windows.TerminateProcess(self.handle, exit_code)) { |
| 143 | 143 | const err = windows.GetLastError(); |
| 144 | 144 | return switch (err) { |
| 145 | | else => error.Unexpected, |
| 145 | else => os.unexpectedErrorWindows(err), |
| 146 | 146 | }; |
| 147 | 147 | } |
| 148 | 148 | self.waitUnwrappedWindows(); |
| ... | ... | @@ -164,7 +164,7 @@ pub const ChildProcess = struct { |
| 164 | 164 | posix.EINVAL => unreachable, |
| 165 | 165 | posix.EPERM => error.PermissionDenied, |
| 166 | 166 | posix.ESRCH => error.ProcessNotFound, |
| 167 | | else => error.Unexpected, |
| 167 | else => os.unexpectedErrorPosix(err), |
| 168 | 168 | }; |
| 169 | 169 | } |
| 170 | 170 | self.waitUnwrapped(); |
| ... | ... | @@ -357,7 +357,7 @@ pub const ChildProcess = struct { |
| 357 | 357 | restore_SIGCHLD(); |
| 358 | 358 | return switch (pid_err) { |
| 359 | 359 | posix.EAGAIN, posix.ENOMEM, posix.ENOSYS => error.SystemResources, |
| 360 | | else => error.Unexpected, |
| 360 | else => os.unexpectedErrorPosix(pid_err), |
| 361 | 361 | }; |
| 362 | 362 | } |
| 363 | 363 | if (pid_result == 0) { |
| ... | ... | @@ -556,9 +556,6 @@ pub const ChildProcess = struct { |
| 556 | 556 | }; |
| 557 | 557 | var piProcInfo: windows.PROCESS_INFORMATION = undefined; |
| 558 | 558 | |
| 559 | | const app_name = %return cstr.addNullByte(self.allocator, self.argv[0]); |
| 560 | | defer self.allocator.free(app_name); |
| 561 | | |
| 562 | 559 | const cwd_slice = if (self.cwd) |cwd| { |
| 563 | 560 | %return cstr.addNullByte(self.allocator, cwd) |
| 564 | 561 | } else { |
| ... | ... | @@ -575,17 +572,42 @@ pub const ChildProcess = struct { |
| 575 | 572 | defer if (maybe_envp_buf) |envp_buf| self.allocator.free(envp_buf); |
| 576 | 573 | const envp_ptr = if (maybe_envp_buf) |envp_buf| envp_buf.ptr else null; |
| 577 | 574 | |
| 578 | | if (windows.CreateProcessA(app_name.ptr, cmd_line.ptr, null, null, windows.TRUE, 0, |
| 579 | | @ptrCast(?&c_void, envp_ptr), |
| 580 | | cwd_ptr, &siStartInfo, &piProcInfo) == windows.FALSE) |
| 575 | // the cwd set in ChildProcess is in effect when choosing the executable path |
| 576 | // to match posix semantics |
| 577 | const app_name = if (self.cwd) |cwd| { |
| 578 | const resolved = %return os.path.resolve(self.allocator, cwd, self.argv[0]); |
| 579 | defer self.allocator.free(resolved); |
| 580 | %return cstr.addNullByte(self.allocator, resolved) |
| 581 | } else { |
| 582 | %return cstr.addNullByte(self.allocator, self.argv[0]) |
| 583 | }; |
| 584 | defer self.allocator.free(app_name); |
| 585 | |
| 586 | windowsCreateProcess(app_name.ptr, cmd_line.ptr, envp_ptr, cwd_ptr, |
| 587 | &siStartInfo, &piProcInfo) %% |no_path_err| |
| 581 | 588 | { |
| 582 | | const err = windows.GetLastError(); |
| 583 | | return switch (err) { |
| 584 | | windows.ERROR.FILE_NOT_FOUND => error.FileNotFound, |
| 585 | | windows.ERROR.INVALID_PARAMETER => unreachable, |
| 586 | | else => error.Unexpected, |
| 587 | | }; |
| 588 | | } |
| 589 | if (no_path_err != error.FileNotFound) |
| 590 | return no_path_err; |
| 591 | |
| 592 | const PATH = %return os.getEnvVarOwned(self.allocator, "PATH"); |
| 593 | defer self.allocator.free(PATH); |
| 594 | |
| 595 | var it = mem.split(PATH, ";"); |
| 596 | while (it.next()) |search_path| { |
| 597 | const joined_path = %return os.path.join(self.allocator, search_path, app_name); |
| 598 | defer self.allocator.free(joined_path); |
| 599 | |
| 600 | if (windowsCreateProcess(joined_path.ptr, cmd_line.ptr, envp_ptr, cwd_ptr, |
| 601 | &siStartInfo, &piProcInfo)) |_| |
| 602 | { |
| 603 | break; |
| 604 | } else |err| if (err == error.FileNotFound) { |
| 605 | continue; |
| 606 | } else { |
| 607 | return err; |
| 608 | } |
| 609 | } |
| 610 | }; |
| 589 | 611 | |
| 590 | 612 | if (stdin_ptr) |outstream| { |
| 591 | 613 | *outstream = io.OutStream { |
| ... | ... | @@ -633,6 +655,24 @@ pub const ChildProcess = struct { |
| 633 | 655 | } |
| 634 | 656 | }; |
| 635 | 657 | |
| 658 | fn windowsCreateProcess(app_name: &u8, cmd_line: &u8, envp_ptr: ?&u8, cwd_ptr: ?&u8, |
| 659 | lpStartupInfo: &windows.STARTUPINFOA, lpProcessInformation: &windows.PROCESS_INFORMATION) -> %void |
| 660 | { |
| 661 | if (windows.CreateProcessA(app_name, cmd_line, null, null, windows.TRUE, 0, |
| 662 | @ptrCast(?&c_void, envp_ptr), cwd_ptr, lpStartupInfo, lpProcessInformation) == 0) |
| 663 | { |
| 664 | const err = windows.GetLastError(); |
| 665 | return switch (err) { |
| 666 | windows.ERROR.FILE_NOT_FOUND, windows.ERROR.PATH_NOT_FOUND => error.FileNotFound, |
| 667 | windows.ERROR.INVALID_PARAMETER => unreachable, |
| 668 | else => os.unexpectedErrorWindows(err), |
| 669 | }; |
| 670 | } |
| 671 | } |
| 672 | |
| 673 | |
| 674 | |
| 675 | |
| 636 | 676 | /// Caller must dealloc. |
| 637 | 677 | /// Guarantees a null byte at result[result.len]. |
| 638 | 678 | fn windowsCreateCommandLine(allocator: &Allocator, argv: []const []const u8) -> %[]u8 { |
| ... | ... | @@ -684,7 +724,7 @@ fn windowsMakePipe(rd: &windows.HANDLE, wr: &windows.HANDLE, sattr: &const SECUR |
| 684 | 724 | if (windows.CreatePipe(rd, wr, sattr, 0) == 0) { |
| 685 | 725 | const err = windows.GetLastError(); |
| 686 | 726 | return switch (err) { |
| 687 | | else => error.Unexpected, |
| 727 | else => os.unexpectedErrorWindows(err), |
| 688 | 728 | }; |
| 689 | 729 | } |
| 690 | 730 | } |
| ... | ... | @@ -693,7 +733,7 @@ fn windowsSetHandleInfo(h: windows.HANDLE, mask: windows.DWORD, flags: windows.D |
| 693 | 733 | if (windows.SetHandleInformation(h, mask, flags) == 0) { |
| 694 | 734 | const err = windows.GetLastError(); |
| 695 | 735 | return switch (err) { |
| 696 | | else => error.Unexpected, |
| 736 | else => os.unexpectedErrorWindows(err), |
| 697 | 737 | }; |
| 698 | 738 | } |
| 699 | 739 | } |
| ... | ... | @@ -724,7 +764,7 @@ fn makePipe() -> %[2]i32 { |
| 724 | 764 | if (err > 0) { |
| 725 | 765 | return switch (err) { |
| 726 | 766 | posix.EMFILE, posix.ENFILE => error.SystemResources, |
| 727 | | else => error.Unexpected, |
| 767 | else => os.unexpectedErrorPosix(err), |
| 728 | 768 | } |
| 729 | 769 | } |
| 730 | 770 | return fds; |