From 11c8c38332ada0585a8690e84c8de3affb34c935 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Fri, 23 Oct 2026 09:23:51 +0200 Subject: [PATCH] disentangle std.c and std.posix on Windows std.c should reflect the CRT, not std.posix's bizarre view of the world. Also: * Audit some incorrect std.c types and function signatures * Remove ws2_32 from std.c (dubious quality, and ws2_32 isn't libc) * Remove remnants of Windows support in std.posix closes https://codeberg.org/ziglang/zig/issues/37382 --- lib/std/Io/Dir.zig | 2 +- lib/std/Io/File.zig | 10 +- lib/std/Io/Threaded.zig | 139 ++++++++++++++------------ lib/std/Io/net.zig | 11 +- lib/std/c.zig | 120 +++++++++++++--------- lib/std/crypto/Certificate/Bundle.zig | 2 +- lib/std/os/windows.zig | 6 +- lib/std/posix.zig | 90 ++++++----------- lib/std/posix/test.zig | 25 ++--- lib/std/process.zig | 21 ++-- lib/std/process/Args.zig | 2 +- lib/std/process/Child.zig | 7 +- src/link/MachO.zig | 4 +- 13 files changed, 234 insertions(+), 205 deletions(-) diff --git a/lib/std/Io/Dir.zig b/lib/std/Io/Dir.zig index 929ce5c2679222c18cfa1c002c2b3dcbdd03a825..5e965d5a1be510baac3e7620ffc3803fff667507 100644 --- a/lib/std/Io/Dir.zig +++ b/lib/std/Io/Dir.zig @@ -12,7 +12,7 @@ const Allocator = std.mem.Allocator; handle: Handle, -pub const Handle = std.posix.fd_t; +pub const Handle = File.Handle; pub const path = std.fs.path; diff --git a/lib/std/Io/File.zig b/lib/std/Io/File.zig index ace3812ca20d720b3d9647029ac4e7d06e8dbd52..1379fbefe2bfa4ed5c5c8b40a8e28c7cfff37835 100644 --- a/lib/std/Io/File.zig +++ b/lib/std/Io/File.zig @@ -23,7 +23,7 @@ pub const Flags = struct { nonblocking: bool, }; -pub const Handle = std.posix.fd_t; +pub const Handle = if (native_os == .windows) std.os.windows.HANDLE else std.posix.fd_t; pub const Reader = @import("File/Reader.zig"); pub const Writer = @import("File/Writer.zig"); @@ -34,10 +34,10 @@ pub const MemoryMap = @import("File/MemoryMap.zig"); /// deadlocking. pub const MultiReader = @import("File/MultiReader.zig"); -pub const INode = std.posix.ino_t; -pub const NLink = std.posix.nlink_t; -pub const Uid = std.posix.uid_t; -pub const Gid = std.posix.gid_t; +pub const INode = if (native_os == .windows) std.os.windows.LARGE_INTEGER else std.posix.ino_t; +pub const NLink = if (native_os == .windows) std.os.windows.ULONG else std.posix.nlink_t; +pub const Uid = if (native_os == .windows) void else std.posix.uid_t; +pub const Gid = if (native_os == .windows) void else std.posix.gid_t; pub const BlockSize = u32; pub const Kind = enum { diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig index bafe7dc7aeabe0d8704afe28353df1106207b7fd..087317eb61f8c4ca008801cc79cf595cc2da5d51 100644 --- a/lib/std/Io/Threaded.zig +++ b/lib/std/Io/Threaded.zig @@ -1614,7 +1614,7 @@ pub const default_PATH = "/usr/local/bin:/bin:/usr/bin"; const max_windows_kernel_bug_retries = 13; comptime { - if (@TypeOf(posix.IOV_MAX) != void) assert(max_iovecs_len <= posix.IOV_MAX); + if (!is_windows and @TypeOf(posix.IOV_MAX) != void) assert(max_iovecs_len <= posix.IOV_MAX); } pub const InitOptions = struct { @@ -1696,7 +1696,7 @@ pub fn init( .disable_memory_mapping = options.disable_memory_mapping, }; - if (posix.Sigaction != void) { + if (!is_windows and posix.Sigaction != void) { // This causes sending `posix.SIG.IO` to thread to interrupt blocking // syscalls, returning `posix.E.INTR`. const act: posix.Sigaction = .{ @@ -1758,7 +1758,7 @@ pub fn setAsyncLimit(t: *Threaded, new_limit: Io.Limit) void { pub fn deinit(t: *Threaded) void { t.join(); - if (posix.Sigaction != void and t.have_signal_handler) { + if (!is_windows and posix.Sigaction != void and t.have_signal_handler) { if (have_sig_io) posix.sigaction(.IO, &t.old_sig_io, null); if (have_sig_pipe) posix.sigaction(.PIPE, &t.old_sig_pipe, null); } @@ -2009,8 +2009,8 @@ const have_preadv = switch (native_os) { .windows, .haiku => false, else => true, }; -const have_sig_io = posix.SIG != void and @hasField(posix.SIG, "IO"); -const have_sig_pipe = posix.SIG != void and @hasField(posix.SIG, "PIPE"); +const have_sig_io = !is_windows and posix.SIG != void and @hasField(posix.SIG, "IO"); +const have_sig_pipe = !is_windows and posix.SIG != void and @hasField(posix.SIG, "PIPE"); const have_sendfile = if (builtin.link_libc) @TypeOf(std.c.sendfile) != void else native_os == .linux; const have_copy_file_range = switch (native_os) { .linux, .freebsd => true, @@ -7283,6 +7283,8 @@ fn fileHardLink( const t: *Threaded = @ptrCast(@alignCast(userdata)); _ = t; + if (is_windows) return error.OperationUnsupported; + var new_path_buffer: [posix.PATH_MAX]u8 = undefined; const new_sub_path_posix = try pathToPosix(new_sub_path, &new_path_buffer); @@ -12229,7 +12231,7 @@ fn netListenUnixPosix( if (!net.has_unix_sockets) return error.AddressFamilyUnsupported; const t: *Threaded = @ptrCast(@alignCast(userdata)); _ = t; - const socket_fd = openSocketPosix(posix.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) { + const socket_fd = openSocketPosix(AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) { error.ProtocolUnsupportedBySystem => return error.AddressFamilyUnsupported, error.ProtocolUnsupportedByAddressFamily => return error.AddressFamilyUnsupported, error.SocketModeUnsupported => return error.AddressFamilyUnsupported, @@ -12308,8 +12310,8 @@ fn netListenUnixWindows( fn posixBindUnix( fd: posix.socket_t, - addr: *const posix.sockaddr, - addr_len: posix.socklen_t, + addr: *const sockaddr, + addr_len: socklen_t, ) !void { const syscall: Syscall = try .start(); while (true) { @@ -12351,8 +12353,8 @@ fn posixBindUnix( fn posixBind( socket_fd: posix.socket_t, - addr: *const posix.sockaddr, - addr_len: posix.socklen_t, + addr: *const sockaddr, + addr_len: socklen_t, ) !void { const syscall: Syscall = try .start(); while (true) { @@ -12386,8 +12388,8 @@ fn posixBind( fn posixConnect( socket_fd: posix.socket_t, - addr: *const posix.sockaddr, - addr_len: posix.socklen_t, + addr: *const sockaddr, + addr_len: socklen_t, ) !void { const syscall: Syscall = try .start(); while (true) switch (posix.errno(posix.system.connect(socket_fd, addr, addr_len))) { @@ -12424,8 +12426,8 @@ fn posixConnect( fn posixConnectUnix( fd: posix.socket_t, - addr: *const posix.sockaddr, - addr_len: posix.socklen_t, + addr: *const sockaddr, + addr_len: socklen_t, ) !void { const syscall: Syscall = try .start(); while (true) { @@ -12468,8 +12470,8 @@ fn posixConnectUnix( fn posixGetSockName( socket_fd: posix.fd_t, - addr: *posix.sockaddr, - addr_len: *posix.socklen_t, + addr: *sockaddr, + addr_len: *socklen_t, ) !void { const syscall: Syscall = try .start(); while (true) { @@ -12610,7 +12612,7 @@ fn netConnectUnixPosix( if (!net.has_unix_sockets) return error.AddressFamilyUnsupported; const t: *Threaded = @ptrCast(@alignCast(userdata)); _ = t; - const socket_fd = openSocketPosix(posix.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) { + const socket_fd = openSocketPosix(AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) { error.ProtocolUnsupportedByAddressFamily => return error.AddressFamilyUnsupported, error.OptionUnsupported => return error.Unexpected, else => |e| return e, @@ -12705,7 +12707,7 @@ fn netBindIpWindows( } fn openSocketPosix( - family: posix.sa_family_t, + family: sa_family_t, options: IpAddress.BindOptions, ) error{ AddressFamilyUnsupported, @@ -12720,7 +12722,7 @@ fn openSocketPosix( Canceled, }!posix.socket_t { const mode, const protocol = try posixSocketModeProtocol(family, options.mode, options.protocol); - const flags: u32 = mode | if (socket_flags_unsupported) 0 else posix.SOCK.CLOEXEC; + const flags: u32 = mode | if (socket_flags_unsupported) 0 else SOCK.CLOEXEC; const syscall: Syscall = try .start(); const socket_fd = while (true) { const rc = posix.system.socket(family, flags, protocol); @@ -12751,7 +12753,7 @@ fn openSocketPosix( if (options.ip6_only) |ip6_only| { if (posix.IPV6 == void) return error.OptionUnsupported; - try setSocketOptionPosix(socket_fd, posix.IPPROTO.IPV6, posix.IPV6.V6ONLY, @intFromBool(ip6_only)); + try setSocketOptionPosix(socket_fd, IPPROTO.IPV6, posix.IPV6.V6ONLY, @intFromBool(ip6_only)); } return socket_fd; @@ -12776,15 +12778,15 @@ fn netSocketCreatePair( const t: *Threaded = @ptrCast(@alignCast(userdata)); _ = t; if (!have_networking) return error.OperationUnsupported; - if (@TypeOf(posix.system.socketpair) == void) return error.OperationUnsupported; + if (is_windows or @TypeOf(posix.system.socketpair) == void) return error.OperationUnsupported; if (native_os == .haiku) @panic("TODO"); - const family: posix.sa_family_t = switch (options.family) { - .ip4 => posix.AF.INET, - .ip6 => posix.AF.INET6, + const family: sa_family_t = switch (options.family) { + .ip4 => AF.INET, + .ip6 => AF.INET6, }; const mode, const protocol = try posixSocketModeProtocol(family, options.mode, options.protocol); - const flags: u32 = mode | if (socket_flags_unsupported) 0 else posix.SOCK.CLOEXEC; + const flags: u32 = mode | if (socket_flags_unsupported) 0 else SOCK.CLOEXEC; var sockets: [2]posix.socket_t = undefined; const syscall: Syscall = try .start(); @@ -12800,7 +12802,7 @@ fn netSocketCreatePair( try setCloexec(sockets[1]); } var storages: [2]PosixAddress = undefined; - var addr_lens: [2]posix.socklen_t = .{ @sizeOf(PosixAddress), @sizeOf(PosixAddress) }; + var addr_lens: [2]socklen_t = .{ @sizeOf(PosixAddress), @sizeOf(PosixAddress) }; try posixGetSockName(sockets[0], &storages[0].any, &addr_lens[0]); try posixGetSockName(sockets[1], &storages[1].any, &addr_lens[1]); return .{ @@ -12926,11 +12928,11 @@ fn netAccept(t: *Threaded, listen_fd: net.Socket.Handle, options: net.Server.Acc fn netAcceptPosix(listen_fd: net.Socket.Handle) net.Server.AcceptError!net.Socket { var storage: PosixAddress = undefined; - var addr_len: posix.socklen_t = @sizeOf(PosixAddress); + var addr_len: socklen_t = @sizeOf(PosixAddress); const syscall: Syscall = try .start(); const fd = while (true) { const rc = if (have_accept4) - posix.system.accept4(listen_fd, &storage.any, &addr_len, posix.SOCK.CLOEXEC) + posix.system.accept4(listen_fd, &storage.any, &addr_len, SOCK.CLOEXEC) else posix.system.accept(listen_fd, &storage.any, &addr_len); switch (posix.errno(rc)) { @@ -13788,7 +13790,7 @@ fn netInterfaceNameResolve( const t: *Threaded = @ptrCast(@alignCast(userdata)); if (native_os == .linux) { - const sock_fd = openSocketPosix(posix.AF.UNIX, .{ .mode = .dgram }) catch |err| switch (err) { + const sock_fd = openSocketPosix(AF.UNIX, .{ .mode = .dgram }) catch |err| switch (err) { error.ProcessFdQuotaExceeded => return error.SystemResources, error.SystemFdQuotaExceeded => return error.SystemResources, error.AddressFamilyUnsupported => return error.Unexpected, @@ -13950,7 +13952,7 @@ fn netInterfaceName(userdata: ?*anyopaque, interface: net.Interface) net.Interfa else => |err| return windows.unexpectedError(err), } var name_w: [net.Interface.Name.max_len:0]windows.WCHAR = undefined; - switch (ConvertInterfaceLuidToNameW.?(&luid, &name_w, name_w.len)) { + switch (ConvertInterfaceLuidToNameW.?(&luid, &name_w, name_w.len + 1)) { .SUCCESS => {}, .INVALID_PARAMETER => unreachable, .NOT_ENOUGH_MEMORY => return error.NameTooLong, @@ -14227,15 +14229,15 @@ fn netLookupFallible( const port_c = std.mem.printSentinel(&port_buffer, "{d}", .{options.port}, 0) catch unreachable; const family: i32 = if (options.family) |f| switch (f) { - .ip4 => posix.AF.INET, - .ip6 => posix.AF.INET6, - } else posix.AF.UNSPEC; + .ip4 => AF.INET, + .ip6 => AF.INET6, + } else AF.UNSPEC; const hints: posix.addrinfo = .{ .flags = .{ .CANONNAME = options.canonical_name_buffer != null, .NUMERICSERV = true }, .family = family, - .socktype = posix.SOCK.STREAM, - .protocol = posix.IPPROTO.TCP, + .socktype = SOCK.STREAM, + .protocol = IPPROTO.TCP, .canonname = null, .addr = null, .addrlen = 0, @@ -14489,47 +14491,54 @@ fn processSetCurrentPath(userdata: ?*anyopaque, path: []const u8) process.SetCur return chdir(path); } +const sockaddr = if (is_windows) ws2_32.sockaddr else posix.sockaddr; +const sa_family_t = if (is_windows) ws2_32.ADDRESS_FAMILY else posix.sa_family_t; +const socklen_t = if (is_windows) ws2_32.socklen_t else posix.socklen_t; +const AF = if (is_windows) ws2_32.AF else posix.AF; +const SOCK = if (is_windows) ws2_32.SOCK else posix.SOCK; +const IPPROTO = if (is_windows) ws2_32.IPPROTO else posix.IPPROTO; + pub const PosixAddress = extern union { - any: posix.sockaddr, - in: posix.sockaddr.in, - in6: posix.sockaddr.in6, + any: sockaddr, + in: sockaddr.in, + in6: sockaddr.in6, }; const UnixAddress = extern union { - any: posix.sockaddr, - un: posix.sockaddr.un, + any: sockaddr, + un: sockaddr.un, }; -pub fn posixAddressFamily(a: *const IpAddress) posix.sa_family_t { +pub fn posixAddressFamily(a: *const IpAddress) sa_family_t { return switch (a.*) { - .ip4 => posix.AF.INET, - .ip6 => posix.AF.INET6, + .ip4 => AF.INET, + .ip6 => AF.INET6, }; } pub fn addressFromPosix(posix_address: *const PosixAddress) IpAddress { return switch (posix_address.any.family) { - posix.AF.INET => .{ .ip4 = address4FromPosix(&posix_address.in) }, - posix.AF.INET6 => .{ .ip6 = address6FromPosix(&posix_address.in6) }, + AF.INET => .{ .ip4 = address4FromPosix(&posix_address.in) }, + AF.INET6 => .{ .ip6 = address6FromPosix(&posix_address.in6) }, else => .{ .ip4 = .loopback(0) }, }; } -pub fn addressToPosix(a: *const IpAddress, storage: *PosixAddress) posix.socklen_t { +pub fn addressToPosix(a: *const IpAddress, storage: *PosixAddress) socklen_t { return switch (a.*) { .ip4 => |ip4| { storage.in = address4ToPosix(ip4); - return @sizeOf(posix.sockaddr.in); + return @sizeOf(sockaddr.in); }, .ip6 => |*ip6| { storage.in6 = address6ToPosix(ip6); - return @sizeOf(posix.sockaddr.in6); + return @sizeOf(sockaddr.in6); }, }; } -fn addressUnixToPosix(a: *const net.UnixAddress, storage: *UnixAddress) posix.socklen_t { - storage.un.family = posix.AF.UNIX; +fn addressUnixToPosix(a: *const net.UnixAddress, storage: *UnixAddress) socklen_t { + storage.un.family = AF.UNIX; var path_len = switch (native_os) { .windows => @min(a.path.len, storage.un.path.len), else => a.path.len, @@ -14545,13 +14554,13 @@ fn addressUnixToPosix(a: *const net.UnixAddress, storage: *UnixAddress) posix.so switch (native_os) { .windows => { if (storage.un.path[0] == 0) @memset(storage.un.path[path_len..], 0); - return @sizeOf(posix.sockaddr.un); + return @sizeOf(sockaddr.un); }, - else => return @intCast(@offsetOf(posix.sockaddr.un, "path") + path_len), + else => return @intCast(@offsetOf(sockaddr.un, "path") + path_len), } } -fn address4FromPosix(in: *const posix.sockaddr.in) net.Ip4Address { +fn address4FromPosix(in: *const sockaddr.in) net.Ip4Address { // The network byte order address in `in.addr` is already the byte order we want. const addr_bytes: *const [4]u8 = @ptrCast(&in.addr); return .{ @@ -14560,7 +14569,7 @@ fn address4FromPosix(in: *const posix.sockaddr.in) net.Ip4Address { }; } -fn address6FromPosix(in6: *const posix.sockaddr.in6) net.Ip6Address { +fn address6FromPosix(in6: *const sockaddr.in6) net.Ip6Address { return .{ .port = std.mem.bigToNative(u16, in6.port), .bytes = in6.addr, @@ -14569,7 +14578,7 @@ fn address6FromPosix(in6: *const posix.sockaddr.in6) net.Ip6Address { }; } -fn address4ToPosix(a: net.Ip4Address) posix.sockaddr.in { +fn address4ToPosix(a: net.Ip4Address) sockaddr.in { // The byte order of `a.bytes` is already equivalent to a network byte order address. const addr_raw: *align(1) const u32 = @ptrCast(&a.bytes); return .{ @@ -14578,7 +14587,7 @@ fn address4ToPosix(a: net.Ip4Address) posix.sockaddr.in { }; } -fn address6ToPosix(a: *const net.Ip6Address) posix.sockaddr.in6 { +fn address6ToPosix(a: *const net.Ip6Address) sockaddr.in6 { return .{ .port = std.mem.nativeToBig(u16, a.port), .flowinfo = a.flow, @@ -14592,21 +14601,21 @@ pub fn errnoBug(err: posix.E) Io.UnexpectedError { return error.Unexpected; } -pub fn posixSocketModeProtocol(family: posix.sa_family_t, mode: net.Socket.Mode, protocol: ?net.Protocol) !struct { u32, u32 } { +pub fn posixSocketModeProtocol(family: sa_family_t, mode: net.Socket.Mode, protocol: ?net.Protocol) !struct { u32, u32 } { return .{ switch (mode) { - .stream => posix.SOCK.STREAM, - .dgram => posix.SOCK.DGRAM, - .seqpacket => posix.SOCK.SEQPACKET, - .raw => posix.SOCK.RAW, - .rdm => if (@hasDecl(posix.SOCK, "RDM")) posix.SOCK.RDM else return error.OptionUnsupported, + .stream => SOCK.STREAM, + .dgram => SOCK.DGRAM, + .seqpacket => SOCK.SEQPACKET, + .raw => SOCK.RAW, + .rdm => if (@hasDecl(SOCK, "RDM")) SOCK.RDM else return error.OptionUnsupported, }, if (protocol) |p| @backingInt(p) else if (is_windows) switch (family) { - posix.AF.UNIX => switch (mode) { + AF.UNIX => switch (mode) { .stream => 0, else => return error.ProtocolUnsupportedByAddressFamily, }, - posix.AF.INET, posix.AF.INET6 => @backingInt(@as(net.Protocol, switch (mode) { + AF.INET, AF.INET6 => @backingInt(@as(net.Protocol, switch (mode) { .stream => .tcp, .dgram => .udp, else => return error.ProtocolUnsupportedByAddressFamily, @@ -17992,7 +18001,7 @@ fn progressParentFile(userdata: ?*anyopaque) std.Progress.ParentFileError!File { return t.environ.zig_progress_file; } -fn inheritParentHandle(handle: posix.fd_t) Io.InheritParentHandleError!void { +fn inheritParentHandle(handle: File.Handle) Io.InheritParentHandleError!void { switch (native_os) { .linux, .dragonfly, diff --git a/lib/std/Io/net.zig b/lib/std/Io/net.zig index f1d8bb0dd4e1180655b369b07295419caa78ed10..a11c06c3f06ddb9a14a4df06aa576e9e1c4cf757 100644 --- a/lib/std/Io/net.zig +++ b/lib/std/Io/net.zig @@ -1016,7 +1016,12 @@ pub const Interface = struct { pub const Name = struct { bytes: [max_len:0]u8, - pub const max_len = if (@TypeOf(std.posix.IFNAMESIZE) == void) 0 else std.posix.IFNAMESIZE - 1; + pub const max_len = if (native_os == .windows) + std.os.windows.IF.MAX_STRING_SIZE + else if (@TypeOf(std.posix.IFNAMESIZE) == void) + 0 + else + std.posix.IFNAMESIZE - 1; pub fn toSlice(n: *const Name) []const u8 { return std.mem.sliceTo(&n.bytes, 0); @@ -1094,7 +1099,7 @@ pub const Socket = struct { /// Underlying platform-defined type which may or may not be /// interchangeable with a file system file descriptor. - pub const Handle = std.posix.fd_t; + pub const Handle = if (native_os == .windows) std.os.windows.HANDLE else std.posix.fd_t; /// Leaves `address` in a valid state. pub fn close(s: *const Socket, io: Io) void { @@ -1517,7 +1522,7 @@ pub const Stream = struct { } }; -pub const cmsg_align = if (@TypeOf(std.posix.cmsg_align) == void) 1 else std.posix.cmsg_align; +pub const cmsg_align = if (native_os == .windows or @TypeOf(std.posix.cmsg_align) == void) 1 else std.posix.cmsg_align; /// Utility Functions for interacting with POSIX socket control messages. /// See also https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_socket.h.html pub const cmsg = struct { diff --git a/lib/std/c.zig b/lib/std/c.zig index 3bb4378a5493308e1b68498c77c49d48429ccd01..eae7f2f1fb1b114d988498611031e5c7c18437aa 100644 --- a/lib/std/c.zig +++ b/lib/std/c.zig @@ -12,7 +12,6 @@ const page_size = std.heap.page_size_min; const linux = std.os.linux; const emscripten = std.os.emscripten; const windows = std.os.windows; -const ws2_32 = std.os.windows.ws2_32; const darwin = @import("c/darwin.zig"); const freebsd = @import("c/freebsd.zig"); const illumos = @import("c/illumos.zig"); @@ -79,7 +78,7 @@ pub fn errno(rc: anytype) E { pub const ino_t = switch (native_os) { .linux => linux.ino_t, .emscripten => emscripten.ino_t, - .windows => windows.LARGE_INTEGER, + .windows => c_ushort, .haiku => i64, // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L38 else => u64, @@ -138,9 +137,10 @@ pub const dev_t = switch (native_os) { pub const mode_t = switch (native_os) { .linux => linux.mode_t, .emscripten => emscripten.mode_t, - .openbsd, .haiku, .netbsd, .illumos, .windows => u32, + .openbsd, .haiku, .netbsd, .illumos => u32, // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L44 .freebsd, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos, .dragonfly, .serenity => u16, + .windows => c_ushort, else => u0, }; @@ -149,7 +149,7 @@ pub const nlink_t = switch (native_os) { .emscripten => emscripten.nlink_t, // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L45 .freebsd, .serenity => u64, - .openbsd, .netbsd, .dragonfly, .illumos, .windows => u32, + .openbsd, .netbsd, .dragonfly, .illumos => u32, .haiku => i32, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => u16, else => u0, @@ -237,9 +237,7 @@ pub const blkcnt_t = switch (native_os) { pub const fd_t = switch (native_os) { .linux => linux.fd_t, - .windows => windows.HANDLE, - .serenity => c_int, - else => i32, + else => c_int, }; pub const ARCH = switch (native_os) { @@ -445,7 +443,6 @@ pub const E = switch (native_os) { TIMEDOUT = 138, TXTBSY = 139, WOULDBLOCK = 140, - DQUOT = 10069, _, }, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => darwin.E, @@ -1827,7 +1824,6 @@ pub const PATH_MAX = switch (native_os) { pub const POLL = switch (native_os) { .linux => linux.POLL, .emscripten => emscripten.POLL, - .windows => ws2_32.POLL, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => struct { pub const IN = 0x001; pub const PRI = 0x002; @@ -1965,7 +1961,7 @@ pub const PROT = switch (native_os) { .linux => linux.PROT, .emscripten => emscripten.PROT, // https://github.com/SerenityOS/serenity/blob/6d59d4d3d9e76e39112842ec487840828f1c9bfe/Kernel/API/POSIX/sys/mman.h#L28-L31 - .openbsd, .haiku, .dragonfly, .netbsd, .illumos, .freebsd, .windows, .serenity => packed struct(u32) { + .openbsd, .haiku, .dragonfly, .netbsd, .illumos, .freebsd, .serenity => packed struct(u32) { READ: bool = false, WRITE: bool = false, EXEC: bool = false, @@ -3796,7 +3792,6 @@ pub const T = switch (native_os) { else => void, }; pub const IOCPARM_MASK = switch (native_os) { - .windows => ws2_32.IOCPARM_MASK, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => 0x1fff, else => void, }; @@ -4448,7 +4443,6 @@ pub const nfds_t = switch (native_os) { .linux => linux.nfds_t, .emscripten => emscripten.nfds_t, .haiku, .illumos => usize, - .windows => c_ulong, .openbsd, .dragonfly, .netbsd, .freebsd, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => u32, // https://github.com/SerenityOS/serenity/blob/265764ff2fec038855193296588a887fc322d76a/Kernel/API/POSIX/poll.h#L32 .serenity => c_uint, @@ -4461,15 +4455,13 @@ pub const perf_event_attr = switch (native_os) { pub const pid_t = switch (native_os) { .linux => linux.pid_t, .emscripten => emscripten.pid_t, - .windows => windows.HANDLE, // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L31-L32 - .serenity => c_int, - else => i32, + else => c_int, }; pub const pollfd = switch (native_os) { .linux => linux.pollfd, .emscripten => emscripten.pollfd, - .windows => ws2_32.pollfd, + .windows => void, // https://github.com/SerenityOS/serenity/blob/265764ff2fec038855193296588a887fc322d76a/Kernel/API/POSIX/poll.h#L26-L30 .serenity => extern struct { fd: fd_t, @@ -4942,7 +4934,6 @@ pub const addrinfo = if (builtin.abi.isAndroid()) extern struct { next: ?*addrinfo, } else switch (native_os) { .linux, .emscripten => linux.addrinfo, - .windows => ws2_32.addrinfo, .freebsd, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => extern struct { flags: AI, family: i32, @@ -5008,7 +4999,6 @@ pub const addrinfo = if (builtin.abi.isAndroid()) extern struct { }; pub const sockaddr = switch (native_os) { .linux, .emscripten => linux.sockaddr, - .windows => ws2_32.sockaddr, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => extern struct { len: u8, family: sa_family_t, @@ -5343,14 +5333,13 @@ pub const sockaddr = switch (native_os) { }; pub const socklen_t = switch (native_os) { .linux, .emscripten => linux.socklen_t, - .windows => ws2_32.socklen_t, + .windows => void, // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L57 else => u32, }; pub const in_port_t = u16; pub const sa_family_t = switch (native_os) { .linux, .emscripten => linux.sa_family_t, - .windows => ws2_32.ADDRESS_FAMILY, .openbsd, .haiku, .dragonfly, .netbsd, .freebsd, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => u8, // https://github.com/SerenityOS/serenity/blob/ac44ec5ebc707f9dd0c3d4759a1e17e91db5d74f/Kernel/API/POSIX/sys/socket.h#L66 .illumos, .serenity => u16, @@ -5403,7 +5392,6 @@ pub const AF = if (builtin.abi.isAndroid()) struct { pub const MAX = 43; } else switch (native_os) { .linux, .emscripten => linux.AF, - .windows => ws2_32.AF, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => struct { pub const UNSPEC = 0; pub const LOCAL = 1; @@ -5952,7 +5940,6 @@ pub const DT = switch (native_os) { pub const MSG = switch (native_os) { .linux => linux.MSG, .emscripten => emscripten.MSG, - .windows => ws2_32.MSG, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => darwin.MSG, .haiku => struct { pub const OOB = 0x0001; @@ -6069,7 +6056,6 @@ pub const MSG = switch (native_os) { pub const SOCK = switch (native_os) { .linux => linux.SOCK, .emscripten => emscripten.SOCK, - .windows => ws2_32.SOCK, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => struct { pub const STREAM = 1; pub const DGRAM = 2; @@ -6178,7 +6164,6 @@ pub const TCP = switch (native_os) { .openbsd => openbsd.TCP, .dragonfly => dragonfly.TCP, .emscripten => emscripten.TCP, - .windows => ws2_32.TCP, .illumos => illumos.TCP, .haiku => haiku.TCP, // https://github.com/SerenityOS/serenity/blob/61ac554a3403838f79ca746bd1c65ded6f97d124/Kernel/API/POSIX/netinet/tcp.h#L13-L14 @@ -6190,7 +6175,6 @@ pub const TCP = switch (native_os) { }; pub const IPPROTO = switch (native_os) { .linux, .emscripten => linux.IPPROTO, - .windows => ws2_32.IPPROTO, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => struct { pub const ICMP = 1; pub const ICMPV6 = 58; @@ -6826,7 +6810,6 @@ pub const IPTOS = switch (native_os) { pub const SOL = switch (native_os) { .linux => linux.SOL, .emscripten => emscripten.SOL, - .windows => ws2_32.SOL, .openbsd, .haiku, .dragonfly, .netbsd, .freebsd, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => struct { pub const SOCKET = 0xffff; }, @@ -6845,7 +6828,6 @@ pub const SOL = switch (native_os) { pub const SO = switch (native_os) { .linux => linux.SO, .emscripten => emscripten.SO, - .windows => ws2_32.SO, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => struct { pub const DEBUG = 0x0001; pub const ACCEPTCONN = 0x0002; @@ -7084,7 +7066,6 @@ pub const SO = switch (native_os) { }; pub const SOMAXCONN = switch (native_os) { .linux => linux.SOMAXCONN, - .windows => ws2_32.SOMAXCONN, // https://github.com/SerenityOS/serenity/blob/ac44ec5ebc707f9dd0c3d4759a1e17e91db5d74f/Kernel/API/POSIX/sys/socket.h#L128 .illumos, .serenity => 128, // https://github.com/freebsd/freebsd-src/blob/9ab31f821ad1c6bad474510447387c50bef2c24c/sys/sys/socket.h#L434 @@ -7153,7 +7134,6 @@ pub const SCM = switch (native_os) { pub const IFNAMESIZE = switch (native_os) { .linux => linux.IFNAMESIZE, .emscripten => emscripten.IFNAMESIZE, - .windows => 30, // https://github.com/SerenityOS/serenity/blob/9882848e0bf783dfc8e8a6d887a848d70d9c58f4/Kernel/API/POSIX/net/if.h#L50 .openbsd, .dragonfly, .netbsd, .freebsd, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos, .serenity => 16, .illumos => 32, @@ -7532,7 +7512,6 @@ pub const AI = if (builtin.abi.isAndroid()) packed struct(u32) { NUMERICSERV: bool = false, _: u19 = 0, }, - .windows => ws2_32.AI, // https://github.com/SerenityOS/serenity/blob/d510d2aeb2facbd8f6c383d70fd1b033e1fee5dd/Userland/Libraries/LibC/netdb.h#L90-L96 .serenity => packed struct(c_int) { PASSIVE: bool = false, @@ -8379,10 +8358,6 @@ pub const port_event = switch (native_os) { pub const AT = switch (native_os) { .linux => linux.AT, - .windows => struct { - /// Remove directory instead of unlinking file - pub const REMOVEDIR = 0x200; - }, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => struct { pub const FDCWD = -2; /// Use effective ids in access check @@ -10436,6 +10411,7 @@ pub extern "c" fn alarm(seconds: c_uint) c_uint; pub const close = switch (native_os) { .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => darwin.@"close$NOCANCEL", + .windows => private._close, else => private.close, }; @@ -10922,19 +10898,31 @@ pub extern "c" fn abort() noreturn; pub extern "c" fn exit(code: c_int) noreturn; pub extern "c" fn _Exit(code: c_int) noreturn; pub extern "c" fn _exit(code: c_int) noreturn; -pub extern "c" fn isatty(fd: fd_t) c_int; -pub extern "c" fn lseek(fd: fd_t, offset: off_t, whence: whence_t) off_t; +pub const isatty = switch (native_os) { + .windows => private._isatty, + else => private.isatty, +}; +pub const lseek = switch (native_os) { + .windows => private._lseeki64, + else => private.lseek, +}; pub extern "c" fn open(path: [*:0]const u8, oflag: O, ...) c_int; pub extern "c" fn openat(fd: c_int, path: [*:0]const u8, oflag: O, ...) c_int; pub extern "c" fn ftruncate(fd: c_int, length: off_t) c_int; pub extern "c" fn raise(sig: SIG) c_int; -pub extern "c" fn read(fd: fd_t, buf: [*]u8, nbyte: usize) isize; +pub const read = switch (native_os) { + .windows => private._read, + else => private.read, +}; pub extern "c" fn readv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint) isize; pub extern "c" fn pread(fd: fd_t, buf: [*]u8, nbyte: usize, offset: off_t) isize; pub extern "c" fn preadv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint, offset: off_t) isize; pub extern "c" fn writev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint) isize; pub extern "c" fn pwritev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: off_t) isize; -pub extern "c" fn write(fd: fd_t, buf: [*]const u8, nbyte: usize) isize; +pub const write = switch (native_os) { + .windows => private._write, + else => private.write, +}; pub extern "c" fn pwrite(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: off_t) isize; pub extern "c" fn mmap(addr: ?*align(page_size) anyopaque, len: usize, prot: PROT, flags: MAP, fd: fd_t, offset: off_t) *anyopaque; pub extern "c" fn munmap(addr: *align(page_size) const anyopaque, len: usize) c_int; @@ -10977,7 +10965,10 @@ pub const fork = switch (native_os) { pub extern "c" fn access(path: [*:0]const u8, mode: c_uint) c_int; pub extern "c" fn faccessat(dirfd: fd_t, path: [*:0]const u8, mode: c_uint, flags: c_uint) c_int; pub extern "c" fn pipe(fds: *[2]fd_t) c_int; -pub extern "c" fn mkdir(path: [*:0]const u8, mode: mode_t) c_int; +pub const mkdir = switch (native_os) { + .windows => private._mkdir, + else => private.mkdir, +}; pub extern "c" fn mkdirat(dirfd: fd_t, path: [*:0]const u8, mode: mode_t) c_int; pub extern "c" fn symlink(existing: [*:0]const u8, new: [*:0]const u8) c_int; pub extern "c" fn symlinkat(oldpath: [*:0]const u8, newdirfd: fd_t, newpath: [*:0]const u8) c_int; @@ -10991,17 +10982,29 @@ pub const fexecve = switch (native_os) { }; pub extern "c" fn execve(path: [*:0]const u8, argv: [*:null]const ?[*:0]const u8, envp: [*:null]const ?[*:0]const u8) c_int; pub extern "c" fn execveat(dirfd: fd_t, path: [*:0]const u8, argv: [*:null]const ?[*:0]const u8, envp: [*:null]const ?[*:0]const u8, flags: EXECVEAT) c_int; -pub extern "c" fn dup(fd: fd_t) c_int; -pub extern "c" fn dup2(old_fd: fd_t, new_fd: fd_t) c_int; +pub const dup = switch (native_os) { + .windows => private._dup, + else => private.dup, +}; +pub const dup2 = switch (native_os) { + .windows => private._dup2, + else => private.dup2, +}; pub extern "c" fn dup3(old: c_int, new: c_int, flags: c_uint) c_int; pub extern "c" fn readlink(noalias path: [*:0]const u8, noalias buf: [*]u8, bufsize: usize) isize; pub extern "c" fn readlinkat(dirfd: fd_t, noalias path: [*:0]const u8, noalias buf: [*]u8, bufsize: usize) isize; -pub extern "c" fn chmod(path: [*:0]const u8, mode: mode_t) c_int; +pub const chmod = switch (native_os) { + .windows => private._chmod, + else => private.chmod, +}; pub extern "c" fn fchmod(fd: fd_t, mode: mode_t) c_int; pub extern "c" fn fchmodat(fd: fd_t, path: [*:0]const u8, mode: mode_t, flags: c_uint) c_int; pub extern "c" fn fchown(fd: fd_t, owner: uid_t, group: gid_t) c_int; pub extern "c" fn fchownat(fd: fd_t, path: [*:0]const u8, owner: uid_t, group: gid_t, flags: c_uint) c_int; -pub extern "c" fn umask(mode: mode_t) mode_t; +pub const umask = switch (native_os) { + .windows => private._umask, + else => private.umask, +}; pub extern "c" fn rmdir(path: [*:0]const u8) c_int; pub extern "c" fn getenv(name: [*:0]const u8) ?[*:0]u8; @@ -11044,7 +11047,7 @@ pub extern "c" fn recv( arg1: ?*anyopaque, arg2: usize, arg3: c_int, -) if (native_os == .windows) c_int else isize; +) isize; pub extern "c" fn recvfrom( sockfd: fd_t, noalias buf: *anyopaque, @@ -11052,7 +11055,7 @@ pub extern "c" fn recvfrom( flags: u32, noalias src_addr: ?*sockaddr, noalias addrlen: ?*socklen_t, -) if (native_os == .windows) c_int else isize; +) isize; pub const recvmsg = switch (native_os) { .windows => {}, @@ -11319,7 +11322,10 @@ pub extern "c" fn setlogmask(maskpri: c_int) c_int; pub extern "c" fn if_nametoindex([*:0]const u8) c_int; -pub extern "c" fn getpid() pid_t; +pub const getpid = switch (native_os) { + .windows => private._getpid, + else => private.getpid, +}; pub extern "c" fn getppid() pid_t; pub extern "c" fn setsid() pid_t; @@ -11882,11 +11888,14 @@ const private = struct { extern "c" fn swab(noalias from: *const anyopaque, noalias to: *anyopaque, n: isize) void; extern "c" fn _swab(noalias from: *const anyopaque, noalias to: *anyopaque, n: isize) void; + extern "c" fn chmod(path: [*:0]const u8, mode: mode_t) c_int; extern "c" fn clock_getres(clk_id: clockid_t, tp: *timespec) c_int; extern "c" fn clock_gettime(clk_id: clockid_t, tp: *timespec) c_int; extern "c" fn clock_nanosleep(clockid: clockid_t, flags: TIMER, t: *const timespec, remain: ?*timespec) c_int; extern "c" fn close(fd: fd_t) c_int; extern "c" fn copy_file_range(fd_in: fd_t, off_in: ?*i64, fd_out: fd_t, off_out: ?*i64, len: usize, flags: c_uint) isize; + extern "c" fn dup(fd: fd_t) c_int; + extern "c" fn dup2(old_fd: fd_t, new_fd: fd_t) c_int; extern "c" fn fexecve(fd: fd_t, argv: [*:null]const ?[*:0]const u8, envp: [*:null]const ?[*:0]const u8) c_int; extern "c" fn flock(fd: fd_t, operation: c_int) c_int; extern "c" fn fork() c_int; @@ -11898,13 +11907,18 @@ const private = struct { .freebsd => isize, .illumos => usize, }; + extern "c" fn getpid() pid_t; extern "c" fn getrusage(who: c_int, usage: *rusage) c_int; extern "c" fn gettimeofday(noalias tv: ?*timeval, noalias tz: ?*timezone) c_int; extern "c" fn ioctl(fd: fd_t, request: c_int, ...) c_int; + extern "c" fn isatty(fd: fd_t) c_int; + extern "c" fn lseek(fd: fd_t, offset: off_t, whence: whence_t) off_t; + extern "c" fn mkdir(path: [*:0]const u8, mode: mode_t) c_int; extern "c" fn msync(addr: *align(page_size) const anyopaque, len: usize, flags: c_int) c_int; extern "c" fn mremap(addr: ?*align(page_size) const anyopaque, old_len: usize, new_len: usize, flags: MREMAP, ...) *anyopaque; extern "c" fn nanosleep(rqtp: *const timespec, rmtp: ?*timespec) c_int; extern "c" fn pipe2(fds: *[2]fd_t, flags: O) c_int; + extern "c" fn read(fd: fd_t, buf: [*]u8, nbyte: usize) isize; extern "c" fn readdir(dir: *DIR) ?*dirent; extern "c" fn realpath(noalias file_name: [*:0]const u8, noalias resolved_name: [*]u8) ?[*:0]u8; extern "c" fn recvmsg(sockfd: fd_t, msg: *msghdr, flags: u32) isize; @@ -11932,7 +11946,21 @@ const private = struct { extern "c" fn sigaltstack(ss: ?*const stack_t, old_ss: ?*stack_t) c_int; extern "c" fn sysconf(sc: c_int) c_long; extern "c" fn shm_open(name: [*:0]const u8, flag: c_int, mode: mode_t) c_int; + extern "c" fn umask(mode: mode_t) mode_t; extern "c" fn wait4(pid: pid_t, status: ?*c_int, options: c_int, ru: ?*rusage) pid_t; + extern "c" fn write(fd: fd_t, buf: [*]const u8, nbyte: usize) isize; + + extern "c" fn _chmod(filename: [*:0]const u8, pmode: c_int) c_int; + extern "c" fn _close(fd: fd_t) c_int; + extern "c" fn _dup(fd: fd_t) c_int; + extern "c" fn _dup2(old_fd: fd_t, new_fd: fd_t) c_int; + extern "c" fn _getpid() pid_t; + extern "c" fn _isatty(fd: fd_t) c_int; + extern "c" fn _lseeki64(fd: fd_t, offset: off_t, whence: whence_t) off_t; + extern "c" fn _mkdir(dirname: [*:0]const u8) c_int; + extern "c" fn _read(fd: fd_t, buf: [*]u8, nbyte: c_uint) c_int; + extern "c" fn _umask(pmode: c_int) c_int; + extern "c" fn _write(fd: fd_t, buf: [*]const u8, nbyte: c_uint) c_int; extern "c" fn pthread_setname_np(thread: pthread_t, name: [*:0]const u8) c_int; diff --git a/lib/std/crypto/Certificate/Bundle.zig b/lib/std/crypto/Certificate/Bundle.zig index 0d13d8e9ab1dbad02d411d81375a51e0b62fa44d..c413061105e3c3c98dccf33e53347b1c0c76ee43 100644 --- a/lib/std/crypto/Certificate/Bundle.zig +++ b/lib/std/crypto/Certificate/Bundle.zig @@ -144,7 +144,7 @@ fn rescanWithPath(cb: *Bundle, gpa: Allocator, io: Io, now: Io.Timestamp, cert_f cb.bytes.shrinkAndFree(gpa, cb.bytes.items.len); } -const RescanWindowsError = Allocator.Error || ParseCertError || std.posix.UnexpectedError || error{FileNotFound}; +const RescanWindowsError = Allocator.Error || ParseCertError || std.Io.UnexpectedError || error{FileNotFound}; fn rescanWindows(cb: *Bundle, gpa: Allocator, io: Io, now: Io.Timestamp) RescanWindowsError!void { cb.bytes.clearRetainingCapacity(); diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 9e3d618ca8838859c7e7589bca0e2dca0d41271a..bbcca773185de35e642fba3e55fb21314bbe795f 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -13,7 +13,7 @@ const mem = std.mem; const assert = std.debug.assert; const math = std.math; const maxInt = std.math.maxInt; -const UnexpectedError = std.posix.UnexpectedError; +const UnexpectedError = std.Io.UnexpectedError; pub const kernel32 = @import("windows/kernel32.zig"); pub const ntdll = @import("windows/ntdll.zig"); @@ -1492,6 +1492,10 @@ pub const TDI = struct { }; }; +pub const IF = struct { + pub const MAX_STRING_SIZE = 256; +}; + pub const NET = struct { pub const LUID = packed struct(ULONG64) { Reserved: u24 = 0, Index: u24, IfType: u16 }; pub const IFINDEX = enum(ULONG) { _ }; diff --git a/lib/std/posix.zig b/lib/std/posix.zig index de41ed68cbe7619c947803c5705e6026525e3a3b..b4a5f8ec06655ca9f46934268ad76830d6a0d815 100644 --- a/lib/std/posix.zig +++ b/lib/std/posix.zig @@ -5,7 +5,7 @@ //! `std.process`. //! //! These APIs are generally lowered to libc function calls if and only if libc -//! is linked. Most operating systems other than Windows, Linux, and WASI +//! is linked. Most operating systems other than Linux and WASI //! require always linking libc because they use it as the stable syscall ABI. const builtin = @import("builtin"); const native_os = builtin.os.tag; @@ -19,21 +19,19 @@ const assert = std.debug.assert; const page_size_min = std.heap.page_size_min; test { - _ = @import("posix/test.zig"); + if (native_os != .windows) _ = @import("posix/test.zig"); } /// Whether to use libc for the POSIX API layer. -const use_libc = builtin.link_libc or switch (native_os) { - .windows => true, - else => false, -}; +const use_libc = builtin.link_libc; const linux = std.os.linux; -const windows = std.os.windows; const wasi = std.os.wasi; /// A libc-compatible API layer. -pub const system = if (use_libc) +pub const system = if (native_os == .windows) + @compileError("Windows does not support POSIX") +else if (use_libc) std.c else switch (native_os) { .linux => linux, @@ -134,14 +132,11 @@ pub const STDIN_FILENO = system.STDIN_FILENO; pub const STDOUT_FILENO = system.STDOUT_FILENO; pub const SYS = system.SYS; pub const Sigaction = system.Sigaction; -/// Windows has no concept of `stat`. -/// /// On Linux, the `stat` bits/wrappers are removed due to having to maintain /// the different varying stat structs per target and libc, leading to runtime /// errors. Users targeting Linux should add a comptime check and use statx, /// similar to how `Io.File.stat` does. pub const Stat = switch (native_os) { - .windows => void, .linux => void, else => system.Stat, }; @@ -406,7 +401,6 @@ pub const ReadError = std.Io.File.Reader.Error; /// The corresponding POSIX limit is `maxInt(isize)`. pub fn read(fd: fd_t, buf: []u8) ReadError!usize { if (buf.len == 0) return 0; - if (native_os == .windows) @compileError("unsupported OS"); if (native_os == .wasi) @compileError("unsupported OS"); // Prevents EINVAL. @@ -441,14 +435,11 @@ pub const OpenError = std.Io.File.OpenError || error{WouldBlock}; /// Open and possibly create a file. Keeps trying if it gets interrupted. /// `file_path` is relative to the open directory handle `dir_fd`. -/// On Windows, `file_path` should be encoded as [WTF-8](https://wtf-8.codeberg.page/). /// On WASI, `file_path` should be encoded as valid UTF-8. /// On other platforms, `file_path` is an opaque sequence of bytes with no particular encoding. /// See also `openatZ`. pub fn openat(dir_fd: fd_t, file_path: []const u8, flags: O, mode: mode_t) OpenError!fd_t { - if (native_os == .windows) { - @compileError("Windows does not support POSIX; use Windows-specific API or cross-platform std.fs API"); - } else if (native_os == .wasi) { + if (native_os == .wasi) { @compileError("use std.Io instead"); } const file_path_c = try toPosixPath(file_path); @@ -457,14 +448,11 @@ pub fn openat(dir_fd: fd_t, file_path: []const u8, flags: O, mode: mode_t) OpenE /// Open and possibly create a file. Keeps trying if it gets interrupted. /// `file_path` is relative to the open directory handle `dir_fd`. -/// On Windows, `file_path` should be encoded as [WTF-8](https://wtf-8.codeberg.page/). /// On WASI, `file_path` should be encoded as valid UTF-8. /// On other platforms, `file_path` is an opaque sequence of bytes with no particular encoding. /// See also `openat`. pub fn openatZ(dir_fd: fd_t, file_path: [*:0]const u8, flags: O, mode: mode_t) OpenError!fd_t { - if (native_os == .windows) { - @compileError("Windows does not support POSIX; use Windows-specific API or cross-platform std.fs API"); - } else if (native_os == .wasi) { + if (native_os == .wasi) { return openat(dir_fd, mem.sliceTo(file_path, 0), flags, mode); } @@ -526,21 +514,17 @@ pub const GetSockNameError = error{ } || UnexpectedError; pub fn getpeername(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSockNameError!void { - if (native_os == .windows) { - @compileError("use std.Io instead"); - } else { - const rc = system.getpeername(sock, addr, addrlen); - switch (errno(rc)) { - .SUCCESS => return, - else => |err| return unexpectedErrno(err), + const rc = system.getpeername(sock, addr, addrlen); + switch (errno(rc)) { + .SUCCESS => return, + else => |err| return unexpectedErrno(err), - .BADF => unreachable, // always a race condition - .FAULT => unreachable, - .INVAL => unreachable, // invalid parameters - .NOTSOCK => return error.FileDescriptorNotASocket, - .NOBUFS => return error.SystemResources, - .NOTCONN => return error.SocketUnconnected, - } + .BADF => unreachable, // always a race condition + .FAULT => unreachable, + .INVAL => unreachable, // invalid parameters + .NOTSOCK => return error.FileDescriptorNotASocket, + .NOBUFS => return error.SystemResources, + .NOTCONN => return error.SocketUnconnected, } } @@ -1008,9 +992,6 @@ pub const PollError = error{ } || UnexpectedError; pub fn poll(fds: []pollfd, timeout: i32) PollError!usize { - if (native_os == .windows) { - @compileError("use std.Io instead"); - } while (true) { const fds_count = cast(nfds_t, fds.len) orelse return error.SystemResources; const rc = system.poll(fds.ptr, fds_count, timeout); @@ -1078,25 +1059,21 @@ pub const SetSockOptError = error{ /// Set a socket's options. pub fn setsockopt(fd: socket_t, level: i32, optname: u32, opt: []const u8) SetSockOptError!void { - if (native_os == .windows) { - @compileError("use std.Io instead"); - } else { - switch (errno(system.setsockopt(fd, level, optname, opt.ptr, @intCast(opt.len)))) { - .SUCCESS => {}, - .BADF => unreachable, // always a race condition - .NOTSOCK => unreachable, // always a race condition - .INVAL => unreachable, - .FAULT => unreachable, - .DOM => return error.TimeoutTooBig, - .ISCONN => return error.AlreadyConnected, - .NOPROTOOPT => return error.InvalidProtocolOption, - .NOMEM => return error.SystemResources, - .NOBUFS => return error.SystemResources, - .PERM => return error.PermissionDenied, - .NODEV => return error.NoDevice, - .OPNOTSUPP => return error.OperationUnsupported, - else => |err| return unexpectedErrno(err), - } + switch (errno(system.setsockopt(fd, level, optname, opt.ptr, @intCast(opt.len)))) { + .SUCCESS => {}, + .BADF => unreachable, // always a race condition + .NOTSOCK => unreachable, // always a race condition + .INVAL => unreachable, + .FAULT => unreachable, + .DOM => return error.TimeoutTooBig, + .ISCONN => return error.AlreadyConnected, + .NOPROTOOPT => return error.InvalidProtocolOption, + .NOMEM => return error.SystemResources, + .NOBUFS => return error.SystemResources, + .PERM => return error.PermissionDenied, + .NODEV => return error.NoDevice, + .OPNOTSUPP => return error.OperationUnsupported, + else => |err| return unexpectedErrno(err), } } @@ -1527,7 +1504,6 @@ pub const PtraceError = error{ pub fn ptrace(request: u32, pid: pid_t, addr: usize, data: usize) PtraceError!void { return switch (native_os) { - .windows, .wasi, .emscripten, .haiku, diff --git a/lib/std/posix/test.zig b/lib/std/posix/test.zig index 93d83d381df952dfc923628006a8eaa1aeced8a7..cb8fbe38f3976bc94ae701995036ea8d5a8f70f0 100644 --- a/lib/std/posix/test.zig +++ b/lib/std/posix/test.zig @@ -36,19 +36,19 @@ test "check WASI CWD" { } test "getuid" { - if (native_os == .windows or native_os == .wasi) return error.SkipZigTest; + if (native_os == .wasi) return error.SkipZigTest; _ = posix.system.getuid(); _ = posix.system.geteuid(); } test "getgid" { - if (native_os == .windows or native_os == .wasi) return error.SkipZigTest; + if (native_os == .wasi) return error.SkipZigTest; _ = posix.system.getgid(); _ = posix.system.getegid(); } test "sigaltstack" { - if (native_os == .windows or native_os == .wasi) return error.SkipZigTest; + if (native_os == .wasi) return error.SkipZigTest; var st: posix.stack_t = undefined; try posix.sigaltstack(null, &st); @@ -102,7 +102,7 @@ test "dl_iterate_phdr" { } test "gethostname" { - if (native_os == .windows or native_os == .wasi) + if (native_os == .wasi) return error.SkipZigTest; var buf: [posix.HOST_NAME_MAX]u8 = undefined; @@ -111,7 +111,7 @@ test "gethostname" { } test "pipe" { - if (native_os == .windows or native_os == .wasi) + if (native_os == .wasi) return error.SkipZigTest; const io = testing.io; @@ -155,7 +155,7 @@ test "memfd_create" { } test "mmap" { - if (native_os == .windows or native_os == .wasi) + if (native_os == .wasi) return error.SkipZigTest; const io = testing.io; @@ -252,7 +252,7 @@ test "mmap" { } test "fcntl" { - if (native_os == .windows or native_os == .wasi) + if (native_os == .wasi) return error.SkipZigTest; const io = testing.io; @@ -351,7 +351,7 @@ test "getrlimit and setrlimit" { test "sigrtmin/max" { if (native_os.isDarwin() or switch (native_os) { - .wasi, .windows, .openbsd, .dragonfly => true, + .wasi, .openbsd, .dragonfly => true, else => false, }) return error.SkipZigTest; @@ -361,7 +361,7 @@ test "sigrtmin/max" { } test "sigset empty/full" { - if (native_os == .wasi or native_os == .windows) + if (native_os == .wasi) return error.SkipZigTest; var set: posix.sigset_t = posix.sigemptyset(); @@ -389,7 +389,7 @@ fn reserved_signo(i: usize) bool { } test "sigset add/del" { - if (native_os == .wasi or native_os == .windows) + if (native_os == .wasi) return error.SkipZigTest; var sigset: posix.sigset_t = posix.sigemptyset(); @@ -426,21 +426,18 @@ test "sigset add/del" { test "getpid" { if (native_os == .wasi) return error.SkipZigTest; - if (native_os == .windows) return error.SkipZigTest; try expect(posix.system.getpid() != 0); } test "getppid" { if (native_os == .wasi) return error.SkipZigTest; - if (native_os == .windows) return error.SkipZigTest; if (native_os == .plan9 and !builtin.link_libc) return error.SkipZigTest; try expect(posix.getppid() >= 0); } test "rename smoke test" { - if (native_os == .windows) return error.SkipZigTest; if (!fstest.isRealPathSupported()) return error.SkipZigTest; const io = testing.io; @@ -452,7 +449,7 @@ test "rename smoke test" { const base_path = try tmp.dir.realPathFileAlloc(io, ".", gpa); defer gpa.free(base_path); - const mode: posix.mode_t = if (native_os == .windows) 0 else 0o666; + const mode: posix.mode_t = 0o666; { // Create some file using `open`. diff --git a/lib/std/process.zig b/lib/std/process.zig index af733757aa13f22df79e314e42c9247290f8170d..68ca72aa5f6ad721096e92f97386555ecb67f785 100644 --- a/lib/std/process.zig +++ b/lib/std/process.zig @@ -415,12 +415,12 @@ pub const SpawnOptions = struct { /// On Linux and Darwin, this obtains rusage statistics from wait4(). request_resource_usage_statistics: bool = false, - /// Set to change the user id when spawning the child process. - uid: ?posix.uid_t = null, - /// Set to change the group id when spawning the child process. - gid: ?posix.gid_t = null, - /// Set to change the process group id when spawning the child process. - pgid: ?posix.pid_t = null, + /// Set to change the user id when spawning the child process. Unsupported on Windows. + uid: ?File.Uid = null, + /// Set to change the group id when spawning the child process. Unsupported on Windows. + gid: ?File.Gid = null, + /// Set to change the process group id when spawning the child process. Unsupported on Windows. + pgid: ?Child.Id = null, /// Start child process in suspended state. /// For Posix systems it's started as if SIGSTOP was sent. @@ -656,7 +656,7 @@ pub fn cleanExit(io: Io) void { /// On some systems, this raises the limit before seeing ProcessFdQuotaExceeded /// errors. On other systems, this does nothing. pub fn raiseFileDescriptorLimit() void { - const have_rlimit = posix.rlimit_resource != void; + const have_rlimit = native_os != .windows and posix.rlimit_resource != void; if (!have_rlimit) return; var lim = posix.getrlimit(.NOFILE) catch return; // Oh well; we tried. @@ -964,6 +964,7 @@ pub const LockMemoryOptions = struct { pub fn lockMemory(memory: []align(std.heap.page_size_min) const u8, options: LockMemoryOptions) LockMemoryError!void { if (native_os == .windows) { // TODO call VirtualLock + return; } if (!options.on_fault and @TypeOf(posix.system.mlock) != void) { switch (posix.errno(posix.system.mlock(memory.ptr, memory.len))) { @@ -1002,6 +1003,10 @@ pub const UnlockMemoryError = error{ /// See also: /// * `lockMemory` pub fn unlockMemory(memory: []align(std.heap.page_size_min) const u8) UnlockMemoryError!void { + if (native_os == .windows) { + // TODO call VirtualUnlock + return; + } if (@TypeOf(posix.system.munlock) == void) return; switch (posix.errno(posix.system.munlock(memory.ptr, memory.len))) { .SUCCESS => return, @@ -1021,6 +1026,7 @@ pub const LockMemoryAllOptions = struct { }; pub fn lockMemoryAll(options: LockMemoryAllOptions) LockMemoryError!void { + if (native_os == .windows) return; if (@TypeOf(posix.system.mlockall) == void) return error.UnsupportedOperation; var flags: posix.MCL = .{ .CURRENT = options.current, @@ -1045,6 +1051,7 @@ pub fn lockMemoryAll(options: LockMemoryAllOptions) LockMemoryError!void { } pub fn unlockMemoryAll() UnlockMemoryError!void { + if (native_os == .windows) return; if (@TypeOf(posix.system.munlockall) == void) return; switch (posix.errno(posix.system.munlockall())) { .SUCCESS => return, diff --git a/lib/std/process/Args.zig b/lib/std/process/Args.zig index 3b21156e8307834802a5a7e6266f75651fa9d4c8..165729244424817017eeeb5e2e00eda6e66f086e 100644 --- a/lib/std/process/Args.zig +++ b/lib/std/process/Args.zig @@ -372,7 +372,7 @@ pub const Iterator = struct { index: usize, args: [][:0]u8, - pub const InitError = error{OutOfMemory} || std.posix.UnexpectedError; + pub const InitError = error{OutOfMemory} || std.Io.UnexpectedError; /// You must call deinit to free the internal buffer of the /// iterator after you are done. diff --git a/lib/std/process/Child.zig b/lib/std/process/Child.zig index a3cba3e7ece8ff9e34c9998bb47ff816e2586e5e..9d0ce79871083729963900bfb80ecb45e4e414f2 100644 --- a/lib/std/process/Child.zig +++ b/lib/std/process/Child.zig @@ -93,10 +93,13 @@ pub const ResourceUsageStatistics = struct { pub const Term = union(enum) { exited: u8, - signal: std.posix.SIG, - stopped: std.posix.SIG, + signal: Signal, + stopped: Signal, unknown: u32, + // This probably needs some more thought for Windows. + const Signal = if (native_os == .windows) std.c.SIG else std.posix.SIG; + pub fn success(t: Term) bool { return switch (t) { .exited => |code| code == 0, diff --git a/src/link/MachO.zig b/src/link/MachO.zig index c1b76db1b10be51d584e54a48767a9b9d84d727f..a43544bf9aeb70c695e7ef051c5c3eee295e0558 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -4438,7 +4438,7 @@ pub const MachError = error{ /// Not enough permissions held to perform the requested kernel /// call. PermissionDenied, -} || std.posix.UnexpectedError; +} || std.Io.UnexpectedError; pub const MachTask = extern struct { port: std.c.mach_port_name_t, @@ -4906,7 +4906,7 @@ pub fn getKernError(err: std.c.kern_return_t) KernE { return @as(KernE, @fromBackingInt(@intCast(@as(u32, @truncate(@as(usize, @intCast(err))))))); } -pub fn unexpectedKernError(err: KernE) std.posix.UnexpectedError { +pub fn unexpectedKernError(err: KernE) std.Io.UnexpectedError { if (std.options.unexpected_error_tracing) { std.debug.print("unexpected error: {d}\n", .{@backingInt(err)}); std.debug.dumpCurrentStackTrace(.{}); -- 2.54.0