Commit 5843b7987e

Ryan Liptak <squeek502@hotmail.com>
2022-12-17 07:14:33
Add error.InvalidExe to CreateProcessW error set and handle it in ChildProcess.spawnWindows
1 parent b362cbb
Changed files (2)
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),
         }
     }
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,
                     }
                 }