mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-03-08 02:24:33 +01:00
std.Io.Threaded: more robust windows process creation error handling
This commit is contained in:
parent
f072313e1e
commit
08d8b412e9
1 changed files with 82 additions and 48 deletions
|
|
@ -13780,7 +13780,29 @@ fn windowsCreateProcessPathExt(
|
|||
const prefixed_path = try windows.wToPrefixedFileW(null, dir_path_z);
|
||||
break :dir dirOpenDirWindows(.cwd(), prefixed_path.span(), .{
|
||||
.iterate = true,
|
||||
}) catch return error.FileNotFound;
|
||||
}) catch |err| switch (err) {
|
||||
// These errors must not be ignored because they should not be able
|
||||
// to affect which file is chosen to execute. Also `error.Canceled`
|
||||
// must never be swallowed.
|
||||
error.Canceled,
|
||||
error.SystemResources,
|
||||
error.Unexpected,
|
||||
error.ProcessFdQuotaExceeded,
|
||||
error.SystemFdQuotaExceeded,
|
||||
=> |e| return e,
|
||||
|
||||
error.AccessDenied,
|
||||
error.PermissionDenied,
|
||||
error.SymLinkLoop,
|
||||
error.FileNotFound,
|
||||
error.NotDir,
|
||||
error.NoDevice,
|
||||
error.NetworkNotFound,
|
||||
error.NameTooLong,
|
||||
error.BadPathName,
|
||||
error.DeviceBusy,
|
||||
=> return error.FileNotFound,
|
||||
};
|
||||
};
|
||||
defer windows.CloseHandle(dir.handle);
|
||||
|
||||
|
|
@ -13984,55 +14006,67 @@ fn windowsCreateProcess(
|
|||
lpStartupInfo: *windows.STARTUPINFOW,
|
||||
lpProcessInformation: *windows.PROCESS_INFORMATION,
|
||||
) !void {
|
||||
if (windows.kernel32.CreateProcessW(
|
||||
app_name,
|
||||
cmd_line,
|
||||
null,
|
||||
null,
|
||||
windows.TRUE,
|
||||
flags,
|
||||
env_ptr,
|
||||
cwd_ptr,
|
||||
lpStartupInfo,
|
||||
lpProcessInformation,
|
||||
) == 0) switch (windows.GetLastError()) {
|
||||
.FILE_NOT_FOUND => return error.FileNotFound,
|
||||
.PATH_NOT_FOUND => return error.FileNotFound,
|
||||
.DIRECTORY => return error.FileNotFound,
|
||||
.ACCESS_DENIED => return error.AccessDenied,
|
||||
.INVALID_PARAMETER => unreachable,
|
||||
.INVALID_NAME => return error.InvalidName,
|
||||
.FILENAME_EXCED_RANGE => return error.NameTooLong,
|
||||
.SHARING_VIOLATION => return error.FileBusy,
|
||||
const syscall: Syscall = try .start();
|
||||
while (true) {
|
||||
if (windows.kernel32.CreateProcessW(
|
||||
app_name,
|
||||
cmd_line,
|
||||
null,
|
||||
null,
|
||||
windows.TRUE,
|
||||
flags,
|
||||
env_ptr,
|
||||
cwd_ptr,
|
||||
lpStartupInfo,
|
||||
lpProcessInformation,
|
||||
) != 0) {
|
||||
return syscall.finish();
|
||||
} else switch (windows.GetLastError()) {
|
||||
.INVALID_PARAMETER => unreachable,
|
||||
.OPERATION_ABORTED => {
|
||||
try syscall.checkCancel();
|
||||
continue;
|
||||
},
|
||||
.FILE_NOT_FOUND => return syscall.fail(error.FileNotFound),
|
||||
.PATH_NOT_FOUND => return syscall.fail(error.FileNotFound),
|
||||
.DIRECTORY => return syscall.fail(error.FileNotFound),
|
||||
.ACCESS_DENIED => return syscall.fail(error.AccessDenied),
|
||||
.INVALID_NAME => return syscall.fail(error.InvalidName),
|
||||
.FILENAME_EXCED_RANGE => return syscall.fail(error.NameTooLong),
|
||||
.SHARING_VIOLATION => return syscall.fail(error.FileBusy),
|
||||
.COMMITMENT_LIMIT => return syscall.fail(error.SystemResources),
|
||||
|
||||
// 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
|
||||
// This one is not mapped to ENOEXEC but it is possible, for example
|
||||
// when calling CreateProcessW on a plain text file with a .exe extension
|
||||
.EXE_MACHINE_TYPE_MISMATCH,
|
||||
=> return error.InvalidExe,
|
||||
// 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
|
||||
// This one is not mapped to ENOEXEC but it is possible, for example
|
||||
// when calling CreateProcessW on a plain text file with a .exe extension
|
||||
.EXE_MACHINE_TYPE_MISMATCH,
|
||||
=> return syscall.fail(error.InvalidExe),
|
||||
|
||||
.COMMITMENT_LIMIT => return error.SystemResources,
|
||||
else => |err| return windows.unexpectedError(err),
|
||||
};
|
||||
else => |err| {
|
||||
syscall.finish();
|
||||
return windows.unexpectedError(err);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Case-insensitive WTF-16 lookup
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue