diff --git a/lib/std/child_process.zig b/lib/std/child_process.zig index be38b9ae45..1d1eab2a14 100644 --- a/lib/std/child_process.zig +++ b/lib/std/child_process.zig @@ -966,7 +966,7 @@ pub const ChildProcess = struct { defer self.allocator.free(cmd_line_w); windowsCreateProcess(app_path_w.ptr, cmd_line_w.ptr, envp_ptr, cwd_w_ptr, &siStartInfo, &piProcInfo) catch |no_path_err| { - if (no_path_err != error.FileNotFound) return no_path_err; + if (no_path_err != error.FileNotFound and no_path_err != error.InvalidExe) return no_path_err; const PATH: [:0]const u16 = std.os.getenvW(unicode.utf8ToUtf16LeStringLiteral("PATH")) orelse &[_:0]u16{}; const PATHEXT: [:0]const u16 = std.os.getenvW(unicode.utf8ToUtf16LeStringLiteral("PATHEXT")) orelse &[_:0]u16{}; @@ -991,7 +991,7 @@ pub const ChildProcess = struct { if (windowsCreateProcess(path_no_ext.ptr, cmd_line_w.ptr, envp_ptr, cwd_w_ptr, &siStartInfo, &piProcInfo)) |_| { break :retry; } else |err| switch (err) { - error.FileNotFound, error.AccessDenied => {}, + error.FileNotFound, error.AccessDenied, error.InvalidExe => {}, else => return err, } @@ -1007,6 +1007,7 @@ pub const ChildProcess = struct { } else |err| switch (err) { error.FileNotFound => continue, error.AccessDenied => continue, + error.InvalidExe => continue, else => return err, } } diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 0bd695a029..d654a60bd9 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -1569,6 +1569,7 @@ pub const CreateProcessError = error{ AccessDenied, InvalidName, NameTooLong, + InvalidExe, Unexpected, }; @@ -1603,6 +1604,27 @@ pub fn CreateProcessW( .INVALID_PARAMETER => unreachable, .INVALID_NAME => return error.InvalidName, .FILENAME_EXCED_RANGE => return error.NameTooLong, + // These are all the system errors that are mapped to ENOEXEC by + // the undocumented _dosmaperr (old CRT) or __acrt_errno_map_os_error + // (newer CRT) functions. Their code can be found in crt/src/dosmap.c (old SDK) + // or urt/misc/errno.cpp (newer SDK) in the Windows SDK. + .BAD_FORMAT, + .INVALID_STARTING_CODESEG, // MIN_EXEC_ERROR in errno.cpp + .INVALID_STACKSEG, + .INVALID_MODULETYPE, + .INVALID_EXE_SIGNATURE, + .EXE_MARKED_INVALID, + .BAD_EXE_FORMAT, + .ITERATED_DATA_EXCEEDS_64k, + .INVALID_MINALLOCSIZE, + .DYNLINK_FROM_INVALID_RING, + .IOPL_NOT_ENABLED, + .INVALID_SEGDPL, + .AUTODATASEG_EXCEEDS_64k, + .RING2SEG_MUST_BE_MOVABLE, + .RELOC_CHAIN_XEEDS_SEGLIM, + .INFLOOP_IN_RELOC_CHAIN, // MAX_EXEC_ERROR in errno.cpp + => return error.InvalidExe, else => |err| return unexpectedError(err), } }