Commit cd62005f19

Andrew Kelley <andrew@ziglang.org>
2024-03-19 06:39:59
extract std.posix from std.os
closes #5019
1 parent 7057bff
lib/compiler/objcopy.zig
@@ -1285,7 +1285,7 @@ const ElfFileHelper = struct {
         for (consolidated.items) |cmd| {
             switch (cmd) {
                 .write_data => |data| {
-                    var iovec = [_]std.os.iovec_const{.{ .iov_base = data.data.ptr, .iov_len = data.data.len }};
+                    var iovec = [_]std.posix.iovec_const{.{ .iov_base = data.data.ptr, .iov_len = data.data.len }};
                     try out_file.pwritevAll(&iovec, data.out_offset);
                 },
                 .copy_range => |range| {
lib/std/c/darwin.zig
@@ -4,7 +4,7 @@ const assert = std.debug.assert;
 const macho = std.macho;
 const native_arch = builtin.target.cpu.arch;
 const maxInt = std.math.maxInt;
-const iovec_const = std.os.iovec_const;
+const iovec_const = std.posix.iovec_const;
 
 pub const aarch64 = @import("darwin/aarch64.zig");
 pub const x86_64 = @import("darwin/x86_64.zig");
@@ -2826,237 +2826,12 @@ pub extern "c" fn posix_spawnp(
     env: [*:null]?[*:0]const u8,
 ) c_int;
 
-pub const PosixSpawn = struct {
-    const errno = std.os.errno;
-    const unexpectedErrno = std.os.unexpectedErrno;
-
-    pub const Error = error{
-        SystemResources,
-        InvalidFileDescriptor,
-        NameTooLong,
-        TooBig,
-        PermissionDenied,
-        InputOutput,
-        FileSystem,
-        FileNotFound,
-        InvalidExe,
-        NotDir,
-        FileBusy,
-        /// Returned when the child fails to execute either in the pre-exec() initialization step, or
-        /// when exec(3) is invoked.
-        ChildExecFailed,
-    } || std.os.UnexpectedError;
-
-    pub const Attr = struct {
-        attr: posix_spawnattr_t,
-
-        pub fn init() Error!Attr {
-            var attr: posix_spawnattr_t = undefined;
-            switch (errno(posix_spawnattr_init(&attr))) {
-                .SUCCESS => return Attr{ .attr = attr },
-                .NOMEM => return error.SystemResources,
-                .INVAL => unreachable,
-                else => |err| return unexpectedErrno(err),
-            }
-        }
-
-        pub fn deinit(self: *Attr) void {
-            defer self.* = undefined;
-            switch (errno(posix_spawnattr_destroy(&self.attr))) {
-                .SUCCESS => return,
-                .INVAL => unreachable, // Invalid parameters.
-                else => unreachable,
-            }
-        }
-
-        pub fn get(self: Attr) Error!u16 {
-            var flags: c_short = undefined;
-            switch (errno(posix_spawnattr_getflags(&self.attr, &flags))) {
-                .SUCCESS => return @as(u16, @bitCast(flags)),
-                .INVAL => unreachable,
-                else => |err| return unexpectedErrno(err),
-            }
-        }
-
-        pub fn set(self: *Attr, flags: u16) Error!void {
-            switch (errno(posix_spawnattr_setflags(&self.attr, @as(c_short, @bitCast(flags))))) {
-                .SUCCESS => return,
-                .INVAL => unreachable,
-                else => |err| return unexpectedErrno(err),
-            }
-        }
-    };
-
-    pub const Actions = struct {
-        actions: posix_spawn_file_actions_t,
-
-        pub fn init() Error!Actions {
-            var actions: posix_spawn_file_actions_t = undefined;
-            switch (errno(posix_spawn_file_actions_init(&actions))) {
-                .SUCCESS => return Actions{ .actions = actions },
-                .NOMEM => return error.SystemResources,
-                .INVAL => unreachable,
-                else => |err| return unexpectedErrno(err),
-            }
-        }
-
-        pub fn deinit(self: *Actions) void {
-            defer self.* = undefined;
-            switch (errno(posix_spawn_file_actions_destroy(&self.actions))) {
-                .SUCCESS => return,
-                .INVAL => unreachable, // Invalid parameters.
-                else => unreachable,
-            }
-        }
-
-        pub fn open(self: *Actions, fd: fd_t, path: []const u8, flags: u32, mode: mode_t) Error!void {
-            const posix_path = try std.os.toPosixPath(path);
-            return self.openZ(fd, &posix_path, flags, mode);
-        }
-
-        pub fn openZ(self: *Actions, fd: fd_t, path: [*:0]const u8, flags: u32, mode: mode_t) Error!void {
-            switch (errno(posix_spawn_file_actions_addopen(&self.actions, fd, path, @as(c_int, @bitCast(flags)), mode))) {
-                .SUCCESS => return,
-                .BADF => return error.InvalidFileDescriptor,
-                .NOMEM => return error.SystemResources,
-                .NAMETOOLONG => return error.NameTooLong,
-                .INVAL => unreachable, // the value of file actions is invalid
-                else => |err| return unexpectedErrno(err),
-            }
-        }
-
-        pub fn close(self: *Actions, fd: fd_t) Error!void {
-            switch (errno(posix_spawn_file_actions_addclose(&self.actions, fd))) {
-                .SUCCESS => return,
-                .BADF => return error.InvalidFileDescriptor,
-                .NOMEM => return error.SystemResources,
-                .INVAL => unreachable, // the value of file actions is invalid
-                .NAMETOOLONG => unreachable,
-                else => |err| return unexpectedErrno(err),
-            }
-        }
-
-        pub fn dup2(self: *Actions, fd: fd_t, newfd: fd_t) Error!void {
-            switch (errno(posix_spawn_file_actions_adddup2(&self.actions, fd, newfd))) {
-                .SUCCESS => return,
-                .BADF => return error.InvalidFileDescriptor,
-                .NOMEM => return error.SystemResources,
-                .INVAL => unreachable, // the value of file actions is invalid
-                .NAMETOOLONG => unreachable,
-                else => |err| return unexpectedErrno(err),
-            }
-        }
-
-        pub fn inherit(self: *Actions, fd: fd_t) Error!void {
-            switch (errno(posix_spawn_file_actions_addinherit_np(&self.actions, fd))) {
-                .SUCCESS => return,
-                .BADF => return error.InvalidFileDescriptor,
-                .NOMEM => return error.SystemResources,
-                .INVAL => unreachable, // the value of file actions is invalid
-                .NAMETOOLONG => unreachable,
-                else => |err| return unexpectedErrno(err),
-            }
-        }
-
-        pub fn chdir(self: *Actions, path: []const u8) Error!void {
-            const posix_path = try std.os.toPosixPath(path);
-            return self.chdirZ(&posix_path);
-        }
-
-        pub fn chdirZ(self: *Actions, path: [*:0]const u8) Error!void {
-            switch (errno(posix_spawn_file_actions_addchdir_np(&self.actions, path))) {
-                .SUCCESS => return,
-                .NOMEM => return error.SystemResources,
-                .NAMETOOLONG => return error.NameTooLong,
-                .BADF => unreachable,
-                .INVAL => unreachable, // the value of file actions is invalid
-                else => |err| return unexpectedErrno(err),
-            }
-        }
-
-        pub fn fchdir(self: *Actions, fd: fd_t) Error!void {
-            switch (errno(posix_spawn_file_actions_addfchdir_np(&self.actions, fd))) {
-                .SUCCESS => return,
-                .BADF => return error.InvalidFileDescriptor,
-                .NOMEM => return error.SystemResources,
-                .INVAL => unreachable, // the value of file actions is invalid
-                .NAMETOOLONG => unreachable,
-                else => |err| return unexpectedErrno(err),
-            }
-        }
-    };
-
-    pub fn spawn(
-        path: []const u8,
-        actions: ?Actions,
-        attr: ?Attr,
-        argv: [*:null]?[*:0]const u8,
-        envp: [*:null]?[*:0]const u8,
-    ) Error!pid_t {
-        const posix_path = try std.os.toPosixPath(path);
-        return spawnZ(&posix_path, actions, attr, argv, envp);
-    }
-
-    pub fn spawnZ(
-        path: [*:0]const u8,
-        actions: ?Actions,
-        attr: ?Attr,
-        argv: [*:null]?[*:0]const u8,
-        envp: [*:null]?[*:0]const u8,
-    ) Error!pid_t {
-        var pid: pid_t = undefined;
-        switch (errno(posix_spawn(
-            &pid,
-            path,
-            if (actions) |a| &a.actions else null,
-            if (attr) |a| &a.attr else null,
-            argv,
-            envp,
-        ))) {
-            .SUCCESS => return pid,
-            .@"2BIG" => return error.TooBig,
-            .NOMEM => return error.SystemResources,
-            .BADF => return error.InvalidFileDescriptor,
-            .ACCES => return error.PermissionDenied,
-            .IO => return error.InputOutput,
-            .LOOP => return error.FileSystem,
-            .NAMETOOLONG => return error.NameTooLong,
-            .NOENT => return error.FileNotFound,
-            .NOEXEC => return error.InvalidExe,
-            .NOTDIR => return error.NotDir,
-            .TXTBSY => return error.FileBusy,
-            .BADARCH => return error.InvalidExe,
-            .BADEXEC => return error.InvalidExe,
-            .FAULT => unreachable,
-            .INVAL => unreachable,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-
-    pub fn waitpid(pid: pid_t, flags: u32) Error!std.os.WaitPidResult {
-        var status: c_int = undefined;
-        while (true) {
-            const rc = waitpid(pid, &status, @as(c_int, @intCast(flags)));
-            switch (errno(rc)) {
-                .SUCCESS => return std.os.WaitPidResult{
-                    .pid = @as(pid_t, @intCast(rc)),
-                    .status = @as(u32, @bitCast(status)),
-                },
-                .INTR => continue,
-                .CHILD => return error.ChildExecFailed,
-                .INVAL => unreachable, // Invalid flags.
-                else => unreachable,
-            }
-        }
-    }
-};
-
 pub fn getKernError(err: kern_return_t) KernE {
     return @as(KernE, @enumFromInt(@as(u32, @truncate(@as(usize, @intCast(err))))));
 }
 
-pub fn unexpectedKernError(err: KernE) std.os.UnexpectedError {
-    if (std.os.unexpected_error_tracing) {
+pub fn unexpectedKernError(err: KernE) std.posix.UnexpectedError {
+    if (std.posix.unexpected_error_tracing) {
         std.debug.print("unexpected error: {d}\n", .{@intFromEnum(err)});
         std.debug.dumpCurrentStackTrace(null);
     }
@@ -3067,7 +2842,7 @@ pub const MachError = error{
     /// Not enough permissions held to perform the requested kernel
     /// call.
     PermissionDenied,
-} || std.os.UnexpectedError;
+} || std.posix.UnexpectedError;
 
 pub const MachTask = extern struct {
     port: mach_port_name_t,
@@ -3076,8 +2851,8 @@ pub const MachTask = extern struct {
         return self.port != TASK_NULL;
     }
 
-    pub fn pidForTask(self: MachTask) MachError!std.os.pid_t {
-        var pid: std.os.pid_t = undefined;
+    pub fn pidForTask(self: MachTask) MachError!std.c.pid_t {
+        var pid: std.c.pid_t = undefined;
         switch (getKernError(pid_for_task(self.port, &pid))) {
             .SUCCESS => return pid,
             .FAILURE => return error.PermissionDenied,
@@ -3517,7 +3292,7 @@ pub const MachThread = extern struct {
     }
 };
 
-pub fn machTaskForPid(pid: std.os.pid_t) MachError!MachTask {
+pub fn machTaskForPid(pid: std.c.pid_t) MachError!MachTask {
     var port: mach_port_name_t = undefined;
     switch (getKernError(task_for_pid(mach_task_self(), pid, &port))) {
         .SUCCESS => {},
lib/std/c/dragonfly.zig
@@ -2,7 +2,7 @@ const builtin = @import("builtin");
 const std = @import("../std.zig");
 const assert = std.debug.assert;
 const maxInt = std.math.maxInt;
-const iovec = std.os.iovec;
+const iovec = std.posix.iovec;
 
 extern "c" threadlocal var errno: c_int;
 pub fn _errno() *c_int {
lib/std/c/freebsd.zig
@@ -2,8 +2,8 @@ const std = @import("../std.zig");
 const assert = std.debug.assert;
 const builtin = @import("builtin");
 const maxInt = std.math.maxInt;
-const iovec = std.os.iovec;
-const iovec_const = std.os.iovec_const;
+const iovec = std.posix.iovec;
+const iovec_const = std.posix.iovec_const;
 
 extern "c" fn __error() *c_int;
 pub const _errno = __error;
lib/std/c/haiku.zig
@@ -2,8 +2,8 @@ const std = @import("../std.zig");
 const assert = std.debug.assert;
 const builtin = @import("builtin");
 const maxInt = std.math.maxInt;
-const iovec = std.os.iovec;
-const iovec_const = std.os.iovec_const;
+const iovec = std.posix.iovec;
+const iovec_const = std.posix.iovec_const;
 
 extern "c" fn _errnop() *c_int;
 
lib/std/c/linux.zig
@@ -3,8 +3,8 @@ const builtin = @import("builtin");
 const native_abi = builtin.abi;
 const native_arch = builtin.cpu.arch;
 const linux = std.os.linux;
-const iovec = std.os.iovec;
-const iovec_const = std.os.iovec_const;
+const iovec = std.posix.iovec;
+const iovec_const = std.posix.iovec_const;
 const FILE = std.c.FILE;
 
 pub const AF = linux.AF;
lib/std/c/netbsd.zig
@@ -2,8 +2,8 @@ const std = @import("../std.zig");
 const assert = std.debug.assert;
 const builtin = @import("builtin");
 const maxInt = std.math.maxInt;
-const iovec = std.os.iovec;
-const iovec_const = std.os.iovec_const;
+const iovec = std.posix.iovec;
+const iovec_const = std.posix.iovec_const;
 const timezone = std.c.timezone;
 const rusage = std.c.rusage;
 
lib/std/c/openbsd.zig
@@ -2,8 +2,8 @@ const std = @import("../std.zig");
 const assert = std.debug.assert;
 const maxInt = std.math.maxInt;
 const builtin = @import("builtin");
-const iovec = std.os.iovec;
-const iovec_const = std.os.iovec_const;
+const iovec = std.posix.iovec;
+const iovec_const = std.posix.iovec_const;
 
 extern "c" fn __errno() *c_int;
 pub const _errno = __errno;
lib/std/c/solaris.zig
@@ -2,8 +2,8 @@ const std = @import("../std.zig");
 const assert = std.debug.assert;
 const builtin = @import("builtin");
 const maxInt = std.math.maxInt;
-const iovec = std.os.iovec;
-const iovec_const = std.os.iovec_const;
+const iovec = std.posix.iovec;
+const iovec_const = std.posix.iovec_const;
 const timezone = std.c.timezone;
 
 extern "c" fn ___errno() *c_int;
lib/std/crypto/Certificate/Bundle/macos.zig
@@ -42,7 +42,7 @@ pub fn rescanMac(cb: *Bundle, gpa: Allocator) RescanMacError!void {
 
         const table_header = try reader.readStructEndian(TableHeader, .big);
 
-        if (@as(std.os.darwin.cssm.DB_RECORDTYPE, @enumFromInt(table_header.table_id)) != .X509_CERTIFICATE) {
+        if (@as(std.c.cssm.DB_RECORDTYPE, @enumFromInt(table_header.table_id)) != .X509_CERTIFICATE) {
             continue;
         }
 
lib/std/crypto/Certificate/Bundle.zig
@@ -125,7 +125,7 @@ fn rescanBSD(cb: *Bundle, gpa: Allocator, cert_file_path: []const u8) RescanBSDE
     cb.bytes.shrinkAndFree(gpa, cb.bytes.items.len);
 }
 
-const RescanWindowsError = Allocator.Error || ParseCertError || std.os.UnexpectedError || error{FileNotFound};
+const RescanWindowsError = Allocator.Error || ParseCertError || std.posix.UnexpectedError || error{FileNotFound};
 
 fn rescanWindows(cb: *Bundle, gpa: Allocator) RescanWindowsError!void {
     cb.bytes.clearRetainingCapacity();
lib/std/crypto/tls/Client.zig
@@ -62,7 +62,7 @@ pub const StreamInterface = struct {
     /// The `iovecs` parameter is mutable because so that function may to
     /// mutate the fields in order to handle partial reads from the underlying
     /// stream layer.
-    pub fn readv(this: @This(), iovecs: []std.os.iovec) ReadError!usize {
+    pub fn readv(this: @This(), iovecs: []std.posix.iovec) ReadError!usize {
         _ = .{ this, iovecs };
         @panic("unimplemented");
     }
@@ -72,7 +72,7 @@ pub const StreamInterface = struct {
 
     /// Returns the number of bytes read, which may be less than the buffer
     /// space provided. A short read does not indicate end-of-stream.
-    pub fn writev(this: @This(), iovecs: []const std.os.iovec_const) WriteError!usize {
+    pub fn writev(this: @This(), iovecs: []const std.posix.iovec_const) WriteError!usize {
         _ = .{ this, iovecs };
         @panic("unimplemented");
     }
@@ -81,7 +81,7 @@ pub const StreamInterface = struct {
     /// space provided, indicating end-of-stream.
     /// The `iovecs` parameter is mutable in case this function needs to mutate
     /// the fields in order to handle partial writes from the underlying layer.
-    pub fn writevAll(this: @This(), iovecs: []std.os.iovec_const) WriteError!usize {
+    pub fn writevAll(this: @This(), iovecs: []std.posix.iovec_const) WriteError!usize {
         // This can be implemented in terms of writev, or specialized if desired.
         _ = .{ this, iovecs };
         @panic("unimplemented");
@@ -215,7 +215,7 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In
     } ++ int2(@intCast(out_handshake.len + host_len)) ++ out_handshake;
 
     {
-        var iovecs = [_]std.os.iovec_const{
+        var iovecs = [_]std.posix.iovec_const{
             .{
                 .iov_base = &plaintext_header,
                 .iov_len = plaintext_header.len,
@@ -677,7 +677,7 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In
                                     P.AEAD.encrypt(ciphertext, auth_tag, &out_cleartext, ad, nonce, p.client_handshake_key);
 
                                     const both_msgs = client_change_cipher_spec_msg ++ finished_msg;
-                                    var both_msgs_vec = [_]std.os.iovec_const{.{
+                                    var both_msgs_vec = [_]std.posix.iovec_const{.{
                                         .iov_base = &both_msgs,
                                         .iov_len = both_msgs.len,
                                     }};
@@ -755,7 +755,7 @@ pub fn writeAllEnd(c: *Client, stream: anytype, bytes: []const u8, end: bool) !v
 /// TLS session, or a truncation attack.
 pub fn writeEnd(c: *Client, stream: anytype, bytes: []const u8, end: bool) !usize {
     var ciphertext_buf: [tls.max_ciphertext_record_len * 4]u8 = undefined;
-    var iovecs_buf: [6]std.os.iovec_const = undefined;
+    var iovecs_buf: [6]std.posix.iovec_const = undefined;
     var prepared = prepareCiphertextRecord(c, &iovecs_buf, &ciphertext_buf, bytes, .application_data);
     if (end) {
         prepared.iovec_end += prepareCiphertextRecord(
@@ -796,7 +796,7 @@ pub fn writeEnd(c: *Client, stream: anytype, bytes: []const u8, end: bool) !usiz
 
 fn prepareCiphertextRecord(
     c: *Client,
-    iovecs: []std.os.iovec_const,
+    iovecs: []std.posix.iovec_const,
     ciphertext_buf: []u8,
     bytes: []const u8,
     inner_content_type: tls.ContentType,
@@ -885,7 +885,7 @@ pub fn eof(c: Client) bool {
 /// If the number read is less than `len` it means the stream reached the end.
 /// Reaching the end of the stream is not an error condition.
 pub fn readAtLeast(c: *Client, stream: anytype, buffer: []u8, len: usize) !usize {
-    var iovecs = [1]std.os.iovec{.{ .iov_base = buffer.ptr, .iov_len = buffer.len }};
+    var iovecs = [1]std.posix.iovec{.{ .iov_base = buffer.ptr, .iov_len = buffer.len }};
     return readvAtLeast(c, stream, &iovecs, len);
 }
 
@@ -908,7 +908,7 @@ pub fn readAll(c: *Client, stream: anytype, buffer: []u8) !usize {
 /// stream is not an error condition.
 /// The `iovecs` parameter is mutable because this function needs to mutate the fields in
 /// order to handle partial reads from the underlying stream layer.
-pub fn readv(c: *Client, stream: anytype, iovecs: []std.os.iovec) !usize {
+pub fn readv(c: *Client, stream: anytype, iovecs: []std.posix.iovec) !usize {
     return readvAtLeast(c, stream, iovecs, 1);
 }
 
@@ -919,7 +919,7 @@ pub fn readv(c: *Client, stream: anytype, iovecs: []std.os.iovec) !usize {
 /// Reaching the end of the stream is not an error condition.
 /// The `iovecs` parameter is mutable because this function needs to mutate the fields in
 /// order to handle partial reads from the underlying stream layer.
-pub fn readvAtLeast(c: *Client, stream: anytype, iovecs: []std.os.iovec, len: usize) !usize {
+pub fn readvAtLeast(c: *Client, stream: anytype, iovecs: []std.posix.iovec, len: usize) !usize {
     if (c.eof()) return 0;
 
     var off_i: usize = 0;
@@ -945,7 +945,7 @@ pub fn readvAtLeast(c: *Client, stream: anytype, iovecs: []std.os.iovec, len: us
 /// function asserts that `eof()` is `false`.
 /// See `readv` for a higher level function that has the same, familiar API as
 /// other read functions, such as `std.fs.File.read`.
-pub fn readvAdvanced(c: *Client, stream: anytype, iovecs: []const std.os.iovec) !usize {
+pub fn readvAdvanced(c: *Client, stream: anytype, iovecs: []const std.posix.iovec) !usize {
     var vp: VecPut = .{ .iovecs = iovecs };
 
     // Give away the buffered cleartext we have, if any.
@@ -998,7 +998,7 @@ pub fn readvAdvanced(c: *Client, stream: anytype, iovecs: []const std.os.iovec)
     c.partial_cleartext_idx = 0;
     const first_iov = c.partially_read_buffer[c.partial_ciphertext_end..];
 
-    var ask_iovecs_buf: [2]std.os.iovec = .{
+    var ask_iovecs_buf: [2]std.posix.iovec = .{
         .{
             .iov_base = first_iov.ptr,
             .iov_len = first_iov.len,
@@ -1352,7 +1352,7 @@ fn SchemeEddsa(comptime scheme: tls.SignatureScheme) type {
 
 /// Abstraction for sending multiple byte buffers to a slice of iovecs.
 const VecPut = struct {
-    iovecs: []const std.os.iovec,
+    iovecs: []const std.posix.iovec,
     idx: usize = 0,
     off: usize = 0,
     total: usize = 0,
@@ -1413,7 +1413,7 @@ const VecPut = struct {
 };
 
 /// Limit iovecs to a specific byte size.
-fn limitVecs(iovecs: []std.os.iovec, len: usize) []std.os.iovec {
+fn limitVecs(iovecs: []std.posix.iovec, len: usize) []std.posix.iovec {
     var bytes_left: usize = len;
     for (iovecs, 0..) |*iovec, vec_i| {
         if (bytes_left <= iovec.iov_len) {
lib/std/crypto/tlcsprng.zig
@@ -6,7 +6,8 @@
 const std = @import("std");
 const builtin = @import("builtin");
 const mem = std.mem;
-const os = std.os;
+const native_os = builtin.os.tag;
+const posix = std.posix;
 
 /// We use this as a layer of indirection because global const pointers cannot
 /// point to thread-local variables.
@@ -15,7 +16,7 @@ pub const interface = std.Random{
     .fillFn = tlsCsprngFill,
 };
 
-const os_has_fork = switch (builtin.os.tag) {
+const os_has_fork = switch (native_os) {
     .dragonfly,
     .freebsd,
     .ios,
@@ -41,7 +42,7 @@ const maybe_have_wipe_on_fork = builtin.os.isAtLeast(.linux, .{
     .minor = 14,
     .patch = 0,
 }) orelse true;
-const is_haiku = builtin.os.tag == .haiku;
+const is_haiku = native_os == .haiku;
 
 const Rng = std.Random.DefaultCsprng;
 
@@ -79,10 +80,10 @@ fn tlsCsprngFill(_: *anyopaque, buffer: []u8) void {
         if (want_fork_safety and maybe_have_wipe_on_fork or is_haiku) {
             // Allocate a per-process page, madvise operates with page
             // granularity.
-            wipe_mem = os.mmap(
+            wipe_mem = posix.mmap(
                 null,
                 @sizeOf(Context),
-                os.PROT.READ | os.PROT.WRITE,
+                posix.PROT.READ | posix.PROT.WRITE,
                 .{ .TYPE = .PRIVATE, .ANONYMOUS = true },
                 -1,
                 0,
@@ -115,11 +116,11 @@ fn tlsCsprngFill(_: *anyopaque, buffer: []u8) void {
                 // Qemu user-mode emulation ignores any valid/invalid madvise
                 // hint and returns success. Check if this is the case by
                 // passing bogus parameters, we expect EINVAL as result.
-                if (os.madvise(wipe_mem.ptr, 0, 0xffffffff)) |_| {
+                if (posix.madvise(wipe_mem.ptr, 0, 0xffffffff)) |_| {
                     break :wof;
                 } else |_| {}
 
-                if (os.madvise(wipe_mem.ptr, wipe_mem.len, os.MADV.WIPEONFORK)) |_| {
+                if (posix.madvise(wipe_mem.ptr, wipe_mem.len, posix.MADV.WIPEONFORK)) |_| {
                     return initAndFill(buffer);
                 } else |_| {}
             }
@@ -164,7 +165,7 @@ fn fillWithCsprng(buffer: []u8) void {
 }
 
 pub fn defaultRandomSeed(buffer: []u8) void {
-    os.getrandom(buffer) catch @panic("getrandom() failed to provide entropy");
+    posix.getrandom(buffer) catch @panic("getrandom() failed to provide entropy");
 }
 
 fn initAndFill(buffer: []u8) void {
lib/std/dwarf/abi.zig
@@ -1,7 +1,8 @@
 const builtin = @import("builtin");
 const std = @import("../std.zig");
-const os = std.os;
 const mem = std.mem;
+const native_os = builtin.os.tag;
+const posix = std.posix;
 
 pub fn supportsUnwinding(target: std.Target) bool {
     return switch (target.cpu.arch) {
@@ -138,7 +139,7 @@ pub fn regBytes(
     reg_number: u8,
     reg_context: ?RegisterContext,
 ) AbiError!RegBytesReturnType(@TypeOf(thread_context_ptr)) {
-    if (builtin.os.tag == .windows) {
+    if (native_os == .windows) {
         return switch (builtin.cpu.arch) {
             .x86 => switch (reg_number) {
                 0 => mem.asBytes(&thread_context_ptr.Eax),
@@ -193,61 +194,61 @@ pub fn regBytes(
 
     const ucontext_ptr = thread_context_ptr;
     return switch (builtin.cpu.arch) {
-        .x86 => switch (builtin.os.tag) {
+        .x86 => switch (native_os) {
             .linux, .netbsd, .solaris, .illumos => switch (reg_number) {
-                0 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.EAX]),
-                1 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.ECX]),
-                2 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.EDX]),
-                3 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.EBX]),
+                0 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.EAX]),
+                1 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.ECX]),
+                2 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.EDX]),
+                3 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.EBX]),
                 4...5 => if (reg_context) |r| bytes: {
                     if (reg_number == 4) {
                         break :bytes if (r.eh_frame and r.is_macho)
-                            mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.EBP])
+                            mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.EBP])
                         else
-                            mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.ESP]);
+                            mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.ESP]);
                     } else {
                         break :bytes if (r.eh_frame and r.is_macho)
-                            mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.ESP])
+                            mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.ESP])
                         else
-                            mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.EBP]);
+                            mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.EBP]);
                     }
                 } else error.RegisterContextRequired,
-                6 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.ESI]),
-                7 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.EDI]),
-                8 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.EIP]),
-                9 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.EFL]),
-                10 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.CS]),
-                11 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.SS]),
-                12 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.DS]),
-                13 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.ES]),
-                14 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.FS]),
-                15 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.GS]),
+                6 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.ESI]),
+                7 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.EDI]),
+                8 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.EIP]),
+                9 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.EFL]),
+                10 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.CS]),
+                11 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.SS]),
+                12 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.DS]),
+                13 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.ES]),
+                14 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.FS]),
+                15 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.GS]),
                 16...23 => error.InvalidRegister, // TODO: Support loading ST0-ST7 from mcontext.fpregs
                 32...39 => error.InvalidRegister, // TODO: Support loading XMM0-XMM7 from mcontext.fpregs
                 else => error.InvalidRegister,
             },
             else => error.UnimplementedOs,
         },
-        .x86_64 => switch (builtin.os.tag) {
+        .x86_64 => switch (native_os) {
             .linux, .solaris, .illumos => switch (reg_number) {
-                0 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.RAX]),
-                1 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.RDX]),
-                2 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.RCX]),
-                3 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.RBX]),
-                4 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.RSI]),
-                5 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.RDI]),
-                6 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.RBP]),
-                7 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.RSP]),
-                8 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.R8]),
-                9 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.R9]),
-                10 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.R10]),
-                11 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.R11]),
-                12 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.R12]),
-                13 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.R13]),
-                14 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.R14]),
-                15 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.R15]),
-                16 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.RIP]),
-                17...32 => |i| if (builtin.os.tag.isSolarish())
+                0 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.RAX]),
+                1 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.RDX]),
+                2 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.RCX]),
+                3 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.RBX]),
+                4 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.RSI]),
+                5 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.RDI]),
+                6 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.RBP]),
+                7 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.RSP]),
+                8 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.R8]),
+                9 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.R9]),
+                10 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.R10]),
+                11 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.R11]),
+                12 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.R12]),
+                13 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.R13]),
+                14 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.R14]),
+                15 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.R15]),
+                16 => mem.asBytes(&ucontext_ptr.mcontext.gregs[posix.REG.RIP]),
+                17...32 => |i| if (native_os.isSolarish())
                     mem.asBytes(&ucontext_ptr.mcontext.fpregs.chip_state.xmm[i - 17])
                 else
                     mem.asBytes(&ucontext_ptr.mcontext.fpregs.xmm[i - 17]),
@@ -317,7 +318,7 @@ pub fn regBytes(
             },
             else => error.UnimplementedOs,
         },
-        .arm => switch (builtin.os.tag) {
+        .arm => switch (native_os) {
             .linux => switch (reg_number) {
                 0 => mem.asBytes(&ucontext_ptr.mcontext.arm_r0),
                 1 => mem.asBytes(&ucontext_ptr.mcontext.arm_r1),
@@ -340,7 +341,7 @@ pub fn regBytes(
             },
             else => error.UnimplementedOs,
         },
-        .aarch64 => switch (builtin.os.tag) {
+        .aarch64 => switch (native_os) {
             .macos, .ios => switch (reg_number) {
                 0...28 => mem.asBytes(&ucontext_ptr.mcontext.ss.regs[reg_number]),
                 29 => mem.asBytes(&ucontext_ptr.mcontext.ss.fp),
lib/std/fs/AtomicFile.zig
@@ -85,5 +85,4 @@ const File = std.fs.File;
 const Dir = std.fs.Dir;
 const fs = std.fs;
 const assert = std.debug.assert;
-// https://github.com/ziglang/zig/issues/5019
-const posix = std.os;
+const posix = std.posix;
lib/std/fs/Dir.zig
@@ -18,7 +18,7 @@ const IteratorError = error{
     InvalidUtf8,
 } || posix.UnexpectedError;
 
-pub const Iterator = switch (builtin.os.tag) {
+pub const Iterator = switch (native_os) {
     .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris, .illumos => struct {
         dir: Dir,
         seek: i64,
@@ -34,7 +34,7 @@ pub const Iterator = switch (builtin.os.tag) {
         /// Memory such as file names referenced in this returned entry becomes invalid
         /// with subsequent calls to `next`, as well as when this `Dir` is deinitialized.
         pub fn next(self: *Self) Error!?Entry {
-            switch (builtin.os.tag) {
+            switch (native_os) {
                 .macos, .ios => return self.nextDarwin(),
                 .freebsd, .netbsd, .dragonfly, .openbsd => return self.nextBsd(),
                 .solaris, .illumos => return self.nextSolaris(),
@@ -183,7 +183,7 @@ pub const Iterator = switch (builtin.os.tag) {
 
                 const name = @as([*]u8, @ptrCast(&bsd_entry.name))[0..bsd_entry.namlen];
 
-                const skip_zero_fileno = switch (builtin.os.tag) {
+                const skip_zero_fileno = switch (native_os) {
                     // fileno=0 is used to mark invalid entries or deleted files.
                     .openbsd, .netbsd => true,
                     else => false,
@@ -315,7 +315,7 @@ pub const Iterator = switch (builtin.os.tag) {
         dir: Dir,
         // The if guard is solely there to prevent compile errors from missing `linux.dirent64`
         // definition when compiling for other OSes. It doesn't do anything when compiling for Linux.
-        buf: [1024]u8 align(if (builtin.os.tag != .linux) 1 else @alignOf(linux.dirent64)),
+        buf: [1024]u8 align(if (native_os != .linux) 1 else @alignOf(linux.dirent64)),
         index: usize,
         end_index: usize,
         first_iter: bool,
@@ -348,7 +348,7 @@ pub const Iterator = switch (builtin.os.tag) {
                         self.first_iter = false;
                     }
                     const rc = linux.getdents64(self.dir.fd, &self.buf, self.buf.len);
-                    switch (linux.getErrno(rc)) {
+                    switch (linux.E.init(rc)) {
                         .SUCCESS => {},
                         .BADF => unreachable, // Dir is invalid or was opened without iteration ability
                         .FAULT => unreachable,
@@ -398,7 +398,7 @@ pub const Iterator = switch (builtin.os.tag) {
     },
     .windows => struct {
         dir: Dir,
-        buf: [1024]u8 align(@alignOf(std.os.windows.FILE_BOTH_DIR_INFORMATION)),
+        buf: [1024]u8 align(@alignOf(windows.FILE_BOTH_DIR_INFORMATION)),
         index: usize,
         end_index: usize,
         first_iter: bool,
@@ -411,8 +411,8 @@ pub const Iterator = switch (builtin.os.tag) {
         /// Memory such as file names referenced in this returned entry becomes invalid
         /// with subsequent calls to `next`, as well as when this `Dir` is deinitialized.
         pub fn next(self: *Self) Error!?Entry {
+            const w = windows;
             while (true) {
-                const w = std.os.windows;
                 if (self.index >= self.end_index) {
                     var io: w.IO_STATUS_BLOCK = undefined;
                     const rc = w.ntdll.NtQueryDirectoryFile(
@@ -582,7 +582,7 @@ pub fn iterateAssumeFirstIteration(self: Dir) Iterator {
 }
 
 fn iterateImpl(self: Dir, first_iter_start_value: bool) Iterator {
-    switch (builtin.os.tag) {
+    switch (native_os) {
         .macos,
         .ios,
         .freebsd,
@@ -770,11 +770,11 @@ pub fn close(self: *Dir) void {
 /// On WASI, `sub_path` should be encoded as valid UTF-8.
 /// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding.
 pub fn openFile(self: Dir, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File {
-    if (builtin.os.tag == .windows) {
-        const path_w = try std.os.windows.sliceToPrefixedFileW(self.fd, sub_path);
+    if (native_os == .windows) {
+        const path_w = try windows.sliceToPrefixedFileW(self.fd, sub_path);
         return self.openFileW(path_w.span(), flags);
     }
-    if (builtin.os.tag == .wasi) {
+    if (native_os == .wasi) {
         var base: std.os.wasi.rights_t = .{};
         if (flags.isRead()) {
             base.FD_READ = true;
@@ -803,9 +803,9 @@ pub fn openFile(self: Dir, sub_path: []const u8, flags: File.OpenFlags) File.Ope
 
 /// Same as `openFile` but the path parameter is null-terminated.
 pub fn openFileZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) File.OpenError!File {
-    switch (builtin.os.tag) {
+    switch (native_os) {
         .windows => {
-            const path_w = try std.os.windows.cStrToPrefixedFileW(self.fd, sub_path);
+            const path_w = try windows.cStrToPrefixedFileW(self.fd, sub_path);
             return self.openFileW(path_w.span(), flags);
         },
         .wasi => {
@@ -884,7 +884,7 @@ pub fn openFileZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) File
 /// Same as `openFile` but Windows-only and the path parameter is
 /// [WTF-16](https://simonsapin.github.io/wtf-8/#potentially-ill-formed-utf-16) encoded.
 pub fn openFileW(self: Dir, sub_path_w: []const u16, flags: File.OpenFlags) File.OpenError!File {
-    const w = std.os.windows;
+    const w = windows;
     const file: File = .{
         .handle = try w.OpenFile(sub_path_w, .{
             .dir = self.fd,
@@ -925,11 +925,11 @@ pub fn openFileW(self: Dir, sub_path_w: []const u16, flags: File.OpenFlags) File
 /// On WASI, `sub_path` should be encoded as valid UTF-8.
 /// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding.
 pub fn createFile(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File {
-    if (builtin.os.tag == .windows) {
-        const path_w = try std.os.windows.sliceToPrefixedFileW(self.fd, sub_path);
+    if (native_os == .windows) {
+        const path_w = try windows.sliceToPrefixedFileW(self.fd, sub_path);
         return self.createFileW(path_w.span(), flags);
     }
-    if (builtin.os.tag == .wasi) {
+    if (native_os == .wasi) {
         return .{
             .handle = try posix.openatWasi(self.fd, sub_path, .{}, .{
                 .CREAT = true,
@@ -957,9 +957,9 @@ pub fn createFile(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File
 
 /// Same as `createFile` but the path parameter is null-terminated.
 pub fn createFileZ(self: Dir, sub_path_c: [*:0]const u8, flags: File.CreateFlags) File.OpenError!File {
-    switch (builtin.os.tag) {
+    switch (native_os) {
         .windows => {
-            const path_w = try std.os.windows.cStrToPrefixedFileW(self.fd, sub_path_c);
+            const path_w = try windows.cStrToPrefixedFileW(self.fd, sub_path_c);
             return self.createFileW(path_w.span(), flags);
         },
         .wasi => {
@@ -968,7 +968,7 @@ pub fn createFileZ(self: Dir, sub_path_c: [*:0]const u8, flags: File.CreateFlags
         else => {},
     }
 
-    var os_flags: std.os.O = .{
+    var os_flags: posix.O = .{
         .ACCMODE = if (flags.read) .RDWR else .WRONLY,
         .CREAT = true,
         .TRUNC = flags.truncate,
@@ -1032,7 +1032,7 @@ pub fn createFileZ(self: Dir, sub_path_c: [*:0]const u8, flags: File.CreateFlags
 /// Same as `createFile` but Windows-only and the path parameter is
 /// [WTF-16](https://simonsapin.github.io/wtf-8/#potentially-ill-formed-utf-16) encoded.
 pub fn createFileW(self: Dir, sub_path_w: []const u16, flags: File.CreateFlags) File.OpenError!File {
-    const w = std.os.windows;
+    const w = windows;
     const read_flag = if (flags.read) @as(u32, w.GENERIC_READ) else 0;
     const file: File = .{
         .handle = try w.OpenFile(sub_path_w, .{
@@ -1145,7 +1145,7 @@ pub fn makePath(self: Dir, sub_path: []const u8) !void {
 /// have been modified regardless.
 /// `sub_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
 fn makeOpenPathAccessMaskW(self: Dir, sub_path: []const u8, access_mask: u32, no_follow: bool) OpenError!Dir {
-    const w = std.os.windows;
+    const w = windows;
     var it = try fs.path.componentIterator(sub_path);
     // If there are no components in the path, then create a dummy component with the full path.
     var component = it.last() orelse fs.path.NativeComponentIterator.Component{
@@ -1180,9 +1180,9 @@ fn makeOpenPathAccessMaskW(self: Dir, sub_path: []const u8, access_mask: u32, no
 /// On WASI, `sub_path` should be encoded as valid UTF-8.
 /// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding.
 pub fn makeOpenPath(self: Dir, sub_path: []const u8, open_dir_options: OpenDirOptions) !Dir {
-    return switch (builtin.os.tag) {
+    return switch (native_os) {
         .windows => {
-            const w = std.os.windows;
+            const w = windows;
             const base_flags = w.STANDARD_RIGHTS_READ | w.FILE_READ_ATTRIBUTES | w.FILE_READ_EA |
                 w.SYNCHRONIZE | w.FILE_TRAVERSE |
                 (if (open_dir_options.iterate) w.FILE_LIST_DIRECTORY else @as(u32, 0));
@@ -1215,11 +1215,11 @@ pub const RealPathError = posix.RealPathError;
 /// Currently supported hosts are: Linux, macOS, and Windows.
 /// See also `Dir.realpathZ`, `Dir.realpathW`, and `Dir.realpathAlloc`.
 pub fn realpath(self: Dir, pathname: []const u8, out_buffer: []u8) RealPathError![]u8 {
-    if (builtin.os.tag == .wasi) {
+    if (native_os == .wasi) {
         @compileError("realpath is not available on WASI");
     }
-    if (builtin.os.tag == .windows) {
-        const pathname_w = try std.os.windows.sliceToPrefixedFileW(self.fd, pathname);
+    if (native_os == .windows) {
+        const pathname_w = try windows.sliceToPrefixedFileW(self.fd, pathname);
         return self.realpathW(pathname_w.span(), out_buffer);
     }
     const pathname_c = try posix.toPosixPath(pathname);
@@ -1229,12 +1229,12 @@ pub fn realpath(self: Dir, pathname: []const u8, out_buffer: []u8) RealPathError
 /// Same as `Dir.realpath` except `pathname` is null-terminated.
 /// See also `Dir.realpath`, `realpathZ`.
 pub fn realpathZ(self: Dir, pathname: [*:0]const u8, out_buffer: []u8) RealPathError![]u8 {
-    if (builtin.os.tag == .windows) {
-        const pathname_w = try posix.windows.cStrToPrefixedFileW(self.fd, pathname);
+    if (native_os == .windows) {
+        const pathname_w = try windows.cStrToPrefixedFileW(self.fd, pathname);
         return self.realpathW(pathname_w.span(), out_buffer);
     }
 
-    const flags: posix.O = switch (builtin.os.tag) {
+    const flags: posix.O = switch (native_os) {
         .linux => .{
             .NONBLOCK = true,
             .CLOEXEC = true,
@@ -1255,14 +1255,8 @@ pub fn realpathZ(self: Dir, pathname: [*:0]const u8, out_buffer: []u8) RealPathE
     };
     defer posix.close(fd);
 
-    // Use of MAX_PATH_BYTES here is valid as the realpath function does not
-    // have a variant that takes an arbitrary-size buffer.
-    // TODO(#4812): Consider reimplementing realpath or using the POSIX.1-2008
-    // NULL out parameter (GNU's canonicalize_file_name) to handle overelong
-    // paths. musl supports passing NULL but restricts the output to PATH_MAX
-    // anyway.
     var buffer: [fs.MAX_PATH_BYTES]u8 = undefined;
-    const out_path = try posix.getFdPath(fd, &buffer);
+    const out_path = try std.os.getFdPath(fd, &buffer);
 
     if (out_path.len > out_buffer.len) {
         return error.NameTooLong;
@@ -1277,7 +1271,7 @@ pub fn realpathZ(self: Dir, pathname: [*:0]const u8, out_buffer: []u8) RealPathE
 /// The result is encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
 /// See also `Dir.realpath`, `realpathW`.
 pub fn realpathW(self: Dir, pathname: []const u16, out_buffer: []u8) RealPathError![]u8 {
-    const w = std.os.windows;
+    const w = windows;
 
     const access_mask = w.GENERIC_READ | w.SYNCHRONIZE;
     const share_access = w.FILE_SHARE_READ;
@@ -1331,16 +1325,16 @@ pub fn realpathAlloc(self: Dir, allocator: Allocator, pathname: []const u8) Real
 /// Not all targets support this. For example, WASI does not have the concept
 /// of a current working directory.
 pub fn setAsCwd(self: Dir) !void {
-    if (builtin.os.tag == .wasi) {
+    if (native_os == .wasi) {
         @compileError("changing cwd is not currently possible in WASI");
     }
-    if (builtin.os.tag == .windows) {
-        var dir_path_buffer: [std.os.windows.PATH_MAX_WIDE]u16 = undefined;
-        const dir_path = try std.os.windows.GetFinalPathNameByHandle(self.fd, .{}, &dir_path_buffer);
+    if (native_os == .windows) {
+        var dir_path_buffer: [windows.PATH_MAX_WIDE]u16 = undefined;
+        const dir_path = try windows.GetFinalPathNameByHandle(self.fd, .{}, &dir_path_buffer);
         if (builtin.link_libc) {
             return posix.chdirW(dir_path);
         }
-        return std.os.windows.SetCurrentDirectory(dir_path);
+        return windows.SetCurrentDirectory(dir_path);
     }
     try posix.fchdir(self.fd);
 }
@@ -1368,9 +1362,9 @@ pub const OpenDirOptions = struct {
 /// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding.
 /// Asserts that the path parameter has no null bytes.
 pub fn openDir(self: Dir, sub_path: []const u8, args: OpenDirOptions) OpenError!Dir {
-    switch (builtin.os.tag) {
+    switch (native_os) {
         .windows => {
-            const sub_path_w = try posix.windows.sliceToPrefixedFileW(self.fd, sub_path);
+            const sub_path_w = try windows.sliceToPrefixedFileW(self.fd, sub_path);
             return self.openDirW(sub_path_w.span().ptr, args);
         },
         .wasi => {
@@ -1427,9 +1421,9 @@ pub fn openDir(self: Dir, sub_path: []const u8, args: OpenDirOptions) OpenError!
 
 /// Same as `openDir` except the parameter is null-terminated.
 pub fn openDirZ(self: Dir, sub_path_c: [*:0]const u8, args: OpenDirOptions) OpenError!Dir {
-    switch (builtin.os.tag) {
+    switch (native_os) {
         .windows => {
-            const sub_path_w = try std.os.windows.cStrToPrefixedFileW(self.fd, sub_path_c);
+            const sub_path_w = try windows.cStrToPrefixedFileW(self.fd, sub_path_c);
             return self.openDirW(sub_path_w.span().ptr, args);
         },
         .wasi => {
@@ -1453,7 +1447,7 @@ pub fn openDirZ(self: Dir, sub_path_c: [*:0]const u8, args: OpenDirOptions) Open
 /// Same as `openDir` except the path parameter is WTF-16 LE encoded, NT-prefixed.
 /// This function asserts the target OS is Windows.
 pub fn openDirW(self: Dir, sub_path_w: [*:0]const u16, args: OpenDirOptions) OpenError!Dir {
-    const w = std.os.windows;
+    const w = windows;
     // TODO remove some of these flags if args.access_sub_paths is false
     const base_flags = w.STANDARD_RIGHTS_READ | w.FILE_READ_ATTRIBUTES | w.FILE_READ_EA |
         w.SYNCHRONIZE | w.FILE_TRAVERSE;
@@ -1487,7 +1481,7 @@ const MakeOpenDirAccessMaskWOptions = struct {
 };
 
 fn makeOpenDirAccessMaskW(self: Dir, sub_path_w: [*:0]const u16, access_mask: u32, flags: MakeOpenDirAccessMaskWOptions) OpenError!Dir {
-    const w = std.os.windows;
+    const w = windows;
 
     var result = Dir{
         .fd = undefined,
@@ -1545,10 +1539,10 @@ pub const DeleteFileError = posix.UnlinkError;
 /// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding.
 /// Asserts that the path parameter has no null bytes.
 pub fn deleteFile(self: Dir, sub_path: []const u8) DeleteFileError!void {
-    if (builtin.os.tag == .windows) {
-        const sub_path_w = try std.os.windows.sliceToPrefixedFileW(self.fd, sub_path);
+    if (native_os == .windows) {
+        const sub_path_w = try windows.sliceToPrefixedFileW(self.fd, sub_path);
         return self.deleteFileW(sub_path_w.span());
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
+    } else if (native_os == .wasi and !builtin.link_libc) {
         posix.unlinkat(self.fd, sub_path, 0) catch |err| switch (err) {
             error.DirNotEmpty => unreachable, // not passing AT.REMOVEDIR
             else => |e| return e,
@@ -1563,7 +1557,7 @@ pub fn deleteFile(self: Dir, sub_path: []const u8) DeleteFileError!void {
 pub fn deleteFileZ(self: Dir, sub_path_c: [*:0]const u8) DeleteFileError!void {
     posix.unlinkatZ(self.fd, sub_path_c, 0) catch |err| switch (err) {
         error.DirNotEmpty => unreachable, // not passing AT.REMOVEDIR
-        error.AccessDenied => |e| switch (builtin.os.tag) {
+        error.AccessDenied => |e| switch (native_os) {
             // non-Linux POSIX systems return EPERM when trying to delete a directory, so
             // we need to handle that case specifically and translate the error
             .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris, .illumos => {
@@ -1615,10 +1609,10 @@ pub const DeleteDirError = error{
 /// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding.
 /// Asserts that the path parameter has no null bytes.
 pub fn deleteDir(self: Dir, sub_path: []const u8) DeleteDirError!void {
-    if (builtin.os.tag == .windows) {
-        const sub_path_w = try std.os.windows.sliceToPrefixedFileW(self.fd, sub_path);
+    if (native_os == .windows) {
+        const sub_path_w = try windows.sliceToPrefixedFileW(self.fd, sub_path);
         return self.deleteDirW(sub_path_w.span());
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
+    } else if (native_os == .wasi and !builtin.link_libc) {
         posix.unlinkat(self.fd, sub_path, posix.AT.REMOVEDIR) catch |err| switch (err) {
             error.IsDir => unreachable, // not possible since we pass AT.REMOVEDIR
             else => |e| return e,
@@ -1691,15 +1685,15 @@ pub fn symLink(
     sym_link_path: []const u8,
     flags: SymLinkFlags,
 ) !void {
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
+    if (native_os == .wasi and !builtin.link_libc) {
         return self.symLinkWasi(target_path, sym_link_path, flags);
     }
-    if (builtin.os.tag == .windows) {
+    if (native_os == .windows) {
         // Target path does not use sliceToPrefixedFileW because certain paths
         // are handled differently when creating a symlink than they would be
         // when converting to an NT namespaced path. CreateSymbolicLink in
         // symLinkW will handle the necessary conversion.
-        var target_path_w: std.os.windows.PathSpace = undefined;
+        var target_path_w: windows.PathSpace = undefined;
         target_path_w.len = try std.unicode.wtf8ToWtf16Le(&target_path_w.data, target_path);
         target_path_w.data[target_path_w.len] = 0;
         // However, we need to canonicalize any path separators to `\`, since if
@@ -1711,7 +1705,7 @@ pub fn symLink(
             mem.nativeToLittle(u16, '\\'),
         );
 
-        const sym_link_path_w = try std.os.windows.sliceToPrefixedFileW(self.fd, sym_link_path);
+        const sym_link_path_w = try windows.sliceToPrefixedFileW(self.fd, sym_link_path);
         return self.symLinkW(target_path_w.span(), sym_link_path_w.span(), flags);
     }
     const target_path_c = try posix.toPosixPath(target_path);
@@ -1736,9 +1730,9 @@ pub fn symLinkZ(
     sym_link_path_c: [*:0]const u8,
     flags: SymLinkFlags,
 ) !void {
-    if (builtin.os.tag == .windows) {
-        const target_path_w = try std.os.windows.cStrToPrefixedFileW(self.fd, target_path_c);
-        const sym_link_path_w = try std.os.windows.cStrToPrefixedFileW(self.fd, sym_link_path_c);
+    if (native_os == .windows) {
+        const target_path_w = try windows.cStrToPrefixedFileW(self.fd, target_path_c);
+        const sym_link_path_w = try windows.cStrToPrefixedFileW(self.fd, sym_link_path_c);
         return self.symLinkW(target_path_w.span(), sym_link_path_w.span(), flags);
     }
     return posix.symlinkatZ(target_path_c, self.fd, sym_link_path_c);
@@ -1756,7 +1750,7 @@ pub fn symLinkW(
     sym_link_path_w: []const u16,
     flags: SymLinkFlags,
 ) !void {
-    return std.os.windows.CreateSymbolicLink(self.fd, sym_link_path_w, target_path_w, flags.is_directory);
+    return windows.CreateSymbolicLink(self.fd, sym_link_path_w, target_path_w, flags.is_directory);
 }
 
 pub const ReadLinkError = posix.ReadLinkError;
@@ -1768,11 +1762,11 @@ pub const ReadLinkError = posix.ReadLinkError;
 /// On WASI, `sub_path` should be encoded as valid UTF-8.
 /// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding.
 pub fn readLink(self: Dir, sub_path: []const u8, buffer: []u8) ReadLinkError![]u8 {
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
+    if (native_os == .wasi and !builtin.link_libc) {
         return self.readLinkWasi(sub_path, buffer);
     }
-    if (builtin.os.tag == .windows) {
-        const sub_path_w = try std.os.windows.sliceToPrefixedFileW(self.fd, sub_path);
+    if (native_os == .windows) {
+        const sub_path_w = try windows.sliceToPrefixedFileW(self.fd, sub_path);
         return self.readLinkW(sub_path_w.span(), buffer);
     }
     const sub_path_c = try posix.toPosixPath(sub_path);
@@ -1786,8 +1780,8 @@ pub fn readLinkWasi(self: Dir, sub_path: []const u8, buffer: []u8) ![]u8 {
 
 /// Same as `readLink`, except the `sub_path_c` parameter is null-terminated.
 pub fn readLinkZ(self: Dir, sub_path_c: [*:0]const u8, buffer: []u8) ![]u8 {
-    if (builtin.os.tag == .windows) {
-        const sub_path_w = try std.os.windows.cStrToPrefixedFileW(self.fd, sub_path_c);
+    if (native_os == .windows) {
+        const sub_path_w = try windows.cStrToPrefixedFileW(self.fd, sub_path_c);
         return self.readLinkW(sub_path_w.span(), buffer);
     }
     return posix.readlinkatZ(self.fd, sub_path_c, buffer);
@@ -1796,7 +1790,7 @@ pub fn readLinkZ(self: Dir, sub_path_c: [*:0]const u8, buffer: []u8) ![]u8 {
 /// Windows-only. Same as `readLink` except the pathname parameter
 /// is WTF16 LE encoded.
 pub fn readLinkW(self: Dir, sub_path_w: []const u16, buffer: []u8) ![]u8 {
-    return std.os.windows.ReadLink(self.fd, sub_path_w, buffer);
+    return windows.ReadLink(self.fd, sub_path_w, buffer);
 }
 
 /// Read all of file contents using a preallocated buffer.
@@ -2319,8 +2313,8 @@ pub const AccessError = posix.AccessError;
 /// For example, instead of testing if a file exists and then opening it, just
 /// open it and handle the error for file not found.
 pub fn access(self: Dir, sub_path: []const u8, flags: File.OpenFlags) AccessError!void {
-    if (builtin.os.tag == .windows) {
-        const sub_path_w = std.os.windows.sliceToPrefixedFileW(self.fd, sub_path) catch |err| switch (err) {
+    if (native_os == .windows) {
+        const sub_path_w = windows.sliceToPrefixedFileW(self.fd, sub_path) catch |err| switch (err) {
             error.AccessDenied => return error.PermissionDenied,
             else => |e| return e,
         };
@@ -2332,8 +2326,8 @@ pub fn access(self: Dir, sub_path: []const u8, flags: File.OpenFlags) AccessErro
 
 /// Same as `access` except the path parameter is null-terminated.
 pub fn accessZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) AccessError!void {
-    if (builtin.os.tag == .windows) {
-        const sub_path_w = std.os.windows.cStrToPrefixedFileW(self.fd, sub_path) catch |err| switch (err) {
+    if (native_os == .windows) {
+        const sub_path_w = windows.cStrToPrefixedFileW(self.fd, sub_path) catch |err| switch (err) {
             error.AccessDenied => return error.PermissionDenied,
             else => |e| return e,
         };
@@ -2355,7 +2349,7 @@ pub fn accessZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) Access
 /// TODO currently this ignores `flags`.
 pub fn accessW(self: Dir, sub_path_w: [*:0]const u16, flags: File.OpenFlags) AccessError!void {
     _ = flags;
-    return posix.faccessatW(self.fd, sub_path_w, 0, 0);
+    return posix.faccessatW(self.fd, sub_path_w);
 }
 
 pub const CopyFileOptions = struct {
@@ -2473,7 +2467,7 @@ fn copy_file(fd_in: posix.fd_t, fd_out: posix.fd_t, maybe_size: ?u64) CopyFileRa
         }
     }
 
-    if (builtin.os.tag == .linux) {
+    if (native_os == .linux) {
         // Try copy_file_range first as that works at the FS level and is the
         // most efficient method (if available).
         var offset: u64 = 0;
@@ -2555,12 +2549,12 @@ pub const StatFileError = File.OpenError || File.StatError || posix.FStatAtError
 /// On WASI, `sub_path` should be encoded as valid UTF-8.
 /// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding.
 pub fn statFile(self: Dir, sub_path: []const u8) StatFileError!Stat {
-    if (builtin.os.tag == .windows) {
+    if (native_os == .windows) {
         var file = try self.openFile(sub_path, .{});
         defer file.close();
         return file.stat();
     }
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
+    if (native_os == .wasi and !builtin.link_libc) {
         const st = try posix.fstatat_wasi(self.fd, sub_path, .{ .SYMLINK_FOLLOW = true });
         return Stat.fromWasi(st);
     }
@@ -2617,9 +2611,10 @@ const builtin = @import("builtin");
 const std = @import("../std.zig");
 const File = std.fs.File;
 const AtomicFile = std.fs.AtomicFile;
-// https://github.com/ziglang/zig/issues/5019
-const posix = std.os;
+const posix = std.posix;
 const mem = std.mem;
 const fs = std.fs;
 const Allocator = std.mem.Allocator;
 const assert = std.debug.assert;
+const windows = std.os.windows;
+const native_os = builtin.os.tag;
lib/std/fs/File.zig
@@ -193,6 +193,58 @@ pub fn isTty(self: File) bool {
     return posix.isatty(self.handle);
 }
 
+pub fn isCygwinPty(file: File) bool {
+    if (builtin.os.tag != .windows) return false;
+
+    const handle = file.handle;
+
+    // If this is a MSYS2/cygwin pty, then it will be a named pipe with a name in one of these formats:
+    //   msys-[...]-ptyN-[...]
+    //   cygwin-[...]-ptyN-[...]
+    //
+    // Example: msys-1888ae32e00d56aa-pty0-to-master
+
+    // First, just check that the handle is a named pipe.
+    // This allows us to avoid the more costly NtQueryInformationFile call
+    // for handles that aren't named pipes.
+    {
+        var io_status: windows.IO_STATUS_BLOCK = undefined;
+        var device_info: windows.FILE_FS_DEVICE_INFORMATION = undefined;
+        const rc = windows.ntdll.NtQueryVolumeInformationFile(handle, &io_status, &device_info, @sizeOf(windows.FILE_FS_DEVICE_INFORMATION), .FileFsDeviceInformation);
+        switch (rc) {
+            .SUCCESS => {},
+            else => return false,
+        }
+        if (device_info.DeviceType != windows.FILE_DEVICE_NAMED_PIPE) return false;
+    }
+
+    const name_bytes_offset = @offsetOf(windows.FILE_NAME_INFO, "FileName");
+    // `NAME_MAX` UTF-16 code units (2 bytes each)
+    // This buffer may not be long enough to handle *all* possible paths
+    // (PATH_MAX_WIDE would be necessary for that), but because we only care
+    // about certain paths and we know they must be within a reasonable length,
+    // we can use this smaller buffer and just return false on any error from
+    // NtQueryInformationFile.
+    const num_name_bytes = windows.MAX_PATH * 2;
+    var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = [_]u8{0} ** (name_bytes_offset + num_name_bytes);
+
+    var io_status_block: windows.IO_STATUS_BLOCK = undefined;
+    const rc = windows.ntdll.NtQueryInformationFile(handle, &io_status_block, &name_info_bytes, @intCast(name_info_bytes.len), .FileNameInformation);
+    switch (rc) {
+        .SUCCESS => {},
+        .INVALID_PARAMETER => unreachable,
+        else => return false,
+    }
+
+    const name_info: *const windows.FILE_NAME_INFO = @ptrCast(&name_info_bytes);
+    const name_bytes = name_info_bytes[name_bytes_offset .. name_bytes_offset + name_info.FileNameLength];
+    const name_wide = std.mem.bytesAsSlice(u16, name_bytes);
+    // The name we get from NtQueryInformationFile will be prefixed with a '\', e.g. \msys-1888ae32e00d56aa-pty0-to-master
+    return (std.mem.startsWith(u16, name_wide, &[_]u16{ '\\', 'm', 's', 'y', 's', '-' }) or
+        std.mem.startsWith(u16, name_wide, &[_]u16{ '\\', 'c', 'y', 'g', 'w', 'i', 'n', '-' })) and
+        std.mem.indexOf(u16, name_wide, &[_]u16{ '-', 'p', 't', 'y' }) != null;
+}
+
 /// Test whether ANSI escape codes will be treated as such.
 pub fn supportsAnsiEscapeCodes(self: File) bool {
     if (builtin.os.tag == .windows) {
@@ -201,7 +253,7 @@ pub fn supportsAnsiEscapeCodes(self: File) bool {
             if (console_mode & windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING != 0) return true;
         }
 
-        return posix.isCygwinPty(self.handle);
+        return self.isCygwinPty();
     }
     if (builtin.os.tag == .wasi) {
         // WASI sanitizes stdout when fd is a tty so ANSI escape codes
@@ -1634,8 +1686,7 @@ const File = @This();
 const std = @import("../std.zig");
 const builtin = @import("builtin");
 const Allocator = std.mem.Allocator;
-// https://github.com/ziglang/zig/issues/5019
-const posix = std.os;
+const posix = std.posix;
 const io = std.io;
 const math = std.math;
 const assert = std.debug.assert;
lib/std/fs/get_app_data_dir.zig
@@ -3,7 +3,8 @@ const builtin = @import("builtin");
 const unicode = std.unicode;
 const mem = std.mem;
 const fs = std.fs;
-const os = std.os;
+const native_os = builtin.os.tag;
+const posix = std.posix;
 
 pub const GetAppDataDirError = error{
     OutOfMemory,
@@ -13,7 +14,7 @@ pub const GetAppDataDirError = error{
 /// Caller owns returned memory.
 /// TODO determine if we can remove the allocator requirement
 pub fn getAppDataDir(allocator: mem.Allocator, appname: []const u8) GetAppDataDirError![]u8 {
-    switch (builtin.os.tag) {
+    switch (native_os) {
         .windows => {
             const local_app_data_dir = std.process.getEnvVarOwned(allocator, "LOCALAPPDATA") catch |err| switch (err) {
                 error.OutOfMemory => |e| return e,
@@ -23,18 +24,18 @@ pub fn getAppDataDir(allocator: mem.Allocator, appname: []const u8) GetAppDataDi
             return fs.path.join(allocator, &[_][]const u8{ local_app_data_dir, appname });
         },
         .macos => {
-            const home_dir = os.getenv("HOME") orelse {
+            const home_dir = posix.getenv("HOME") orelse {
                 // TODO look in /etc/passwd
                 return error.AppDataDirUnavailable;
             };
             return fs.path.join(allocator, &[_][]const u8{ home_dir, "Library", "Application Support", appname });
         },
         .linux, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris, .illumos => {
-            if (os.getenv("XDG_DATA_HOME")) |xdg| {
+            if (posix.getenv("XDG_DATA_HOME")) |xdg| {
                 return fs.path.join(allocator, &[_][]const u8{ xdg, appname });
             }
 
-            const home_dir = os.getenv("HOME") orelse {
+            const home_dir = posix.getenv("HOME") orelse {
                 // TODO look in /etc/passwd
                 return error.AppDataDirUnavailable;
             };
@@ -48,7 +49,7 @@ pub fn getAppDataDir(allocator: mem.Allocator, appname: []const u8) GetAppDataDi
             }
             // TODO look into directory_which
             const be_user_settings = 0xbbe;
-            const rc = os.system.find_directory(be_user_settings, -1, true, dir_path_ptr, 1);
+            const rc = std.c.find_directory(be_user_settings, -1, true, dir_path_ptr, 1);
             const settings_dir = try allocator.dupeZ(u8, mem.sliceTo(dir_path_ptr, 0));
             defer allocator.free(settings_dir);
             switch (rc) {
@@ -61,7 +62,7 @@ pub fn getAppDataDir(allocator: mem.Allocator, appname: []const u8) GetAppDataDi
 }
 
 test "getAppDataDir" {
-    if (builtin.os.tag == .wasi) return error.SkipZigTest;
+    if (native_os == .wasi) return error.SkipZigTest;
 
     // We can't actually validate the result
     const dir = getAppDataDir(std.testing.allocator, "zig") catch return;
lib/std/fs/test.zig
@@ -1,10 +1,12 @@
 const std = @import("../std.zig");
 const builtin = @import("builtin");
 const testing = std.testing;
-const os = std.os;
 const fs = std.fs;
 const mem = std.mem;
 const wasi = std.os.wasi;
+const native_os = builtin.os.tag;
+const windows = std.os.windows;
+const posix = std.posix;
 
 const ArenaAllocator = std.heap.ArenaAllocator;
 const Dir = std.fs.Dir;
@@ -25,7 +27,7 @@ const PathType = enum {
         };
     }
 
-    pub const TransformError = std.os.RealPathError || error{OutOfMemory};
+    pub const TransformError = posix.RealPathError || error{OutOfMemory};
     pub const TransformFn = fn (allocator: mem.Allocator, dir: Dir, relative_path: [:0]const u8) TransformError![:0]const u8;
 
     pub fn getTransformFn(comptime path_type: PathType) TransformFn {
@@ -42,7 +44,7 @@ const PathType = enum {
                     // The final path may not actually exist which would cause realpath to fail.
                     // So instead, we get the path of the dir and join it with the relative path.
                     var fd_path_buf: [fs.MAX_PATH_BYTES]u8 = undefined;
-                    const dir_path = try os.getFdPath(dir.fd, &fd_path_buf);
+                    const dir_path = try std.os.getFdPath(dir.fd, &fd_path_buf);
                     return fs.path.joinZ(allocator, &.{ dir_path, relative_path });
                 }
             }.transform,
@@ -51,8 +53,8 @@ const PathType = enum {
                     // Any drive absolute path (C:\foo) can be converted into a UNC path by
                     // using '127.0.0.1' as the server name and '<drive letter>$' as the share name.
                     var fd_path_buf: [fs.MAX_PATH_BYTES]u8 = undefined;
-                    const dir_path = try os.getFdPath(dir.fd, &fd_path_buf);
-                    const windows_path_type = std.os.windows.getUnprefixedPathType(u8, dir_path);
+                    const dir_path = try std.os.getFdPath(dir.fd, &fd_path_buf);
+                    const windows_path_type = windows.getUnprefixedPathType(u8, dir_path);
                     switch (windows_path_type) {
                         .unc_absolute => return fs.path.joinZ(allocator, &.{ dir_path, relative_path }),
                         .drive_absolute => {
@@ -102,7 +104,7 @@ const TestContext = struct {
     pub fn transformPath(self: *TestContext, relative_path: [:0]const u8) ![:0]const u8 {
         const allocator = self.arena.allocator();
         const transformed_path = try self.transform_fn(allocator, self.dir, relative_path);
-        if (builtin.os.tag == .windows) {
+        if (native_os == .windows) {
             const transformed_sep_path = try allocator.dupeZ(u8, transformed_path);
             std.mem.replaceScalar(u8, transformed_sep_path, switch (self.path_sep) {
                 '/' => '\\',
@@ -119,7 +121,7 @@ const TestContext = struct {
     /// If path separators are replaced, then the result is allocated by the
     /// TestContext's arena and will be free'd during `TestContext.deinit`.
     pub fn toCanonicalPathSep(self: *TestContext, path: [:0]const u8) ![:0]const u8 {
-        if (builtin.os.tag == .windows) {
+        if (native_os == .windows) {
             const allocator = self.arena.allocator();
             const transformed_sep_path = try allocator.dupeZ(u8, path);
             std.mem.replaceScalar(u8, transformed_sep_path, '/', '\\');
@@ -157,7 +159,7 @@ fn testWithPathTypeIfSupported(comptime path_type: PathType, comptime path_sep:
 fn setupSymlink(dir: Dir, target: []const u8, link: []const u8, flags: SymLinkFlags) !void {
     return dir.symLink(target, link, flags) catch |err| switch (err) {
         // Symlink requires admin privileges on windows, so this test can legitimately fail.
-        error.AccessDenied => if (builtin.os.tag == .windows) return error.SkipZigTest else return err,
+        error.AccessDenied => if (native_os == .windows) return error.SkipZigTest else return err,
         else => return err,
     };
 }
@@ -166,7 +168,7 @@ fn setupSymlink(dir: Dir, target: []const u8, link: []const u8, flags: SymLinkFl
 // AccessDenied, then make the test failure silent (it is not a Zig failure).
 fn setupSymlinkAbsolute(target: []const u8, link: []const u8, flags: SymLinkFlags) !void {
     return fs.symLinkAbsolute(target, link, flags) catch |err| switch (err) {
-        error.AccessDenied => if (builtin.os.tag == .windows) return error.SkipZigTest else return err,
+        error.AccessDenied => if (native_os == .windows) return error.SkipZigTest else return err,
         else => return err,
     };
 }
@@ -232,60 +234,58 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" {
 
             var symlink = switch (builtin.target.os.tag) {
                 .windows => windows_symlink: {
-                    const w = std.os.windows;
-
-                    const sub_path_w = try std.os.windows.cStrToPrefixedFileW(ctx.dir.fd, "symlink");
+                    const sub_path_w = try windows.cStrToPrefixedFileW(ctx.dir.fd, "symlink");
 
                     var result = Dir{
                         .fd = undefined,
                     };
 
                     const path_len_bytes = @as(u16, @intCast(sub_path_w.span().len * 2));
-                    var nt_name = w.UNICODE_STRING{
+                    var nt_name = windows.UNICODE_STRING{
                         .Length = path_len_bytes,
                         .MaximumLength = path_len_bytes,
                         .Buffer = @constCast(&sub_path_w.data),
                     };
-                    var attr = w.OBJECT_ATTRIBUTES{
-                        .Length = @sizeOf(w.OBJECT_ATTRIBUTES),
+                    var attr = windows.OBJECT_ATTRIBUTES{
+                        .Length = @sizeOf(windows.OBJECT_ATTRIBUTES),
                         .RootDirectory = if (fs.path.isAbsoluteWindowsW(sub_path_w.span())) null else ctx.dir.fd,
                         .Attributes = 0,
                         .ObjectName = &nt_name,
                         .SecurityDescriptor = null,
                         .SecurityQualityOfService = null,
                     };
-                    var io: w.IO_STATUS_BLOCK = undefined;
-                    const rc = w.ntdll.NtCreateFile(
+                    var io: windows.IO_STATUS_BLOCK = undefined;
+                    const rc = windows.ntdll.NtCreateFile(
                         &result.fd,
-                        w.STANDARD_RIGHTS_READ | w.FILE_READ_ATTRIBUTES | w.FILE_READ_EA | w.SYNCHRONIZE | w.FILE_TRAVERSE,
+                        windows.STANDARD_RIGHTS_READ | windows.FILE_READ_ATTRIBUTES | windows.FILE_READ_EA | windows.SYNCHRONIZE | windows.FILE_TRAVERSE,
                         &attr,
                         &io,
                         null,
-                        w.FILE_ATTRIBUTE_NORMAL,
-                        w.FILE_SHARE_READ | w.FILE_SHARE_WRITE,
-                        w.FILE_OPEN,
+                        windows.FILE_ATTRIBUTE_NORMAL,
+                        windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE,
+                        windows.FILE_OPEN,
                         // FILE_OPEN_REPARSE_POINT is the important thing here
-                        w.FILE_OPEN_REPARSE_POINT | w.FILE_DIRECTORY_FILE | w.FILE_SYNCHRONOUS_IO_NONALERT | w.FILE_OPEN_FOR_BACKUP_INTENT,
+                        windows.FILE_OPEN_REPARSE_POINT | windows.FILE_DIRECTORY_FILE | windows.FILE_SYNCHRONOUS_IO_NONALERT | windows.FILE_OPEN_FOR_BACKUP_INTENT,
                         null,
                         0,
                     );
 
                     switch (rc) {
                         .SUCCESS => break :windows_symlink result,
-                        else => return w.unexpectedStatus(rc),
+                        else => return windows.unexpectedStatus(rc),
                     }
                 },
                 .linux => linux_symlink: {
-                    const sub_path_c = try os.toPosixPath("symlink");
+                    const sub_path_c = try posix.toPosixPath("symlink");
                     // the O_NOFOLLOW | O_PATH combination can obtain a fd to a symlink
                     // note that if O_DIRECTORY is set, then this will error with ENOTDIR
-                    const flags: os.O = .{
+                    const flags: posix.O = .{
                         .NOFOLLOW = true,
                         .PATH = true,
                         .ACCMODE = .RDONLY,
                         .CLOEXEC = true,
                     };
-                    const fd = try os.openatZ(ctx.dir.fd, &sub_path_c, flags, 0);
+                    const fd = try posix.openatZ(ctx.dir.fd, &sub_path_c, flags, 0);
                     break :linux_symlink Dir{ .fd = fd };
                 },
                 else => unreachable,
@@ -315,7 +315,7 @@ test "openDir" {
 }
 
 test "accessAbsolute" {
-    if (builtin.os.tag == .wasi) return error.SkipZigTest;
+    if (native_os == .wasi) return error.SkipZigTest;
 
     var tmp = tmpDir(.{});
     defer tmp.cleanup();
@@ -333,7 +333,7 @@ test "accessAbsolute" {
 }
 
 test "openDirAbsolute" {
-    if (builtin.os.tag == .wasi) return error.SkipZigTest;
+    if (native_os == .wasi) return error.SkipZigTest;
 
     var tmp = tmpDir(.{});
     defer tmp.cleanup();
@@ -361,14 +361,14 @@ test "openDirAbsolute" {
 }
 
 test "openDir cwd parent '..'" {
-    if (builtin.os.tag == .wasi) return error.SkipZigTest;
+    if (native_os == .wasi) return error.SkipZigTest;
 
     var dir = try fs.cwd().openDir("..", .{});
     defer dir.close();
 }
 
 test "openDir non-cwd parent '..'" {
-    switch (builtin.os.tag) {
+    switch (native_os) {
         .wasi, .netbsd, .openbsd => return error.SkipZigTest,
         else => {},
     }
@@ -392,7 +392,7 @@ test "openDir non-cwd parent '..'" {
 }
 
 test "readLinkAbsolute" {
-    if (builtin.os.tag == .wasi) return error.SkipZigTest;
+    if (native_os == .wasi) return error.SkipZigTest;
 
     var tmp = tmpDir(.{});
     defer tmp.cleanup();
@@ -587,7 +587,7 @@ test "Dir.Iterator but dir is deleted during iteration" {
     try std.testing.expect(entry == null);
 
     // On Linux, we can opt-in to receiving a more specific error by calling `nextLinux`
-    if (builtin.os.tag == .linux) {
+    if (native_os == .linux) {
         try std.testing.expectError(error.DirNotFound, iterator.nextLinux());
     }
 }
@@ -744,7 +744,7 @@ test "directory operations on files" {
 
 test "file operations on directories" {
     // TODO: fix this test on FreeBSD. https://github.com/ziglang/zig/issues/1759
-    if (builtin.os.tag == .freebsd) return error.SkipZigTest;
+    if (native_os == .freebsd) return error.SkipZigTest;
 
     try testWithAllSupportedPathTypes(struct {
         fn impl(ctx: *TestContext) !void {
@@ -754,7 +754,7 @@ test "file operations on directories" {
 
             try testing.expectError(error.IsDir, ctx.dir.createFile(test_dir_name, .{}));
             try testing.expectError(error.IsDir, ctx.dir.deleteFile(test_dir_name));
-            switch (builtin.os.tag) {
+            switch (native_os) {
                 // no error when reading a directory.
                 .dragonfly, .netbsd => {},
                 // Currently, WASI will return error.Unexpected (via ENOTCAPABLE) when attempting fd_read on a directory handle.
@@ -895,7 +895,7 @@ test "Dir.rename directories" {
 
 test "Dir.rename directory onto empty dir" {
     // TODO: Fix on Windows, see https://github.com/ziglang/zig/issues/6364
-    if (builtin.os.tag == .windows) return error.SkipZigTest;
+    if (native_os == .windows) return error.SkipZigTest;
 
     try testWithAllSupportedPathTypes(struct {
         fn impl(ctx: *TestContext) !void {
@@ -916,7 +916,7 @@ test "Dir.rename directory onto empty dir" {
 
 test "Dir.rename directory onto non-empty dir" {
     // TODO: Fix on Windows, see https://github.com/ziglang/zig/issues/6364
-    if (builtin.os.tag == .windows) return error.SkipZigTest;
+    if (native_os == .windows) return error.SkipZigTest;
 
     try testWithAllSupportedPathTypes(struct {
         fn impl(ctx: *TestContext) !void {
@@ -942,7 +942,7 @@ test "Dir.rename directory onto non-empty dir" {
 
 test "Dir.rename file <-> dir" {
     // TODO: Fix on Windows, see https://github.com/ziglang/zig/issues/6364
-    if (builtin.os.tag == .windows) return error.SkipZigTest;
+    if (native_os == .windows) return error.SkipZigTest;
 
     try testWithAllSupportedPathTypes(struct {
         fn impl(ctx: *TestContext) !void {
@@ -979,7 +979,7 @@ test "rename" {
 }
 
 test "renameAbsolute" {
-    if (builtin.os.tag == .wasi) return error.SkipZigTest;
+    if (native_os == .wasi) return error.SkipZigTest;
 
     var tmp_dir = tmpDir(.{});
     defer tmp_dir.cleanup();
@@ -1032,14 +1032,14 @@ test "renameAbsolute" {
 }
 
 test "openSelfExe" {
-    if (builtin.os.tag == .wasi) return error.SkipZigTest;
+    if (native_os == .wasi) return error.SkipZigTest;
 
     const self_exe_file = try std.fs.openSelfExe(.{});
     self_exe_file.close();
 }
 
 test "selfExePath" {
-    if (builtin.os.tag == .wasi) return error.SkipZigTest;
+    if (native_os == .wasi) return error.SkipZigTest;
 
     var buf: [fs.MAX_PATH_BYTES]u8 = undefined;
     const buf_self_exe_path = try std.fs.selfExePath(&buf);
@@ -1120,7 +1120,7 @@ test "makePath, put some files in it, deleteTreeMinStackSize" {
 }
 
 test "makePath in a directory that no longer exists" {
-    if (builtin.os.tag == .windows) return error.SkipZigTest; // Windows returns FileBusy if attempting to remove an open dir
+    if (native_os == .windows) return error.SkipZigTest; // Windows returns FileBusy if attempting to remove an open dir
 
     var tmp = tmpDir(.{});
     defer tmp.cleanup();
@@ -1182,7 +1182,7 @@ test "makepath relative walks" {
     try tmp.dir.makePath(relPath);
 
     // How .. is handled is different on Windows than non-Windows
-    switch (builtin.os.tag) {
+    switch (native_os) {
         .windows => {
             // On Windows, .. is resolved before passing the path to NtCreateFile,
             // meaning everything except `first/C` drops out.
@@ -1248,12 +1248,12 @@ test "max file name component lengths" {
     var tmp = tmpDir(.{ .iterate = true });
     defer tmp.cleanup();
 
-    if (builtin.os.tag == .windows) {
+    if (native_os == .windows) {
         // U+FFFF is the character with the largest code point that is encoded as a single
         // UTF-16 code unit, so Windows allows for NAME_MAX of them.
-        const maxed_windows_filename = ("\u{FFFF}".*) ** std.os.windows.NAME_MAX;
+        const maxed_windows_filename = ("\u{FFFF}".*) ** windows.NAME_MAX;
         try testFilenameLimits(tmp.dir, &maxed_windows_filename);
-    } else if (builtin.os.tag == .wasi) {
+    } else if (native_os == .wasi) {
         // On WASI, the maxed filename depends on the host OS, so in order for this test to
         // work on any host, we need to use a length that will work for all platforms
         // (i.e. the minimum MAX_NAME_BYTES of all supported platforms).
@@ -1274,7 +1274,7 @@ test "writev, readv" {
 
     var buf1: [line1.len]u8 = undefined;
     var buf2: [line2.len]u8 = undefined;
-    var write_vecs = [_]std.os.iovec_const{
+    var write_vecs = [_]posix.iovec_const{
         .{
             .iov_base = line1,
             .iov_len = line1.len,
@@ -1284,7 +1284,7 @@ test "writev, readv" {
             .iov_len = line2.len,
         },
     };
-    var read_vecs = [_]std.os.iovec{
+    var read_vecs = [_]posix.iovec{
         .{
             .iov_base = &buf2,
             .iov_len = buf2.len,
@@ -1316,7 +1316,7 @@ test "pwritev, preadv" {
 
     var buf1: [line1.len]u8 = undefined;
     var buf2: [line2.len]u8 = undefined;
-    var write_vecs = [_]std.os.iovec_const{
+    var write_vecs = [_]posix.iovec_const{
         .{
             .iov_base = line1,
             .iov_len = line1.len,
@@ -1326,7 +1326,7 @@ test "pwritev, preadv" {
             .iov_len = line2.len,
         },
     };
-    var read_vecs = [_]std.os.iovec{
+    var read_vecs = [_]posix.iovec{
         .{
             .iov_base = &buf2,
             .iov_len = buf2.len,
@@ -1376,7 +1376,7 @@ test "sendfile" {
 
     const line1 = "line1\n";
     const line2 = "second line\n";
-    var vecs = [_]std.os.iovec_const{
+    var vecs = [_]posix.iovec_const{
         .{
             .iov_base = line1,
             .iov_len = line1.len,
@@ -1399,7 +1399,7 @@ test "sendfile" {
     const header2 = "second header\n";
     const trailer1 = "trailer1\n";
     const trailer2 = "second trailer\n";
-    var hdtr = [_]std.os.iovec_const{
+    var hdtr = [_]posix.iovec_const{
         .{
             .iov_base = header1,
             .iov_len = header1.len,
@@ -1510,7 +1510,7 @@ test "AtomicFile" {
 }
 
 test "open file with exclusive nonblocking lock twice" {
-    if (builtin.os.tag == .wasi) return error.SkipZigTest;
+    if (native_os == .wasi) return error.SkipZigTest;
 
     try testWithAllSupportedPathTypes(struct {
         fn impl(ctx: *TestContext) !void {
@@ -1526,7 +1526,7 @@ test "open file with exclusive nonblocking lock twice" {
 }
 
 test "open file with shared and exclusive nonblocking lock" {
-    if (builtin.os.tag == .wasi) return error.SkipZigTest;
+    if (native_os == .wasi) return error.SkipZigTest;
 
     try testWithAllSupportedPathTypes(struct {
         fn impl(ctx: *TestContext) !void {
@@ -1542,7 +1542,7 @@ test "open file with shared and exclusive nonblocking lock" {
 }
 
 test "open file with exclusive and shared nonblocking lock" {
-    if (builtin.os.tag == .wasi) return error.SkipZigTest;
+    if (native_os == .wasi) return error.SkipZigTest;
 
     try testWithAllSupportedPathTypes(struct {
         fn impl(ctx: *TestContext) !void {
@@ -1601,7 +1601,7 @@ test "open file with exclusive lock twice, make sure second lock waits" {
 }
 
 test "open file with exclusive nonblocking lock twice (absolute paths)" {
-    if (builtin.os.tag == .wasi) return error.SkipZigTest;
+    if (native_os == .wasi) return error.SkipZigTest;
 
     var random_bytes: [12]u8 = undefined;
     std.crypto.random.bytes(&random_bytes);
@@ -1634,7 +1634,7 @@ test "open file with exclusive nonblocking lock twice (absolute paths)" {
 }
 
 test "walker" {
-    if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;
+    if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;
 
     var tmp = tmpDir(.{ .iterate = true });
     defer tmp.cleanup();
@@ -1687,7 +1687,7 @@ test "walker" {
 }
 
 test "walker without fully iterating" {
-    if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;
+    if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;
 
     var tmp = tmpDir(.{ .iterate = true });
     defer tmp.cleanup();
@@ -1710,9 +1710,9 @@ test "walker without fully iterating" {
 }
 
 test "'.' and '..' in fs.Dir functions" {
-    if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest;
+    if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;
 
-    if (builtin.os.tag == .windows and builtin.cpu.arch == .aarch64) {
+    if (native_os == .windows and builtin.cpu.arch == .aarch64) {
         // https://github.com/ziglang/zig/issues/17134
         return error.SkipZigTest;
     }
@@ -1750,7 +1750,7 @@ test "'.' and '..' in fs.Dir functions" {
 }
 
 test "'.' and '..' in absolute functions" {
-    if (builtin.os.tag == .wasi) return error.SkipZigTest;
+    if (native_os == .wasi) return error.SkipZigTest;
 
     var tmp = tmpDir(.{});
     defer tmp.cleanup();
@@ -1794,7 +1794,7 @@ test "'.' and '..' in absolute functions" {
 }
 
 test "chmod" {
-    if (builtin.os.tag == .windows or builtin.os.tag == .wasi)
+    if (native_os == .windows or native_os == .wasi)
         return error.SkipZigTest;
 
     var tmp = tmpDir(.{});
@@ -1816,7 +1816,7 @@ test "chmod" {
 }
 
 test "chown" {
-    if (builtin.os.tag == .windows or builtin.os.tag == .wasi)
+    if (native_os == .windows or native_os == .wasi)
         return error.SkipZigTest;
 
     var tmp = tmpDir(.{});
@@ -1849,7 +1849,7 @@ test "File.Metadata" {
 }
 
 test "File.Permissions" {
-    if (builtin.os.tag == .wasi)
+    if (native_os == .wasi)
         return error.SkipZigTest;
 
     var tmp = tmpDir(.{});
@@ -1875,7 +1875,7 @@ test "File.Permissions" {
 }
 
 test "File.PermissionsUnix" {
-    if (builtin.os.tag == .windows or builtin.os.tag == .wasi)
+    if (native_os == .windows or native_os == .wasi)
         return error.SkipZigTest;
 
     var tmp = tmpDir(.{});
@@ -1910,7 +1910,7 @@ test "File.PermissionsUnix" {
 }
 
 test "delete a read-only file on windows" {
-    if (builtin.os.tag != .windows)
+    if (native_os != .windows)
         return error.SkipZigTest;
 
     var tmp = testing.tmpDir(.{});
@@ -1941,7 +1941,7 @@ test "delete a read-only file on windows" {
 }
 
 test "delete a setAsCwd directory on Windows" {
-    if (builtin.os.tag != .windows) return error.SkipZigTest;
+    if (native_os != .windows) return error.SkipZigTest;
 
     var tmp = tmpDir(.{});
     // Set tmp dir as current working directory.
@@ -1956,7 +1956,7 @@ test "delete a setAsCwd directory on Windows" {
 }
 
 test "invalid UTF-8/WTF-8 paths" {
-    const expected_err = switch (builtin.os.tag) {
+    const expected_err = switch (native_os) {
         .wasi => error.InvalidUtf8,
         .windows => error.InvalidWtf8,
         else => return error.SkipZigTest,
@@ -1993,13 +1993,13 @@ test "invalid UTF-8/WTF-8 paths" {
 
             try testing.expectError(expected_err, ctx.dir.symLink(invalid_path, invalid_path, .{}));
             try testing.expectError(expected_err, ctx.dir.symLinkZ(invalid_path, invalid_path, .{}));
-            if (builtin.os.tag == .wasi) {
+            if (native_os == .wasi) {
                 try testing.expectError(expected_err, ctx.dir.symLinkWasi(invalid_path, invalid_path, .{}));
             }
 
             try testing.expectError(expected_err, ctx.dir.readLink(invalid_path, &[_]u8{}));
             try testing.expectError(expected_err, ctx.dir.readLinkZ(invalid_path, &[_]u8{}));
-            if (builtin.os.tag == .wasi) {
+            if (native_os == .wasi) {
                 try testing.expectError(expected_err, ctx.dir.readLinkWasi(invalid_path, &[_]u8{}));
             }
 
@@ -2023,7 +2023,7 @@ test "invalid UTF-8/WTF-8 paths" {
 
             try testing.expectError(expected_err, ctx.dir.statFile(invalid_path));
 
-            if (builtin.os.tag != .wasi) {
+            if (native_os != .wasi) {
                 try testing.expectError(expected_err, ctx.dir.realpath(invalid_path, &[_]u8{}));
                 try testing.expectError(expected_err, ctx.dir.realpathZ(invalid_path, &[_]u8{}));
                 try testing.expectError(expected_err, ctx.dir.realpathAlloc(testing.allocator, invalid_path));
@@ -2032,7 +2032,7 @@ test "invalid UTF-8/WTF-8 paths" {
             try testing.expectError(expected_err, fs.rename(ctx.dir, invalid_path, ctx.dir, invalid_path));
             try testing.expectError(expected_err, fs.renameZ(ctx.dir, invalid_path, ctx.dir, invalid_path));
 
-            if (builtin.os.tag != .wasi and ctx.path_type != .relative) {
+            if (native_os != .wasi and ctx.path_type != .relative) {
                 try testing.expectError(expected_err, fs.updateFileAbsolute(invalid_path, invalid_path, .{}));
                 try testing.expectError(expected_err, fs.copyFileAbsolute(invalid_path, invalid_path, .{}));
                 try testing.expectError(expected_err, fs.makeDirAbsolute(invalid_path));
lib/std/hash/benchmark.zig
@@ -367,7 +367,7 @@ pub fn main() !void {
             i += 1;
             if (i == args.len) {
                 usage();
-                std.os.exit(1);
+                std.process.exit(1);
             }
 
             seed = try std.fmt.parseUnsigned(u32, args[i], 10);
@@ -376,7 +376,7 @@ pub fn main() !void {
             i += 1;
             if (i == args.len) {
                 usage();
-                std.os.exit(1);
+                std.process.exit(1);
             }
 
             filter = args[i];
@@ -384,7 +384,7 @@ pub fn main() !void {
             i += 1;
             if (i == args.len) {
                 usage();
-                std.os.exit(1);
+                std.process.exit(1);
             }
 
             const c = try std.fmt.parseUnsigned(usize, args[i], 10);
@@ -393,13 +393,13 @@ pub fn main() !void {
             i += 1;
             if (i == args.len) {
                 usage();
-                std.os.exit(1);
+                std.process.exit(1);
             }
 
             key_size = try std.fmt.parseUnsigned(usize, args[i], 10);
             if (key_size.? > block_size) {
                 try stdout.print("key_size cannot exceed block size of {}\n", .{block_size});
-                std.os.exit(1);
+                std.process.exit(1);
             }
         } else if (std.mem.eql(u8, args[i], "--iterative-only")) {
             test_iterative_only = true;
@@ -410,7 +410,7 @@ pub fn main() !void {
             return;
         } else {
             usage();
-            std.os.exit(1);
+            std.process.exit(1);
         }
     }
 
lib/std/heap/PageAllocator.zig
@@ -2,9 +2,11 @@ const std = @import("../std.zig");
 const builtin = @import("builtin");
 const Allocator = std.mem.Allocator;
 const mem = std.mem;
-const os = std.os;
 const maxInt = std.math.maxInt;
 const assert = std.debug.assert;
+const native_os = builtin.os.tag;
+const windows = std.os.windows;
+const posix = std.posix;
 
 pub const vtable = Allocator.VTable{
     .alloc = alloc,
@@ -19,22 +21,21 @@ fn alloc(_: *anyopaque, n: usize, log2_align: u8, ra: usize) ?[*]u8 {
     if (n > maxInt(usize) - (mem.page_size - 1)) return null;
     const aligned_len = mem.alignForward(usize, n, mem.page_size);
 
-    if (builtin.os.tag == .windows) {
-        const w = os.windows;
-        const addr = w.VirtualAlloc(
+    if (native_os == .windows) {
+        const addr = windows.VirtualAlloc(
             null,
             aligned_len,
-            w.MEM_COMMIT | w.MEM_RESERVE,
-            w.PAGE_READWRITE,
+            windows.MEM_COMMIT | windows.MEM_RESERVE,
+            windows.PAGE_READWRITE,
         ) catch return null;
         return @ptrCast(addr);
     }
 
     const hint = @atomicLoad(@TypeOf(std.heap.next_mmap_addr_hint), &std.heap.next_mmap_addr_hint, .unordered);
-    const slice = os.mmap(
+    const slice = posix.mmap(
         hint,
         aligned_len,
-        os.PROT.READ | os.PROT.WRITE,
+        posix.PROT.READ | posix.PROT.WRITE,
         .{ .TYPE = .PRIVATE, .ANONYMOUS = true },
         -1,
         0,
@@ -56,8 +57,7 @@ fn resize(
     _ = return_address;
     const new_size_aligned = mem.alignForward(usize, new_size, mem.page_size);
 
-    if (builtin.os.tag == .windows) {
-        const w = os.windows;
+    if (native_os == .windows) {
         if (new_size <= buf_unaligned.len) {
             const base_addr = @intFromPtr(buf_unaligned.ptr);
             const old_addr_end = base_addr + buf_unaligned.len;
@@ -65,10 +65,10 @@ fn resize(
             if (old_addr_end > new_addr_end) {
                 // For shrinking that is not releasing, we will only
                 // decommit the pages not needed anymore.
-                w.VirtualFree(
+                windows.VirtualFree(
                     @as(*anyopaque, @ptrFromInt(new_addr_end)),
                     old_addr_end - new_addr_end,
-                    w.MEM_DECOMMIT,
+                    windows.MEM_DECOMMIT,
                 );
             }
             return true;
@@ -87,7 +87,7 @@ fn resize(
     if (new_size_aligned < buf_aligned_len) {
         const ptr = buf_unaligned.ptr + new_size_aligned;
         // TODO: if the next_mmap_addr_hint is within the unmapped range, update it
-        os.munmap(@alignCast(ptr[0 .. buf_aligned_len - new_size_aligned]));
+        posix.munmap(@alignCast(ptr[0 .. buf_aligned_len - new_size_aligned]));
         return true;
     }
 
@@ -100,10 +100,10 @@ fn free(_: *anyopaque, slice: []u8, log2_buf_align: u8, return_address: usize) v
     _ = log2_buf_align;
     _ = return_address;
 
-    if (builtin.os.tag == .windows) {
-        os.windows.VirtualFree(slice.ptr, 0, os.windows.MEM_RELEASE);
+    if (native_os == .windows) {
+        windows.VirtualFree(slice.ptr, 0, windows.MEM_RELEASE);
     } else {
         const buf_aligned_len = mem.alignForward(usize, slice.len, mem.page_size);
-        os.munmap(@alignCast(slice.ptr[0..buf_aligned_len]));
+        posix.munmap(@alignCast(slice.ptr[0..buf_aligned_len]));
     }
 }
lib/std/http/Client.zig
@@ -220,7 +220,7 @@ pub const Connection = struct {
 
     pub const Protocol = enum { plain, tls };
 
-    pub fn readvDirectTls(conn: *Connection, buffers: []std.os.iovec) ReadError!usize {
+    pub fn readvDirectTls(conn: *Connection, buffers: []std.posix.iovec) ReadError!usize {
         return conn.tls_client.readv(conn.stream, buffers) catch |err| {
             // https://github.com/ziglang/zig/issues/2473
             if (mem.startsWith(u8, @errorName(err), "TlsAlert")) return error.TlsAlert;
@@ -234,7 +234,7 @@ pub const Connection = struct {
         };
     }
 
-    pub fn readvDirect(conn: *Connection, buffers: []std.os.iovec) ReadError!usize {
+    pub fn readvDirect(conn: *Connection, buffers: []std.posix.iovec) ReadError!usize {
         if (conn.protocol == .tls) {
             if (disable_tls) unreachable;
 
@@ -252,7 +252,7 @@ pub const Connection = struct {
     pub fn fill(conn: *Connection) ReadError!void {
         if (conn.read_end != conn.read_start) return;
 
-        var iovecs = [1]std.os.iovec{
+        var iovecs = [1]std.posix.iovec{
             .{ .iov_base = &conn.read_buf, .iov_len = conn.read_buf.len },
         };
         const nread = try conn.readvDirect(&iovecs);
@@ -288,7 +288,7 @@ pub const Connection = struct {
             return available_read;
         }
 
-        var iovecs = [2]std.os.iovec{
+        var iovecs = [2]std.posix.iovec{
             .{ .iov_base = buffer.ptr, .iov_len = buffer.len },
             .{ .iov_base = &conn.read_buf, .iov_len = conn.read_buf.len },
         };
@@ -1387,7 +1387,7 @@ pub fn connectTcp(client: *Client, host: []const u8, port: u16, protocol: Connec
     return &conn.data;
 }
 
-pub const ConnectUnixError = Allocator.Error || std.os.SocketError || error{NameTooLong} || std.os.ConnectError;
+pub const ConnectUnixError = Allocator.Error || std.posix.SocketError || error{NameTooLong} || std.posix.ConnectError;
 
 /// Connect to `path` as a unix domain socket. This will reuse a connection if one is already open.
 ///
lib/std/io/c_writer.zig
@@ -2,7 +2,6 @@ const std = @import("../std.zig");
 const builtin = @import("builtin");
 const io = std.io;
 const testing = std.testing;
-const os = std.os;
 
 pub const CWriter = io.Writer(*std.c.FILE, std.fs.File.WriteError, cWriterWrite);
 
@@ -13,7 +12,7 @@ pub fn cWriter(c_file: *std.c.FILE) CWriter {
 fn cWriterWrite(c_file: *std.c.FILE, bytes: []const u8) std.fs.File.WriteError!usize {
     const amt_written = std.c.fwrite(bytes.ptr, 1, bytes.len, c_file);
     if (amt_written >= 0) return amt_written;
-    switch (@as(os.E, @enumFromInt(std.c._errno().*))) {
+    switch (@as(std.c.E, @enumFromInt(std.c._errno().*))) {
         .SUCCESS => unreachable,
         .INVAL => unreachable,
         .FAULT => unreachable,
@@ -26,11 +25,11 @@ fn cWriterWrite(c_file: *std.c.FILE, bytes: []const u8) std.fs.File.WriteError!u
         .NOSPC => return error.NoSpaceLeft,
         .PERM => return error.AccessDenied,
         .PIPE => return error.BrokenPipe,
-        else => |err| return os.unexpectedErrno(err),
+        else => |err| return std.posix.unexpectedErrno(err),
     }
 }
 
-test "C Writer" {
+test cWriter {
     if (!builtin.link_libc or builtin.os.tag == .wasi) return error.SkipZigTest;
 
     const filename = "tmp_io_test_file.txt";
lib/std/os/linux/errno/generic.zig
@@ -1,460 +0,0 @@
-pub const E = enum(u16) {
-    /// No error occurred.
-    /// Same code used for `NSROK`.
-    SUCCESS = 0,
-
-    /// Operation not permitted
-    PERM = 1,
-
-    /// No such file or directory
-    NOENT = 2,
-
-    /// No such process
-    SRCH = 3,
-
-    /// Interrupted system call
-    INTR = 4,
-
-    /// I/O error
-    IO = 5,
-
-    /// No such device or address
-    NXIO = 6,
-
-    /// Arg list too long
-    @"2BIG" = 7,
-
-    /// Exec format error
-    NOEXEC = 8,
-
-    /// Bad file number
-    BADF = 9,
-
-    /// No child processes
-    CHILD = 10,
-
-    /// Try again
-    /// Also means: WOULDBLOCK: operation would block
-    AGAIN = 11,
-
-    /// Out of memory
-    NOMEM = 12,
-
-    /// Permission denied
-    ACCES = 13,
-
-    /// Bad address
-    FAULT = 14,
-
-    /// Block device required
-    NOTBLK = 15,
-
-    /// Device or resource busy
-    BUSY = 16,
-
-    /// File exists
-    EXIST = 17,
-
-    /// Cross-device link
-    XDEV = 18,
-
-    /// No such device
-    NODEV = 19,
-
-    /// Not a directory
-    NOTDIR = 20,
-
-    /// Is a directory
-    ISDIR = 21,
-
-    /// Invalid argument
-    INVAL = 22,
-
-    /// File table overflow
-    NFILE = 23,
-
-    /// Too many open files
-    MFILE = 24,
-
-    /// Not a typewriter
-    NOTTY = 25,
-
-    /// Text file busy
-    TXTBSY = 26,
-
-    /// File too large
-    FBIG = 27,
-
-    /// No space left on device
-    NOSPC = 28,
-
-    /// Illegal seek
-    SPIPE = 29,
-
-    /// Read-only file system
-    ROFS = 30,
-
-    /// Too many links
-    MLINK = 31,
-
-    /// Broken pipe
-    PIPE = 32,
-
-    /// Math argument out of domain of func
-    DOM = 33,
-
-    /// Math result not representable
-    RANGE = 34,
-
-    /// Resource deadlock would occur
-    DEADLK = 35,
-
-    /// File name too long
-    NAMETOOLONG = 36,
-
-    /// No record locks available
-    NOLCK = 37,
-
-    /// Function not implemented
-    NOSYS = 38,
-
-    /// Directory not empty
-    NOTEMPTY = 39,
-
-    /// Too many symbolic links encountered
-    LOOP = 40,
-
-    /// No message of desired type
-    NOMSG = 42,
-
-    /// Identifier removed
-    IDRM = 43,
-
-    /// Channel number out of range
-    CHRNG = 44,
-
-    /// Level 2 not synchronized
-    L2NSYNC = 45,
-
-    /// Level 3 halted
-    L3HLT = 46,
-
-    /// Level 3 reset
-    L3RST = 47,
-
-    /// Link number out of range
-    LNRNG = 48,
-
-    /// Protocol driver not attached
-    UNATCH = 49,
-
-    /// No CSI structure available
-    NOCSI = 50,
-
-    /// Level 2 halted
-    L2HLT = 51,
-
-    /// Invalid exchange
-    BADE = 52,
-
-    /// Invalid request descriptor
-    BADR = 53,
-
-    /// Exchange full
-    XFULL = 54,
-
-    /// No anode
-    NOANO = 55,
-
-    /// Invalid request code
-    BADRQC = 56,
-
-    /// Invalid slot
-    BADSLT = 57,
-
-    /// Bad font file format
-    BFONT = 59,
-
-    /// Device not a stream
-    NOSTR = 60,
-
-    /// No data available
-    NODATA = 61,
-
-    /// Timer expired
-    TIME = 62,
-
-    /// Out of streams resources
-    NOSR = 63,
-
-    /// Machine is not on the network
-    NONET = 64,
-
-    /// Package not installed
-    NOPKG = 65,
-
-    /// Object is remote
-    REMOTE = 66,
-
-    /// Link has been severed
-    NOLINK = 67,
-
-    /// Advertise error
-    ADV = 68,
-
-    /// Srmount error
-    SRMNT = 69,
-
-    /// Communication error on send
-    COMM = 70,
-
-    /// Protocol error
-    PROTO = 71,
-
-    /// Multihop attempted
-    MULTIHOP = 72,
-
-    /// RFS specific error
-    DOTDOT = 73,
-
-    /// Not a data message
-    BADMSG = 74,
-
-    /// Value too large for defined data type
-    OVERFLOW = 75,
-
-    /// Name not unique on network
-    NOTUNIQ = 76,
-
-    /// File descriptor in bad state
-    BADFD = 77,
-
-    /// Remote address changed
-    REMCHG = 78,
-
-    /// Can not access a needed shared library
-    LIBACC = 79,
-
-    /// Accessing a corrupted shared library
-    LIBBAD = 80,
-
-    /// .lib section in a.out corrupted
-    LIBSCN = 81,
-
-    /// Attempting to link in too many shared libraries
-    LIBMAX = 82,
-
-    /// Cannot exec a shared library directly
-    LIBEXEC = 83,
-
-    /// Illegal byte sequence
-    ILSEQ = 84,
-
-    /// Interrupted system call should be restarted
-    RESTART = 85,
-
-    /// Streams pipe error
-    STRPIPE = 86,
-
-    /// Too many users
-    USERS = 87,
-
-    /// Socket operation on non-socket
-    NOTSOCK = 88,
-
-    /// Destination address required
-    DESTADDRREQ = 89,
-
-    /// Message too long
-    MSGSIZE = 90,
-
-    /// Protocol wrong type for socket
-    PROTOTYPE = 91,
-
-    /// Protocol not available
-    NOPROTOOPT = 92,
-
-    /// Protocol not supported
-    PROTONOSUPPORT = 93,
-
-    /// Socket type not supported
-    SOCKTNOSUPPORT = 94,
-
-    /// Operation not supported on transport endpoint
-    /// This code also means `NOTSUP`.
-    OPNOTSUPP = 95,
-
-    /// Protocol family not supported
-    PFNOSUPPORT = 96,
-
-    /// Address family not supported by protocol
-    AFNOSUPPORT = 97,
-
-    /// Address already in use
-    ADDRINUSE = 98,
-
-    /// Cannot assign requested address
-    ADDRNOTAVAIL = 99,
-
-    /// Network is down
-    NETDOWN = 100,
-
-    /// Network is unreachable
-    NETUNREACH = 101,
-
-    /// Network dropped connection because of reset
-    NETRESET = 102,
-
-    /// Software caused connection abort
-    CONNABORTED = 103,
-
-    /// Connection reset by peer
-    CONNRESET = 104,
-
-    /// No buffer space available
-    NOBUFS = 105,
-
-    /// Transport endpoint is already connected
-    ISCONN = 106,
-
-    /// Transport endpoint is not connected
-    NOTCONN = 107,
-
-    /// Cannot send after transport endpoint shutdown
-    SHUTDOWN = 108,
-
-    /// Too many references: cannot splice
-    TOOMANYREFS = 109,
-
-    /// Connection timed out
-    TIMEDOUT = 110,
-
-    /// Connection refused
-    CONNREFUSED = 111,
-
-    /// Host is down
-    HOSTDOWN = 112,
-
-    /// No route to host
-    HOSTUNREACH = 113,
-
-    /// Operation already in progress
-    ALREADY = 114,
-
-    /// Operation now in progress
-    INPROGRESS = 115,
-
-    /// Stale NFS file handle
-    STALE = 116,
-
-    /// Structure needs cleaning
-    UCLEAN = 117,
-
-    /// Not a XENIX named type file
-    NOTNAM = 118,
-
-    /// No XENIX semaphores available
-    NAVAIL = 119,
-
-    /// Is a named type file
-    ISNAM = 120,
-
-    /// Remote I/O error
-    REMOTEIO = 121,
-
-    /// Quota exceeded
-    DQUOT = 122,
-
-    /// No medium found
-    NOMEDIUM = 123,
-
-    /// Wrong medium type
-    MEDIUMTYPE = 124,
-
-    /// Operation canceled
-    CANCELED = 125,
-
-    /// Required key not available
-    NOKEY = 126,
-
-    /// Key has expired
-    KEYEXPIRED = 127,
-
-    /// Key has been revoked
-    KEYREVOKED = 128,
-
-    /// Key was rejected by service
-    KEYREJECTED = 129,
-
-    // for robust mutexes
-
-    /// Owner died
-    OWNERDEAD = 130,
-
-    /// State not recoverable
-    NOTRECOVERABLE = 131,
-
-    /// Operation not possible due to RF-kill
-    RFKILL = 132,
-
-    /// Memory page has hardware error
-    HWPOISON = 133,
-
-    // nameserver query return codes
-
-    /// DNS server returned answer with no data
-    NSRNODATA = 160,
-
-    /// DNS server claims query was misformatted
-    NSRFORMERR = 161,
-
-    /// DNS server returned general failure
-    NSRSERVFAIL = 162,
-
-    /// Domain name not found
-    NSRNOTFOUND = 163,
-
-    /// DNS server does not implement requested operation
-    NSRNOTIMP = 164,
-
-    /// DNS server refused query
-    NSRREFUSED = 165,
-
-    /// Misformatted DNS query
-    NSRBADQUERY = 166,
-
-    /// Misformatted domain name
-    NSRBADNAME = 167,
-
-    /// Unsupported address family
-    NSRBADFAMILY = 168,
-
-    /// Misformatted DNS reply
-    NSRBADRESP = 169,
-
-    /// Could not contact DNS servers
-    NSRCONNREFUSED = 170,
-
-    /// Timeout while contacting DNS servers
-    NSRTIMEOUT = 171,
-
-    /// End of file
-    NSROF = 172,
-
-    /// Error reading file
-    NSRFILE = 173,
-
-    /// Out of memory
-    NSRNOMEM = 174,
-
-    /// Application terminated lookup
-    NSRDESTRUCTION = 175,
-
-    /// Domain name is too long
-    NSRQUERYDOMAINTOOLONG = 176,
-
-    /// Domain name is too long
-    NSRCNAMELOOP = 177,
-
-    _,
-};
lib/std/os/linux/errno/mips.zig
@@ -1,141 +0,0 @@
-//! These are MIPS ABI compatible.
-pub const E = enum(i32) {
-    /// No error occurred.
-    SUCCESS = 0,
-
-    PERM = 1,
-    NOENT = 2,
-    SRCH = 3,
-    INTR = 4,
-    IO = 5,
-    NXIO = 6,
-    @"2BIG" = 7,
-    NOEXEC = 8,
-    BADF = 9,
-    CHILD = 10,
-    /// Also used for WOULDBLOCK.
-    AGAIN = 11,
-    NOMEM = 12,
-    ACCES = 13,
-    FAULT = 14,
-    NOTBLK = 15,
-    BUSY = 16,
-    EXIST = 17,
-    XDEV = 18,
-    NODEV = 19,
-    NOTDIR = 20,
-    ISDIR = 21,
-    INVAL = 22,
-    NFILE = 23,
-    MFILE = 24,
-    NOTTY = 25,
-    TXTBSY = 26,
-    FBIG = 27,
-    NOSPC = 28,
-    SPIPE = 29,
-    ROFS = 30,
-    MLINK = 31,
-    PIPE = 32,
-    DOM = 33,
-    RANGE = 34,
-
-    NOMSG = 35,
-    IDRM = 36,
-    CHRNG = 37,
-    L2NSYNC = 38,
-    L3HLT = 39,
-    L3RST = 40,
-    LNRNG = 41,
-    UNATCH = 42,
-    NOCSI = 43,
-    L2HLT = 44,
-    DEADLK = 45,
-    NOLCK = 46,
-    BADE = 50,
-    BADR = 51,
-    XFULL = 52,
-    NOANO = 53,
-    BADRQC = 54,
-    BADSLT = 55,
-    DEADLOCK = 56,
-    BFONT = 59,
-    NOSTR = 60,
-    NODATA = 61,
-    TIME = 62,
-    NOSR = 63,
-    NONET = 64,
-    NOPKG = 65,
-    REMOTE = 66,
-    NOLINK = 67,
-    ADV = 68,
-    SRMNT = 69,
-    COMM = 70,
-    PROTO = 71,
-    DOTDOT = 73,
-    MULTIHOP = 74,
-    BADMSG = 77,
-    NAMETOOLONG = 78,
-    OVERFLOW = 79,
-    NOTUNIQ = 80,
-    BADFD = 81,
-    REMCHG = 82,
-    LIBACC = 83,
-    LIBBAD = 84,
-    LIBSCN = 85,
-    LIBMAX = 86,
-    LIBEXEC = 87,
-    ILSEQ = 88,
-    NOSYS = 89,
-    LOOP = 90,
-    RESTART = 91,
-    STRPIPE = 92,
-    NOTEMPTY = 93,
-    USERS = 94,
-    NOTSOCK = 95,
-    DESTADDRREQ = 96,
-    MSGSIZE = 97,
-    PROTOTYPE = 98,
-    NOPROTOOPT = 99,
-    PROTONOSUPPORT = 120,
-    SOCKTNOSUPPORT = 121,
-    OPNOTSUPP = 122,
-    PFNOSUPPORT = 123,
-    AFNOSUPPORT = 124,
-    ADDRINUSE = 125,
-    ADDRNOTAVAIL = 126,
-    NETDOWN = 127,
-    NETUNREACH = 128,
-    NETRESET = 129,
-    CONNABORTED = 130,
-    CONNRESET = 131,
-    NOBUFS = 132,
-    ISCONN = 133,
-    NOTCONN = 134,
-    UCLEAN = 135,
-    NOTNAM = 137,
-    NAVAIL = 138,
-    ISNAM = 139,
-    REMOTEIO = 140,
-    SHUTDOWN = 143,
-    TOOMANYREFS = 144,
-    TIMEDOUT = 145,
-    CONNREFUSED = 146,
-    HOSTDOWN = 147,
-    HOSTUNREACH = 148,
-    ALREADY = 149,
-    INPROGRESS = 150,
-    STALE = 151,
-    CANCELED = 158,
-    NOMEDIUM = 159,
-    MEDIUMTYPE = 160,
-    NOKEY = 161,
-    KEYEXPIRED = 162,
-    KEYREVOKED = 163,
-    KEYREJECTED = 164,
-    OWNERDEAD = 165,
-    NOTRECOVERABLE = 166,
-    RFKILL = 167,
-    HWPOISON = 168,
-    DQUOT = 1133,
-    _,
-};
lib/std/os/linux/errno/sparc.zig
@@ -1,144 +0,0 @@
-//! These match the SunOS error numbering scheme.
-pub const E = enum(i32) {
-    /// No error occurred.
-    SUCCESS = 0,
-
-    PERM = 1,
-    NOENT = 2,
-    SRCH = 3,
-    INTR = 4,
-    IO = 5,
-    NXIO = 6,
-    @"2BIG" = 7,
-    NOEXEC = 8,
-    BADF = 9,
-    CHILD = 10,
-    /// Also used for WOULDBLOCK
-    AGAIN = 11,
-    NOMEM = 12,
-    ACCES = 13,
-    FAULT = 14,
-    NOTBLK = 15,
-    BUSY = 16,
-    EXIST = 17,
-    XDEV = 18,
-    NODEV = 19,
-    NOTDIR = 20,
-    ISDIR = 21,
-    INVAL = 22,
-    NFILE = 23,
-    MFILE = 24,
-    NOTTY = 25,
-    TXTBSY = 26,
-    FBIG = 27,
-    NOSPC = 28,
-    SPIPE = 29,
-    ROFS = 30,
-    MLINK = 31,
-    PIPE = 32,
-    DOM = 33,
-    RANGE = 34,
-
-    INPROGRESS = 36,
-    ALREADY = 37,
-    NOTSOCK = 38,
-    DESTADDRREQ = 39,
-    MSGSIZE = 40,
-    PROTOTYPE = 41,
-    NOPROTOOPT = 42,
-    PROTONOSUPPORT = 43,
-    SOCKTNOSUPPORT = 44,
-    /// Also used for NOTSUP
-    OPNOTSUPP = 45,
-    PFNOSUPPORT = 46,
-    AFNOSUPPORT = 47,
-    ADDRINUSE = 48,
-    ADDRNOTAVAIL = 49,
-    NETDOWN = 50,
-    NETUNREACH = 51,
-    NETRESET = 52,
-    CONNABORTED = 53,
-    CONNRESET = 54,
-    NOBUFS = 55,
-    ISCONN = 56,
-    NOTCONN = 57,
-    SHUTDOWN = 58,
-    TOOMANYREFS = 59,
-    TIMEDOUT = 60,
-    CONNREFUSED = 61,
-    LOOP = 62,
-    NAMETOOLONG = 63,
-    HOSTDOWN = 64,
-    HOSTUNREACH = 65,
-    NOTEMPTY = 66,
-    PROCLIM = 67,
-    USERS = 68,
-    DQUOT = 69,
-    STALE = 70,
-    REMOTE = 71,
-    NOSTR = 72,
-    TIME = 73,
-    NOSR = 74,
-    NOMSG = 75,
-    BADMSG = 76,
-    IDRM = 77,
-    DEADLK = 78,
-    NOLCK = 79,
-    NONET = 80,
-    RREMOTE = 81,
-    NOLINK = 82,
-    ADV = 83,
-    SRMNT = 84,
-    COMM = 85,
-    PROTO = 86,
-    MULTIHOP = 87,
-    DOTDOT = 88,
-    REMCHG = 89,
-    NOSYS = 90,
-    STRPIPE = 91,
-    OVERFLOW = 92,
-    BADFD = 93,
-    CHRNG = 94,
-    L2NSYNC = 95,
-    L3HLT = 96,
-    L3RST = 97,
-    LNRNG = 98,
-    UNATCH = 99,
-    NOCSI = 100,
-    L2HLT = 101,
-    BADE = 102,
-    BADR = 103,
-    XFULL = 104,
-    NOANO = 105,
-    BADRQC = 106,
-    BADSLT = 107,
-    DEADLOCK = 108,
-    BFONT = 109,
-    LIBEXEC = 110,
-    NODATA = 111,
-    LIBBAD = 112,
-    NOPKG = 113,
-    LIBACC = 114,
-    NOTUNIQ = 115,
-    RESTART = 116,
-    UCLEAN = 117,
-    NOTNAM = 118,
-    NAVAIL = 119,
-    ISNAM = 120,
-    REMOTEIO = 121,
-    ILSEQ = 122,
-    LIBMAX = 123,
-    LIBSCN = 124,
-    NOMEDIUM = 125,
-    MEDIUMTYPE = 126,
-    CANCELED = 127,
-    NOKEY = 128,
-    KEYEXPIRED = 129,
-    KEYREVOKED = 130,
-    KEYREJECTED = 131,
-    OWNERDEAD = 132,
-    NOTRECOVERABLE = 133,
-    RFKILL = 134,
-    HWPOISON = 135,
-    _,
-};
lib/std/os/linux/arm-eabi.zig
@@ -2,8 +2,8 @@ const std = @import("../../std.zig");
 const maxInt = std.math.maxInt;
 const linux = std.os.linux;
 const SYS = linux.SYS;
-const iovec = std.os.iovec;
-const iovec_const = std.os.iovec_const;
+const iovec = std.posix.iovec;
+const iovec_const = std.posix.iovec_const;
 const socklen_t = linux.socklen_t;
 const stack_t = linux.stack_t;
 const sigset_t = linux.sigset_t;
lib/std/os/linux/arm64.zig
@@ -4,8 +4,8 @@ const linux = std.os.linux;
 const SYS = linux.SYS;
 const socklen_t = linux.socklen_t;
 const sockaddr = linux.sockaddr;
-const iovec = std.os.iovec;
-const iovec_const = std.os.iovec_const;
+const iovec = std.posix.iovec;
+const iovec_const = std.posix.iovec_const;
 const uid_t = linux.uid_t;
 const gid_t = linux.gid_t;
 const pid_t = linux.pid_t;
lib/std/os/linux/bpf.zig
@@ -1,5 +1,5 @@
 const std = @import("../../std.zig");
-const errno = getErrno;
+const errno = linux.E.init;
 const unexpectedErrno = std.os.unexpectedErrno;
 const expectEqual = std.testing.expectEqual;
 const expectError = std.testing.expectError;
@@ -8,7 +8,6 @@ const expect = std.testing.expect;
 const linux = std.os.linux;
 const fd_t = linux.fd_t;
 const pid_t = linux.pid_t;
-const getErrno = linux.getErrno;
 
 pub const btf = @import("bpf/btf.zig");
 pub const kern = @import("bpf/kern.zig");
lib/std/os/linux/io_uring_sqe.zig
@@ -2,8 +2,7 @@
 //! Split into its own file to compartmentalize the initialization methods.
 
 const std = @import("../../std.zig");
-const os = std.os;
-const linux = os.linux;
+const linux = std.os.linux;
 
 pub const io_uring_sqe = extern struct {
     opcode: linux.IORING_OP,
@@ -40,7 +39,7 @@ pub const io_uring_sqe = extern struct {
         };
     }
 
-    pub fn prep_fsync(sqe: *linux.io_uring_sqe, fd: os.fd_t, flags: u32) void {
+    pub fn prep_fsync(sqe: *linux.io_uring_sqe, fd: linux.fd_t, flags: u32) void {
         sqe.* = .{
             .opcode = .FSYNC,
             .flags = 0,
@@ -62,7 +61,7 @@ pub const io_uring_sqe = extern struct {
     pub fn prep_rw(
         sqe: *linux.io_uring_sqe,
         op: linux.IORING_OP,
-        fd: os.fd_t,
+        fd: linux.fd_t,
         addr: u64,
         len: usize,
         offset: u64,
@@ -85,15 +84,15 @@ pub const io_uring_sqe = extern struct {
         };
     }
 
-    pub fn prep_read(sqe: *linux.io_uring_sqe, fd: os.fd_t, buffer: []u8, offset: u64) void {
+    pub fn prep_read(sqe: *linux.io_uring_sqe, fd: linux.fd_t, buffer: []u8, offset: u64) void {
         sqe.prep_rw(.READ, fd, @intFromPtr(buffer.ptr), buffer.len, offset);
     }
 
-    pub fn prep_write(sqe: *linux.io_uring_sqe, fd: os.fd_t, buffer: []const u8, offset: u64) void {
+    pub fn prep_write(sqe: *linux.io_uring_sqe, fd: linux.fd_t, buffer: []const u8, offset: u64) void {
         sqe.prep_rw(.WRITE, fd, @intFromPtr(buffer.ptr), buffer.len, offset);
     }
 
-    pub fn prep_splice(sqe: *linux.io_uring_sqe, fd_in: os.fd_t, off_in: u64, fd_out: os.fd_t, off_out: u64, len: usize) void {
+    pub fn prep_splice(sqe: *linux.io_uring_sqe, fd_in: linux.fd_t, off_in: u64, fd_out: linux.fd_t, off_out: u64, len: usize) void {
         sqe.prep_rw(.SPLICE, fd_out, undefined, len, off_out);
         sqe.addr = off_in;
         sqe.splice_fd_in = fd_in;
@@ -101,8 +100,8 @@ pub const io_uring_sqe = extern struct {
 
     pub fn prep_readv(
         sqe: *linux.io_uring_sqe,
-        fd: os.fd_t,
-        iovecs: []const os.iovec,
+        fd: linux.fd_t,
+        iovecs: []const std.posix.iovec,
         offset: u64,
     ) void {
         sqe.prep_rw(.READV, fd, @intFromPtr(iovecs.ptr), iovecs.len, offset);
@@ -110,28 +109,28 @@ pub const io_uring_sqe = extern struct {
 
     pub fn prep_writev(
         sqe: *linux.io_uring_sqe,
-        fd: os.fd_t,
-        iovecs: []const os.iovec_const,
+        fd: linux.fd_t,
+        iovecs: []const std.posix.iovec_const,
         offset: u64,
     ) void {
         sqe.prep_rw(.WRITEV, fd, @intFromPtr(iovecs.ptr), iovecs.len, offset);
     }
 
-    pub fn prep_read_fixed(sqe: *linux.io_uring_sqe, fd: os.fd_t, buffer: *os.iovec, offset: u64, buffer_index: u16) void {
+    pub fn prep_read_fixed(sqe: *linux.io_uring_sqe, fd: linux.fd_t, buffer: *std.posix.iovec, offset: u64, buffer_index: u16) void {
         sqe.prep_rw(.READ_FIXED, fd, @intFromPtr(buffer.iov_base), buffer.iov_len, offset);
         sqe.buf_index = buffer_index;
     }
 
-    pub fn prep_write_fixed(sqe: *linux.io_uring_sqe, fd: os.fd_t, buffer: *os.iovec, offset: u64, buffer_index: u16) void {
+    pub fn prep_write_fixed(sqe: *linux.io_uring_sqe, fd: linux.fd_t, buffer: *std.posix.iovec, offset: u64, buffer_index: u16) void {
         sqe.prep_rw(.WRITE_FIXED, fd, @intFromPtr(buffer.iov_base), buffer.iov_len, offset);
         sqe.buf_index = buffer_index;
     }
 
     pub fn prep_accept(
         sqe: *linux.io_uring_sqe,
-        fd: os.fd_t,
-        addr: ?*os.sockaddr,
-        addrlen: ?*os.socklen_t,
+        fd: linux.fd_t,
+        addr: ?*linux.sockaddr,
+        addrlen: ?*linux.socklen_t,
         flags: u32,
     ) void {
         // `addr` holds a pointer to `sockaddr`, and `addr2` holds a pointer to socklen_t`.
@@ -142,9 +141,9 @@ pub const io_uring_sqe = extern struct {
 
     pub fn prep_accept_direct(
         sqe: *linux.io_uring_sqe,
-        fd: os.fd_t,
-        addr: ?*os.sockaddr,
-        addrlen: ?*os.socklen_t,
+        fd: linux.fd_t,
+        addr: ?*linux.sockaddr,
+        addrlen: ?*linux.socklen_t,
         flags: u32,
         file_index: u32,
     ) void {
@@ -154,9 +153,9 @@ pub const io_uring_sqe = extern struct {
 
     pub fn prep_multishot_accept_direct(
         sqe: *linux.io_uring_sqe,
-        fd: os.fd_t,
-        addr: ?*os.sockaddr,
-        addrlen: ?*os.socklen_t,
+        fd: linux.fd_t,
+        addr: ?*linux.sockaddr,
+        addrlen: ?*linux.socklen_t,
         flags: u32,
     ) void {
         prep_multishot_accept(sqe, fd, addr, addrlen, flags);
@@ -177,9 +176,9 @@ pub const io_uring_sqe = extern struct {
 
     pub fn prep_connect(
         sqe: *linux.io_uring_sqe,
-        fd: os.fd_t,
-        addr: *const os.sockaddr,
-        addrlen: os.socklen_t,
+        fd: linux.fd_t,
+        addr: *const linux.sockaddr,
+        addrlen: linux.socklen_t,
     ) void {
         // `addrlen` maps to `sqe.off` (u64) instead of `sqe.len` (which is only a u32).
         sqe.prep_rw(.CONNECT, fd, @intFromPtr(addr), 0, addrlen);
@@ -187,22 +186,22 @@ pub const io_uring_sqe = extern struct {
 
     pub fn prep_epoll_ctl(
         sqe: *linux.io_uring_sqe,
-        epfd: os.fd_t,
-        fd: os.fd_t,
+        epfd: linux.fd_t,
+        fd: linux.fd_t,
         op: u32,
         ev: ?*linux.epoll_event,
     ) void {
         sqe.prep_rw(.EPOLL_CTL, epfd, @intFromPtr(ev), op, @intCast(fd));
     }
 
-    pub fn prep_recv(sqe: *linux.io_uring_sqe, fd: os.fd_t, buffer: []u8, flags: u32) void {
+    pub fn prep_recv(sqe: *linux.io_uring_sqe, fd: linux.fd_t, buffer: []u8, flags: u32) void {
         sqe.prep_rw(.RECV, fd, @intFromPtr(buffer.ptr), buffer.len, 0);
         sqe.rw_flags = flags;
     }
 
     pub fn prep_recv_multishot(
         sqe: *linux.io_uring_sqe,
-        fd: os.fd_t,
+        fd: linux.fd_t,
         buffer: []u8,
         flags: u32,
     ) void {
@@ -212,8 +211,8 @@ pub const io_uring_sqe = extern struct {
 
     pub fn prep_recvmsg(
         sqe: *linux.io_uring_sqe,
-        fd: os.fd_t,
-        msg: *os.msghdr,
+        fd: linux.fd_t,
+        msg: *linux.msghdr,
         flags: u32,
     ) void {
         sqe.prep_rw(.RECVMSG, fd, @intFromPtr(msg), 1, 0);
@@ -222,26 +221,26 @@ pub const io_uring_sqe = extern struct {
 
     pub fn prep_recvmsg_multishot(
         sqe: *linux.io_uring_sqe,
-        fd: os.fd_t,
-        msg: *os.msghdr,
+        fd: linux.fd_t,
+        msg: *linux.msghdr,
         flags: u32,
     ) void {
         sqe.prep_recvmsg(fd, msg, flags);
         sqe.ioprio |= linux.IORING_RECV_MULTISHOT;
     }
 
-    pub fn prep_send(sqe: *linux.io_uring_sqe, fd: os.fd_t, buffer: []const u8, flags: u32) void {
+    pub fn prep_send(sqe: *linux.io_uring_sqe, fd: linux.fd_t, buffer: []const u8, flags: u32) void {
         sqe.prep_rw(.SEND, fd, @intFromPtr(buffer.ptr), buffer.len, 0);
         sqe.rw_flags = flags;
     }
 
-    pub fn prep_send_zc(sqe: *linux.io_uring_sqe, fd: os.fd_t, buffer: []const u8, flags: u32, zc_flags: u16) void {
+    pub fn prep_send_zc(sqe: *linux.io_uring_sqe, fd: linux.fd_t, buffer: []const u8, flags: u32, zc_flags: u16) void {
         sqe.prep_rw(.SEND_ZC, fd, @intFromPtr(buffer.ptr), buffer.len, 0);
         sqe.rw_flags = flags;
         sqe.ioprio = zc_flags;
     }
 
-    pub fn prep_send_zc_fixed(sqe: *linux.io_uring_sqe, fd: os.fd_t, buffer: []const u8, flags: u32, zc_flags: u16, buf_index: u16) void {
+    pub fn prep_send_zc_fixed(sqe: *linux.io_uring_sqe, fd: linux.fd_t, buffer: []const u8, flags: u32, zc_flags: u16, buf_index: u16) void {
         prep_send_zc(sqe, fd, buffer, flags, zc_flags);
         sqe.ioprio |= linux.IORING_RECVSEND_FIXED_BUF;
         sqe.buf_index = buf_index;
@@ -249,8 +248,8 @@ pub const io_uring_sqe = extern struct {
 
     pub fn prep_sendmsg_zc(
         sqe: *linux.io_uring_sqe,
-        fd: os.fd_t,
-        msg: *const os.msghdr_const,
+        fd: linux.fd_t,
+        msg: *const linux.msghdr_const,
         flags: u32,
     ) void {
         prep_sendmsg(sqe, fd, msg, flags);
@@ -259,8 +258,8 @@ pub const io_uring_sqe = extern struct {
 
     pub fn prep_sendmsg(
         sqe: *linux.io_uring_sqe,
-        fd: os.fd_t,
-        msg: *const os.msghdr_const,
+        fd: linux.fd_t,
+        msg: *const linux.msghdr_const,
         flags: u32,
     ) void {
         sqe.prep_rw(.SENDMSG, fd, @intFromPtr(msg), 1, 0);
@@ -269,10 +268,10 @@ pub const io_uring_sqe = extern struct {
 
     pub fn prep_openat(
         sqe: *linux.io_uring_sqe,
-        fd: os.fd_t,
+        fd: linux.fd_t,
         path: [*:0]const u8,
         flags: linux.O,
-        mode: os.mode_t,
+        mode: linux.mode_t,
     ) void {
         sqe.prep_rw(.OPENAT, fd, @intFromPtr(path), mode, 0);
         sqe.rw_flags = @bitCast(flags);
@@ -280,17 +279,17 @@ pub const io_uring_sqe = extern struct {
 
     pub fn prep_openat_direct(
         sqe: *linux.io_uring_sqe,
-        fd: os.fd_t,
+        fd: linux.fd_t,
         path: [*:0]const u8,
         flags: linux.O,
-        mode: os.mode_t,
+        mode: linux.mode_t,
         file_index: u32,
     ) void {
         prep_openat(sqe, fd, path, flags, mode);
         __io_uring_set_target_fixed_file(sqe, file_index);
     }
 
-    pub fn prep_close(sqe: *linux.io_uring_sqe, fd: os.fd_t) void {
+    pub fn prep_close(sqe: *linux.io_uring_sqe, fd: linux.fd_t) void {
         sqe.* = .{
             .opcode = .CLOSE,
             .flags = 0,
@@ -316,7 +315,7 @@ pub const io_uring_sqe = extern struct {
 
     pub fn prep_timeout(
         sqe: *linux.io_uring_sqe,
-        ts: *const os.linux.kernel_timespec,
+        ts: *const linux.kernel_timespec,
         count: u32,
         flags: u32,
     ) void {
@@ -345,7 +344,7 @@ pub const io_uring_sqe = extern struct {
 
     pub fn prep_link_timeout(
         sqe: *linux.io_uring_sqe,
-        ts: *const os.linux.kernel_timespec,
+        ts: *const linux.kernel_timespec,
         flags: u32,
     ) void {
         sqe.prep_rw(.LINK_TIMEOUT, -1, @intFromPtr(ts), 1, 0);
@@ -354,7 +353,7 @@ pub const io_uring_sqe = extern struct {
 
     pub fn prep_poll_add(
         sqe: *linux.io_uring_sqe,
-        fd: os.fd_t,
+        fd: linux.fd_t,
         poll_mask: u32,
     ) void {
         sqe.prep_rw(.POLL_ADD, fd, @intFromPtr(@as(?*anyopaque, null)), 0, 0);
@@ -393,7 +392,7 @@ pub const io_uring_sqe = extern struct {
 
     pub fn prep_fallocate(
         sqe: *linux.io_uring_sqe,
-        fd: os.fd_t,
+        fd: linux.fd_t,
         mode: i32,
         offset: u64,
         len: u64,
@@ -418,7 +417,7 @@ pub const io_uring_sqe = extern struct {
 
     pub fn prep_statx(
         sqe: *linux.io_uring_sqe,
-        fd: os.fd_t,
+        fd: linux.fd_t,
         path: [*:0]const u8,
         flags: u32,
         mask: u32,
@@ -439,7 +438,7 @@ pub const io_uring_sqe = extern struct {
 
     pub fn prep_shutdown(
         sqe: *linux.io_uring_sqe,
-        sockfd: os.socket_t,
+        sockfd: linux.socket_t,
         how: u32,
     ) void {
         sqe.prep_rw(.SHUTDOWN, sockfd, 0, how, 0);
@@ -447,9 +446,9 @@ pub const io_uring_sqe = extern struct {
 
     pub fn prep_renameat(
         sqe: *linux.io_uring_sqe,
-        old_dir_fd: os.fd_t,
+        old_dir_fd: linux.fd_t,
         old_path: [*:0]const u8,
-        new_dir_fd: os.fd_t,
+        new_dir_fd: linux.fd_t,
         new_path: [*:0]const u8,
         flags: u32,
     ) void {
@@ -466,7 +465,7 @@ pub const io_uring_sqe = extern struct {
 
     pub fn prep_unlinkat(
         sqe: *linux.io_uring_sqe,
-        dir_fd: os.fd_t,
+        dir_fd: linux.fd_t,
         path: [*:0]const u8,
         flags: u32,
     ) void {
@@ -476,9 +475,9 @@ pub const io_uring_sqe = extern struct {
 
     pub fn prep_mkdirat(
         sqe: *linux.io_uring_sqe,
-        dir_fd: os.fd_t,
+        dir_fd: linux.fd_t,
         path: [*:0]const u8,
-        mode: os.mode_t,
+        mode: linux.mode_t,
     ) void {
         sqe.prep_rw(.MKDIRAT, dir_fd, @intFromPtr(path), mode, 0);
     }
@@ -486,7 +485,7 @@ pub const io_uring_sqe = extern struct {
     pub fn prep_symlinkat(
         sqe: *linux.io_uring_sqe,
         target: [*:0]const u8,
-        new_dir_fd: os.fd_t,
+        new_dir_fd: linux.fd_t,
         link_path: [*:0]const u8,
     ) void {
         sqe.prep_rw(
@@ -500,9 +499,9 @@ pub const io_uring_sqe = extern struct {
 
     pub fn prep_linkat(
         sqe: *linux.io_uring_sqe,
-        old_dir_fd: os.fd_t,
+        old_dir_fd: linux.fd_t,
         old_path: [*:0]const u8,
-        new_dir_fd: os.fd_t,
+        new_dir_fd: linux.fd_t,
         new_path: [*:0]const u8,
         flags: u32,
     ) void {
@@ -541,9 +540,9 @@ pub const io_uring_sqe = extern struct {
 
     pub fn prep_multishot_accept(
         sqe: *linux.io_uring_sqe,
-        fd: os.fd_t,
-        addr: ?*os.sockaddr,
-        addrlen: ?*os.socklen_t,
+        fd: linux.fd_t,
+        addr: ?*linux.sockaddr,
+        addrlen: ?*linux.socklen_t,
         flags: u32,
     ) void {
         prep_accept(sqe, fd, addr, addrlen, flags);
lib/std/os/linux/IoUring.zig
@@ -4,12 +4,12 @@ const builtin = @import("builtin");
 const assert = std.debug.assert;
 const mem = std.mem;
 const net = std.net;
-const os = std.os;
 const posix = std.posix;
-const linux = os.linux;
+const linux = std.os.linux;
 const testing = std.testing;
+const is_linux = builtin.os.tag == .linux;
 
-fd: os.fd_t = -1,
+fd: posix.fd_t = -1,
 sq: SubmissionQueue,
 cq: CompletionQueue,
 flags: u32,
@@ -45,7 +45,7 @@ pub fn init_params(entries: u16, p: *linux.io_uring_params) !IoUring {
     assert(p.resv[2] == 0);
 
     const res = linux.io_uring_setup(entries, p);
-    switch (linux.getErrno(res)) {
+    switch (linux.E.init(res)) {
         .SUCCESS => {},
         .FAULT => return error.ParamsOutsideAccessibleAddressSpace,
         // The resv array contains non-zero data, p.flags contains an unsupported flag,
@@ -59,11 +59,11 @@ pub fn init_params(entries: u16, p: *linux.io_uring_params) !IoUring {
         // or a container seccomp policy prohibits io_uring syscalls:
         .PERM => return error.PermissionDenied,
         .NOSYS => return error.SystemOutdated,
-        else => |errno| return os.unexpectedErrno(errno),
+        else => |errno| return posix.unexpectedErrno(errno),
     }
-    const fd = @as(os.fd_t, @intCast(res));
+    const fd = @as(posix.fd_t, @intCast(res));
     assert(fd >= 0);
-    errdefer os.close(fd);
+    errdefer posix.close(fd);
 
     // Kernel versions 5.4 and up use only one mmap() for the submission and completion queues.
     // This is not an optional feature for us... if the kernel does it, we have to do it.
@@ -121,7 +121,7 @@ pub fn deinit(self: *IoUring) void {
     // The mmaps depend on the fd, so the order of these calls is important:
     self.cq.deinit();
     self.sq.deinit();
-    os.close(self.fd);
+    posix.close(self.fd);
     self.fd = -1;
 }
 
@@ -174,7 +174,7 @@ pub fn submit_and_wait(self: *IoUring, wait_nr: u32) !u32 {
 pub fn enter(self: *IoUring, to_submit: u32, min_complete: u32, flags: u32) !u32 {
     assert(self.fd >= 0);
     const res = linux.io_uring_enter(self.fd, to_submit, min_complete, flags, null);
-    switch (linux.getErrno(res)) {
+    switch (linux.E.init(res)) {
         .SUCCESS => {},
         // The kernel was unable to allocate memory or ran out of resources for the request.
         // The application should wait for some completions and try again:
@@ -200,7 +200,7 @@ pub fn enter(self: *IoUring, to_submit: u32, min_complete: u32, flags: u32) !u32
         // The operation was interrupted by a delivery of a signal before it could complete.
         // This can happen while waiting for events with IORING_ENTER_GETEVENTS:
         .INTR => return error.SignalInterrupt,
-        else => |errno| return os.unexpectedErrno(errno),
+        else => |errno| return posix.unexpectedErrno(errno),
     }
     return @as(u32, @intCast(res));
 }
@@ -344,7 +344,7 @@ pub fn cq_advance(self: *IoUring, count: u32) void {
 /// apply to the write, since the fsync may complete before the write is issued to the disk.
 /// You should preferably use `link_with_next_sqe()` on a write's SQE to link it with an fsync,
 /// or else insert a full write barrier using `drain_previous_sqes()` when queueing an fsync.
-pub fn fsync(self: *IoUring, user_data: u64, fd: os.fd_t, flags: u32) !*linux.io_uring_sqe {
+pub fn fsync(self: *IoUring, user_data: u64, fd: posix.fd_t, flags: u32) !*linux.io_uring_sqe {
     const sqe = try self.get_sqe();
     sqe.prep_fsync(fd, flags);
     sqe.user_data = user_data;
@@ -369,7 +369,7 @@ pub const ReadBuffer = union(enum) {
     buffer: []u8,
 
     /// io_uring will read directly into these buffers using readv.
-    iovecs: []const os.iovec,
+    iovecs: []const posix.iovec,
 
     /// io_uring will select a buffer that has previously been provided with `provide_buffers`.
     /// The buffer group reference by `group_id` must contain at least one buffer for the read to work.
@@ -389,7 +389,7 @@ pub const ReadBuffer = union(enum) {
 pub fn read(
     self: *IoUring,
     user_data: u64,
-    fd: os.fd_t,
+    fd: posix.fd_t,
     buffer: ReadBuffer,
     offset: u64,
 ) !*linux.io_uring_sqe {
@@ -412,7 +412,7 @@ pub fn read(
 pub fn write(
     self: *IoUring,
     user_data: u64,
-    fd: os.fd_t,
+    fd: posix.fd_t,
     buffer: []const u8,
     offset: u64,
 ) !*linux.io_uring_sqe {
@@ -436,7 +436,7 @@ pub fn write(
 /// See https://github.com/axboe/liburing/issues/291
 ///
 /// Returns a pointer to the SQE so that you can further modify the SQE for advanced use cases.
-pub fn splice(self: *IoUring, user_data: u64, fd_in: os.fd_t, off_in: u64, fd_out: os.fd_t, off_out: u64, len: usize) !*linux.io_uring_sqe {
+pub fn splice(self: *IoUring, user_data: u64, fd_in: posix.fd_t, off_in: u64, fd_out: posix.fd_t, off_out: u64, len: usize) !*linux.io_uring_sqe {
     const sqe = try self.get_sqe();
     sqe.prep_splice(fd_in, off_in, fd_out, off_out, len);
     sqe.user_data = user_data;
@@ -451,8 +451,8 @@ pub fn splice(self: *IoUring, user_data: u64, fd_in: os.fd_t, off_in: u64, fd_ou
 pub fn read_fixed(
     self: *IoUring,
     user_data: u64,
-    fd: os.fd_t,
-    buffer: *os.iovec,
+    fd: posix.fd_t,
+    buffer: *posix.iovec,
     offset: u64,
     buffer_index: u16,
 ) !*linux.io_uring_sqe {
@@ -469,8 +469,8 @@ pub fn read_fixed(
 pub fn writev(
     self: *IoUring,
     user_data: u64,
-    fd: os.fd_t,
-    iovecs: []const os.iovec_const,
+    fd: posix.fd_t,
+    iovecs: []const posix.iovec_const,
     offset: u64,
 ) !*linux.io_uring_sqe {
     const sqe = try self.get_sqe();
@@ -487,8 +487,8 @@ pub fn writev(
 pub fn write_fixed(
     self: *IoUring,
     user_data: u64,
-    fd: os.fd_t,
-    buffer: *os.iovec,
+    fd: posix.fd_t,
+    buffer: *posix.iovec,
     offset: u64,
     buffer_index: u16,
 ) !*linux.io_uring_sqe {
@@ -504,9 +504,9 @@ pub fn write_fixed(
 pub fn accept(
     self: *IoUring,
     user_data: u64,
-    fd: os.fd_t,
-    addr: ?*os.sockaddr,
-    addrlen: ?*os.socklen_t,
+    fd: posix.fd_t,
+    addr: ?*posix.sockaddr,
+    addrlen: ?*posix.socklen_t,
     flags: u32,
 ) !*linux.io_uring_sqe {
     const sqe = try self.get_sqe();
@@ -526,9 +526,9 @@ pub fn accept(
 pub fn accept_multishot(
     self: *IoUring,
     user_data: u64,
-    fd: os.fd_t,
-    addr: ?*os.sockaddr,
-    addrlen: ?*os.socklen_t,
+    fd: posix.fd_t,
+    addr: ?*posix.sockaddr,
+    addrlen: ?*posix.socklen_t,
     flags: u32,
 ) !*linux.io_uring_sqe {
     const sqe = try self.get_sqe();
@@ -551,9 +551,9 @@ pub fn accept_multishot(
 pub fn accept_direct(
     self: *IoUring,
     user_data: u64,
-    fd: os.fd_t,
-    addr: ?*os.sockaddr,
-    addrlen: ?*os.socklen_t,
+    fd: posix.fd_t,
+    addr: ?*posix.sockaddr,
+    addrlen: ?*posix.socklen_t,
     flags: u32,
 ) !*linux.io_uring_sqe {
     const sqe = try self.get_sqe();
@@ -567,9 +567,9 @@ pub fn accept_direct(
 pub fn accept_multishot_direct(
     self: *IoUring,
     user_data: u64,
-    fd: os.fd_t,
-    addr: ?*os.sockaddr,
-    addrlen: ?*os.socklen_t,
+    fd: posix.fd_t,
+    addr: ?*posix.sockaddr,
+    addrlen: ?*posix.socklen_t,
     flags: u32,
 ) !*linux.io_uring_sqe {
     const sqe = try self.get_sqe();
@@ -583,9 +583,9 @@ pub fn accept_multishot_direct(
 pub fn connect(
     self: *IoUring,
     user_data: u64,
-    fd: os.fd_t,
-    addr: *const os.sockaddr,
-    addrlen: os.socklen_t,
+    fd: posix.fd_t,
+    addr: *const posix.sockaddr,
+    addrlen: posix.socklen_t,
 ) !*linux.io_uring_sqe {
     const sqe = try self.get_sqe();
     sqe.prep_connect(fd, addr, addrlen);
@@ -598,8 +598,8 @@ pub fn connect(
 pub fn epoll_ctl(
     self: *IoUring,
     user_data: u64,
-    epfd: os.fd_t,
-    fd: os.fd_t,
+    epfd: posix.fd_t,
+    fd: posix.fd_t,
     op: u32,
     ev: ?*linux.epoll_event,
 ) !*linux.io_uring_sqe {
@@ -629,7 +629,7 @@ pub const RecvBuffer = union(enum) {
 pub fn recv(
     self: *IoUring,
     user_data: u64,
-    fd: os.fd_t,
+    fd: posix.fd_t,
     buffer: RecvBuffer,
     flags: u32,
 ) !*linux.io_uring_sqe {
@@ -653,7 +653,7 @@ pub fn recv(
 pub fn send(
     self: *IoUring,
     user_data: u64,
-    fd: os.fd_t,
+    fd: posix.fd_t,
     buffer: []const u8,
     flags: u32,
 ) !*linux.io_uring_sqe {
@@ -681,7 +681,7 @@ pub fn send(
 pub fn send_zc(
     self: *IoUring,
     user_data: u64,
-    fd: os.fd_t,
+    fd: posix.fd_t,
     buffer: []const u8,
     send_flags: u32,
     zc_flags: u16,
@@ -698,7 +698,7 @@ pub fn send_zc(
 pub fn send_zc_fixed(
     self: *IoUring,
     user_data: u64,
-    fd: os.fd_t,
+    fd: posix.fd_t,
     buffer: []const u8,
     send_flags: u32,
     zc_flags: u16,
@@ -716,8 +716,8 @@ pub fn send_zc_fixed(
 pub fn recvmsg(
     self: *IoUring,
     user_data: u64,
-    fd: os.fd_t,
-    msg: *os.msghdr,
+    fd: posix.fd_t,
+    msg: *posix.msghdr,
     flags: u32,
 ) !*linux.io_uring_sqe {
     const sqe = try self.get_sqe();
@@ -732,8 +732,8 @@ pub fn recvmsg(
 pub fn sendmsg(
     self: *IoUring,
     user_data: u64,
-    fd: os.fd_t,
-    msg: *const os.msghdr_const,
+    fd: posix.fd_t,
+    msg: *const posix.msghdr_const,
     flags: u32,
 ) !*linux.io_uring_sqe {
     const sqe = try self.get_sqe();
@@ -748,8 +748,8 @@ pub fn sendmsg(
 pub fn sendmsg_zc(
     self: *IoUring,
     user_data: u64,
-    fd: os.fd_t,
-    msg: *const os.msghdr_const,
+    fd: posix.fd_t,
+    msg: *const posix.msghdr_const,
     flags: u32,
 ) !*linux.io_uring_sqe {
     const sqe = try self.get_sqe();
@@ -764,10 +764,10 @@ pub fn sendmsg_zc(
 pub fn openat(
     self: *IoUring,
     user_data: u64,
-    fd: os.fd_t,
+    fd: posix.fd_t,
     path: [*:0]const u8,
     flags: linux.O,
-    mode: os.mode_t,
+    mode: posix.mode_t,
 ) !*linux.io_uring_sqe {
     const sqe = try self.get_sqe();
     sqe.prep_openat(fd, path, flags, mode);
@@ -789,10 +789,10 @@ pub fn openat(
 pub fn openat_direct(
     self: *IoUring,
     user_data: u64,
-    fd: os.fd_t,
+    fd: posix.fd_t,
     path: [*:0]const u8,
     flags: linux.O,
-    mode: os.mode_t,
+    mode: posix.mode_t,
     file_index: u32,
 ) !*linux.io_uring_sqe {
     const sqe = try self.get_sqe();
@@ -804,7 +804,7 @@ pub fn openat_direct(
 /// Queues (but does not submit) an SQE to perform a `close(2)`.
 /// Returns a pointer to the SQE.
 /// Available since 5.6.
-pub fn close(self: *IoUring, user_data: u64, fd: os.fd_t) !*linux.io_uring_sqe {
+pub fn close(self: *IoUring, user_data: u64, fd: posix.fd_t) !*linux.io_uring_sqe {
     const sqe = try self.get_sqe();
     sqe.prep_close(fd);
     sqe.user_data = user_data;
@@ -836,7 +836,7 @@ pub fn close_direct(self: *IoUring, user_data: u64, file_index: u32) !*linux.io_
 pub fn timeout(
     self: *IoUring,
     user_data: u64,
-    ts: *const os.linux.kernel_timespec,
+    ts: *const linux.kernel_timespec,
     count: u32,
     flags: u32,
 ) !*linux.io_uring_sqe {
@@ -885,7 +885,7 @@ pub fn timeout_remove(
 pub fn link_timeout(
     self: *IoUring,
     user_data: u64,
-    ts: *const os.linux.kernel_timespec,
+    ts: *const linux.kernel_timespec,
     flags: u32,
 ) !*linux.io_uring_sqe {
     const sqe = try self.get_sqe();
@@ -899,7 +899,7 @@ pub fn link_timeout(
 pub fn poll_add(
     self: *IoUring,
     user_data: u64,
-    fd: os.fd_t,
+    fd: posix.fd_t,
     poll_mask: u32,
 ) !*linux.io_uring_sqe {
     const sqe = try self.get_sqe();
@@ -942,7 +942,7 @@ pub fn poll_update(
 pub fn fallocate(
     self: *IoUring,
     user_data: u64,
-    fd: os.fd_t,
+    fd: posix.fd_t,
     mode: i32,
     offset: u64,
     len: u64,
@@ -958,7 +958,7 @@ pub fn fallocate(
 pub fn statx(
     self: *IoUring,
     user_data: u64,
-    fd: os.fd_t,
+    fd: posix.fd_t,
     path: [:0]const u8,
     flags: u32,
     mask: u32,
@@ -997,7 +997,7 @@ pub fn cancel(
 pub fn shutdown(
     self: *IoUring,
     user_data: u64,
-    sockfd: os.socket_t,
+    sockfd: posix.socket_t,
     how: u32,
 ) !*linux.io_uring_sqe {
     const sqe = try self.get_sqe();
@@ -1011,9 +1011,9 @@ pub fn shutdown(
 pub fn renameat(
     self: *IoUring,
     user_data: u64,
-    old_dir_fd: os.fd_t,
+    old_dir_fd: posix.fd_t,
     old_path: [*:0]const u8,
-    new_dir_fd: os.fd_t,
+    new_dir_fd: posix.fd_t,
     new_path: [*:0]const u8,
     flags: u32,
 ) !*linux.io_uring_sqe {
@@ -1028,7 +1028,7 @@ pub fn renameat(
 pub fn unlinkat(
     self: *IoUring,
     user_data: u64,
-    dir_fd: os.fd_t,
+    dir_fd: posix.fd_t,
     path: [*:0]const u8,
     flags: u32,
 ) !*linux.io_uring_sqe {
@@ -1043,9 +1043,9 @@ pub fn unlinkat(
 pub fn mkdirat(
     self: *IoUring,
     user_data: u64,
-    dir_fd: os.fd_t,
+    dir_fd: posix.fd_t,
     path: [*:0]const u8,
-    mode: os.mode_t,
+    mode: posix.mode_t,
 ) !*linux.io_uring_sqe {
     const sqe = try self.get_sqe();
     sqe.prep_mkdirat(dir_fd, path, mode);
@@ -1059,7 +1059,7 @@ pub fn symlinkat(
     self: *IoUring,
     user_data: u64,
     target: [*:0]const u8,
-    new_dir_fd: os.fd_t,
+    new_dir_fd: posix.fd_t,
     link_path: [*:0]const u8,
 ) !*linux.io_uring_sqe {
     const sqe = try self.get_sqe();
@@ -1073,9 +1073,9 @@ pub fn symlinkat(
 pub fn linkat(
     self: *IoUring,
     user_data: u64,
-    old_dir_fd: os.fd_t,
+    old_dir_fd: posix.fd_t,
     old_path: [*:0]const u8,
-    new_dir_fd: os.fd_t,
+    new_dir_fd: posix.fd_t,
     new_path: [*:0]const u8,
     flags: u32,
 ) !*linux.io_uring_sqe {
@@ -1147,7 +1147,7 @@ pub fn waitid(
 /// Registering file descriptors will wait for the ring to idle.
 /// Files are automatically unregistered by the kernel when the ring is torn down.
 /// An application need unregister only if it wants to register a new array of file descriptors.
-pub fn register_files(self: *IoUring, fds: []const os.fd_t) !void {
+pub fn register_files(self: *IoUring, fds: []const posix.fd_t) !void {
     assert(self.fd >= 0);
     const res = linux.io_uring_register(
         self.fd,
@@ -1166,7 +1166,7 @@ pub fn register_files(self: *IoUring, fds: []const os.fd_t) !void {
 /// * removing an existing entry (set the fd to -1)
 /// * replacing an existing entry with a new fd
 /// Adding new file descriptors must be done with `register_files`.
-pub fn register_files_update(self: *IoUring, offset: u32, fds: []const os.fd_t) !void {
+pub fn register_files_update(self: *IoUring, offset: u32, fds: []const posix.fd_t) !void {
     assert(self.fd >= 0);
 
     const FilesUpdate = extern struct {
@@ -1192,7 +1192,7 @@ pub fn register_files_update(self: *IoUring, offset: u32, fds: []const os.fd_t)
 /// Registers the file descriptor for an eventfd that will be notified of completion events on
 ///  an io_uring instance.
 /// Only a single a eventfd can be registered at any given point in time.
-pub fn register_eventfd(self: *IoUring, fd: os.fd_t) !void {
+pub fn register_eventfd(self: *IoUring, fd: posix.fd_t) !void {
     assert(self.fd >= 0);
     const res = linux.io_uring_register(
         self.fd,
@@ -1207,7 +1207,7 @@ pub fn register_eventfd(self: *IoUring, fd: os.fd_t) !void {
 /// an io_uring instance. Notifications are only posted for events that complete in an async manner.
 /// This means that events that complete inline while being submitted do not trigger a notification event.
 /// Only a single eventfd can be registered at any given point in time.
-pub fn register_eventfd_async(self: *IoUring, fd: os.fd_t) !void {
+pub fn register_eventfd_async(self: *IoUring, fd: posix.fd_t) !void {
     assert(self.fd >= 0);
     const res = linux.io_uring_register(
         self.fd,
@@ -1231,7 +1231,7 @@ pub fn unregister_eventfd(self: *IoUring) !void {
 }
 
 /// Registers an array of buffers for use with `read_fixed` and `write_fixed`.
-pub fn register_buffers(self: *IoUring, buffers: []const os.iovec) !void {
+pub fn register_buffers(self: *IoUring, buffers: []const posix.iovec) !void {
     assert(self.fd >= 0);
     const res = linux.io_uring_register(
         self.fd,
@@ -1246,15 +1246,15 @@ pub fn register_buffers(self: *IoUring, buffers: []const os.iovec) !void {
 pub fn unregister_buffers(self: *IoUring) !void {
     assert(self.fd >= 0);
     const res = linux.io_uring_register(self.fd, .UNREGISTER_BUFFERS, null, 0);
-    switch (linux.getErrno(res)) {
+    switch (linux.E.init(res)) {
         .SUCCESS => {},
         .NXIO => return error.BuffersNotRegistered,
-        else => |errno| return os.unexpectedErrno(errno),
+        else => |errno| return posix.unexpectedErrno(errno),
     }
 }
 
 fn handle_registration_result(res: usize) !void {
-    switch (linux.getErrno(res)) {
+    switch (linux.E.init(res)) {
         .SUCCESS => {},
         // One or more fds in the array are invalid, or the kernel does not support sparse sets:
         .BADF => return error.FileDescriptorInvalid,
@@ -1271,7 +1271,7 @@ fn handle_registration_result(res: usize) !void {
         .NOMEM => return error.SystemResources,
         // Attempt to register files on a ring already registering files or being torn down:
         .NXIO => return error.RingShuttingDownOrAlreadyRegisteringFiles,
-        else => |errno| return os.unexpectedErrno(errno),
+        else => |errno| return posix.unexpectedErrno(errno),
     }
 }
 
@@ -1279,10 +1279,10 @@ fn handle_registration_result(res: usize) !void {
 pub fn unregister_files(self: *IoUring) !void {
     assert(self.fd >= 0);
     const res = linux.io_uring_register(self.fd, .UNREGISTER_FILES, null, 0);
-    switch (linux.getErrno(res)) {
+    switch (linux.E.init(res)) {
         .SUCCESS => {},
         .NXIO => return error.FilesNotRegistered,
-        else => |errno| return os.unexpectedErrno(errno),
+        else => |errno| return posix.unexpectedErrno(errno),
     }
 }
 
@@ -1355,36 +1355,36 @@ pub const SubmissionQueue = struct {
     sqe_head: u32 = 0,
     sqe_tail: u32 = 0,
 
-    pub fn init(fd: os.fd_t, p: linux.io_uring_params) !SubmissionQueue {
+    pub fn init(fd: posix.fd_t, p: linux.io_uring_params) !SubmissionQueue {
         assert(fd >= 0);
         assert((p.features & linux.IORING_FEAT_SINGLE_MMAP) != 0);
         const size = @max(
             p.sq_off.array + p.sq_entries * @sizeOf(u32),
             p.cq_off.cqes + p.cq_entries * @sizeOf(linux.io_uring_cqe),
         );
-        const mmap = try os.mmap(
+        const mmap = try posix.mmap(
             null,
             size,
-            os.PROT.READ | os.PROT.WRITE,
+            posix.PROT.READ | posix.PROT.WRITE,
             .{ .TYPE = .SHARED, .POPULATE = true },
             fd,
             linux.IORING_OFF_SQ_RING,
         );
-        errdefer os.munmap(mmap);
+        errdefer posix.munmap(mmap);
         assert(mmap.len == size);
 
         // The motivation for the `sqes` and `array` indirection is to make it possible for the
         // application to preallocate static linux.io_uring_sqe entries and then replay them when needed.
         const size_sqes = p.sq_entries * @sizeOf(linux.io_uring_sqe);
-        const mmap_sqes = try os.mmap(
+        const mmap_sqes = try posix.mmap(
             null,
             size_sqes,
-            os.PROT.READ | os.PROT.WRITE,
+            posix.PROT.READ | posix.PROT.WRITE,
             .{ .TYPE = .SHARED, .POPULATE = true },
             fd,
             linux.IORING_OFF_SQES,
         );
-        errdefer os.munmap(mmap_sqes);
+        errdefer posix.munmap(mmap_sqes);
         assert(mmap_sqes.len == size_sqes);
 
         const array: [*]u32 = @ptrCast(@alignCast(&mmap[p.sq_off.array]));
@@ -1406,8 +1406,8 @@ pub const SubmissionQueue = struct {
     }
 
     pub fn deinit(self: *SubmissionQueue) void {
-        os.munmap(self.mmap_sqes);
-        os.munmap(self.mmap);
+        posix.munmap(self.mmap_sqes);
+        posix.munmap(self.mmap);
     }
 };
 
@@ -1418,7 +1418,7 @@ pub const CompletionQueue = struct {
     overflow: *u32,
     cqes: []linux.io_uring_cqe,
 
-    pub fn init(fd: os.fd_t, p: linux.io_uring_params, sq: SubmissionQueue) !CompletionQueue {
+    pub fn init(fd: posix.fd_t, p: linux.io_uring_params, sq: SubmissionQueue) !CompletionQueue {
         assert(fd >= 0);
         assert((p.features & linux.IORING_FEAT_SINGLE_MMAP) != 0);
         const mmap = sq.mmap;
@@ -1506,7 +1506,7 @@ pub const BufferGroup = struct {
     }
 
     // Prepare recv operation which will select buffer from this group.
-    pub fn recv(self: *BufferGroup, user_data: u64, fd: os.fd_t, flags: u32) !*linux.io_uring_sqe {
+    pub fn recv(self: *BufferGroup, user_data: u64, fd: posix.fd_t, flags: u32) !*linux.io_uring_sqe {
         var sqe = try self.ring.get_sqe();
         sqe.prep_rw(.RECV, fd, 0, 0, 0);
         sqe.rw_flags = flags;
@@ -1517,7 +1517,7 @@ pub const BufferGroup = struct {
     }
 
     // Prepare multishot recv operation which will select buffer from this group.
-    pub fn recv_multishot(self: *BufferGroup, user_data: u64, fd: os.fd_t, flags: u32) !*linux.io_uring_sqe {
+    pub fn recv_multishot(self: *BufferGroup, user_data: u64, fd: posix.fd_t, flags: u32) !*linux.io_uring_sqe {
         var sqe = try self.recv(user_data, fd, flags);
         sqe.ioprio |= linux.IORING_RECV_MULTISHOT;
         return sqe;
@@ -1559,20 +1559,20 @@ pub const BufferGroup = struct {
 /// `fd` is IO_Uring.fd for which the provided buffer ring is being registered.
 /// `entries` is the number of entries requested in the buffer ring, must be power of 2.
 /// `group_id` is the chosen buffer group ID, unique in IO_Uring.
-pub fn setup_buf_ring(fd: os.fd_t, entries: u16, group_id: u16) !*align(mem.page_size) linux.io_uring_buf_ring {
+pub fn setup_buf_ring(fd: posix.fd_t, entries: u16, group_id: u16) !*align(mem.page_size) linux.io_uring_buf_ring {
     if (entries == 0 or entries > 1 << 15) return error.EntriesNotInRange;
     if (!std.math.isPowerOfTwo(entries)) return error.EntriesNotPowerOfTwo;
 
     const mmap_size = entries * @sizeOf(linux.io_uring_buf);
-    const mmap = try os.mmap(
+    const mmap = try posix.mmap(
         null,
         mmap_size,
-        os.PROT.READ | os.PROT.WRITE,
+        posix.PROT.READ | posix.PROT.WRITE,
         .{ .TYPE = .PRIVATE, .ANONYMOUS = true },
         -1,
         0,
     );
-    errdefer os.munmap(mmap);
+    errdefer posix.munmap(mmap);
     assert(mmap.len == mmap_size);
 
     const br: *align(mem.page_size) linux.io_uring_buf_ring = @ptrCast(mmap.ptr);
@@ -1580,7 +1580,7 @@ pub fn setup_buf_ring(fd: os.fd_t, entries: u16, group_id: u16) !*align(mem.page
     return br;
 }
 
-fn register_buf_ring(fd: os.fd_t, addr: u64, entries: u32, group_id: u16) !void {
+fn register_buf_ring(fd: posix.fd_t, addr: u64, entries: u32, group_id: u16) !void {
     var reg = mem.zeroInit(linux.io_uring_buf_reg, .{
         .ring_addr = addr,
         .ring_entries = entries,
@@ -1595,7 +1595,7 @@ fn register_buf_ring(fd: os.fd_t, addr: u64, entries: u32, group_id: u16) !void
     try handle_register_buf_ring_result(res);
 }
 
-fn unregister_buf_ring(fd: os.fd_t, group_id: u16) !void {
+fn unregister_buf_ring(fd: posix.fd_t, group_id: u16) !void {
     var reg = mem.zeroInit(linux.io_uring_buf_reg, .{
         .bgid = group_id,
     });
@@ -1609,20 +1609,20 @@ fn unregister_buf_ring(fd: os.fd_t, group_id: u16) !void {
 }
 
 fn handle_register_buf_ring_result(res: usize) !void {
-    switch (linux.getErrno(res)) {
+    switch (linux.E.init(res)) {
         .SUCCESS => {},
         .INVAL => return error.ArgumentsInvalid,
-        else => |errno| return os.unexpectedErrno(errno),
+        else => |errno| return posix.unexpectedErrno(errno),
     }
 }
 
 // Unregisters a previously registered shared buffer ring, returned from io_uring_setup_buf_ring.
-pub fn free_buf_ring(fd: os.fd_t, br: *align(mem.page_size) linux.io_uring_buf_ring, entries: u32, group_id: u16) void {
+pub fn free_buf_ring(fd: posix.fd_t, br: *align(mem.page_size) linux.io_uring_buf_ring, entries: u32, group_id: u16) void {
     unregister_buf_ring(fd, group_id) catch {};
     var mmap: []align(mem.page_size) u8 = undefined;
     mmap.ptr = @ptrCast(br);
     mmap.len = entries * @sizeOf(linux.io_uring_buf);
-    os.munmap(mmap);
+    posix.munmap(mmap);
 }
 
 /// Initialises `br` so that it is ready to be used.
@@ -1664,7 +1664,7 @@ pub fn buf_ring_advance(br: *linux.io_uring_buf_ring, count: u16) void {
 }
 
 test "structs/offsets/entries" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     try testing.expectEqual(@as(usize, 120), @sizeOf(linux.io_uring_params));
     try testing.expectEqual(@as(usize, 64), @sizeOf(linux.io_uring_sqe));
@@ -1679,7 +1679,7 @@ test "structs/offsets/entries" {
 }
 
 test "nop" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(1, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -1688,7 +1688,7 @@ test "nop" {
     };
     defer {
         ring.deinit();
-        testing.expectEqual(@as(os.fd_t, -1), ring.fd) catch @panic("test failed");
+        testing.expectEqual(@as(posix.fd_t, -1), ring.fd) catch @panic("test failed");
     }
 
     const sqe = try ring.nop(0xaaaaaaaa);
@@ -1746,7 +1746,7 @@ test "nop" {
 }
 
 test "readv" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(1, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -1755,8 +1755,8 @@ test "readv" {
     };
     defer ring.deinit();
 
-    const fd = try os.openZ("/dev/zero", .{ .ACCMODE = .RDONLY, .CLOEXEC = true }, 0);
-    defer os.close(fd);
+    const fd = try posix.openZ("/dev/zero", .{ .ACCMODE = .RDONLY, .CLOEXEC = true }, 0);
+    defer posix.close(fd);
 
     // Linux Kernel 5.4 supports IORING_REGISTER_FILES but not sparse fd sets (i.e. an fd of -1).
     // Linux Kernel 5.5 adds support for sparse fd sets.
@@ -1764,13 +1764,13 @@ test "readv" {
     // https://github.com/torvalds/linux/blob/v5.4/fs/io_uring.c#L3119-L3124 vs
     // https://github.com/torvalds/linux/blob/v5.8/fs/io_uring.c#L6687-L6691
     // We therefore avoid stressing sparse fd sets here:
-    var registered_fds = [_]os.fd_t{0} ** 1;
+    var registered_fds = [_]posix.fd_t{0} ** 1;
     const fd_index = 0;
     registered_fds[fd_index] = fd;
     try ring.register_files(registered_fds[0..]);
 
     var buffer = [_]u8{42} ** 128;
-    var iovecs = [_]os.iovec{os.iovec{ .iov_base = &buffer, .iov_len = buffer.len }};
+    var iovecs = [_]posix.iovec{posix.iovec{ .iov_base = &buffer, .iov_len = buffer.len }};
     const sqe = try ring.read(0xcccccccc, fd_index, .{ .iovecs = iovecs[0..] }, 0);
     try testing.expectEqual(linux.IORING_OP.READV, sqe.opcode);
     sqe.flags |= linux.IOSQE_FIXED_FILE;
@@ -1788,7 +1788,7 @@ test "readv" {
 }
 
 test "writev/fsync/readv" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(4, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -1806,12 +1806,12 @@ test "writev/fsync/readv" {
     const fd = file.handle;
 
     const buffer_write = [_]u8{42} ** 128;
-    const iovecs_write = [_]os.iovec_const{
-        os.iovec_const{ .iov_base = &buffer_write, .iov_len = buffer_write.len },
+    const iovecs_write = [_]posix.iovec_const{
+        posix.iovec_const{ .iov_base = &buffer_write, .iov_len = buffer_write.len },
     };
     var buffer_read = [_]u8{0} ** 128;
-    var iovecs_read = [_]os.iovec{
-        os.iovec{ .iov_base = &buffer_read, .iov_len = buffer_read.len },
+    var iovecs_read = [_]posix.iovec{
+        posix.iovec{ .iov_base = &buffer_read, .iov_len = buffer_read.len },
     };
 
     const sqe_writev = try ring.writev(0xdddddddd, fd, iovecs_write[0..], 17);
@@ -1858,7 +1858,7 @@ test "writev/fsync/readv" {
 }
 
 test "write/read" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(2, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -1905,7 +1905,7 @@ test "write/read" {
 }
 
 test "splice/read" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(4, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -1929,7 +1929,7 @@ test "splice/read" {
     var buffer_read = [_]u8{98} ** 20;
     _ = try file_src.write(&buffer_write);
 
-    const fds = try os.pipe();
+    const fds = try posix.pipe();
     const pipe_offset: u64 = std.math.maxInt(u64);
 
     const sqe_splice_to_pipe = try ring.splice(0x11111111, fd_src, 0, fds[1], pipe_offset, buffer_write.len);
@@ -1976,7 +1976,7 @@ test "splice/read" {
 }
 
 test "write_fixed/read_fixed" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(2, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -1998,7 +1998,7 @@ test "write_fixed/read_fixed" {
     @memset(&raw_buffers[0], 'z');
     raw_buffers[0][0.."foobar".len].* = "foobar".*;
 
-    var buffers = [2]os.iovec{
+    var buffers = [2]posix.iovec{
         .{ .iov_base = &raw_buffers[0], .iov_len = raw_buffers[0].len },
         .{ .iov_base = &raw_buffers[1], .iov_len = raw_buffers[1].len },
     };
@@ -2041,7 +2041,7 @@ test "write_fixed/read_fixed" {
 }
 
 test "openat" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(1, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -2063,7 +2063,7 @@ test "openat" {
     } else @intFromPtr(path);
 
     const flags: linux.O = .{ .CLOEXEC = true, .ACCMODE = .RDWR, .CREAT = true };
-    const mode: os.mode_t = 0o666;
+    const mode: posix.mode_t = 0o666;
     const sqe_openat = try ring.openat(0x33333333, tmp.dir.fd, path, flags, mode);
     try testing.expectEqual(linux.io_uring_sqe{
         .opcode = .OPENAT,
@@ -2091,11 +2091,11 @@ test "openat" {
     try testing.expect(cqe_openat.res > 0);
     try testing.expectEqual(@as(u32, 0), cqe_openat.flags);
 
-    os.close(cqe_openat.res);
+    posix.close(cqe_openat.res);
 }
 
 test "close" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(1, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -2126,7 +2126,7 @@ test "close" {
 }
 
 test "accept/connect/send/recv" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(16, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -2167,7 +2167,7 @@ test "accept/connect/send/recv" {
 }
 
 test "sendmsg/recvmsg" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(2, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -2178,24 +2178,24 @@ test "sendmsg/recvmsg" {
 
     var address_server = try net.Address.parseIp4("127.0.0.1", 0);
 
-    const server = try os.socket(address_server.any.family, os.SOCK.DGRAM, 0);
-    defer os.close(server);
-    try os.setsockopt(server, os.SOL.SOCKET, os.SO.REUSEPORT, &mem.toBytes(@as(c_int, 1)));
-    try os.setsockopt(server, os.SOL.SOCKET, os.SO.REUSEADDR, &mem.toBytes(@as(c_int, 1)));
-    try os.bind(server, &address_server.any, address_server.getOsSockLen());
+    const server = try posix.socket(address_server.any.family, posix.SOCK.DGRAM, 0);
+    defer posix.close(server);
+    try posix.setsockopt(server, posix.SOL.SOCKET, posix.SO.REUSEPORT, &mem.toBytes(@as(c_int, 1)));
+    try posix.setsockopt(server, posix.SOL.SOCKET, posix.SO.REUSEADDR, &mem.toBytes(@as(c_int, 1)));
+    try posix.bind(server, &address_server.any, address_server.getOsSockLen());
 
     // set address_server to the OS-chosen IP/port.
-    var slen: os.socklen_t = address_server.getOsSockLen();
-    try os.getsockname(server, &address_server.any, &slen);
+    var slen: posix.socklen_t = address_server.getOsSockLen();
+    try posix.getsockname(server, &address_server.any, &slen);
 
-    const client = try os.socket(address_server.any.family, os.SOCK.DGRAM, 0);
-    defer os.close(client);
+    const client = try posix.socket(address_server.any.family, posix.SOCK.DGRAM, 0);
+    defer posix.close(client);
 
     const buffer_send = [_]u8{42} ** 128;
-    const iovecs_send = [_]os.iovec_const{
-        os.iovec_const{ .iov_base = &buffer_send, .iov_len = buffer_send.len },
+    const iovecs_send = [_]posix.iovec_const{
+        posix.iovec_const{ .iov_base = &buffer_send, .iov_len = buffer_send.len },
     };
-    const msg_send = os.msghdr_const{
+    const msg_send: posix.msghdr_const = .{
         .name = &address_server.any,
         .namelen = address_server.getOsSockLen(),
         .iov = &iovecs_send,
@@ -2210,12 +2210,12 @@ test "sendmsg/recvmsg" {
     try testing.expectEqual(client, sqe_sendmsg.fd);
 
     var buffer_recv = [_]u8{0} ** 128;
-    var iovecs_recv = [_]os.iovec{
-        os.iovec{ .iov_base = &buffer_recv, .iov_len = buffer_recv.len },
+    var iovecs_recv = [_]posix.iovec{
+        posix.iovec{ .iov_base = &buffer_recv, .iov_len = buffer_recv.len },
     };
     const addr = [_]u8{0} ** 4;
     var address_recv = net.Address.initIp4(addr, 0);
-    var msg_recv: os.msghdr = os.msghdr{
+    var msg_recv: posix.msghdr = .{
         .name = &address_recv.any,
         .namelen = address_recv.getOsSockLen(),
         .iov = &iovecs_recv,
@@ -2254,7 +2254,7 @@ test "sendmsg/recvmsg" {
 }
 
 test "timeout (after a relative time)" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(1, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -2265,7 +2265,7 @@ test "timeout (after a relative time)" {
 
     const ms = 10;
     const margin = 5;
-    const ts = os.linux.kernel_timespec{ .tv_sec = 0, .tv_nsec = ms * 1000000 };
+    const ts: linux.kernel_timespec = .{ .tv_sec = 0, .tv_nsec = ms * 1000000 };
 
     const started = std.time.milliTimestamp();
     const sqe = try ring.timeout(0x55555555, &ts, 0, 0);
@@ -2285,7 +2285,7 @@ test "timeout (after a relative time)" {
 }
 
 test "timeout (after a number of completions)" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(2, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -2294,7 +2294,7 @@ test "timeout (after a number of completions)" {
     };
     defer ring.deinit();
 
-    const ts = os.linux.kernel_timespec{ .tv_sec = 3, .tv_nsec = 0 };
+    const ts: linux.kernel_timespec = .{ .tv_sec = 3, .tv_nsec = 0 };
     const count_completions: u64 = 1;
     const sqe_timeout = try ring.timeout(0x66666666, &ts, count_completions, 0);
     try testing.expectEqual(linux.IORING_OP.TIMEOUT, sqe_timeout.opcode);
@@ -2318,7 +2318,7 @@ test "timeout (after a number of completions)" {
 }
 
 test "timeout_remove" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(2, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -2327,7 +2327,7 @@ test "timeout_remove" {
     };
     defer ring.deinit();
 
-    const ts = os.linux.kernel_timespec{ .tv_sec = 3, .tv_nsec = 0 };
+    const ts: linux.kernel_timespec = .{ .tv_sec = 3, .tv_nsec = 0 };
     const sqe_timeout = try ring.timeout(0x88888888, &ts, 0, 0);
     try testing.expectEqual(linux.IORING_OP.TIMEOUT, sqe_timeout.opcode);
     try testing.expectEqual(@as(u64, 0x88888888), sqe_timeout.user_data);
@@ -2343,7 +2343,7 @@ test "timeout_remove" {
     // * kernel 5.10 gives user data 0x88888888 first, 0x99999999 second
     // * kernel 5.18 gives user data 0x99999999 first, 0x88888888 second
 
-    var cqes: [2]os.linux.io_uring_cqe = undefined;
+    var cqes: [2]linux.io_uring_cqe = undefined;
     cqes[0] = try ring.copy_cqe();
     cqes[1] = try ring.copy_cqe();
 
@@ -2378,7 +2378,7 @@ test "timeout_remove" {
 }
 
 test "accept/connect/recv/link_timeout" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(16, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -2395,7 +2395,7 @@ test "accept/connect/recv/link_timeout" {
     const sqe_recv = try ring.recv(0xffffffff, socket_test_harness.server, .{ .buffer = buffer_recv[0..] }, 0);
     sqe_recv.flags |= linux.IOSQE_IO_LINK;
 
-    const ts = os.linux.kernel_timespec{ .tv_sec = 0, .tv_nsec = 1000000 };
+    const ts = linux.kernel_timespec{ .tv_sec = 0, .tv_nsec = 1000000 };
     _ = try ring.link_timeout(0x22222222, &ts, 0);
 
     const nr_wait = try ring.submit();
@@ -2427,7 +2427,7 @@ test "accept/connect/recv/link_timeout" {
 }
 
 test "fallocate" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(1, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -2473,7 +2473,7 @@ test "fallocate" {
 }
 
 test "statx" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(1, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -2525,12 +2525,12 @@ test "statx" {
         .flags = 0,
     }, cqe);
 
-    try testing.expect(buf.mask & os.linux.STATX_SIZE == os.linux.STATX_SIZE);
+    try testing.expect(buf.mask & linux.STATX_SIZE == linux.STATX_SIZE);
     try testing.expectEqual(@as(u64, 6), buf.size);
 }
 
 test "accept/connect/recv/cancel" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(16, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -2580,7 +2580,7 @@ test "accept/connect/recv/cancel" {
 }
 
 test "register_files_update" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(1, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -2589,10 +2589,10 @@ test "register_files_update" {
     };
     defer ring.deinit();
 
-    const fd = try os.openZ("/dev/zero", .{ .ACCMODE = .RDONLY, .CLOEXEC = true }, 0);
-    defer os.close(fd);
+    const fd = try posix.openZ("/dev/zero", .{ .ACCMODE = .RDONLY, .CLOEXEC = true }, 0);
+    defer posix.close(fd);
 
-    var registered_fds = [_]os.fd_t{0} ** 2;
+    var registered_fds = [_]posix.fd_t{0} ** 2;
     const fd_index = 0;
     const fd_index2 = 1;
     registered_fds[fd_index] = fd;
@@ -2607,8 +2607,8 @@ test "register_files_update" {
     // Test IORING_REGISTER_FILES_UPDATE
     // Only available since Linux 5.5
 
-    const fd2 = try os.openZ("/dev/zero", .{ .ACCMODE = .RDONLY, .CLOEXEC = true }, 0);
-    defer os.close(fd2);
+    const fd2 = try posix.openZ("/dev/zero", .{ .ACCMODE = .RDONLY, .CLOEXEC = true }, 0);
+    defer posix.close(fd2);
 
     registered_fds[fd_index] = fd2;
     registered_fds[fd_index2] = -1;
@@ -2660,14 +2660,14 @@ test "register_files_update" {
 
         try testing.expectEqual(@as(u32, 1), try ring.submit());
         const cqe = try ring.copy_cqe();
-        try testing.expectEqual(os.linux.E.BADF, cqe.err());
+        try testing.expectEqual(linux.E.BADF, cqe.err());
     }
 
     try ring.unregister_files();
 }
 
 test "shutdown" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(16, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -2680,17 +2680,17 @@ test "shutdown" {
 
     // Socket bound, expect shutdown to work
     {
-        const server = try os.socket(address.any.family, os.SOCK.STREAM | os.SOCK.CLOEXEC, 0);
-        defer os.close(server);
-        try os.setsockopt(server, os.SOL.SOCKET, os.SO.REUSEADDR, &mem.toBytes(@as(c_int, 1)));
-        try os.bind(server, &address.any, address.getOsSockLen());
-        try os.listen(server, 1);
+        const server = try posix.socket(address.any.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0);
+        defer posix.close(server);
+        try posix.setsockopt(server, posix.SOL.SOCKET, posix.SO.REUSEADDR, &mem.toBytes(@as(c_int, 1)));
+        try posix.bind(server, &address.any, address.getOsSockLen());
+        try posix.listen(server, 1);
 
         // set address to the OS-chosen IP/port.
-        var slen: os.socklen_t = address.getOsSockLen();
-        try os.getsockname(server, &address.any, &slen);
+        var slen: posix.socklen_t = address.getOsSockLen();
+        try posix.getsockname(server, &address.any, &slen);
 
-        const shutdown_sqe = try ring.shutdown(0x445445445, server, os.linux.SHUT.RD);
+        const shutdown_sqe = try ring.shutdown(0x445445445, server, linux.SHUT.RD);
         try testing.expectEqual(linux.IORING_OP.SHUTDOWN, shutdown_sqe.opcode);
         try testing.expectEqual(@as(i32, server), shutdown_sqe.fd);
 
@@ -2713,10 +2713,10 @@ test "shutdown" {
 
     // Socket not bound, expect to fail with ENOTCONN
     {
-        const server = try os.socket(address.any.family, os.SOCK.STREAM | os.SOCK.CLOEXEC, 0);
-        defer os.close(server);
+        const server = try posix.socket(address.any.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0);
+        defer posix.close(server);
 
-        const shutdown_sqe = ring.shutdown(0x445445445, server, os.linux.SHUT.RD) catch |err| switch (err) {
+        const shutdown_sqe = ring.shutdown(0x445445445, server, linux.SHUT.RD) catch |err| switch (err) {
             else => |errno| std.debug.panic("unhandled errno: {}", .{errno}),
         };
         try testing.expectEqual(linux.IORING_OP.SHUTDOWN, shutdown_sqe.opcode);
@@ -2726,12 +2726,12 @@ test "shutdown" {
 
         const cqe = try ring.copy_cqe();
         try testing.expectEqual(@as(u64, 0x445445445), cqe.user_data);
-        try testing.expectEqual(os.linux.E.NOTCONN, cqe.err());
+        try testing.expectEqual(linux.E.NOTCONN, cqe.err());
     }
 }
 
 test "renameat" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(1, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -2800,7 +2800,7 @@ test "renameat" {
 }
 
 test "unlinkat" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(1, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -2852,7 +2852,7 @@ test "unlinkat" {
 }
 
 test "mkdirat" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(1, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -2896,7 +2896,7 @@ test "mkdirat" {
 }
 
 test "symlinkat" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(1, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -2944,7 +2944,7 @@ test "symlinkat" {
 }
 
 test "linkat" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(1, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -3003,7 +3003,7 @@ test "linkat" {
 }
 
 test "provide_buffers: read" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(1, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -3012,8 +3012,8 @@ test "provide_buffers: read" {
     };
     defer ring.deinit();
 
-    const fd = try os.openZ("/dev/zero", .{ .ACCMODE = .RDONLY, .CLOEXEC = true }, 0);
-    defer os.close(fd);
+    const fd = try posix.openZ("/dev/zero", .{ .ACCMODE = .RDONLY, .CLOEXEC = true }, 0);
+    defer posix.close(fd);
 
     const group_id = 1337;
     const buffer_id = 0;
@@ -3135,7 +3135,7 @@ test "provide_buffers: read" {
 }
 
 test "remove_buffers" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(1, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -3144,8 +3144,8 @@ test "remove_buffers" {
     };
     defer ring.deinit();
 
-    const fd = try os.openZ("/dev/zero", .{ .ACCMODE = .RDONLY, .CLOEXEC = true }, 0);
-    defer os.close(fd);
+    const fd = try posix.openZ("/dev/zero", .{ .ACCMODE = .RDONLY, .CLOEXEC = true }, 0);
+    defer posix.close(fd);
 
     const group_id = 1337;
     const buffer_id = 0;
@@ -3224,7 +3224,7 @@ test "remove_buffers" {
 }
 
 test "provide_buffers: accept/connect/send/recv" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(16, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -3391,9 +3391,9 @@ test "provide_buffers: accept/connect/send/recv" {
 
 /// Used for testing server/client interactions.
 const SocketTestHarness = struct {
-    listener: os.socket_t,
-    server: os.socket_t,
-    client: os.socket_t,
+    listener: posix.socket_t,
+    server: posix.socket_t,
+    client: posix.socket_t,
 
     fn close(self: SocketTestHarness) void {
         posix.close(self.client);
@@ -3408,12 +3408,12 @@ fn createSocketTestHarness(ring: *IoUring) !SocketTestHarness {
     errdefer posix.close(listener_socket);
 
     // Submit 1 accept
-    var accept_addr: os.sockaddr = undefined;
-    var accept_addr_len: os.socklen_t = @sizeOf(@TypeOf(accept_addr));
+    var accept_addr: posix.sockaddr = undefined;
+    var accept_addr_len: posix.socklen_t = @sizeOf(@TypeOf(accept_addr));
     _ = try ring.accept(0xaaaaaaaa, listener_socket, &accept_addr, &accept_addr_len, 0);
 
     // Create a TCP client socket
-    const client = try os.socket(address.any.family, os.SOCK.STREAM | os.SOCK.CLOEXEC, 0);
+    const client = try posix.socket(address.any.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0);
     errdefer posix.close(client);
     _ = try ring.connect(0xcccccccc, client, &address.any, address.getOsSockLen());
 
@@ -3451,24 +3451,24 @@ fn createSocketTestHarness(ring: *IoUring) !SocketTestHarness {
     };
 }
 
-fn createListenerSocket(address: *net.Address) !os.socket_t {
+fn createListenerSocket(address: *net.Address) !posix.socket_t {
     const kernel_backlog = 1;
-    const listener_socket = try os.socket(address.any.family, os.SOCK.STREAM | os.SOCK.CLOEXEC, 0);
+    const listener_socket = try posix.socket(address.any.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0);
     errdefer posix.close(listener_socket);
 
-    try os.setsockopt(listener_socket, os.SOL.SOCKET, os.SO.REUSEADDR, &mem.toBytes(@as(c_int, 1)));
-    try os.bind(listener_socket, &address.any, address.getOsSockLen());
-    try os.listen(listener_socket, kernel_backlog);
+    try posix.setsockopt(listener_socket, posix.SOL.SOCKET, posix.SO.REUSEADDR, &mem.toBytes(@as(c_int, 1)));
+    try posix.bind(listener_socket, &address.any, address.getOsSockLen());
+    try posix.listen(listener_socket, kernel_backlog);
 
     // set address to the OS-chosen IP/port.
-    var slen: os.socklen_t = address.getOsSockLen();
-    try os.getsockname(listener_socket, &address.any, &slen);
+    var slen: posix.socklen_t = address.getOsSockLen();
+    try posix.getsockname(listener_socket, &address.any, &slen);
 
     return listener_socket;
 }
 
 test "accept multishot" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(16, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -3482,8 +3482,8 @@ test "accept multishot" {
     defer posix.close(listener_socket);
 
     // submit multishot accept operation
-    var addr: os.sockaddr = undefined;
-    var addr_len: os.socklen_t = @sizeOf(@TypeOf(addr));
+    var addr: posix.sockaddr = undefined;
+    var addr_len: posix.socklen_t = @sizeOf(@TypeOf(addr));
     const userdata: u64 = 0xaaaaaaaa;
     _ = try ring.accept_multishot(userdata, listener_socket, &addr, &addr_len, 0);
     try testing.expectEqual(@as(u32, 1), try ring.submit());
@@ -3491,9 +3491,9 @@ test "accept multishot" {
     var nr: usize = 4; // number of clients to connect
     while (nr > 0) : (nr -= 1) {
         // connect client
-        const client = try os.socket(address.any.family, os.SOCK.STREAM | os.SOCK.CLOEXEC, 0);
+        const client = try posix.socket(address.any.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0);
         errdefer posix.close(client);
-        try os.connect(client, &address.any, address.getOsSockLen());
+        try posix.connect(client, &address.any, address.getOsSockLen());
 
         // test accept completion
         var cqe = try ring.copy_cqe();
@@ -3571,7 +3571,7 @@ test "accept_direct" {
     var address = try net.Address.parseIp4("127.0.0.1", 0);
 
     // register direct file descriptors
-    var registered_fds = [_]os.fd_t{-1} ** 2;
+    var registered_fds = [_]posix.fd_t{-1} ** 2;
     try ring.register_files(registered_fds[0..]);
 
     const listener_socket = try createListenerSocket(&address);
@@ -3591,19 +3591,19 @@ test "accept_direct" {
             try testing.expectEqual(@as(u32, 1), try ring.submit());
 
             // connect
-            const client = try os.socket(address.any.family, os.SOCK.STREAM | os.SOCK.CLOEXEC, 0);
-            try os.connect(client, &address.any, address.getOsSockLen());
+            const client = try posix.socket(address.any.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0);
+            try posix.connect(client, &address.any, address.getOsSockLen());
             defer posix.close(client);
 
             // accept completion
             const cqe_accept = try ring.copy_cqe();
-            try testing.expectEqual(os.E.SUCCESS, cqe_accept.err());
+            try testing.expectEqual(posix.E.SUCCESS, cqe_accept.err());
             const fd_index = cqe_accept.res;
             try testing.expect(fd_index < registered_fds.len);
             try testing.expect(cqe_accept.user_data == accept_userdata);
 
             // send data
-            _ = try os.send(client, buffer_send, 0);
+            _ = try posix.send(client, buffer_send, 0);
 
             // Example of how to use registered fd:
             // Submit receive to fixed file returned by accept (fd_index).
@@ -3625,13 +3625,13 @@ test "accept_direct" {
             _ = try ring.accept_direct(accept_userdata, listener_socket, null, null, 0);
             try testing.expectEqual(@as(u32, 1), try ring.submit());
             // connect
-            const client = try os.socket(address.any.family, os.SOCK.STREAM | os.SOCK.CLOEXEC, 0);
-            try os.connect(client, &address.any, address.getOsSockLen());
+            const client = try posix.socket(address.any.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0);
+            try posix.connect(client, &address.any, address.getOsSockLen());
             defer posix.close(client);
             // completion with error
             const cqe_accept = try ring.copy_cqe();
             try testing.expect(cqe_accept.user_data == accept_userdata);
-            try testing.expectEqual(os.E.NFILE, cqe_accept.err());
+            try testing.expectEqual(posix.E.NFILE, cqe_accept.err());
         }
         // return file descriptors to kernel
         try ring.register_files_update(0, registered_fds[0..]);
@@ -3651,7 +3651,7 @@ test "accept_multishot_direct" {
 
     var address = try net.Address.parseIp4("127.0.0.1", 0);
 
-    var registered_fds = [_]os.fd_t{-1} ** 2;
+    var registered_fds = [_]posix.fd_t{-1} ** 2;
     try ring.register_files(registered_fds[0..]);
 
     const listener_socket = try createListenerSocket(&address);
@@ -3667,8 +3667,8 @@ test "accept_multishot_direct" {
 
         for (registered_fds) |_| {
             // connect
-            const client = try os.socket(address.any.family, os.SOCK.STREAM | os.SOCK.CLOEXEC, 0);
-            try os.connect(client, &address.any, address.getOsSockLen());
+            const client = try posix.socket(address.any.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0);
+            try posix.connect(client, &address.any, address.getOsSockLen());
             defer posix.close(client);
 
             // accept completion
@@ -3682,13 +3682,13 @@ test "accept_multishot_direct" {
         // Multishot is terminated (more flag is not set).
         {
             // connect
-            const client = try os.socket(address.any.family, os.SOCK.STREAM | os.SOCK.CLOEXEC, 0);
-            try os.connect(client, &address.any, address.getOsSockLen());
+            const client = try posix.socket(address.any.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0);
+            try posix.connect(client, &address.any, address.getOsSockLen());
             defer posix.close(client);
             // completion with error
             const cqe_accept = try ring.copy_cqe();
             try testing.expect(cqe_accept.user_data == accept_userdata);
-            try testing.expectEqual(os.E.NFILE, cqe_accept.err());
+            try testing.expectEqual(posix.E.NFILE, cqe_accept.err());
             try testing.expect(cqe_accept.flags & linux.IORING_CQE_F_MORE == 0); // has more is not set
         }
         // return file descriptors to kernel
@@ -3708,16 +3708,16 @@ test "socket" {
     defer ring.deinit();
 
     // prepare, submit socket operation
-    _ = try ring.socket(0, linux.AF.INET, os.SOCK.STREAM, 0, 0);
+    _ = try ring.socket(0, linux.AF.INET, posix.SOCK.STREAM, 0, 0);
     try testing.expectEqual(@as(u32, 1), try ring.submit());
 
     // test completion
     var cqe = try ring.copy_cqe();
-    try testing.expectEqual(os.E.SUCCESS, cqe.err());
-    const fd: os.fd_t = @intCast(cqe.res);
+    try testing.expectEqual(posix.E.SUCCESS, cqe.err());
+    const fd: posix.fd_t = @intCast(cqe.res);
     try testing.expect(fd > 2);
 
-    os.close(fd);
+    posix.close(fd);
 }
 
 test "socket_direct/socket_direct_alloc/close_direct" {
@@ -3730,29 +3730,29 @@ test "socket_direct/socket_direct_alloc/close_direct" {
     };
     defer ring.deinit();
 
-    var registered_fds = [_]os.fd_t{-1} ** 3;
+    var registered_fds = [_]posix.fd_t{-1} ** 3;
     try ring.register_files(registered_fds[0..]);
 
     // create socket in registered file descriptor at index 0 (last param)
-    _ = try ring.socket_direct(0, linux.AF.INET, os.SOCK.STREAM, 0, 0, 0);
+    _ = try ring.socket_direct(0, linux.AF.INET, posix.SOCK.STREAM, 0, 0, 0);
     try testing.expectEqual(@as(u32, 1), try ring.submit());
     var cqe_socket = try ring.copy_cqe();
-    try testing.expectEqual(os.E.SUCCESS, cqe_socket.err());
+    try testing.expectEqual(posix.E.SUCCESS, cqe_socket.err());
     try testing.expect(cqe_socket.res == 0);
 
     // create socket in registered file descriptor at index 1 (last param)
-    _ = try ring.socket_direct(0, linux.AF.INET, os.SOCK.STREAM, 0, 0, 1);
+    _ = try ring.socket_direct(0, linux.AF.INET, posix.SOCK.STREAM, 0, 0, 1);
     try testing.expectEqual(@as(u32, 1), try ring.submit());
     cqe_socket = try ring.copy_cqe();
-    try testing.expectEqual(os.E.SUCCESS, cqe_socket.err());
+    try testing.expectEqual(posix.E.SUCCESS, cqe_socket.err());
     try testing.expect(cqe_socket.res == 0); // res is 0 when index is specified
 
     // create socket in kernel chosen file descriptor index (_alloc version)
     // completion res has index from registered files
-    _ = try ring.socket_direct_alloc(0, linux.AF.INET, os.SOCK.STREAM, 0, 0);
+    _ = try ring.socket_direct_alloc(0, linux.AF.INET, posix.SOCK.STREAM, 0, 0);
     try testing.expectEqual(@as(u32, 1), try ring.submit());
     cqe_socket = try ring.copy_cqe();
-    try testing.expectEqual(os.E.SUCCESS, cqe_socket.err());
+    try testing.expectEqual(posix.E.SUCCESS, cqe_socket.err());
     try testing.expect(cqe_socket.res == 2); // returns registered file index
 
     // use sockets from registered_fds in connect operation
@@ -3782,17 +3782,17 @@ test "socket_direct/socket_direct_alloc/close_direct" {
         }
         // test connect completion
         try testing.expect(cqe_connect.user_data == connect_userdata);
-        try testing.expectEqual(os.E.SUCCESS, cqe_connect.err());
+        try testing.expectEqual(posix.E.SUCCESS, cqe_connect.err());
         // test accept completion
         try testing.expect(cqe_accept.user_data == accept_userdata);
-        try testing.expectEqual(os.E.SUCCESS, cqe_accept.err());
+        try testing.expectEqual(posix.E.SUCCESS, cqe_accept.err());
 
         //  submit and test close_direct
         _ = try ring.close_direct(close_userdata, @intCast(fd_index));
         try testing.expectEqual(@as(u32, 1), try ring.submit());
         var cqe_close = try ring.copy_cqe();
         try testing.expect(cqe_close.user_data == close_userdata);
-        try testing.expectEqual(os.E.SUCCESS, cqe_close.err());
+        try testing.expectEqual(posix.E.SUCCESS, cqe_close.err());
     }
 
     try ring.unregister_files();
@@ -3808,35 +3808,35 @@ test "openat_direct/close_direct" {
     };
     defer ring.deinit();
 
-    var registered_fds = [_]os.fd_t{-1} ** 3;
+    var registered_fds = [_]posix.fd_t{-1} ** 3;
     try ring.register_files(registered_fds[0..]);
 
     var tmp = std.testing.tmpDir(.{});
     defer tmp.cleanup();
     const path = "test_io_uring_close_direct";
     const flags: linux.O = .{ .ACCMODE = .RDWR, .CREAT = true };
-    const mode: os.mode_t = 0o666;
+    const mode: posix.mode_t = 0o666;
     const user_data: u64 = 0;
 
     // use registered file at index 0 (last param)
     _ = try ring.openat_direct(user_data, tmp.dir.fd, path, flags, mode, 0);
     try testing.expectEqual(@as(u32, 1), try ring.submit());
     var cqe = try ring.copy_cqe();
-    try testing.expectEqual(os.E.SUCCESS, cqe.err());
+    try testing.expectEqual(posix.E.SUCCESS, cqe.err());
     try testing.expect(cqe.res == 0);
 
     // use registered file at index 1
     _ = try ring.openat_direct(user_data, tmp.dir.fd, path, flags, mode, 1);
     try testing.expectEqual(@as(u32, 1), try ring.submit());
     cqe = try ring.copy_cqe();
-    try testing.expectEqual(os.E.SUCCESS, cqe.err());
+    try testing.expectEqual(posix.E.SUCCESS, cqe.err());
     try testing.expect(cqe.res == 0); // res is 0 when we specify index
 
     // let kernel choose registered file index
     _ = try ring.openat_direct(user_data, tmp.dir.fd, path, flags, mode, linux.IORING_FILE_INDEX_ALLOC);
     try testing.expectEqual(@as(u32, 1), try ring.submit());
     cqe = try ring.copy_cqe();
-    try testing.expectEqual(os.E.SUCCESS, cqe.err());
+    try testing.expectEqual(posix.E.SUCCESS, cqe.err());
     try testing.expect(cqe.res == 2); // chosen index is in res
 
     // close all open file descriptors
@@ -3844,7 +3844,7 @@ test "openat_direct/close_direct" {
         _ = try ring.close_direct(user_data, @intCast(fd_index));
         try testing.expectEqual(@as(u32, 1), try ring.submit());
         var cqe_close = try ring.copy_cqe();
-        try testing.expectEqual(os.E.SUCCESS, cqe_close.err());
+        try testing.expectEqual(posix.E.SUCCESS, cqe_close.err());
     }
     try ring.unregister_files();
 }
@@ -3859,13 +3859,13 @@ test "waitid" {
     };
     defer ring.deinit();
 
-    const pid = try os.fork();
+    const pid = try posix.fork();
     if (pid == 0) {
-        os.exit(7);
+        posix.exit(7);
     }
 
-    var siginfo: os.siginfo_t = undefined;
-    _ = try ring.waitid(0, .PID, pid, &siginfo, os.W.EXITED, 0);
+    var siginfo: posix.siginfo_t = undefined;
+    _ = try ring.waitid(0, .PID, pid, &siginfo, posix.W.EXITED, 0);
 
     try testing.expectEqual(1, try ring.submit());
 
@@ -3877,13 +3877,13 @@ test "waitid" {
 
 /// For use in tests. Returns SkipZigTest if kernel version is less than required.
 inline fn skipKernelLessThan(required: std.SemanticVersion) !void {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var uts: linux.utsname = undefined;
     const res = linux.uname(&uts);
-    switch (linux.getErrno(res)) {
+    switch (linux.E.init(res)) {
         .SUCCESS => {},
-        else => |errno| return os.unexpectedErrno(errno),
+        else => |errno| return posix.unexpectedErrno(errno),
     }
 
     const release = mem.sliceTo(&uts.release, 0);
@@ -3893,7 +3893,7 @@ inline fn skipKernelLessThan(required: std.SemanticVersion) !void {
 }
 
 test BufferGroup {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     // Init IoUring
     var ring = IoUring.init(16, 0) catch |err| switch (err) {
@@ -3948,7 +3948,7 @@ test BufferGroup {
         const cqe = try ring.copy_cqe();
         try testing.expectEqual(2, cqe.user_data); // matches submitted user_data
         try testing.expect(cqe.res >= 0); // success
-        try testing.expectEqual(os.E.SUCCESS, cqe.err());
+        try testing.expectEqual(posix.E.SUCCESS, cqe.err());
         try testing.expectEqual(data.len, @as(usize, @intCast(cqe.res))); // cqe.res holds received data len
 
         // Read buffer_id and used buffer len from cqe
@@ -3963,7 +3963,7 @@ test BufferGroup {
 }
 
 test "ring mapped buffers recv" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(16, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -4029,7 +4029,7 @@ test "ring mapped buffers recv" {
             const cqe = try ring.copy_cqe();
             try testing.expectEqual(user_data, cqe.user_data);
             try testing.expect(cqe.res < 0); // fail
-            try testing.expectEqual(os.E.NOBUFS, cqe.err());
+            try testing.expectEqual(posix.E.NOBUFS, cqe.err());
             try testing.expect(cqe.flags & linux.IORING_CQE_F_BUFFER == 0); // IORING_CQE_F_BUFFER flags is set on success only
             try testing.expectError(error.NoBufferSelected, cqe.buffer_id());
         }
@@ -4049,7 +4049,7 @@ test "ring mapped buffers recv" {
 }
 
 test "ring mapped buffers multishot recv" {
-    if (builtin.os.tag != .linux) return error.SkipZigTest;
+    if (!is_linux) return error.SkipZigTest;
 
     var ring = IoUring.init(16, 0) catch |err| switch (err) {
         error.SystemOutdated => return error.SkipZigTest,
@@ -4120,7 +4120,7 @@ test "ring mapped buffers multishot recv" {
             const cqe = try ring.copy_cqe();
             try testing.expectEqual(recv_user_data, cqe.user_data);
             try testing.expect(cqe.res < 0); // fail
-            try testing.expectEqual(os.E.NOBUFS, cqe.err());
+            try testing.expectEqual(posix.E.NOBUFS, cqe.err());
             try testing.expect(cqe.flags & linux.IORING_CQE_F_BUFFER == 0); // IORING_CQE_F_BUFFER flags is set on success only
             // has more is not set
             // indicates that multishot is finished
@@ -4194,7 +4194,7 @@ test "ring mapped buffers multishot recv" {
 fn expect_buf_grp_recv(
     ring: *IoUring,
     buf_grp: *BufferGroup,
-    fd: os.fd_t,
+    fd: posix.fd_t,
     user_data: u64,
     expected: []const u8,
 ) !u16 {
@@ -4220,7 +4220,7 @@ fn expect_buf_grp_cqe(
     try testing.expect(cqe.res >= 0); // success
     try testing.expect(cqe.flags & linux.IORING_CQE_F_BUFFER == linux.IORING_CQE_F_BUFFER); // IORING_CQE_F_BUFFER flag is set
     try testing.expectEqual(expected.len, @as(usize, @intCast(cqe.res)));
-    try testing.expectEqual(os.E.SUCCESS, cqe.err());
+    try testing.expectEqual(posix.E.SUCCESS, cqe.err());
 
     // get buffer from pool
     const buffer_id = try cqe.buffer_id();
lib/std/os/linux/mips.zig
@@ -3,8 +3,8 @@ const maxInt = std.math.maxInt;
 const linux = std.os.linux;
 const SYS = linux.SYS;
 const socklen_t = linux.socklen_t;
-const iovec = std.os.iovec;
-const iovec_const = std.os.iovec_const;
+const iovec = std.posix.iovec;
+const iovec_const = std.posix.iovec_const;
 const uid_t = linux.uid_t;
 const gid_t = linux.gid_t;
 const pid_t = linux.pid_t;
lib/std/os/linux/mips64.zig
@@ -3,8 +3,8 @@ const maxInt = std.math.maxInt;
 const linux = std.os.linux;
 const SYS = linux.SYS;
 const socklen_t = linux.socklen_t;
-const iovec = std.os.iovec;
-const iovec_const = std.os.iovec_const;
+const iovec = std.posix.iovec;
+const iovec_const = std.posix.iovec_const;
 const uid_t = linux.uid_t;
 const gid_t = linux.gid_t;
 const pid_t = linux.pid_t;
lib/std/os/linux/powerpc.zig
@@ -3,8 +3,8 @@ const maxInt = std.math.maxInt;
 const linux = std.os.linux;
 const SYS = linux.SYS;
 const socklen_t = linux.socklen_t;
-const iovec = std.os.iovec;
-const iovec_const = std.os.iovec_const;
+const iovec = std.posix.iovec;
+const iovec_const = std.posix.iovec_const;
 const uid_t = linux.uid_t;
 const gid_t = linux.gid_t;
 const pid_t = linux.pid_t;
lib/std/os/linux/powerpc64.zig
@@ -3,8 +3,8 @@ const maxInt = std.math.maxInt;
 const linux = std.os.linux;
 const SYS = linux.SYS;
 const socklen_t = linux.socklen_t;
-const iovec = std.os.iovec;
-const iovec_const = std.os.iovec_const;
+const iovec = std.posix.iovec;
+const iovec_const = std.posix.iovec_const;
 const uid_t = linux.uid_t;
 const gid_t = linux.gid_t;
 const pid_t = linux.pid_t;
lib/std/os/linux/riscv64.zig
@@ -1,6 +1,6 @@
 const std = @import("../../std.zig");
-const iovec = std.os.iovec;
-const iovec_const = std.os.iovec_const;
+const iovec = std.posix.iovec;
+const iovec_const = std.posix.iovec_const;
 const linux = std.os.linux;
 const SYS = linux.SYS;
 const uid_t = std.os.linux.uid_t;
lib/std/os/linux/sparc64.zig
@@ -10,8 +10,8 @@ const linux = std.os.linux;
 const SYS = linux.SYS;
 const sockaddr = linux.sockaddr;
 const socklen_t = linux.socklen_t;
-const iovec = std.os.iovec;
-const iovec_const = std.os.iovec_const;
+const iovec = std.posix.iovec;
+const iovec_const = std.posix.iovec_const;
 const timespec = linux.timespec;
 
 pub fn syscall_pipe(fd: *[2]i32) usize {
lib/std/os/linux/test.zig
@@ -18,7 +18,7 @@ test "fallocate" {
     try expect((try file.stat()).size == 0);
 
     const len: i64 = 65536;
-    switch (linux.getErrno(linux.fallocate(file.handle, 0, 0, len))) {
+    switch (linux.E.init(linux.fallocate(file.handle, 0, 0, len))) {
         .SUCCESS => {},
         .NOSYS => return error.SkipZigTest,
         .OPNOTSUPP => return error.SkipZigTest,
@@ -34,11 +34,11 @@ test "getpid" {
 
 test "timer" {
     const epoll_fd = linux.epoll_create();
-    var err: linux.E = linux.getErrno(epoll_fd);
+    var err: linux.E = linux.E.init(epoll_fd);
     try expect(err == .SUCCESS);
 
     const timer_fd = linux.timerfd_create(linux.CLOCK.MONOTONIC, .{});
-    try expect(linux.getErrno(timer_fd) == .SUCCESS);
+    try expect(linux.E.init(timer_fd) == .SUCCESS);
 
     const time_interval = linux.timespec{
         .tv_sec = 0,
@@ -50,7 +50,7 @@ test "timer" {
         .it_value = time_interval,
     };
 
-    err = linux.getErrno(linux.timerfd_settime(@as(i32, @intCast(timer_fd)), .{}, &new_time, null));
+    err = linux.E.init(linux.timerfd_settime(@as(i32, @intCast(timer_fd)), .{}, &new_time, null));
     try expect(err == .SUCCESS);
 
     var event = linux.epoll_event{
@@ -58,13 +58,13 @@ test "timer" {
         .data = linux.epoll_data{ .ptr = 0 },
     };
 
-    err = linux.getErrno(linux.epoll_ctl(@as(i32, @intCast(epoll_fd)), linux.EPOLL.CTL_ADD, @as(i32, @intCast(timer_fd)), &event));
+    err = linux.E.init(linux.epoll_ctl(@as(i32, @intCast(epoll_fd)), linux.EPOLL.CTL_ADD, @as(i32, @intCast(timer_fd)), &event));
     try expect(err == .SUCCESS);
 
     const events_one: linux.epoll_event = undefined;
     var events = [_]linux.epoll_event{events_one} ** 8;
 
-    err = linux.getErrno(linux.epoll_wait(@as(i32, @intCast(epoll_fd)), &events, 8, -1));
+    err = linux.E.init(linux.epoll_wait(@as(i32, @intCast(epoll_fd)), &events, 8, -1));
     try expect(err == .SUCCESS);
 }
 
@@ -77,7 +77,7 @@ test "statx" {
     defer file.close();
 
     var statx_buf: linux.Statx = undefined;
-    switch (linux.getErrno(linux.statx(file.handle, "", linux.AT.EMPTY_PATH, linux.STATX_BASIC_STATS, &statx_buf))) {
+    switch (linux.E.init(linux.statx(file.handle, "", linux.AT.EMPTY_PATH, linux.STATX_BASIC_STATS, &statx_buf))) {
         .SUCCESS => {},
         // The statx syscall was only introduced in linux 4.11
         .NOSYS => return error.SkipZigTest,
@@ -85,7 +85,7 @@ test "statx" {
     }
 
     var stat_buf: linux.Stat = undefined;
-    switch (linux.getErrno(linux.fstatat(file.handle, "", &stat_buf, linux.AT.EMPTY_PATH))) {
+    switch (linux.E.init(linux.fstatat(file.handle, "", &stat_buf, linux.AT.EMPTY_PATH))) {
         .SUCCESS => {},
         else => unreachable,
     }
lib/std/os/linux/tls.zig
@@ -1,10 +1,11 @@
 const std = @import("std");
-const os = std.os;
 const mem = std.mem;
 const elf = std.elf;
 const math = std.math;
 const assert = std.debug.assert;
 const native_arch = @import("builtin").cpu.arch;
+const linux = std.os.linux;
+const posix = std.posix;
 
 // This file implements the two TLS variants [1] used by ELF-based systems.
 //
@@ -111,7 +112,7 @@ pub var tls_image: TLSImage = undefined;
 pub fn setThreadPointer(addr: usize) void {
     switch (native_arch) {
         .x86 => {
-            var user_desc = std.os.linux.user_desc{
+            var user_desc: linux.user_desc = .{
                 .entry_number = tls_image.gdt_entry_number,
                 .base_addr = addr,
                 .limit = 0xfffff,
@@ -124,7 +125,7 @@ pub fn setThreadPointer(addr: usize) void {
                     .useable = 1,
                 },
             };
-            const rc = std.os.linux.syscall1(.set_thread_area, @intFromPtr(&user_desc));
+            const rc = linux.syscall1(.set_thread_area, @intFromPtr(&user_desc));
             assert(rc == 0);
 
             const gdt_entry_number = user_desc.entry_number;
@@ -137,7 +138,7 @@ pub fn setThreadPointer(addr: usize) void {
             );
         },
         .x86_64 => {
-            const rc = std.os.linux.syscall2(.arch_prctl, std.os.linux.ARCH.SET_FS, addr);
+            const rc = linux.syscall2(.arch_prctl, linux.ARCH.SET_FS, addr);
             assert(rc == 0);
         },
         .aarch64, .aarch64_be => {
@@ -148,7 +149,7 @@ pub fn setThreadPointer(addr: usize) void {
             );
         },
         .arm, .thumb => {
-            const rc = std.os.linux.syscall1(.set_tls, addr);
+            const rc = linux.syscall1(.set_tls, addr);
             assert(rc == 0);
         },
         .riscv64 => {
@@ -159,7 +160,7 @@ pub fn setThreadPointer(addr: usize) void {
             );
         },
         .mips, .mipsel, .mips64, .mips64el => {
-            const rc = std.os.linux.syscall1(.set_thread_area, addr);
+            const rc = linux.syscall1(.set_thread_area, addr);
             assert(rc == 0);
         },
         .powerpc, .powerpcle => {
@@ -320,14 +321,14 @@ pub fn initStaticTLS(phdrs: []elf.Phdr) void {
             break :blk main_thread_tls_buffer[0..tls_image.alloc_size];
         }
 
-        const alloc_tls_area = os.mmap(
+        const alloc_tls_area = posix.mmap(
             null,
             tls_image.alloc_size + tls_image.alloc_align - 1,
-            os.PROT.READ | os.PROT.WRITE,
+            posix.PROT.READ | posix.PROT.WRITE,
             .{ .TYPE = .PRIVATE, .ANONYMOUS = true },
             -1,
             0,
-        ) catch os.abort();
+        ) catch posix.abort();
 
         // Make sure the slice is correctly aligned.
         const begin_addr = @intFromPtr(alloc_tls_area.ptr);
lib/std/os/linux/vdso.zig
@@ -5,7 +5,7 @@ const mem = std.mem;
 const maxInt = std.math.maxInt;
 
 pub fn lookup(vername: []const u8, name: []const u8) usize {
-    const vdso_addr = std.os.system.getauxval(std.elf.AT_SYSINFO_EHDR);
+    const vdso_addr = linux.getauxval(std.elf.AT_SYSINFO_EHDR);
     if (vdso_addr == 0) return 0;
 
     const eh = @as(*elf.Ehdr, @ptrFromInt(vdso_addr));
lib/std/os/linux/x86.zig
@@ -3,8 +3,8 @@ const maxInt = std.math.maxInt;
 const linux = std.os.linux;
 const SYS = linux.SYS;
 const socklen_t = linux.socklen_t;
-const iovec = std.os.iovec;
-const iovec_const = std.os.iovec_const;
+const iovec = std.posix.iovec;
+const iovec_const = std.posix.iovec_const;
 const uid_t = linux.uid_t;
 const gid_t = linux.gid_t;
 const pid_t = linux.pid_t;
lib/std/os/linux/x86_64.zig
@@ -2,8 +2,8 @@ const std = @import("../../std.zig");
 const maxInt = std.math.maxInt;
 const linux = std.os.linux;
 const SYS = linux.SYS;
-const iovec = std.os.iovec;
-const iovec_const = std.os.iovec_const;
+const iovec = std.posix.iovec;
+const iovec_const = std.posix.iovec_const;
 
 const pid_t = linux.pid_t;
 const uid_t = linux.uid_t;
lib/std/os/plan9/errno.zig
@@ -1,84 +0,0 @@
-//! Ported from /sys/include/ape/errno.h
-pub const E = enum(u16) {
-    SUCCESS = 0,
-    DOM = 1000,
-    RANGE = 1001,
-    PLAN9 = 1002,
-
-    @"2BIG" = 1,
-    ACCES = 2,
-    AGAIN = 3,
-    // WOULDBLOCK = 3, // TODO errno.h has 2 names for 3
-    BADF = 4,
-    BUSY = 5,
-    CHILD = 6,
-    DEADLK = 7,
-    EXIST = 8,
-    FAULT = 9,
-    FBIG = 10,
-    INTR = 11,
-    INVAL = 12,
-    IO = 13,
-    ISDIR = 14,
-    MFILE = 15,
-    MLINK = 16,
-    NAMETOOLONG = 17,
-    NFILE = 18,
-    NODEV = 19,
-    NOENT = 20,
-    NOEXEC = 21,
-    NOLCK = 22,
-    NOMEM = 23,
-    NOSPC = 24,
-    NOSYS = 25,
-    NOTDIR = 26,
-    NOTEMPTY = 27,
-    NOTTY = 28,
-    NXIO = 29,
-    PERM = 30,
-    PIPE = 31,
-    ROFS = 32,
-    SPIPE = 33,
-    SRCH = 34,
-    XDEV = 35,
-
-    // bsd networking software
-    NOTSOCK = 36,
-    PROTONOSUPPORT = 37,
-    // PROTOTYPE = 37, // TODO errno.h has two names for 37
-    CONNREFUSED = 38,
-    AFNOSUPPORT = 39,
-    NOBUFS = 40,
-    OPNOTSUPP = 41,
-    ADDRINUSE = 42,
-    DESTADDRREQ = 43,
-    MSGSIZE = 44,
-    NOPROTOOPT = 45,
-    SOCKTNOSUPPORT = 46,
-    PFNOSUPPORT = 47,
-    ADDRNOTAVAIL = 48,
-    NETDOWN = 49,
-    NETUNREACH = 50,
-    NETRESET = 51,
-    CONNABORTED = 52,
-    ISCONN = 53,
-    NOTCONN = 54,
-    SHUTDOWN = 55,
-    TOOMANYREFS = 56,
-    TIMEDOUT = 57,
-    HOSTDOWN = 58,
-    HOSTUNREACH = 59,
-    GREG = 60,
-
-    // These added in 1003.1b-1993
-    CANCELED = 61,
-    INPROGRESS = 62,
-
-    // We just add these to be compatible with std.os, which uses them,
-    // They should never get used.
-    DQUOT,
-    CONNRESET,
-    OVERFLOW,
-    LOOP,
-    TXTBSY,
-};
lib/std/os/windows/test.zig
@@ -245,7 +245,7 @@ test "loadWinsockExtensionFunction" {
     const LPFN_CONNECTEX = *const fn (
         Socket: windows.ws2_32.SOCKET,
         SockAddr: *const windows.ws2_32.sockaddr,
-        SockLen: std.os.socklen_t,
+        SockLen: std.posix.socklen_t,
         SendBuf: ?*const anyopaque,
         SendBufLen: windows.DWORD,
         BytesSent: *windows.DWORD,
@@ -254,7 +254,7 @@ test "loadWinsockExtensionFunction" {
 
     _ = windows.loadWinsockExtensionFunction(
         LPFN_CONNECTEX,
-        try std.os.socket(std.os.AF.INET, std.os.SOCK.DGRAM, 0),
+        try std.posix.socket(std.posix.AF.INET, std.posix.SOCK.DGRAM, 0),
         windows.ws2_32.WSAID_CONNECTEX,
     ) catch |err| switch (err) {
         error.OperationNotSupported => unreachable,
lib/std/os/emscripten.zig
@@ -1,8 +1,8 @@
 const std = @import("std");
 const builtin = @import("builtin");
 const wasi = std.os.wasi;
-const iovec = std.os.iovec;
-const iovec_const = std.os.iovec_const;
+const iovec = std.posix.iovec;
+const iovec_const = std.posix.iovec_const;
 const c = std.c;
 
 pub const FILE = c.FILE;
lib/std/os/linux.zig
@@ -18,9 +18,9 @@ const is_mips = native_arch.isMIPS();
 const is_ppc = native_arch.isPPC();
 const is_ppc64 = native_arch.isPPC64();
 const is_sparc = native_arch.isSPARC();
-const iovec = std.os.iovec;
-const iovec_const = std.os.iovec_const;
-const ACCMODE = std.os.ACCMODE;
+const iovec = std.posix.iovec;
+const iovec_const = std.posix.iovec_const;
+const ACCMODE = std.posix.ACCMODE;
 
 test {
     if (builtin.os.tag == .linux) {
@@ -451,10 +451,11 @@ fn splitValue64(val: i64) [2]u32 {
 }
 
 /// Get the errno from a syscall return value, or 0 for no error.
-pub fn getErrno(r: usize) E {
-    const signed_r = @as(isize, @bitCast(r));
+/// The public API is exposed via the `E` namespace.
+fn errnoFromSyscall(r: usize) E {
+    const signed_r: isize = @bitCast(r);
     const int = if (signed_r > -4096 and signed_r < 0) -signed_r else 0;
-    return @as(E, @enumFromInt(int));
+    return @enumFromInt(int);
 }
 
 pub fn dup(old: i32) usize {
@@ -1561,7 +1562,7 @@ pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigact
         .sparc, .sparc64 => syscall5(.rt_sigaction, sig, ksa_arg, oldksa_arg, @intFromPtr(ksa.restorer), mask_size),
         else => syscall4(.rt_sigaction, sig, ksa_arg, oldksa_arg, mask_size),
     };
-    if (getErrno(result) != .SUCCESS) return result;
+    if (E.init(result) != .SUCCESS) return result;
 
     if (oact) |old| {
         old.handler.handler = oldksa.handler;
@@ -1648,12 +1649,12 @@ pub fn sendmmsg(fd: i32, msgvec: [*]mmsghdr_const, vlen: u32, flags: u32) usize
                     if (next_unsent < i) {
                         const batch_size = i - next_unsent;
                         const r = syscall4(.sendmmsg, @as(usize, @bitCast(@as(isize, fd))), @intFromPtr(&msgvec[next_unsent]), batch_size, flags);
-                        if (getErrno(r) != 0) return next_unsent;
+                        if (E.init(r) != 0) return next_unsent;
                         if (r < batch_size) return next_unsent + r;
                     }
                     // send current message as own packet
                     const r = sendmsg(fd, &msg.msg_hdr, flags);
-                    if (getErrno(r) != 0) return r;
+                    if (E.init(r) != 0) return r;
                     // Linux limits the total bytes sent by sendmsg to INT_MAX, so this cast is safe.
                     msg.msg_len = @as(u32, @intCast(r));
                     next_unsent = i + 1;
@@ -1665,7 +1666,7 @@ pub fn sendmmsg(fd: i32, msgvec: [*]mmsghdr_const, vlen: u32, flags: u32) usize
         if (next_unsent < kvlen or next_unsent == 0) { // want to make sure at least one syscall occurs (e.g. to trigger MSG.EOR)
             const batch_size = kvlen - next_unsent;
             const r = syscall4(.sendmmsg, @as(usize, @bitCast(@as(isize, fd))), @intFromPtr(&msgvec[next_unsent]), batch_size, flags);
-            if (getErrno(r) != 0) return r;
+            if (E.init(r) != 0) return r;
             return next_unsent + r;
         }
         return kvlen;
@@ -2263,13 +2264,609 @@ pub fn map_shadow_stack(addr: u64, size: u64, flags: u32) usize {
 }
 
 pub const E = switch (native_arch) {
-    .mips, .mipsel => @import("linux/errno/mips.zig").E,
-    .sparc, .sparcel, .sparc64 => @import("linux/errno/sparc.zig").E,
-    else => @import("linux/errno/generic.zig").E,
+    .mips, .mipsel => enum(i32) {
+        /// No error occurred.
+        SUCCESS = 0,
+
+        PERM = 1,
+        NOENT = 2,
+        SRCH = 3,
+        INTR = 4,
+        IO = 5,
+        NXIO = 6,
+        @"2BIG" = 7,
+        NOEXEC = 8,
+        BADF = 9,
+        CHILD = 10,
+        /// Also used for WOULDBLOCK.
+        AGAIN = 11,
+        NOMEM = 12,
+        ACCES = 13,
+        FAULT = 14,
+        NOTBLK = 15,
+        BUSY = 16,
+        EXIST = 17,
+        XDEV = 18,
+        NODEV = 19,
+        NOTDIR = 20,
+        ISDIR = 21,
+        INVAL = 22,
+        NFILE = 23,
+        MFILE = 24,
+        NOTTY = 25,
+        TXTBSY = 26,
+        FBIG = 27,
+        NOSPC = 28,
+        SPIPE = 29,
+        ROFS = 30,
+        MLINK = 31,
+        PIPE = 32,
+        DOM = 33,
+        RANGE = 34,
+
+        NOMSG = 35,
+        IDRM = 36,
+        CHRNG = 37,
+        L2NSYNC = 38,
+        L3HLT = 39,
+        L3RST = 40,
+        LNRNG = 41,
+        UNATCH = 42,
+        NOCSI = 43,
+        L2HLT = 44,
+        DEADLK = 45,
+        NOLCK = 46,
+        BADE = 50,
+        BADR = 51,
+        XFULL = 52,
+        NOANO = 53,
+        BADRQC = 54,
+        BADSLT = 55,
+        DEADLOCK = 56,
+        BFONT = 59,
+        NOSTR = 60,
+        NODATA = 61,
+        TIME = 62,
+        NOSR = 63,
+        NONET = 64,
+        NOPKG = 65,
+        REMOTE = 66,
+        NOLINK = 67,
+        ADV = 68,
+        SRMNT = 69,
+        COMM = 70,
+        PROTO = 71,
+        DOTDOT = 73,
+        MULTIHOP = 74,
+        BADMSG = 77,
+        NAMETOOLONG = 78,
+        OVERFLOW = 79,
+        NOTUNIQ = 80,
+        BADFD = 81,
+        REMCHG = 82,
+        LIBACC = 83,
+        LIBBAD = 84,
+        LIBSCN = 85,
+        LIBMAX = 86,
+        LIBEXEC = 87,
+        ILSEQ = 88,
+        NOSYS = 89,
+        LOOP = 90,
+        RESTART = 91,
+        STRPIPE = 92,
+        NOTEMPTY = 93,
+        USERS = 94,
+        NOTSOCK = 95,
+        DESTADDRREQ = 96,
+        MSGSIZE = 97,
+        PROTOTYPE = 98,
+        NOPROTOOPT = 99,
+        PROTONOSUPPORT = 120,
+        SOCKTNOSUPPORT = 121,
+        OPNOTSUPP = 122,
+        PFNOSUPPORT = 123,
+        AFNOSUPPORT = 124,
+        ADDRINUSE = 125,
+        ADDRNOTAVAIL = 126,
+        NETDOWN = 127,
+        NETUNREACH = 128,
+        NETRESET = 129,
+        CONNABORTED = 130,
+        CONNRESET = 131,
+        NOBUFS = 132,
+        ISCONN = 133,
+        NOTCONN = 134,
+        UCLEAN = 135,
+        NOTNAM = 137,
+        NAVAIL = 138,
+        ISNAM = 139,
+        REMOTEIO = 140,
+        SHUTDOWN = 143,
+        TOOMANYREFS = 144,
+        TIMEDOUT = 145,
+        CONNREFUSED = 146,
+        HOSTDOWN = 147,
+        HOSTUNREACH = 148,
+        ALREADY = 149,
+        INPROGRESS = 150,
+        STALE = 151,
+        CANCELED = 158,
+        NOMEDIUM = 159,
+        MEDIUMTYPE = 160,
+        NOKEY = 161,
+        KEYEXPIRED = 162,
+        KEYREVOKED = 163,
+        KEYREJECTED = 164,
+        OWNERDEAD = 165,
+        NOTRECOVERABLE = 166,
+        RFKILL = 167,
+        HWPOISON = 168,
+        DQUOT = 1133,
+        _,
+
+        pub const init = errnoFromSyscall;
+    },
+    .sparc, .sparcel, .sparc64 => enum(i32) {
+        /// No error occurred.
+        SUCCESS = 0,
+
+        PERM = 1,
+        NOENT = 2,
+        SRCH = 3,
+        INTR = 4,
+        IO = 5,
+        NXIO = 6,
+        @"2BIG" = 7,
+        NOEXEC = 8,
+        BADF = 9,
+        CHILD = 10,
+        /// Also used for WOULDBLOCK
+        AGAIN = 11,
+        NOMEM = 12,
+        ACCES = 13,
+        FAULT = 14,
+        NOTBLK = 15,
+        BUSY = 16,
+        EXIST = 17,
+        XDEV = 18,
+        NODEV = 19,
+        NOTDIR = 20,
+        ISDIR = 21,
+        INVAL = 22,
+        NFILE = 23,
+        MFILE = 24,
+        NOTTY = 25,
+        TXTBSY = 26,
+        FBIG = 27,
+        NOSPC = 28,
+        SPIPE = 29,
+        ROFS = 30,
+        MLINK = 31,
+        PIPE = 32,
+        DOM = 33,
+        RANGE = 34,
+
+        INPROGRESS = 36,
+        ALREADY = 37,
+        NOTSOCK = 38,
+        DESTADDRREQ = 39,
+        MSGSIZE = 40,
+        PROTOTYPE = 41,
+        NOPROTOOPT = 42,
+        PROTONOSUPPORT = 43,
+        SOCKTNOSUPPORT = 44,
+        /// Also used for NOTSUP
+        OPNOTSUPP = 45,
+        PFNOSUPPORT = 46,
+        AFNOSUPPORT = 47,
+        ADDRINUSE = 48,
+        ADDRNOTAVAIL = 49,
+        NETDOWN = 50,
+        NETUNREACH = 51,
+        NETRESET = 52,
+        CONNABORTED = 53,
+        CONNRESET = 54,
+        NOBUFS = 55,
+        ISCONN = 56,
+        NOTCONN = 57,
+        SHUTDOWN = 58,
+        TOOMANYREFS = 59,
+        TIMEDOUT = 60,
+        CONNREFUSED = 61,
+        LOOP = 62,
+        NAMETOOLONG = 63,
+        HOSTDOWN = 64,
+        HOSTUNREACH = 65,
+        NOTEMPTY = 66,
+        PROCLIM = 67,
+        USERS = 68,
+        DQUOT = 69,
+        STALE = 70,
+        REMOTE = 71,
+        NOSTR = 72,
+        TIME = 73,
+        NOSR = 74,
+        NOMSG = 75,
+        BADMSG = 76,
+        IDRM = 77,
+        DEADLK = 78,
+        NOLCK = 79,
+        NONET = 80,
+        RREMOTE = 81,
+        NOLINK = 82,
+        ADV = 83,
+        SRMNT = 84,
+        COMM = 85,
+        PROTO = 86,
+        MULTIHOP = 87,
+        DOTDOT = 88,
+        REMCHG = 89,
+        NOSYS = 90,
+        STRPIPE = 91,
+        OVERFLOW = 92,
+        BADFD = 93,
+        CHRNG = 94,
+        L2NSYNC = 95,
+        L3HLT = 96,
+        L3RST = 97,
+        LNRNG = 98,
+        UNATCH = 99,
+        NOCSI = 100,
+        L2HLT = 101,
+        BADE = 102,
+        BADR = 103,
+        XFULL = 104,
+        NOANO = 105,
+        BADRQC = 106,
+        BADSLT = 107,
+        DEADLOCK = 108,
+        BFONT = 109,
+        LIBEXEC = 110,
+        NODATA = 111,
+        LIBBAD = 112,
+        NOPKG = 113,
+        LIBACC = 114,
+        NOTUNIQ = 115,
+        RESTART = 116,
+        UCLEAN = 117,
+        NOTNAM = 118,
+        NAVAIL = 119,
+        ISNAM = 120,
+        REMOTEIO = 121,
+        ILSEQ = 122,
+        LIBMAX = 123,
+        LIBSCN = 124,
+        NOMEDIUM = 125,
+        MEDIUMTYPE = 126,
+        CANCELED = 127,
+        NOKEY = 128,
+        KEYEXPIRED = 129,
+        KEYREVOKED = 130,
+        KEYREJECTED = 131,
+        OWNERDEAD = 132,
+        NOTRECOVERABLE = 133,
+        RFKILL = 134,
+        HWPOISON = 135,
+        _,
+
+        pub const init = errnoFromSyscall;
+    },
+    else => enum(u16) {
+        /// No error occurred.
+        /// Same code used for `NSROK`.
+        SUCCESS = 0,
+        /// Operation not permitted
+        PERM = 1,
+        /// No such file or directory
+        NOENT = 2,
+        /// No such process
+        SRCH = 3,
+        /// Interrupted system call
+        INTR = 4,
+        /// I/O error
+        IO = 5,
+        /// No such device or address
+        NXIO = 6,
+        /// Arg list too long
+        @"2BIG" = 7,
+        /// Exec format error
+        NOEXEC = 8,
+        /// Bad file number
+        BADF = 9,
+        /// No child processes
+        CHILD = 10,
+        /// Try again
+        /// Also means: WOULDBLOCK: operation would block
+        AGAIN = 11,
+        /// Out of memory
+        NOMEM = 12,
+        /// Permission denied
+        ACCES = 13,
+        /// Bad address
+        FAULT = 14,
+        /// Block device required
+        NOTBLK = 15,
+        /// Device or resource busy
+        BUSY = 16,
+        /// File exists
+        EXIST = 17,
+        /// Cross-device link
+        XDEV = 18,
+        /// No such device
+        NODEV = 19,
+        /// Not a directory
+        NOTDIR = 20,
+        /// Is a directory
+        ISDIR = 21,
+        /// Invalid argument
+        INVAL = 22,
+        /// File table overflow
+        NFILE = 23,
+        /// Too many open files
+        MFILE = 24,
+        /// Not a typewriter
+        NOTTY = 25,
+        /// Text file busy
+        TXTBSY = 26,
+        /// File too large
+        FBIG = 27,
+        /// No space left on device
+        NOSPC = 28,
+        /// Illegal seek
+        SPIPE = 29,
+        /// Read-only file system
+        ROFS = 30,
+        /// Too many links
+        MLINK = 31,
+        /// Broken pipe
+        PIPE = 32,
+        /// Math argument out of domain of func
+        DOM = 33,
+        /// Math result not representable
+        RANGE = 34,
+        /// Resource deadlock would occur
+        DEADLK = 35,
+        /// File name too long
+        NAMETOOLONG = 36,
+        /// No record locks available
+        NOLCK = 37,
+        /// Function not implemented
+        NOSYS = 38,
+        /// Directory not empty
+        NOTEMPTY = 39,
+        /// Too many symbolic links encountered
+        LOOP = 40,
+        /// No message of desired type
+        NOMSG = 42,
+        /// Identifier removed
+        IDRM = 43,
+        /// Channel number out of range
+        CHRNG = 44,
+        /// Level 2 not synchronized
+        L2NSYNC = 45,
+        /// Level 3 halted
+        L3HLT = 46,
+        /// Level 3 reset
+        L3RST = 47,
+        /// Link number out of range
+        LNRNG = 48,
+        /// Protocol driver not attached
+        UNATCH = 49,
+        /// No CSI structure available
+        NOCSI = 50,
+        /// Level 2 halted
+        L2HLT = 51,
+        /// Invalid exchange
+        BADE = 52,
+        /// Invalid request descriptor
+        BADR = 53,
+        /// Exchange full
+        XFULL = 54,
+        /// No anode
+        NOANO = 55,
+        /// Invalid request code
+        BADRQC = 56,
+        /// Invalid slot
+        BADSLT = 57,
+        /// Bad font file format
+        BFONT = 59,
+        /// Device not a stream
+        NOSTR = 60,
+        /// No data available
+        NODATA = 61,
+        /// Timer expired
+        TIME = 62,
+        /// Out of streams resources
+        NOSR = 63,
+        /// Machine is not on the network
+        NONET = 64,
+        /// Package not installed
+        NOPKG = 65,
+        /// Object is remote
+        REMOTE = 66,
+        /// Link has been severed
+        NOLINK = 67,
+        /// Advertise error
+        ADV = 68,
+        /// Srmount error
+        SRMNT = 69,
+        /// Communication error on send
+        COMM = 70,
+        /// Protocol error
+        PROTO = 71,
+        /// Multihop attempted
+        MULTIHOP = 72,
+        /// RFS specific error
+        DOTDOT = 73,
+        /// Not a data message
+        BADMSG = 74,
+        /// Value too large for defined data type
+        OVERFLOW = 75,
+        /// Name not unique on network
+        NOTUNIQ = 76,
+        /// File descriptor in bad state
+        BADFD = 77,
+        /// Remote address changed
+        REMCHG = 78,
+        /// Can not access a needed shared library
+        LIBACC = 79,
+        /// Accessing a corrupted shared library
+        LIBBAD = 80,
+        /// .lib section in a.out corrupted
+        LIBSCN = 81,
+        /// Attempting to link in too many shared libraries
+        LIBMAX = 82,
+        /// Cannot exec a shared library directly
+        LIBEXEC = 83,
+        /// Illegal byte sequence
+        ILSEQ = 84,
+        /// Interrupted system call should be restarted
+        RESTART = 85,
+        /// Streams pipe error
+        STRPIPE = 86,
+        /// Too many users
+        USERS = 87,
+        /// Socket operation on non-socket
+        NOTSOCK = 88,
+        /// Destination address required
+        DESTADDRREQ = 89,
+        /// Message too long
+        MSGSIZE = 90,
+        /// Protocol wrong type for socket
+        PROTOTYPE = 91,
+        /// Protocol not available
+        NOPROTOOPT = 92,
+        /// Protocol not supported
+        PROTONOSUPPORT = 93,
+        /// Socket type not supported
+        SOCKTNOSUPPORT = 94,
+        /// Operation not supported on transport endpoint
+        /// This code also means `NOTSUP`.
+        OPNOTSUPP = 95,
+        /// Protocol family not supported
+        PFNOSUPPORT = 96,
+        /// Address family not supported by protocol
+        AFNOSUPPORT = 97,
+        /// Address already in use
+        ADDRINUSE = 98,
+        /// Cannot assign requested address
+        ADDRNOTAVAIL = 99,
+        /// Network is down
+        NETDOWN = 100,
+        /// Network is unreachable
+        NETUNREACH = 101,
+        /// Network dropped connection because of reset
+        NETRESET = 102,
+        /// Software caused connection abort
+        CONNABORTED = 103,
+        /// Connection reset by peer
+        CONNRESET = 104,
+        /// No buffer space available
+        NOBUFS = 105,
+        /// Transport endpoint is already connected
+        ISCONN = 106,
+        /// Transport endpoint is not connected
+        NOTCONN = 107,
+        /// Cannot send after transport endpoint shutdown
+        SHUTDOWN = 108,
+        /// Too many references: cannot splice
+        TOOMANYREFS = 109,
+        /// Connection timed out
+        TIMEDOUT = 110,
+        /// Connection refused
+        CONNREFUSED = 111,
+        /// Host is down
+        HOSTDOWN = 112,
+        /// No route to host
+        HOSTUNREACH = 113,
+        /// Operation already in progress
+        ALREADY = 114,
+        /// Operation now in progress
+        INPROGRESS = 115,
+        /// Stale NFS file handle
+        STALE = 116,
+        /// Structure needs cleaning
+        UCLEAN = 117,
+        /// Not a XENIX named type file
+        NOTNAM = 118,
+        /// No XENIX semaphores available
+        NAVAIL = 119,
+        /// Is a named type file
+        ISNAM = 120,
+        /// Remote I/O error
+        REMOTEIO = 121,
+        /// Quota exceeded
+        DQUOT = 122,
+        /// No medium found
+        NOMEDIUM = 123,
+        /// Wrong medium type
+        MEDIUMTYPE = 124,
+        /// Operation canceled
+        CANCELED = 125,
+        /// Required key not available
+        NOKEY = 126,
+        /// Key has expired
+        KEYEXPIRED = 127,
+        /// Key has been revoked
+        KEYREVOKED = 128,
+        /// Key was rejected by service
+        KEYREJECTED = 129,
+        // for robust mutexes
+        /// Owner died
+        OWNERDEAD = 130,
+        /// State not recoverable
+        NOTRECOVERABLE = 131,
+        /// Operation not possible due to RF-kill
+        RFKILL = 132,
+        /// Memory page has hardware error
+        HWPOISON = 133,
+        // nameserver query return codes
+        /// DNS server returned answer with no data
+        NSRNODATA = 160,
+        /// DNS server claims query was misformatted
+        NSRFORMERR = 161,
+        /// DNS server returned general failure
+        NSRSERVFAIL = 162,
+        /// Domain name not found
+        NSRNOTFOUND = 163,
+        /// DNS server does not implement requested operation
+        NSRNOTIMP = 164,
+        /// DNS server refused query
+        NSRREFUSED = 165,
+        /// Misformatted DNS query
+        NSRBADQUERY = 166,
+        /// Misformatted domain name
+        NSRBADNAME = 167,
+        /// Unsupported address family
+        NSRBADFAMILY = 168,
+        /// Misformatted DNS reply
+        NSRBADRESP = 169,
+        /// Could not contact DNS servers
+        NSRCONNREFUSED = 170,
+        /// Timeout while contacting DNS servers
+        NSRTIMEOUT = 171,
+        /// End of file
+        NSROF = 172,
+        /// Error reading file
+        NSRFILE = 173,
+        /// Out of memory
+        NSRNOMEM = 174,
+        /// Application terminated lookup
+        NSRDESTRUCTION = 175,
+        /// Domain name is too long
+        NSRQUERYDOMAINTOOLONG = 176,
+        /// Domain name is too long
+        NSRCNAMELOOP = 177,
+
+        _,
+
+        pub const init = errnoFromSyscall;
+    },
 };
 
 pub const pid_t = i32;
 pub const fd_t = i32;
+pub const socket_t = i32;
 pub const uid_t = u32;
 pub const gid_t = u32;
 pub const clock_t = isize;
lib/std/os/plan9.zig
@@ -11,13 +11,96 @@ pub const syscall_bits = switch (builtin.cpu.arch) {
     .x86_64 => @import("plan9/x86_64.zig"),
     else => @compileError("more plan9 syscall implementations (needs more inline asm in stage2"),
 };
-pub const E = @import("plan9/errno.zig").E;
-/// Get the errno from a syscall return value, or 0 for no error.
-pub fn getErrno(r: usize) E {
-    const signed_r = @as(isize, @bitCast(r));
-    const int = if (signed_r > -4096 and signed_r < 0) -signed_r else 0;
-    return @as(E, @enumFromInt(int));
-}
+/// Ported from /sys/include/ape/errno.h
+pub const E = enum(u16) {
+    SUCCESS = 0,
+    DOM = 1000,
+    RANGE = 1001,
+    PLAN9 = 1002,
+
+    @"2BIG" = 1,
+    ACCES = 2,
+    AGAIN = 3,
+    // WOULDBLOCK = 3, // TODO errno.h has 2 names for 3
+    BADF = 4,
+    BUSY = 5,
+    CHILD = 6,
+    DEADLK = 7,
+    EXIST = 8,
+    FAULT = 9,
+    FBIG = 10,
+    INTR = 11,
+    INVAL = 12,
+    IO = 13,
+    ISDIR = 14,
+    MFILE = 15,
+    MLINK = 16,
+    NAMETOOLONG = 17,
+    NFILE = 18,
+    NODEV = 19,
+    NOENT = 20,
+    NOEXEC = 21,
+    NOLCK = 22,
+    NOMEM = 23,
+    NOSPC = 24,
+    NOSYS = 25,
+    NOTDIR = 26,
+    NOTEMPTY = 27,
+    NOTTY = 28,
+    NXIO = 29,
+    PERM = 30,
+    PIPE = 31,
+    ROFS = 32,
+    SPIPE = 33,
+    SRCH = 34,
+    XDEV = 35,
+
+    // bsd networking software
+    NOTSOCK = 36,
+    PROTONOSUPPORT = 37,
+    // PROTOTYPE = 37, // TODO errno.h has two names for 37
+    CONNREFUSED = 38,
+    AFNOSUPPORT = 39,
+    NOBUFS = 40,
+    OPNOTSUPP = 41,
+    ADDRINUSE = 42,
+    DESTADDRREQ = 43,
+    MSGSIZE = 44,
+    NOPROTOOPT = 45,
+    SOCKTNOSUPPORT = 46,
+    PFNOSUPPORT = 47,
+    ADDRNOTAVAIL = 48,
+    NETDOWN = 49,
+    NETUNREACH = 50,
+    NETRESET = 51,
+    CONNABORTED = 52,
+    ISCONN = 53,
+    NOTCONN = 54,
+    SHUTDOWN = 55,
+    TOOMANYREFS = 56,
+    TIMEDOUT = 57,
+    HOSTDOWN = 58,
+    HOSTUNREACH = 59,
+    GREG = 60,
+
+    // These added in 1003.1b-1993
+    CANCELED = 61,
+    INPROGRESS = 62,
+
+    // We just add these to be compatible with std.os, which uses them,
+    // They should never get used.
+    DQUOT,
+    CONNRESET,
+    OVERFLOW,
+    LOOP,
+    TXTBSY,
+
+    pub fn init(r: usize) E {
+        const signed_r: isize = @bitCast(r);
+        const int = if (signed_r > -4096 and signed_r < 0) -signed_r else 0;
+        return @enumFromInt(int);
+    }
+};
 // The max bytes that can be in the errstr buff
 pub const ERRMAX = 128;
 var errstr_buf: [ERRMAX]u8 = undefined;
lib/std/os/wasi.zig
@@ -17,8 +17,8 @@ comptime {
     // assert(@alignOf(u64) == 8);
 }
 
-pub const iovec_t = std.os.iovec;
-pub const ciovec_t = std.os.iovec_const;
+pub const iovec_t = std.posix.iovec;
+pub const ciovec_t = std.posix.iovec_const;
 
 pub extern "wasi_snapshot_preview1" fn args_get(argv: [*][*:0]u8, argv_buf: [*]u8) errno_t;
 pub extern "wasi_snapshot_preview1" fn args_sizes_get(argc: *usize, argv_buf_size: *usize) errno_t;
lib/std/os/windows.zig
@@ -11,6 +11,7 @@ const assert = std.debug.assert;
 const math = std.math;
 const maxInt = std.math.maxInt;
 const native_arch = builtin.cpu.arch;
+const UnexpectedError = std.posix.UnexpectedError;
 
 test {
     if (builtin.os.tag == .windows) {
@@ -547,7 +548,7 @@ pub const GetQueuedCompletionStatusError = error{
     Cancelled,
     EOF,
     Timeout,
-} || std.os.UnexpectedError;
+} || UnexpectedError;
 
 pub fn GetQueuedCompletionStatusEx(
     completion_port: HANDLE,
@@ -1701,7 +1702,7 @@ pub fn VirtualProtectEx(handle: HANDLE, addr: ?LPVOID, size: SIZE_T, new_prot: D
         .SUCCESS => return old_prot,
         .INVALID_ADDRESS => return error.InvalidAddress,
         // TODO: map errors
-        else => |rc| return std.os.windows.unexpectedStatus(rc),
+        else => |rc| return unexpectedStatus(rc),
     }
 }
 
@@ -1946,7 +1947,7 @@ pub fn SetFileTime(
 pub const LockFileError = error{
     SystemResources,
     WouldBlock,
-} || std.os.UnexpectedError;
+} || UnexpectedError;
 
 pub fn LockFile(
     FileHandle: HANDLE,
@@ -1983,7 +1984,7 @@ pub fn LockFile(
 
 pub const UnlockFileError = error{
     RangeNotLocked,
-} || std.os.UnexpectedError;
+} || UnexpectedError;
 
 pub fn UnlockFile(
     FileHandle: HANDLE,
@@ -2672,8 +2673,8 @@ pub fn loadWinsockExtensionFunction(comptime T: type, sock: ws2_32.SOCKET, guid:
 
 /// Call this when you made a windows DLL call or something that does SetLastError
 /// and you get an unexpected error.
-pub fn unexpectedError(err: Win32Error) std.os.UnexpectedError {
-    if (std.os.unexpected_error_tracing) {
+pub fn unexpectedError(err: Win32Error) UnexpectedError {
+    if (std.posix.unexpected_error_tracing) {
         // 614 is the length of the longest windows error description
         var buf_wstr: [614]WCHAR = undefined;
         const len = kernel32.FormatMessageW(
@@ -2694,14 +2695,14 @@ pub fn unexpectedError(err: Win32Error) std.os.UnexpectedError {
     return error.Unexpected;
 }
 
-pub fn unexpectedWSAError(err: ws2_32.WinsockError) std.os.UnexpectedError {
+pub fn unexpectedWSAError(err: ws2_32.WinsockError) UnexpectedError {
     return unexpectedError(@as(Win32Error, @enumFromInt(@intFromEnum(err))));
 }
 
 /// Call this when you made a windows NtDll call
 /// and you get an unexpected status.
-pub fn unexpectedStatus(status: NTSTATUS) std.os.UnexpectedError {
-    if (std.os.unexpected_error_tracing) {
+pub fn unexpectedStatus(status: NTSTATUS) UnexpectedError {
+    if (std.posix.unexpected_error_tracing) {
         std.debug.print("error.Unexpected NTSTATUS=0x{x}\n", .{@intFromEnum(status)});
         std.debug.dumpCurrentStackTrace(@returnAddress());
     }
@@ -4246,7 +4247,7 @@ pub const KNONVOLATILE_CONTEXT_POINTERS = switch (native_arch) {
 
 pub const EXCEPTION_POINTERS = extern struct {
     ExceptionRecord: *EXCEPTION_RECORD,
-    ContextRecord: *std.os.windows.CONTEXT,
+    ContextRecord: *CONTEXT,
 };
 
 pub const VECTORED_EXCEPTION_HANDLER = *const fn (ExceptionInfo: *EXCEPTION_POINTERS) callconv(WINAPI) c_long;
lib/std/os/test.zig โ†’ lib/std/posix/test.zig
@@ -1,5 +1,5 @@
 const std = @import("../std.zig");
-const os = std.os;
+const posix = std.posix;
 const testing = std.testing;
 const expect = testing.expect;
 const expectEqual = testing.expectEqual;
@@ -10,6 +10,7 @@ const mem = std.mem;
 const elf = std.elf;
 const File = std.fs.File;
 const Thread = std.Thread;
+const linux = std.os.linux;
 
 const a = std.testing.allocator;
 
@@ -31,26 +32,26 @@ test "chdir smoke test" {
 
     // Get current working directory path
     var old_cwd_buf: [fs.MAX_PATH_BYTES]u8 = undefined;
-    const old_cwd = try os.getcwd(old_cwd_buf[0..]);
+    const old_cwd = try posix.getcwd(old_cwd_buf[0..]);
 
     {
         // Firstly, changing to itself should have no effect
-        try os.chdir(old_cwd);
+        try posix.chdir(old_cwd);
         var new_cwd_buf: [fs.MAX_PATH_BYTES]u8 = undefined;
-        const new_cwd = try os.getcwd(new_cwd_buf[0..]);
+        const new_cwd = try posix.getcwd(new_cwd_buf[0..]);
         try expect(mem.eql(u8, old_cwd, new_cwd));
     }
 
     // Next, change current working directory to one level above
     if (native_os != .wasi) { // WASI does not support navigating outside of Preopens
         const parent = fs.path.dirname(old_cwd) orelse unreachable; // old_cwd should be absolute
-        try os.chdir(parent);
+        try posix.chdir(parent);
 
         // Restore cwd because process may have other tests that do not tolerate chdir.
-        defer os.chdir(old_cwd) catch unreachable;
+        defer posix.chdir(old_cwd) catch unreachable;
 
         var new_cwd_buf: [fs.MAX_PATH_BYTES]u8 = undefined;
-        const new_cwd = try os.getcwd(new_cwd_buf[0..]);
+        const new_cwd = try posix.getcwd(new_cwd_buf[0..]);
         try expect(mem.eql(u8, parent, new_cwd));
     }
 
@@ -65,10 +66,10 @@ test "chdir smoke test" {
         var tmp_dir = try fs.cwd().makeOpenPath("zig-test-tmp", .{});
 
         // Change current working directory to tmp directory
-        try os.chdir("zig-test-tmp");
+        try posix.chdir("zig-test-tmp");
 
         var new_cwd_buf: [fs.MAX_PATH_BYTES]u8 = undefined;
-        const new_cwd = try os.getcwd(new_cwd_buf[0..]);
+        const new_cwd = try posix.getcwd(new_cwd_buf[0..]);
 
         // On Windows, fs.path.resolve returns an uppercase drive letter, but the drive letter returned by getcwd may be lowercase
         var resolved_cwd_buf: [fs.MAX_PATH_BYTES]u8 = undefined;
@@ -80,7 +81,7 @@ test "chdir smoke test" {
 
         // Restore cwd because process may have other tests that do not tolerate chdir.
         tmp_dir.close();
-        os.chdir(old_cwd) catch unreachable;
+        posix.chdir(old_cwd) catch unreachable;
         try fs.cwd().deleteDir("zig-test-tmp");
     }
 }
@@ -105,39 +106,39 @@ test "open smoke test" {
     };
 
     var file_path: []u8 = undefined;
-    var fd: os.fd_t = undefined;
-    const mode: os.mode_t = if (native_os == .windows) 0 else 0o666;
+    var fd: posix.fd_t = undefined;
+    const mode: posix.mode_t = if (native_os == .windows) 0 else 0o666;
 
     // Create some file using `open`.
     file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
-    fd = try os.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode);
-    os.close(fd);
+    fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode);
+    posix.close(fd);
 
     // Try this again with the same flags. This op should fail with error.PathAlreadyExists.
     file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
-    try expectError(error.PathAlreadyExists, os.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode));
+    try expectError(error.PathAlreadyExists, posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode));
 
     // Try opening without `EXCL` flag.
     file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
-    fd = try os.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true }, mode);
-    os.close(fd);
+    fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true }, mode);
+    posix.close(fd);
 
     // Try opening as a directory which should fail.
     file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
-    try expectError(error.NotDir, os.open(file_path, .{ .ACCMODE = .RDWR, .DIRECTORY = true }, mode));
+    try expectError(error.NotDir, posix.open(file_path, .{ .ACCMODE = .RDWR, .DIRECTORY = true }, mode));
 
     // Create some directory
     file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });
-    try os.mkdir(file_path, mode);
+    try posix.mkdir(file_path, mode);
 
     // Open dir using `open`
     file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });
-    fd = try os.open(file_path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, mode);
-    os.close(fd);
+    fd = try posix.open(file_path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, mode);
+    posix.close(fd);
 
     // Try opening as file which should fail.
     file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });
-    try expectError(error.IsDir, os.open(file_path, .{ .ACCMODE = .RDWR }, mode));
+    try expectError(error.IsDir, posix.open(file_path, .{ .ACCMODE = .RDWR }, mode));
 }
 
 test "openat smoke test" {
@@ -149,49 +150,49 @@ test "openat smoke test" {
     var tmp = tmpDir(.{});
     defer tmp.cleanup();
 
-    var fd: os.fd_t = undefined;
-    const mode: os.mode_t = if (native_os == .windows) 0 else 0o666;
+    var fd: posix.fd_t = undefined;
+    const mode: posix.mode_t = if (native_os == .windows) 0 else 0o666;
 
     // Create some file using `openat`.
-    fd = try os.openat(tmp.dir.fd, "some_file", os.CommonOpenFlags.lower(.{
+    fd = try posix.openat(tmp.dir.fd, "some_file", CommonOpenFlags.lower(.{
         .ACCMODE = .RDWR,
         .CREAT = true,
         .EXCL = true,
     }), mode);
-    os.close(fd);
+    posix.close(fd);
 
     // Try this again with the same flags. This op should fail with error.PathAlreadyExists.
-    try expectError(error.PathAlreadyExists, os.openat(tmp.dir.fd, "some_file", os.CommonOpenFlags.lower(.{
+    try expectError(error.PathAlreadyExists, posix.openat(tmp.dir.fd, "some_file", CommonOpenFlags.lower(.{
         .ACCMODE = .RDWR,
         .CREAT = true,
         .EXCL = true,
     }), mode));
 
     // Try opening without `EXCL` flag.
-    fd = try os.openat(tmp.dir.fd, "some_file", os.CommonOpenFlags.lower(.{
+    fd = try posix.openat(tmp.dir.fd, "some_file", CommonOpenFlags.lower(.{
         .ACCMODE = .RDWR,
         .CREAT = true,
     }), mode);
-    os.close(fd);
+    posix.close(fd);
 
     // Try opening as a directory which should fail.
-    try expectError(error.NotDir, os.openat(tmp.dir.fd, "some_file", os.CommonOpenFlags.lower(.{
+    try expectError(error.NotDir, posix.openat(tmp.dir.fd, "some_file", CommonOpenFlags.lower(.{
         .ACCMODE = .RDWR,
         .DIRECTORY = true,
     }), mode));
 
     // Create some directory
-    try os.mkdirat(tmp.dir.fd, "some_dir", mode);
+    try posix.mkdirat(tmp.dir.fd, "some_dir", mode);
 
     // Open dir using `open`
-    fd = try os.openat(tmp.dir.fd, "some_dir", os.CommonOpenFlags.lower(.{
+    fd = try posix.openat(tmp.dir.fd, "some_dir", CommonOpenFlags.lower(.{
         .ACCMODE = .RDONLY,
         .DIRECTORY = true,
     }), mode);
-    os.close(fd);
+    posix.close(fd);
 
     // Try opening as file which should fail.
-    try expectError(error.IsDir, os.openat(tmp.dir.fd, "some_dir", os.CommonOpenFlags.lower(.{
+    try expectError(error.IsDir, posix.openat(tmp.dir.fd, "some_dir", CommonOpenFlags.lower(.{
         .ACCMODE = .RDWR,
     }), mode));
 }
@@ -211,7 +212,7 @@ test "symlink with relative paths" {
     try cwd.writeFile("file.txt", "nonsense");
 
     if (native_os == .windows) {
-        os.windows.CreateSymbolicLink(
+        std.os.windows.CreateSymbolicLink(
             cwd.fd,
             &[_]u16{ 's', 'y', 'm', 'l', 'i', 'n', 'k', 'e', 'd' },
             &[_:0]u16{ 'f', 'i', 'l', 'e', '.', 't', 'x', 't' },
@@ -226,11 +227,11 @@ test "symlink with relative paths" {
             else => return err,
         };
     } else {
-        try os.symlink("file.txt", "symlinked");
+        try posix.symlink("file.txt", "symlinked");
     }
 
     var buffer: [fs.MAX_PATH_BYTES]u8 = undefined;
-    const given = try os.readlink("symlinked", buffer[0..]);
+    const given = try posix.readlink("symlinked", buffer[0..]);
     try expect(mem.eql(u8, "file.txt", given));
 
     try cwd.deleteFile("file.txt");
@@ -247,7 +248,7 @@ test "readlink on Windows" {
 
 fn testReadlink(target_path: []const u8, symlink_path: []const u8) !void {
     var buffer: [fs.MAX_PATH_BYTES]u8 = undefined;
-    const given = try os.readlink(symlink_path, buffer[0..]);
+    const given = try posix.readlink(symlink_path, buffer[0..]);
     try expect(mem.eql(u8, target_path, given));
 }
 
@@ -268,7 +269,7 @@ test "link with relative paths" {
     cwd.deleteFile("new.txt") catch {};
 
     try cwd.writeFile("example.txt", "example");
-    try os.link("example.txt", "new.txt", 0);
+    try posix.link("example.txt", "new.txt", 0);
 
     const efd = try cwd.openFile("example.txt", .{});
     defer efd.close();
@@ -277,17 +278,17 @@ test "link with relative paths" {
     defer nfd.close();
 
     {
-        const estat = try os.fstat(efd.handle);
-        const nstat = try os.fstat(nfd.handle);
+        const estat = try posix.fstat(efd.handle);
+        const nstat = try posix.fstat(nfd.handle);
 
         try testing.expectEqual(estat.ino, nstat.ino);
         try testing.expectEqual(@as(@TypeOf(nstat.nlink), 2), nstat.nlink);
     }
 
-    try os.unlink("new.txt");
+    try posix.unlink("new.txt");
 
     {
-        const estat = try os.fstat(efd.handle);
+        const estat = try posix.fstat(efd.handle);
         try testing.expectEqual(@as(@TypeOf(estat.nlink), 1), estat.nlink);
     }
 
@@ -312,7 +313,7 @@ test "linkat with different directories" {
     tmp.dir.deleteFile("new.txt") catch {};
 
     try cwd.writeFile("example.txt", "example");
-    try os.linkat(cwd.fd, "example.txt", tmp.dir.fd, "new.txt", 0);
+    try posix.linkat(cwd.fd, "example.txt", tmp.dir.fd, "new.txt", 0);
 
     const efd = try cwd.openFile("example.txt", .{});
     defer efd.close();
@@ -321,17 +322,17 @@ test "linkat with different directories" {
 
     {
         defer nfd.close();
-        const estat = try os.fstat(efd.handle);
-        const nstat = try os.fstat(nfd.handle);
+        const estat = try posix.fstat(efd.handle);
+        const nstat = try posix.fstat(nfd.handle);
 
         try testing.expectEqual(estat.ino, nstat.ino);
         try testing.expectEqual(@as(@TypeOf(nstat.nlink), 2), nstat.nlink);
     }
 
-    try os.unlinkat(tmp.dir.fd, "new.txt", 0);
+    try posix.unlinkat(tmp.dir.fd, "new.txt", 0);
 
     {
-        const estat = try os.fstat(efd.handle);
+        const estat = try posix.fstat(efd.handle);
         try testing.expectEqual(@as(@TypeOf(estat.nlink), 1), estat.nlink);
     }
 
@@ -351,12 +352,12 @@ test "fstatat" {
 
     // fetch file's info on the opened fd directly
     const file = try tmp.dir.openFile("file.txt", .{});
-    const stat = try os.fstat(file.handle);
+    const stat = try posix.fstat(file.handle);
     defer file.close();
 
     // now repeat but using `fstatat` instead
-    const flags = if (native_os == .wasi) 0x0 else os.AT.SYMLINK_NOFOLLOW;
-    const statat = try os.fstatat(tmp.dir.fd, "file.txt", flags);
+    const flags = if (native_os == .wasi) 0x0 else posix.AT.SYMLINK_NOFOLLOW;
+    const statat = try posix.fstatat(tmp.dir.fd, "file.txt", flags);
     try expectEqual(stat, statat);
 }
 
@@ -369,7 +370,7 @@ test "readlinkat" {
 
     // create a symbolic link
     if (native_os == .windows) {
-        os.windows.CreateSymbolicLink(
+        std.os.windows.CreateSymbolicLink(
             tmp.dir.fd,
             &[_]u16{ 'l', 'i', 'n', 'k' },
             &[_:0]u16{ 'f', 'i', 'l', 'e', '.', 't', 'x', 't' },
@@ -380,12 +381,12 @@ test "readlinkat" {
             else => return err,
         };
     } else {
-        try os.symlinkat("file.txt", tmp.dir.fd, "link");
+        try posix.symlinkat("file.txt", tmp.dir.fd, "link");
     }
 
     // read the link
     var buffer: [fs.MAX_PATH_BYTES]u8 = undefined;
-    const read_link = try os.readlinkat(tmp.dir.fd, "link", buffer[0..]);
+    const read_link = try posix.readlinkat(tmp.dir.fd, "link", buffer[0..]);
     try expect(mem.eql(u8, "file.txt", read_link));
 }
 
@@ -456,8 +457,8 @@ fn testTls() !void {
 test "getrandom" {
     var buf_a: [50]u8 = undefined;
     var buf_b: [50]u8 = undefined;
-    try os.getrandom(&buf_a);
-    try os.getrandom(&buf_b);
+    try posix.getrandom(&buf_a);
+    try posix.getrandom(&buf_b);
     // If this test fails the chance is significantly higher that there is a bug than
     // that two sets of 50 bytes were equal.
     try expect(!mem.eql(u8, &buf_a, &buf_b));
@@ -466,23 +467,23 @@ test "getrandom" {
 test "getcwd" {
     // at least call it so it gets compiled
     var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
-    _ = os.getcwd(&buf) catch undefined;
+    _ = posix.getcwd(&buf) catch undefined;
 }
 
 test "sigaltstack" {
     if (native_os == .windows or native_os == .wasi) return error.SkipZigTest;
 
-    var st: os.stack_t = undefined;
-    try os.sigaltstack(null, &st);
+    var st: posix.stack_t = undefined;
+    try posix.sigaltstack(null, &st);
     // Setting a stack size less than MINSIGSTKSZ returns ENOMEM
     st.flags = 0;
     st.size = 1;
-    try testing.expectError(error.SizeTooSmall, os.sigaltstack(&st, null));
+    try testing.expectError(error.SizeTooSmall, posix.sigaltstack(&st, null));
 }
 
 // If the type is not available use void to avoid erroring out when `iter_fn` is
 // analyzed
-const dl_phdr_info = if (@hasDecl(os.system, "dl_phdr_info")) os.dl_phdr_info else anyopaque;
+const dl_phdr_info = if (@hasDecl(posix.system, "dl_phdr_info")) posix.dl_phdr_info else anyopaque;
 
 const IterFnError = error{
     MissingPtLoadSegment,
@@ -527,7 +528,7 @@ test "dl_iterate_phdr" {
     if (builtin.object_format != .elf) return error.SkipZigTest;
 
     var counter: usize = 0;
-    try os.dl_iterate_phdr(&counter, IterFnError, iter_fn);
+    try posix.dl_iterate_phdr(&counter, IterFnError, iter_fn);
     try expect(counter != 0);
 }
 
@@ -535,8 +536,8 @@ test "gethostname" {
     if (native_os == .windows or native_os == .wasi)
         return error.SkipZigTest;
 
-    var buf: [os.HOST_NAME_MAX]u8 = undefined;
-    const hostname = try os.gethostname(&buf);
+    var buf: [posix.HOST_NAME_MAX]u8 = undefined;
+    const hostname = try posix.gethostname(&buf);
     try expect(hostname.len != 0);
 }
 
@@ -544,13 +545,13 @@ test "pipe" {
     if (native_os == .windows or native_os == .wasi)
         return error.SkipZigTest;
 
-    const fds = try os.pipe();
-    try expect((try os.write(fds[1], "hello")) == 5);
+    const fds = try posix.pipe();
+    try expect((try posix.write(fds[1], "hello")) == 5);
     var buf: [16]u8 = undefined;
-    try expect((try os.read(fds[0], buf[0..])) == 5);
+    try expect((try posix.read(fds[0], buf[0..])) == 5);
     try testing.expectEqualSlices(u8, buf[0..5], "hello");
-    os.close(fds[1]);
-    os.close(fds[0]);
+    posix.close(fds[1]);
+    posix.close(fds[0]);
 }
 
 test "argsAlloc" {
@@ -569,17 +570,17 @@ test "memfd_create" {
         else => return error.SkipZigTest,
     }
 
-    const fd = os.memfd_create("test", 0) catch |err| switch (err) {
+    const fd = posix.memfd_create("test", 0) catch |err| switch (err) {
         // Related: https://github.com/ziglang/zig/issues/4019
         error.SystemOutdated => return error.SkipZigTest,
         else => |e| return e,
     };
-    defer os.close(fd);
-    try expect((try os.write(fd, "test")) == 4);
-    try os.lseek_SET(fd, 0);
+    defer posix.close(fd);
+    try expect((try posix.write(fd, "test")) == 4);
+    try posix.lseek_SET(fd, 0);
 
     var buf: [10]u8 = undefined;
-    const bytes_read = try os.read(fd, &buf);
+    const bytes_read = try posix.read(fd, &buf);
     try expect(bytes_read == 4);
     try expect(mem.eql(u8, buf[0..4], "test"));
 }
@@ -593,15 +594,15 @@ test "mmap" {
 
     // Simple mmap() call with non page-aligned size
     {
-        const data = try os.mmap(
+        const data = try posix.mmap(
             null,
             1234,
-            os.PROT.READ | os.PROT.WRITE,
+            posix.PROT.READ | posix.PROT.WRITE,
             .{ .TYPE = .PRIVATE, .ANONYMOUS = true },
             -1,
             0,
         );
-        defer os.munmap(data);
+        defer posix.munmap(data);
 
         try testing.expectEqual(@as(usize, 1234), data.len);
 
@@ -635,15 +636,15 @@ test "mmap" {
         const file = try tmp.dir.openFile(test_out_file, .{});
         defer file.close();
 
-        const data = try os.mmap(
+        const data = try posix.mmap(
             null,
             alloc_size,
-            os.PROT.READ,
+            posix.PROT.READ,
             .{ .TYPE = .PRIVATE },
             file.handle,
             0,
         );
-        defer os.munmap(data);
+        defer posix.munmap(data);
 
         var mem_stream = io.fixedBufferStream(data);
         const stream = mem_stream.reader();
@@ -659,15 +660,15 @@ test "mmap" {
         const file = try tmp.dir.openFile(test_out_file, .{});
         defer file.close();
 
-        const data = try os.mmap(
+        const data = try posix.mmap(
             null,
             alloc_size / 2,
-            os.PROT.READ,
+            posix.PROT.READ,
             .{ .TYPE = .PRIVATE },
             file.handle,
             alloc_size / 2,
         );
-        defer os.munmap(data);
+        defer posix.munmap(data);
 
         var mem_stream = io.fixedBufferStream(data);
         const stream = mem_stream.reader();
@@ -683,14 +684,14 @@ test "mmap" {
 
 test "getenv" {
     if (native_os == .wasi and !builtin.link_libc) {
-        // std.os.getenv is not supported on WASI due to the need of allocation
+        // std.posix.getenv is not supported on WASI due to the need of allocation
         return error.SkipZigTest;
     }
 
     if (native_os == .windows) {
-        try expect(os.getenvW(&[_:0]u16{ 'B', 'O', 'G', 'U', 'S', 0x11, 0x22, 0x33, 0x44, 0x55 }) == null);
+        try expect(std.process.getenvW(&[_:0]u16{ 'B', 'O', 'G', 'U', 'S', 0x11, 0x22, 0x33, 0x44, 0x55 }) == null);
     } else {
-        try expect(os.getenvZ("BOGUSDOESNOTEXISTENVVAR") == null);
+        try expect(posix.getenvZ("BOGUSDOESNOTEXISTENVVAR") == null);
     }
 }
 
@@ -711,18 +712,18 @@ test "fcntl" {
 
     // Note: The test assumes createFile opens the file with CLOEXEC
     {
-        const flags = try os.fcntl(file.handle, os.F.GETFD, 0);
-        try expect((flags & os.FD_CLOEXEC) != 0);
+        const flags = try posix.fcntl(file.handle, posix.F.GETFD, 0);
+        try expect((flags & posix.FD_CLOEXEC) != 0);
     }
     {
-        _ = try os.fcntl(file.handle, os.F.SETFD, 0);
-        const flags = try os.fcntl(file.handle, os.F.GETFD, 0);
-        try expect((flags & os.FD_CLOEXEC) == 0);
+        _ = try posix.fcntl(file.handle, posix.F.SETFD, 0);
+        const flags = try posix.fcntl(file.handle, posix.F.GETFD, 0);
+        try expect((flags & posix.FD_CLOEXEC) == 0);
     }
     {
-        _ = try os.fcntl(file.handle, os.F.SETFD, os.FD_CLOEXEC);
-        const flags = try os.fcntl(file.handle, os.F.GETFD, 0);
-        try expect((flags & os.FD_CLOEXEC) != 0);
+        _ = try posix.fcntl(file.handle, posix.F.SETFD, posix.FD_CLOEXEC);
+        const flags = try posix.fcntl(file.handle, posix.F.GETFD, 0);
+        try expect((flags & posix.FD_CLOEXEC) != 0);
     }
 }
 
@@ -731,7 +732,7 @@ test "signalfd" {
         .linux, .solaris, .illumos => {},
         else => return error.SkipZigTest,
     }
-    _ = &os.signalfd;
+    _ = &posix.signalfd;
 }
 
 test "sync" {
@@ -748,8 +749,8 @@ test "sync" {
         tmp.dir.deleteFile(test_out_file) catch {};
     }
 
-    os.sync();
-    try os.syncfs(file.handle);
+    posix.sync();
+    try posix.syncfs(file.handle);
 }
 
 test "fsync" {
@@ -768,23 +769,23 @@ test "fsync" {
         tmp.dir.deleteFile(test_out_file) catch {};
     }
 
-    try os.fsync(file.handle);
-    try os.fdatasync(file.handle);
+    try posix.fsync(file.handle);
+    try posix.fdatasync(file.handle);
 }
 
 test "getrlimit and setrlimit" {
-    if (!@hasDecl(os.system, "rlimit")) {
+    if (!@hasDecl(posix.system, "rlimit")) {
         return error.SkipZigTest;
     }
 
-    inline for (std.meta.fields(os.rlimit_resource)) |field| {
-        const resource = @as(os.rlimit_resource, @enumFromInt(field.value));
-        const limit = try os.getrlimit(resource);
+    inline for (std.meta.fields(posix.rlimit_resource)) |field| {
+        const resource = @as(posix.rlimit_resource, @enumFromInt(field.value));
+        const limit = try posix.getrlimit(resource);
 
         // XNU kernel does not support RLIMIT_STACK if a custom stack is active,
         // which looks to always be the case. EINVAL is returned.
         // See https://github.com/apple-oss-distributions/xnu/blob/5e3eaea39dcf651e66cb99ba7d70e32cc4a99587/bsd/kern/kern_resource.c#L1173
-        if (builtin.os.tag.isDarwin() and resource == .STACK) {
+        if (native_os.isDarwin() and resource == .STACK) {
             continue;
         }
 
@@ -794,11 +795,11 @@ test "getrlimit and setrlimit" {
         // This happens for example if RLIMIT_MEMLOCK is bigger than ~2GiB.
         // In that case the following the limit would be RLIM_INFINITY and the following setrlimit fails with EPERM.
         if (comptime builtin.cpu.arch.isMIPS() and builtin.link_libc) {
-            if (limit.cur != os.linux.RLIM.INFINITY) {
-                try os.setrlimit(resource, limit);
+            if (limit.cur != linux.RLIM.INFINITY) {
+                try posix.setrlimit(resource, limit);
             }
         } else {
-            try os.setrlimit(resource, limit);
+            try posix.setrlimit(resource, limit);
         }
     }
 }
@@ -807,15 +808,15 @@ test "shutdown socket" {
     if (native_os == .wasi)
         return error.SkipZigTest;
     if (native_os == .windows) {
-        _ = try os.windows.WSAStartup(2, 2);
+        _ = try std.os.windows.WSAStartup(2, 2);
     }
     defer {
         if (native_os == .windows) {
-            os.windows.WSACleanup() catch unreachable;
+            std.os.windows.WSACleanup() catch unreachable;
         }
     }
-    const sock = try os.socket(os.AF.INET, os.SOCK.STREAM, 0);
-    os.shutdown(sock, .both) catch |err| switch (err) {
+    const sock = try posix.socket(posix.AF.INET, posix.SOCK.STREAM, 0);
+    posix.shutdown(sock, .both) catch |err| switch (err) {
         error.SocketNotConnected => {},
         else => |e| return e,
     };
@@ -838,63 +839,63 @@ test "sigaction" {
     const S = struct {
         var handler_called_count: u32 = 0;
 
-        fn handler(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const anyopaque) callconv(.C) void {
+        fn handler(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*const anyopaque) callconv(.C) void {
             _ = ctx_ptr;
             // Check that we received the correct signal.
             switch (native_os) {
                 .netbsd => {
-                    if (sig == os.SIG.USR1 and sig == info.info.signo)
+                    if (sig == posix.SIG.USR1 and sig == info.info.signo)
                         handler_called_count += 1;
                 },
                 else => {
-                    if (sig == os.SIG.USR1 and sig == info.signo)
+                    if (sig == posix.SIG.USR1 and sig == info.signo)
                         handler_called_count += 1;
                 },
             }
         }
     };
 
-    var sa = os.Sigaction{
+    var sa: posix.Sigaction = .{
         .handler = .{ .sigaction = &S.handler },
-        .mask = os.empty_sigset,
-        .flags = os.SA.SIGINFO | os.SA.RESETHAND,
+        .mask = posix.empty_sigset,
+        .flags = posix.SA.SIGINFO | posix.SA.RESETHAND,
     };
-    var old_sa: os.Sigaction = undefined;
+    var old_sa: posix.Sigaction = undefined;
 
     // Install the new signal handler.
-    try os.sigaction(os.SIG.USR1, &sa, null);
+    try posix.sigaction(posix.SIG.USR1, &sa, null);
 
     // Check that we can read it back correctly.
-    try os.sigaction(os.SIG.USR1, null, &old_sa);
+    try posix.sigaction(posix.SIG.USR1, null, &old_sa);
     try testing.expectEqual(&S.handler, old_sa.handler.sigaction.?);
-    try testing.expect((old_sa.flags & os.SA.SIGINFO) != 0);
+    try testing.expect((old_sa.flags & posix.SA.SIGINFO) != 0);
 
     // Invoke the handler.
-    try os.raise(os.SIG.USR1);
+    try posix.raise(posix.SIG.USR1);
     try testing.expect(S.handler_called_count == 1);
 
     // Check if passing RESETHAND correctly reset the handler to SIG_DFL
-    try os.sigaction(os.SIG.USR1, null, &old_sa);
-    try testing.expectEqual(os.SIG.DFL, old_sa.handler.handler);
+    try posix.sigaction(posix.SIG.USR1, null, &old_sa);
+    try testing.expectEqual(posix.SIG.DFL, old_sa.handler.handler);
 
     // Reinstall the signal w/o RESETHAND and re-raise
-    sa.flags = os.SA.SIGINFO;
-    try os.sigaction(os.SIG.USR1, &sa, null);
-    try os.raise(os.SIG.USR1);
+    sa.flags = posix.SA.SIGINFO;
+    try posix.sigaction(posix.SIG.USR1, &sa, null);
+    try posix.raise(posix.SIG.USR1);
     try testing.expect(S.handler_called_count == 2);
 
     // Now set the signal to ignored
-    sa.handler = .{ .handler = os.SIG.IGN };
+    sa.handler = .{ .handler = posix.SIG.IGN };
     sa.flags = 0;
-    try os.sigaction(os.SIG.USR1, &sa, null);
+    try posix.sigaction(posix.SIG.USR1, &sa, null);
 
     // Re-raise to ensure handler is actually ignored
-    try os.raise(os.SIG.USR1);
+    try posix.raise(posix.SIG.USR1);
     try testing.expect(S.handler_called_count == 2);
 
     // Ensure that ignored state is returned when querying
-    try os.sigaction(os.SIG.USR1, null, &old_sa);
-    try testing.expectEqual(os.SIG.IGN, old_sa.handler.handler.?);
+    try posix.sigaction(posix.SIG.USR1, null, &old_sa);
+    try testing.expectEqual(posix.SIG.IGN, old_sa.handler.handler.?);
 }
 
 test "dup & dup2" {
@@ -910,13 +911,13 @@ test "dup & dup2" {
         var file = try tmp.dir.createFile("os_dup_test", .{});
         defer file.close();
 
-        var duped = std.fs.File{ .handle = try os.dup(file.handle) };
+        var duped = std.fs.File{ .handle = try posix.dup(file.handle) };
         defer duped.close();
         try duped.writeAll("dup");
 
         // Tests aren't run in parallel so using the next fd shouldn't be an issue.
         const new_fd = duped.handle + 1;
-        try os.dup2(file.handle, new_fd);
+        try posix.dup2(file.handle, new_fd);
         var dup2ed = std.fs.File{ .handle = new_fd };
         defer dup2ed.close();
         try dup2ed.writeAll("dup2");
@@ -938,9 +939,9 @@ test "writev longer than IOV_MAX" {
     var file = try tmp.dir.createFile("pwritev", .{});
     defer file.close();
 
-    const iovecs = [_]os.iovec_const{.{ .iov_base = "a", .iov_len = 1 }} ** (os.IOV_MAX + 1);
+    const iovecs = [_]posix.iovec_const{.{ .iov_base = "a", .iov_len = 1 }} ** (posix.IOV_MAX + 1);
     const amt = try file.writev(&iovecs);
-    try testing.expectEqual(@as(usize, os.IOV_MAX), amt);
+    try testing.expectEqual(@as(usize, posix.IOV_MAX), amt);
 }
 
 test "POSIX file locking with fcntl" {
@@ -964,46 +965,46 @@ test "POSIX file locking with fcntl" {
     const fd = file.handle;
 
     // Place an exclusive lock on the first byte, and a shared lock on the second byte:
-    var struct_flock = std.mem.zeroInit(os.Flock, .{ .type = os.F.WRLCK });
-    _ = try os.fcntl(fd, os.F.SETLK, @intFromPtr(&struct_flock));
+    var struct_flock = std.mem.zeroInit(posix.Flock, .{ .type = posix.F.WRLCK });
+    _ = try posix.fcntl(fd, posix.F.SETLK, @intFromPtr(&struct_flock));
     struct_flock.start = 1;
-    struct_flock.type = os.F.RDLCK;
-    _ = try os.fcntl(fd, os.F.SETLK, @intFromPtr(&struct_flock));
+    struct_flock.type = posix.F.RDLCK;
+    _ = try posix.fcntl(fd, posix.F.SETLK, @intFromPtr(&struct_flock));
 
     // Check the locks in a child process:
-    const pid = try os.fork();
+    const pid = try posix.fork();
     if (pid == 0) {
         // child expects be denied the exclusive lock:
         struct_flock.start = 0;
-        struct_flock.type = os.F.WRLCK;
-        try expectError(error.Locked, os.fcntl(fd, os.F.SETLK, @intFromPtr(&struct_flock)));
+        struct_flock.type = posix.F.WRLCK;
+        try expectError(error.Locked, posix.fcntl(fd, posix.F.SETLK, @intFromPtr(&struct_flock)));
         // child expects to get the shared lock:
         struct_flock.start = 1;
-        struct_flock.type = os.F.RDLCK;
-        _ = try os.fcntl(fd, os.F.SETLK, @intFromPtr(&struct_flock));
+        struct_flock.type = posix.F.RDLCK;
+        _ = try posix.fcntl(fd, posix.F.SETLK, @intFromPtr(&struct_flock));
         // child waits for the exclusive lock in order to test deadlock:
         struct_flock.start = 0;
-        struct_flock.type = os.F.WRLCK;
-        _ = try os.fcntl(fd, os.F.SETLKW, @intFromPtr(&struct_flock));
+        struct_flock.type = posix.F.WRLCK;
+        _ = try posix.fcntl(fd, posix.F.SETLKW, @intFromPtr(&struct_flock));
         // child exits without continuing:
-        os.exit(0);
+        posix.exit(0);
     } else {
         // parent waits for child to get shared lock:
         std.time.sleep(1 * std.time.ns_per_ms);
         // parent expects deadlock when attempting to upgrade the shared lock to exclusive:
         struct_flock.start = 1;
-        struct_flock.type = os.F.WRLCK;
-        try expectError(error.DeadLock, os.fcntl(fd, os.F.SETLKW, @intFromPtr(&struct_flock)));
+        struct_flock.type = posix.F.WRLCK;
+        try expectError(error.DeadLock, posix.fcntl(fd, posix.F.SETLKW, @intFromPtr(&struct_flock)));
         // parent releases exclusive lock:
         struct_flock.start = 0;
-        struct_flock.type = os.F.UNLCK;
-        _ = try os.fcntl(fd, os.F.SETLK, @intFromPtr(&struct_flock));
+        struct_flock.type = posix.F.UNLCK;
+        _ = try posix.fcntl(fd, posix.F.SETLK, @intFromPtr(&struct_flock));
         // parent releases shared lock:
         struct_flock.start = 1;
-        struct_flock.type = os.F.UNLCK;
-        _ = try os.fcntl(fd, os.F.SETLK, @intFromPtr(&struct_flock));
+        struct_flock.type = posix.F.UNLCK;
+        _ = try posix.fcntl(fd, posix.F.SETLK, @intFromPtr(&struct_flock));
         // parent waits for child:
-        const result = os.waitpid(pid, 0);
+        const result = posix.waitpid(pid, 0);
         try expect(result.status == 0 * 256);
     }
 }
@@ -1026,43 +1027,43 @@ test "rename smoke test" {
     };
 
     var file_path: []u8 = undefined;
-    var fd: os.fd_t = undefined;
-    const mode: os.mode_t = if (native_os == .windows) 0 else 0o666;
+    var fd: posix.fd_t = undefined;
+    const mode: posix.mode_t = if (native_os == .windows) 0 else 0o666;
 
     // Create some file using `open`.
     file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
-    fd = try os.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode);
-    os.close(fd);
+    fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode);
+    posix.close(fd);
 
     // Rename the file
     var new_file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_other_file" });
-    try os.rename(file_path, new_file_path);
+    try posix.rename(file_path, new_file_path);
 
     // Try opening renamed file
     file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_other_file" });
-    fd = try os.open(file_path, .{ .ACCMODE = .RDWR }, mode);
-    os.close(fd);
+    fd = try posix.open(file_path, .{ .ACCMODE = .RDWR }, mode);
+    posix.close(fd);
 
     // Try opening original file - should fail with error.FileNotFound
     file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
-    try expectError(error.FileNotFound, os.open(file_path, .{ .ACCMODE = .RDWR }, mode));
+    try expectError(error.FileNotFound, posix.open(file_path, .{ .ACCMODE = .RDWR }, mode));
 
     // Create some directory
     file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });
-    try os.mkdir(file_path, mode);
+    try posix.mkdir(file_path, mode);
 
     // Rename the directory
     new_file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_other_dir" });
-    try os.rename(file_path, new_file_path);
+    try posix.rename(file_path, new_file_path);
 
     // Try opening renamed directory
     file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_other_dir" });
-    fd = try os.open(file_path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, mode);
-    os.close(fd);
+    fd = try posix.open(file_path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, mode);
+    posix.close(fd);
 
     // Try opening original directory - should fail with error.FileNotFound
     file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });
-    try expectError(error.FileNotFound, os.open(file_path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, mode));
+    try expectError(error.FileNotFound, posix.open(file_path, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, mode));
 }
 
 test "access smoke test" {
@@ -1083,50 +1084,49 @@ test "access smoke test" {
     };
 
     var file_path: []u8 = undefined;
-    var fd: os.fd_t = undefined;
-    const mode: os.mode_t = if (native_os == .windows) 0 else 0o666;
+    var fd: posix.fd_t = undefined;
+    const mode: posix.mode_t = if (native_os == .windows) 0 else 0o666;
 
     // Create some file using `open`.
     file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
-    fd = try os.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode);
-    os.close(fd);
+    fd = try posix.open(file_path, .{ .ACCMODE = .RDWR, .CREAT = true, .EXCL = true }, mode);
+    posix.close(fd);
 
     // Try to access() the file
     file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_file" });
-    if (builtin.os.tag == .windows) {
-        try os.access(file_path, os.F_OK);
+    if (native_os == .windows) {
+        try posix.access(file_path, posix.F_OK);
     } else {
-        try os.access(file_path, os.F_OK | os.W_OK | os.R_OK);
+        try posix.access(file_path, posix.F_OK | posix.W_OK | posix.R_OK);
     }
 
     // Try to access() a non-existent file - should fail with error.FileNotFound
     file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_other_file" });
-    try expectError(error.FileNotFound, os.access(file_path, os.F_OK));
+    try expectError(error.FileNotFound, posix.access(file_path, posix.F_OK));
 
     // Create some directory
     file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });
-    try os.mkdir(file_path, mode);
+    try posix.mkdir(file_path, mode);
 
     // Try to access() the directory
     file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });
-    try os.access(file_path, os.F_OK);
+    try posix.access(file_path, posix.F_OK);
 }
 
 test "timerfd" {
     if (native_os != .linux) return error.SkipZigTest;
 
-    const linux = os.linux;
-    const tfd = try os.timerfd_create(linux.CLOCK.MONOTONIC, .{ .CLOEXEC = true });
-    defer os.close(tfd);
+    const tfd = try posix.timerfd_create(linux.CLOCK.MONOTONIC, .{ .CLOEXEC = true });
+    defer posix.close(tfd);
 
-    // Fire event 10_000_000ns = 10ms after the os.timerfd_settime call.
+    // Fire event 10_000_000ns = 10ms after the posix.timerfd_settime call.
     var sit: linux.itimerspec = .{ .it_interval = .{ .tv_sec = 0, .tv_nsec = 0 }, .it_value = .{ .tv_sec = 0, .tv_nsec = 10 * (1000 * 1000) } };
-    try os.timerfd_settime(tfd, .{}, &sit, null);
+    try posix.timerfd_settime(tfd, .{}, &sit, null);
 
-    var fds: [1]os.pollfd = .{.{ .fd = tfd, .events = os.linux.POLL.IN, .revents = 0 }};
-    try expectEqual(@as(usize, 1), try os.poll(&fds, -1)); // -1 => infinite waiting
+    var fds: [1]posix.pollfd = .{.{ .fd = tfd, .events = linux.POLL.IN, .revents = 0 }};
+    try expectEqual(@as(usize, 1), try posix.poll(&fds, -1)); // -1 => infinite waiting
 
-    const git = try os.timerfd_gettime(tfd);
+    const git = try posix.timerfd_gettime(tfd);
     const expect_disarmed_timer: linux.itimerspec = .{ .it_interval = .{ .tv_sec = 0, .tv_nsec = 0 }, .it_value = .{ .tv_sec = 0, .tv_nsec = 0 } };
     try expectEqual(expect_disarmed_timer, git);
 }
@@ -1138,7 +1138,7 @@ test "isatty" {
     var file = try tmp.dir.createFile("foo", .{});
     defer file.close();
 
-    try expectEqual(os.isatty(file.handle), false);
+    try expectEqual(posix.isatty(file.handle), false);
 }
 
 test "read with empty buffer" {
@@ -1163,7 +1163,7 @@ test "read with empty buffer" {
 
     const bytes = try allocator.alloc(u8, 0);
 
-    _ = try os.read(file.handle, bytes);
+    _ = try posix.read(file.handle, bytes);
 }
 
 test "pread with empty buffer" {
@@ -1188,7 +1188,7 @@ test "pread with empty buffer" {
 
     const bytes = try allocator.alloc(u8, 0);
 
-    _ = try os.pread(file.handle, bytes, 0);
+    _ = try posix.pread(file.handle, bytes, 0);
 }
 
 test "write with empty buffer" {
@@ -1213,7 +1213,7 @@ test "write with empty buffer" {
 
     const bytes = try allocator.alloc(u8, 0);
 
-    _ = try os.write(file.handle, bytes);
+    _ = try posix.write(file.handle, bytes);
 }
 
 test "pwrite with empty buffer" {
@@ -1238,11 +1238,11 @@ test "pwrite with empty buffer" {
 
     const bytes = try allocator.alloc(u8, 0);
 
-    _ = try os.pwrite(file.handle, bytes, 0);
+    _ = try posix.pwrite(file.handle, bytes, 0);
 }
 
-fn expectMode(dir: os.fd_t, file: []const u8, mode: os.mode_t) !void {
-    const st = try os.fstatat(dir, file, os.AT.SYMLINK_NOFOLLOW);
+fn expectMode(dir: posix.fd_t, file: []const u8, mode: posix.mode_t) !void {
+    const st = try posix.fstatat(dir, file, posix.AT.SYMLINK_NOFOLLOW);
     try expectEqual(mode, st.mode & 0b111_111_111);
 }
 
@@ -1252,31 +1252,31 @@ test "fchmodat smoke test" {
     var tmp = tmpDir(.{});
     defer tmp.cleanup();
 
-    try expectError(error.FileNotFound, os.fchmodat(tmp.dir.fd, "regfile", 0o666, 0));
-    const fd = try os.openat(
+    try expectError(error.FileNotFound, posix.fchmodat(tmp.dir.fd, "regfile", 0o666, 0));
+    const fd = try posix.openat(
         tmp.dir.fd,
         "regfile",
         .{ .ACCMODE = .WRONLY, .CREAT = true, .EXCL = true, .TRUNC = true },
         0o644,
     );
-    os.close(fd);
-    try os.symlinkat("regfile", tmp.dir.fd, "symlink");
+    posix.close(fd);
+    try posix.symlinkat("regfile", tmp.dir.fd, "symlink");
     const sym_mode = blk: {
-        const st = try os.fstatat(tmp.dir.fd, "symlink", os.AT.SYMLINK_NOFOLLOW);
+        const st = try posix.fstatat(tmp.dir.fd, "symlink", posix.AT.SYMLINK_NOFOLLOW);
         break :blk st.mode & 0b111_111_111;
     };
 
-    try os.fchmodat(tmp.dir.fd, "regfile", 0o640, 0);
+    try posix.fchmodat(tmp.dir.fd, "regfile", 0o640, 0);
     try expectMode(tmp.dir.fd, "regfile", 0o640);
-    try os.fchmodat(tmp.dir.fd, "regfile", 0o600, os.AT.SYMLINK_NOFOLLOW);
+    try posix.fchmodat(tmp.dir.fd, "regfile", 0o600, posix.AT.SYMLINK_NOFOLLOW);
     try expectMode(tmp.dir.fd, "regfile", 0o600);
 
-    try os.fchmodat(tmp.dir.fd, "symlink", 0o640, 0);
+    try posix.fchmodat(tmp.dir.fd, "symlink", 0o640, 0);
     try expectMode(tmp.dir.fd, "regfile", 0o640);
     try expectMode(tmp.dir.fd, "symlink", sym_mode);
 
     var test_link = true;
-    os.fchmodat(tmp.dir.fd, "symlink", 0o600, os.AT.SYMLINK_NOFOLLOW) catch |err| switch (err) {
+    posix.fchmodat(tmp.dir.fd, "symlink", 0o600, posix.AT.SYMLINK_NOFOLLOW) catch |err| switch (err) {
         error.OperationNotSupported => test_link = false,
         else => |e| return e,
     };
@@ -1284,3 +1284,34 @@ test "fchmodat smoke test" {
         try expectMode(tmp.dir.fd, "symlink", 0o600);
     try expectMode(tmp.dir.fd, "regfile", 0o640);
 }
+
+const CommonOpenFlags = packed struct {
+    ACCMODE: posix.ACCMODE = .RDONLY,
+    CREAT: bool = false,
+    EXCL: bool = false,
+    LARGEFILE: bool = false,
+    DIRECTORY: bool = false,
+    CLOEXEC: bool = false,
+    NONBLOCK: bool = false,
+
+    pub fn lower(cof: CommonOpenFlags) posix.O {
+        if (native_os == .wasi) return .{
+            .read = cof.ACCMODE != .WRONLY,
+            .write = cof.ACCMODE != .RDONLY,
+            .CREAT = cof.CREAT,
+            .EXCL = cof.EXCL,
+            .DIRECTORY = cof.DIRECTORY,
+            .NONBLOCK = cof.NONBLOCK,
+        };
+        var result: posix.O = .{
+            .ACCMODE = cof.ACCMODE,
+            .CREAT = cof.CREAT,
+            .EXCL = cof.EXCL,
+            .DIRECTORY = cof.DIRECTORY,
+            .NONBLOCK = cof.NONBLOCK,
+            .CLOEXEC = cof.CLOEXEC,
+        };
+        if (@hasField(posix.O, "LARGEFILE")) result.LARGEFILE = cof.LARGEFILE;
+        return result;
+    }
+};
lib/std/Random/benchmark.zig
@@ -144,7 +144,7 @@ pub fn main() !void {
             i += 1;
             if (i == args.len) {
                 usage();
-                std.os.exit(1);
+                std.process.exit(1);
             }
 
             filter = args[i];
@@ -152,7 +152,7 @@ pub fn main() !void {
             i += 1;
             if (i == args.len) {
                 usage();
-                std.os.exit(1);
+                std.process.exit(1);
             }
 
             const c = try std.fmt.parseUnsigned(usize, args[i], 10);
@@ -170,7 +170,7 @@ pub fn main() !void {
             return;
         } else {
             usage();
-            std.os.exit(1);
+            std.process.exit(1);
         }
     }
 
lib/std/Thread/Futex.zig
@@ -1,13 +1,20 @@
-//! Futex is a mechanism used to block (`wait`) and unblock (`wake`) threads using a 32bit memory address as hints.
-//! Blocking a thread is acknowledged only if the 32bit memory address is equal to a given value.
-//! This check helps avoid block/unblock deadlocks which occur if a `wake()` happens before a `wait()`.
-//! Using Futex, other Thread synchronization primitives can be built which efficiently wait for cross-thread events or signals.
+//! A mechanism used to block (`wait`) and unblock (`wake`) threads using a
+//! 32bit memory address as hints.
+//!
+//! Blocking a thread is acknowledged only if the 32bit memory address is equal
+//! to a given value. This check helps avoid block/unblock deadlocks which
+//! occur if a `wake()` happens before a `wait()`.
+//!
+//! Using Futex, other Thread synchronization primitives can be built which
+//! efficiently wait for cross-thread events or signals.
 
 const std = @import("../std.zig");
 const builtin = @import("builtin");
 const Futex = @This();
+const windows = std.os.windows;
+const linux = std.os.linux;
+const c = std.c;
 
-const os = std.os;
 const assert = std.debug.assert;
 const testing = std.testing;
 const atomic = std.atomic;
@@ -124,18 +131,18 @@ const SingleThreadedImpl = struct {
 // as it's generally already a linked target and is autoloaded into all processes anyway.
 const WindowsImpl = struct {
     fn wait(ptr: *const atomic.Value(u32), expect: u32, timeout: ?u64) error{Timeout}!void {
-        var timeout_value: os.windows.LARGE_INTEGER = undefined;
-        var timeout_ptr: ?*const os.windows.LARGE_INTEGER = null;
+        var timeout_value: windows.LARGE_INTEGER = undefined;
+        var timeout_ptr: ?*const windows.LARGE_INTEGER = null;
 
         // NTDLL functions work with time in units of 100 nanoseconds.
         // Positive values are absolute deadlines while negative values are relative durations.
         if (timeout) |delay| {
-            timeout_value = @as(os.windows.LARGE_INTEGER, @intCast(delay / 100));
+            timeout_value = @as(windows.LARGE_INTEGER, @intCast(delay / 100));
             timeout_value = -timeout_value;
             timeout_ptr = &timeout_value;
         }
 
-        const rc = os.windows.ntdll.RtlWaitOnAddress(
+        const rc = windows.ntdll.RtlWaitOnAddress(
             ptr,
             &expect,
             @sizeOf(@TypeOf(expect)),
@@ -157,8 +164,8 @@ const WindowsImpl = struct {
         assert(max_waiters != 0);
 
         switch (max_waiters) {
-            1 => os.windows.ntdll.RtlWakeAddressSingle(address),
-            else => os.windows.ntdll.RtlWakeAddressAll(address),
+            1 => windows.ntdll.RtlWakeAddressSingle(address),
+            else => windows.ntdll.RtlWakeAddressAll(address),
         }
     }
 };
@@ -189,10 +196,10 @@ const DarwinImpl = struct {
         var timeout_overflowed = false;
 
         const addr: *const anyopaque = ptr;
-        const flags = os.darwin.UL_COMPARE_AND_WAIT | os.darwin.ULF_NO_ERRNO;
+        const flags = c.UL_COMPARE_AND_WAIT | c.ULF_NO_ERRNO;
         const status = blk: {
             if (supports_ulock_wait2) {
-                break :blk os.darwin.__ulock_wait2(flags, addr, expect, timeout_ns, 0);
+                break :blk c.__ulock_wait2(flags, addr, expect, timeout_ns, 0);
             }
 
             const timeout_us = std.math.cast(u32, timeout_ns / std.time.ns_per_us) orelse overflow: {
@@ -200,11 +207,11 @@ const DarwinImpl = struct {
                 break :overflow std.math.maxInt(u32);
             };
 
-            break :blk os.darwin.__ulock_wait(flags, addr, expect, timeout_us);
+            break :blk c.__ulock_wait(flags, addr, expect, timeout_us);
         };
 
         if (status >= 0) return;
-        switch (@as(std.os.E, @enumFromInt(-status))) {
+        switch (@as(c.E, @enumFromInt(-status))) {
             // Wait was interrupted by the OS or other spurious signalling.
             .INTR => {},
             // Address of the futex was paged out. This is unlikely, but possible in theory, and
@@ -221,17 +228,17 @@ const DarwinImpl = struct {
     }
 
     fn wake(ptr: *const atomic.Value(u32), max_waiters: u32) void {
-        var flags: u32 = os.darwin.UL_COMPARE_AND_WAIT | os.darwin.ULF_NO_ERRNO;
+        var flags: u32 = c.UL_COMPARE_AND_WAIT | c.ULF_NO_ERRNO;
         if (max_waiters > 1) {
-            flags |= os.darwin.ULF_WAKE_ALL;
+            flags |= c.ULF_WAKE_ALL;
         }
 
         while (true) {
             const addr: *const anyopaque = ptr;
-            const status = os.darwin.__ulock_wake(flags, addr, 0);
+            const status = c.__ulock_wake(flags, addr, 0);
 
             if (status >= 0) return;
-            switch (@as(std.os.E, @enumFromInt(-status))) {
+            switch (@as(c.E, @enumFromInt(-status))) {
                 .INTR => continue, // spurious wake()
                 .FAULT => unreachable, // __ulock_wake doesn't generate EFAULT according to darwin pthread_cond_t
                 .NOENT => return, // nothing was woken up
@@ -245,20 +252,20 @@ const DarwinImpl = struct {
 // https://man7.org/linux/man-pages/man2/futex.2.html
 const LinuxImpl = struct {
     fn wait(ptr: *const atomic.Value(u32), expect: u32, timeout: ?u64) error{Timeout}!void {
-        var ts: os.timespec = undefined;
+        var ts: linux.timespec = undefined;
         if (timeout) |timeout_ns| {
             ts.tv_sec = @as(@TypeOf(ts.tv_sec), @intCast(timeout_ns / std.time.ns_per_s));
             ts.tv_nsec = @as(@TypeOf(ts.tv_nsec), @intCast(timeout_ns % std.time.ns_per_s));
         }
 
-        const rc = os.linux.futex_wait(
+        const rc = linux.futex_wait(
             @as(*const i32, @ptrCast(&ptr.raw)),
-            os.linux.FUTEX.PRIVATE_FLAG | os.linux.FUTEX.WAIT,
+            linux.FUTEX.PRIVATE_FLAG | linux.FUTEX.WAIT,
             @as(i32, @bitCast(expect)),
             if (timeout != null) &ts else null,
         );
 
-        switch (os.linux.getErrno(rc)) {
+        switch (linux.E.init(rc)) {
             .SUCCESS => {}, // notified by `wake()`
             .INTR => {}, // spurious wakeup
             .AGAIN => {}, // ptr.* != expect
@@ -273,13 +280,13 @@ const LinuxImpl = struct {
     }
 
     fn wake(ptr: *const atomic.Value(u32), max_waiters: u32) void {
-        const rc = os.linux.futex_wake(
+        const rc = linux.futex_wake(
             @as(*const i32, @ptrCast(&ptr.raw)),
-            os.linux.FUTEX.PRIVATE_FLAG | os.linux.FUTEX.WAKE,
+            linux.FUTEX.PRIVATE_FLAG | linux.FUTEX.WAKE,
             std.math.cast(i32, max_waiters) orelse std.math.maxInt(i32),
         );
 
-        switch (os.linux.getErrno(rc)) {
+        switch (linux.E.init(rc)) {
             .SUCCESS => {}, // successful wake up
             .INVAL => {}, // invalid futex_wait() on ptr done elsewhere
             .FAULT => {}, // pointer became invalid while doing the wake
@@ -292,28 +299,28 @@ const LinuxImpl = struct {
 const FreebsdImpl = struct {
     fn wait(ptr: *const atomic.Value(u32), expect: u32, timeout: ?u64) error{Timeout}!void {
         var tm_size: usize = 0;
-        var tm: os.freebsd._umtx_time = undefined;
-        var tm_ptr: ?*const os.freebsd._umtx_time = null;
+        var tm: c._umtx_time = undefined;
+        var tm_ptr: ?*const c._umtx_time = null;
 
         if (timeout) |timeout_ns| {
             tm_ptr = &tm;
             tm_size = @sizeOf(@TypeOf(tm));
 
             tm._flags = 0; // use relative time not UMTX_ABSTIME
-            tm._clockid = os.CLOCK.MONOTONIC;
+            tm._clockid = c.CLOCK.MONOTONIC;
             tm._timeout.tv_sec = @as(@TypeOf(tm._timeout.tv_sec), @intCast(timeout_ns / std.time.ns_per_s));
             tm._timeout.tv_nsec = @as(@TypeOf(tm._timeout.tv_nsec), @intCast(timeout_ns % std.time.ns_per_s));
         }
 
-        const rc = os.freebsd._umtx_op(
+        const rc = c._umtx_op(
             @intFromPtr(&ptr.raw),
-            @intFromEnum(os.freebsd.UMTX_OP.WAIT_UINT_PRIVATE),
+            @intFromEnum(c.UMTX_OP.WAIT_UINT_PRIVATE),
             @as(c_ulong, expect),
             tm_size,
             @intFromPtr(tm_ptr),
         );
 
-        switch (os.errno(rc)) {
+        switch (std.posix.errno(rc)) {
             .SUCCESS => {},
             .FAULT => unreachable, // one of the args points to invalid memory
             .INVAL => unreachable, // arguments should be correct
@@ -327,15 +334,15 @@ const FreebsdImpl = struct {
     }
 
     fn wake(ptr: *const atomic.Value(u32), max_waiters: u32) void {
-        const rc = os.freebsd._umtx_op(
+        const rc = c._umtx_op(
             @intFromPtr(&ptr.raw),
-            @intFromEnum(os.freebsd.UMTX_OP.WAKE_PRIVATE),
+            @intFromEnum(c.UMTX_OP.WAKE_PRIVATE),
             @as(c_ulong, max_waiters),
             0, // there is no timeout struct
             0, // there is no timeout struct pointer
         );
 
-        switch (os.errno(rc)) {
+        switch (std.posix.errno(rc)) {
             .SUCCESS => {},
             .FAULT => {}, // it's ok if the ptr doesn't point to valid memory
             .INVAL => unreachable, // arguments should be correct
@@ -347,21 +354,21 @@ const FreebsdImpl = struct {
 // https://man.openbsd.org/futex.2
 const OpenbsdImpl = struct {
     fn wait(ptr: *const atomic.Value(u32), expect: u32, timeout: ?u64) error{Timeout}!void {
-        var ts: os.timespec = undefined;
+        var ts: c.timespec = undefined;
         if (timeout) |timeout_ns| {
             ts.tv_sec = @as(@TypeOf(ts.tv_sec), @intCast(timeout_ns / std.time.ns_per_s));
             ts.tv_nsec = @as(@TypeOf(ts.tv_nsec), @intCast(timeout_ns % std.time.ns_per_s));
         }
 
-        const rc = os.openbsd.futex(
+        const rc = c.futex(
             @as(*const volatile u32, @ptrCast(&ptr.raw)),
-            os.openbsd.FUTEX_WAIT | os.openbsd.FUTEX_PRIVATE_FLAG,
+            c.FUTEX_WAIT | c.FUTEX_PRIVATE_FLAG,
             @as(c_int, @bitCast(expect)),
             if (timeout != null) &ts else null,
             null, // FUTEX_WAIT takes no requeue address
         );
 
-        switch (os.errno(rc)) {
+        switch (std.posix.errno(rc)) {
             .SUCCESS => {}, // woken up by wake
             .NOSYS => unreachable, // the futex operation shouldn't be invalid
             .FAULT => unreachable, // ptr was invalid
@@ -378,9 +385,9 @@ const OpenbsdImpl = struct {
     }
 
     fn wake(ptr: *const atomic.Value(u32), max_waiters: u32) void {
-        const rc = os.openbsd.futex(
+        const rc = c.futex(
             @as(*const volatile u32, @ptrCast(&ptr.raw)),
-            os.openbsd.FUTEX_WAKE | os.openbsd.FUTEX_PRIVATE_FLAG,
+            c.FUTEX_WAKE | c.FUTEX_PRIVATE_FLAG,
             std.math.cast(c_int, max_waiters) orelse std.math.maxInt(c_int),
             null, // FUTEX_WAKE takes no timeout ptr
             null, // FUTEX_WAKE takes no requeue address
@@ -415,9 +422,9 @@ const DragonflyImpl = struct {
 
         const value = @as(c_int, @bitCast(expect));
         const addr = @as(*const volatile c_int, @ptrCast(&ptr.raw));
-        const rc = os.dragonfly.umtx_sleep(addr, value, timeout_us);
+        const rc = c.umtx_sleep(addr, value, timeout_us);
 
-        switch (os.errno(rc)) {
+        switch (std.posix.errno(rc)) {
             .SUCCESS => {},
             .BUSY => {}, // ptr != expect
             .AGAIN => { // maybe timed out, or paged out, or hit 2s kernel refresh
@@ -444,7 +451,7 @@ const DragonflyImpl = struct {
         // > umtx_wakeup() will generally return 0 unless the address is bad.
         // We are fine with the address being bad (e.g. for Semaphore.post() where Semaphore.wait() frees the Semaphore)
         const addr = @as(*const volatile c_int, @ptrCast(&ptr.raw));
-        _ = os.dragonfly.umtx_wakeup(addr, to_wake);
+        _ = c.umtx_wakeup(addr, to_wake);
     }
 };
 
@@ -496,8 +503,8 @@ const WasmImpl = struct {
 /// https://go.dev/src/runtime/sema.go
 const PosixImpl = struct {
     const Event = struct {
-        cond: std.c.pthread_cond_t,
-        mutex: std.c.pthread_mutex_t,
+        cond: c.pthread_cond_t,
+        mutex: c.pthread_mutex_t,
         state: enum { empty, waiting, notified },
 
         fn init(self: *Event) void {
@@ -509,18 +516,18 @@ const PosixImpl = struct {
 
         fn deinit(self: *Event) void {
             // Some platforms reportedly give EINVAL for statically initialized pthread types.
-            const rc = std.c.pthread_cond_destroy(&self.cond);
+            const rc = c.pthread_cond_destroy(&self.cond);
             assert(rc == .SUCCESS or rc == .INVAL);
 
-            const rm = std.c.pthread_mutex_destroy(&self.mutex);
+            const rm = c.pthread_mutex_destroy(&self.mutex);
             assert(rm == .SUCCESS or rm == .INVAL);
 
             self.* = undefined;
         }
 
         fn wait(self: *Event, timeout: ?u64) error{Timeout}!void {
-            assert(std.c.pthread_mutex_lock(&self.mutex) == .SUCCESS);
-            defer assert(std.c.pthread_mutex_unlock(&self.mutex) == .SUCCESS);
+            assert(c.pthread_mutex_lock(&self.mutex) == .SUCCESS);
+            defer assert(c.pthread_mutex_unlock(&self.mutex) == .SUCCESS);
 
             // Early return if the event was already set.
             if (self.state == .notified) {
@@ -530,9 +537,9 @@ const PosixImpl = struct {
             // Compute the absolute timeout if one was specified.
             // POSIX requires that REALTIME is used by default for the pthread timedwait functions.
             // This can be changed with pthread_condattr_setclock, but it's an extension and may not be available everywhere.
-            var ts: os.timespec = undefined;
+            var ts: c.timespec = undefined;
             if (timeout) |timeout_ns| {
-                os.clock_gettime(os.CLOCK.REALTIME, &ts) catch unreachable;
+                c.clock_gettime(c.CLOCK.REALTIME, &ts) catch unreachable;
                 ts.tv_sec +|= @as(@TypeOf(ts.tv_sec), @intCast(timeout_ns / std.time.ns_per_s));
                 ts.tv_nsec += @as(@TypeOf(ts.tv_nsec), @intCast(timeout_ns % std.time.ns_per_s));
 
@@ -549,8 +556,8 @@ const PosixImpl = struct {
             while (true) {
                 // Block using either pthread_cond_wait or pthread_cond_timewait if there's an absolute timeout.
                 const rc = blk: {
-                    if (timeout == null) break :blk std.c.pthread_cond_wait(&self.cond, &self.mutex);
-                    break :blk std.c.pthread_cond_timedwait(&self.cond, &self.mutex, &ts);
+                    if (timeout == null) break :blk c.pthread_cond_wait(&self.cond, &self.mutex);
+                    break :blk c.pthread_cond_timedwait(&self.cond, &self.mutex, &ts);
                 };
 
                 // After waking up, check if the event was set.
@@ -574,8 +581,8 @@ const PosixImpl = struct {
         }
 
         fn set(self: *Event) void {
-            assert(std.c.pthread_mutex_lock(&self.mutex) == .SUCCESS);
-            defer assert(std.c.pthread_mutex_unlock(&self.mutex) == .SUCCESS);
+            assert(c.pthread_mutex_lock(&self.mutex) == .SUCCESS);
+            defer assert(c.pthread_mutex_unlock(&self.mutex) == .SUCCESS);
 
             // Make sure that multiple calls to set() were not done on the same Event.
             const old_state = self.state;
@@ -586,7 +593,7 @@ const PosixImpl = struct {
             // the condition variable once it observes the new state, potentially causing a UAF if done unlocked.
             self.state = .notified;
             if (old_state == .waiting) {
-                assert(std.c.pthread_cond_signal(&self.cond) == .SUCCESS);
+                assert(c.pthread_cond_signal(&self.cond) == .SUCCESS);
             }
         }
     };
@@ -732,7 +739,7 @@ const PosixImpl = struct {
     };
 
     const Bucket = struct {
-        mutex: std.c.pthread_mutex_t align(atomic.cache_line) = .{},
+        mutex: c.pthread_mutex_t align(atomic.cache_line) = .{},
         pending: atomic.Value(usize) = atomic.Value(usize).init(0),
         treap: Treap = .{},
 
@@ -798,8 +805,8 @@ const PosixImpl = struct {
 
         var waiter: Waiter = undefined;
         {
-            assert(std.c.pthread_mutex_lock(&bucket.mutex) == .SUCCESS);
-            defer assert(std.c.pthread_mutex_unlock(&bucket.mutex) == .SUCCESS);
+            assert(c.pthread_mutex_lock(&bucket.mutex) == .SUCCESS);
+            defer assert(c.pthread_mutex_unlock(&bucket.mutex) == .SUCCESS);
 
             cancelled = ptr.load(.monotonic) != expect;
             if (cancelled) {
@@ -821,8 +828,8 @@ const PosixImpl = struct {
             // If we return early without waiting, the waiter on the stack would be invalidated and the wake() thread risks a UAF.
             defer if (!cancelled) waiter.event.wait(null) catch unreachable;
 
-            assert(std.c.pthread_mutex_lock(&bucket.mutex) == .SUCCESS);
-            defer assert(std.c.pthread_mutex_unlock(&bucket.mutex) == .SUCCESS);
+            assert(c.pthread_mutex_lock(&bucket.mutex) == .SUCCESS);
+            defer assert(c.pthread_mutex_unlock(&bucket.mutex) == .SUCCESS);
 
             cancelled = WaitQueue.tryRemove(&bucket.treap, address, &waiter);
             if (cancelled) {
@@ -871,8 +878,8 @@ const PosixImpl = struct {
             }
         };
 
-        assert(std.c.pthread_mutex_lock(&bucket.mutex) == .SUCCESS);
-        defer assert(std.c.pthread_mutex_unlock(&bucket.mutex) == .SUCCESS);
+        assert(c.pthread_mutex_lock(&bucket.mutex) == .SUCCESS);
+        defer assert(c.pthread_mutex_unlock(&bucket.mutex) == .SUCCESS);
 
         // Another pending check again to avoid the WaitQueue lookup if not necessary.
         if (bucket.pending.load(.monotonic) > 0) {
lib/std/Thread/Mutex.zig
@@ -23,7 +23,6 @@ const std = @import("../std.zig");
 const builtin = @import("builtin");
 const Mutex = @This();
 
-const os = std.os;
 const assert = std.debug.assert;
 const testing = std.testing;
 const Thread = std.Thread;
@@ -117,36 +116,40 @@ const SingleThreadedImpl = struct {
 // SRWLOCK on windows is almost always faster than Futex solution.
 // It also implements an efficient Condition with requeue support for us.
 const WindowsImpl = struct {
-    srwlock: os.windows.SRWLOCK = .{},
+    srwlock: windows.SRWLOCK = .{},
 
     fn tryLock(self: *@This()) bool {
-        return os.windows.kernel32.TryAcquireSRWLockExclusive(&self.srwlock) != os.windows.FALSE;
+        return windows.kernel32.TryAcquireSRWLockExclusive(&self.srwlock) != windows.FALSE;
     }
 
     fn lock(self: *@This()) void {
-        os.windows.kernel32.AcquireSRWLockExclusive(&self.srwlock);
+        windows.kernel32.AcquireSRWLockExclusive(&self.srwlock);
     }
 
     fn unlock(self: *@This()) void {
-        os.windows.kernel32.ReleaseSRWLockExclusive(&self.srwlock);
+        windows.kernel32.ReleaseSRWLockExclusive(&self.srwlock);
     }
+
+    const windows = std.os.windows;
 };
 
 // os_unfair_lock on darwin supports priority inheritance and is generally faster than Futex solutions.
 const DarwinImpl = struct {
-    oul: os.darwin.os_unfair_lock = .{},
+    oul: c.os_unfair_lock = .{},
 
     fn tryLock(self: *@This()) bool {
-        return os.darwin.os_unfair_lock_trylock(&self.oul);
+        return c.os_unfair_lock_trylock(&self.oul);
     }
 
     fn lock(self: *@This()) void {
-        os.darwin.os_unfair_lock_lock(&self.oul);
+        c.os_unfair_lock_lock(&self.oul);
     }
 
     fn unlock(self: *@This()) void {
-        os.darwin.os_unfair_lock_unlock(&self.oul);
+        c.os_unfair_lock_unlock(&self.oul);
     }
+
+    const c = std.c;
 };
 
 const FutexImpl = struct {
lib/std/zig/system/darwin/macos.zig
@@ -3,7 +3,6 @@ const builtin = @import("builtin");
 const assert = std.debug.assert;
 const mem = std.mem;
 const testing = std.testing;
-const os = std.os;
 
 const Target = std.Target;
 
@@ -397,7 +396,7 @@ test "detect" {
 pub fn detectNativeCpuAndFeatures() ?Target.Cpu {
     var cpu_family: std.c.CPUFAMILY = undefined;
     var len: usize = @sizeOf(std.c.CPUFAMILY);
-    os.sysctlbynameZ("hw.cpufamily", &cpu_family, &len, null, 0) catch |err| switch (err) {
+    std.posix.sysctlbynameZ("hw.cpufamily", &cpu_family, &len, null, 0) catch |err| switch (err) {
         error.NameTooLong => unreachable, // constant, known good value
         error.PermissionDenied => unreachable, // only when setting values,
         error.SystemResources => unreachable, // memory already on the stack
lib/std/zig/system/NativePaths.zig
@@ -137,21 +137,21 @@ pub fn detect(arena: Allocator, native_target: std.Target) !NativePaths {
         // variables to search for headers and libraries.
         // We use os.getenv here since this part won't be executed on
         // windows, to get rid of unnecessary error handling.
-        if (std.os.getenv("C_INCLUDE_PATH")) |c_include_path| {
+        if (std.posix.getenv("C_INCLUDE_PATH")) |c_include_path| {
             var it = mem.tokenizeScalar(u8, c_include_path, ':');
             while (it.next()) |dir| {
                 try self.addIncludeDir(dir);
             }
         }
 
-        if (std.os.getenv("CPLUS_INCLUDE_PATH")) |cplus_include_path| {
+        if (std.posix.getenv("CPLUS_INCLUDE_PATH")) |cplus_include_path| {
             var it = mem.tokenizeScalar(u8, cplus_include_path, ':');
             while (it.next()) |dir| {
                 try self.addIncludeDir(dir);
             }
         }
 
-        if (std.os.getenv("LIBRARY_PATH")) |library_path| {
+        if (std.posix.getenv("LIBRARY_PATH")) |library_path| {
             var it = mem.tokenizeScalar(u8, library_path, ':');
             while (it.next()) |dir| {
                 try self.addLibDir(dir);
lib/std/zig/Server.zig
@@ -146,7 +146,7 @@ pub fn serveMessage(
     header: OutMessage.Header,
     bufs: []const []const u8,
 ) !void {
-    var iovecs: [10]std.os.iovec_const = undefined;
+    var iovecs: [10]std.posix.iovec_const = undefined;
     const header_le = bswap(header);
     iovecs[0] = .{
         .iov_base = @as([*]const u8, @ptrCast(&header_le)),
lib/std/zig/system.zig
@@ -168,7 +168,7 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
     if (query.os_tag == null) {
         switch (builtin.target.os.tag) {
             .linux => {
-                const uts = std.os.uname();
+                const uts = posix.uname();
                 const release = mem.sliceTo(&uts.release, 0);
                 // The release field sometimes has a weird format,
                 // `Version.parse` will attempt to find some meaningful interpretation.
@@ -181,7 +181,7 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
                 }
             },
             .solaris, .illumos => {
-                const uts = std.os.uname();
+                const uts = posix.uname();
                 const release = mem.sliceTo(&uts.release, 0);
                 if (std.SemanticVersion.parse(release)) |ver| {
                     os.version_range.semver.min = ver;
@@ -206,7 +206,7 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
                 var value: u32 = undefined;
                 var len: usize = @sizeOf(@TypeOf(value));
 
-                std.os.sysctlbynameZ(key, &value, &len, null, 0) catch |err| switch (err) {
+                posix.sysctlbynameZ(key, &value, &len, null, 0) catch |err| switch (err) {
                     error.NameTooLong => unreachable, // constant, known good value
                     error.PermissionDenied => unreachable, // only when setting values,
                     error.SystemResources => unreachable, // memory already on the stack
@@ -257,15 +257,15 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
             },
             .openbsd => {
                 const mib: [2]c_int = [_]c_int{
-                    std.os.CTL.KERN,
-                    std.os.KERN.OSRELEASE,
+                    posix.CTL.KERN,
+                    posix.KERN.OSRELEASE,
                 };
                 var buf: [64]u8 = undefined;
                 // consider that sysctl result includes null-termination
                 // reserve 1 byte to ensure we never overflow when appending ".0"
                 var len: usize = buf.len - 1;
 
-                std.os.sysctl(&mib, &buf, &len, null, 0) catch |err| switch (err) {
+                posix.sysctl(&mib, &buf, &len, null, 0) catch |err| switch (err) {
                     error.NameTooLong => unreachable, // constant, known good value
                     error.PermissionDenied => unreachable, // only when setting values,
                     error.SystemResources => unreachable, // memory already on the stack
@@ -636,8 +636,8 @@ pub fn abiAndDynamicLinkerFromFile(
 
             // So far, no luck. Next we try to see if the information is
             // present in the symlink data for the dynamic linker path.
-            var link_buf: [std.os.PATH_MAX]u8 = undefined;
-            const link_name = std.os.readlink(dl_path, &link_buf) catch |err| switch (err) {
+            var link_buf: [posix.PATH_MAX]u8 = undefined;
+            const link_name = posix.readlink(dl_path, &link_buf) catch |err| switch (err) {
                 error.NameTooLong => unreachable,
                 error.InvalidUtf8 => unreachable, // WASI only
                 error.InvalidWtf8 => unreachable, // Windows only
@@ -670,7 +670,7 @@ pub fn abiAndDynamicLinkerFromFile(
 
         // Nothing worked so far. Finally we fall back to hard-coded search paths.
         // Some distros such as Debian keep their libc.so.6 in `/lib/$triple/`.
-        var path_buf: [std.os.PATH_MAX]u8 = undefined;
+        var path_buf: [posix.PATH_MAX]u8 = undefined;
         var index: usize = 0;
         const prefix = "/lib/";
         const cpu_arch = @tagName(result.cpu.arch);
@@ -1138,6 +1138,7 @@ const fs = std.fs;
 const assert = std.debug.assert;
 const Target = std.Target;
 const native_endian = builtin.cpu.arch.endian();
+const posix = std.posix;
 
 test {
     _ = NativePaths;
lib/std/builtin.zig
@@ -782,7 +782,7 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace, ret_addr
         },
         .wasi => {
             std.debug.print("{s}", .{msg});
-            std.os.abort();
+            std.posix.abort();
         },
         .uefi => {
             const uefi = std.os.uefi;
@@ -830,9 +830,9 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace, ret_addr
             }
 
             // Didn't have boot_services, just fallback to whatever.
-            std.os.abort();
+            std.posix.abort();
         },
-        .cuda, .amdhsa => std.os.abort(),
+        .cuda, .amdhsa => std.posix.abort(),
         .plan9 => {
             var status: [std.os.plan9.ERRMAX]u8 = undefined;
             const len = @min(msg.len, status.len - 1);
lib/std/c.zig
@@ -2,12 +2,13 @@ const std = @import("std");
 const builtin = @import("builtin");
 const c = @This();
 const page_size = std.mem.page_size;
-const iovec = std.os.iovec;
-const iovec_const = std.os.iovec_const;
+const iovec = std.posix.iovec;
+const iovec_const = std.posix.iovec_const;
 const wasi = @import("c/wasi.zig");
 const native_abi = builtin.abi;
 const native_arch = builtin.cpu.arch;
 const native_os = builtin.os.tag;
+const linux = std.os.linux;
 
 /// If not linking libc, returns false.
 /// If linking musl libc, returns true.
@@ -208,7 +209,7 @@ pub const pthread_rwlock_t = switch (native_os) {
 };
 
 pub const AT = switch (native_os) {
-    .linux => std.os.linux.AT,
+    .linux => linux.AT,
     .windows => struct {
         /// Remove directory instead of unlinking file
         pub const REMOVEDIR = 0x200;
@@ -326,9 +327,9 @@ pub const AT = switch (native_os) {
 };
 
 pub const O = switch (native_os) {
-    .linux => std.os.linux.O,
+    .linux => linux.O,
     .emscripten => packed struct(u32) {
-        ACCMODE: std.os.ACCMODE = .RDONLY,
+        ACCMODE: std.posix.ACCMODE = .RDONLY,
         _2: u4 = 0,
         CREAT: bool = false,
         EXCL: bool = false,
@@ -369,7 +370,7 @@ pub const O = switch (native_os) {
         _: u3 = 0,
     },
     .solaris, .illumos => packed struct(u32) {
-        ACCMODE: std.os.ACCMODE = .RDONLY,
+        ACCMODE: std.posix.ACCMODE = .RDONLY,
         NDELAY: bool = false,
         APPEND: bool = false,
         SYNC: bool = false,
@@ -396,7 +397,7 @@ pub const O = switch (native_os) {
         _: u6 = 0,
     },
     .netbsd => packed struct(u32) {
-        ACCMODE: std.os.ACCMODE = .RDONLY,
+        ACCMODE: std.posix.ACCMODE = .RDONLY,
         NONBLOCK: bool = false,
         APPEND: bool = false,
         SHLOCK: bool = false,
@@ -420,7 +421,7 @@ pub const O = switch (native_os) {
         _: u8 = 0,
     },
     .openbsd => packed struct(u32) {
-        ACCMODE: std.os.ACCMODE = .RDONLY,
+        ACCMODE: std.posix.ACCMODE = .RDONLY,
         NONBLOCK: bool = false,
         APPEND: bool = false,
         SHLOCK: bool = false,
@@ -438,7 +439,7 @@ pub const O = switch (native_os) {
         _: u14 = 0,
     },
     .haiku => packed struct(u32) {
-        ACCMODE: std.os.ACCMODE = .RDONLY,
+        ACCMODE: std.posix.ACCMODE = .RDONLY,
         _2: u4 = 0,
         CLOEXEC: bool = false,
         NONBLOCK: bool = false,
@@ -458,7 +459,7 @@ pub const O = switch (native_os) {
         _: u10 = 0,
     },
     .macos, .ios, .tvos, .watchos => packed struct(u32) {
-        ACCMODE: std.os.ACCMODE = .RDONLY,
+        ACCMODE: std.posix.ACCMODE = .RDONLY,
         NONBLOCK: bool = false,
         APPEND: bool = false,
         SHLOCK: bool = false,
@@ -485,7 +486,7 @@ pub const O = switch (native_os) {
         POPUP: bool = false,
     },
     .dragonfly => packed struct(u32) {
-        ACCMODE: std.os.ACCMODE = .RDONLY,
+        ACCMODE: std.posix.ACCMODE = .RDONLY,
         NONBLOCK: bool = false,
         APPEND: bool = false,
         SHLOCK: bool = false,
@@ -511,7 +512,7 @@ pub const O = switch (native_os) {
         _: u4 = 0,
     },
     .freebsd => packed struct(u32) {
-        ACCMODE: std.os.ACCMODE = .RDONLY,
+        ACCMODE: std.posix.ACCMODE = .RDONLY,
         NONBLOCK: bool = false,
         APPEND: bool = false,
         SHLOCK: bool = false,
@@ -538,7 +539,7 @@ pub const O = switch (native_os) {
 };
 
 pub const MAP = switch (native_os) {
-    .linux => std.os.linux.MAP,
+    .linux => linux.MAP,
     .emscripten => packed struct(u32) {
         TYPE: enum(u4) {
             SHARED = 0x01,
@@ -683,7 +684,7 @@ pub const cc_t = u8;
 
 /// Indices into the `cc` array in the `termios` struct.
 pub const V = switch (native_os) {
-    .linux => std.os.linux.V,
+    .linux => linux.V,
     .macos, .ios, .tvos, .watchos, .netbsd, .openbsd => enum {
         EOF,
         EOL,
@@ -782,7 +783,7 @@ pub const V = switch (native_os) {
 };
 
 pub const NCCS = switch (native_os) {
-    .linux => std.os.linux.NCCS,
+    .linux => linux.NCCS,
     .macos, .ios, .tvos, .watchos, .freebsd, .kfreebsd, .netbsd, .openbsd, .dragonfly => 20,
     .haiku => 11,
     .solaris, .illumos => 19,
@@ -791,7 +792,7 @@ pub const NCCS = switch (native_os) {
 };
 
 pub const termios = switch (native_os) {
-    .linux => std.os.linux.termios,
+    .linux => linux.termios,
     .macos, .ios, .tvos, .watchos => extern struct {
         iflag: tc_iflag_t,
         oflag: tc_oflag_t,
@@ -841,7 +842,7 @@ pub const termios = switch (native_os) {
 };
 
 pub const tc_iflag_t = switch (native_os) {
-    .linux => std.os.linux.tc_iflag_t,
+    .linux => linux.tc_iflag_t,
     .macos, .ios, .tvos, .watchos => packed struct(u64) {
         IGNBRK: bool = false,
         BRKINT: bool = false,
@@ -951,7 +952,7 @@ pub const tc_iflag_t = switch (native_os) {
 };
 
 pub const tc_oflag_t = switch (native_os) {
-    .linux => std.os.linux.tc_oflag_t,
+    .linux => linux.tc_oflag_t,
     .macos, .ios, .tvos, .watchos => packed struct(u64) {
         OPOST: bool = false,
         ONLCR: bool = false,
@@ -1042,13 +1043,13 @@ pub const tc_oflag_t = switch (native_os) {
 };
 
 pub const CSIZE = switch (native_os) {
-    .linux => std.os.linux.CSIZE,
+    .linux => linux.CSIZE,
     .haiku => enum(u1) { CS7, CS8 },
     else => enum(u2) { CS5, CS6, CS7, CS8 },
 };
 
 pub const tc_cflag_t = switch (native_os) {
-    .linux => std.os.linux.tc_cflag_t,
+    .linux => linux.tc_cflag_t,
     .macos, .ios, .tvos, .watchos => packed struct(u64) {
         CIGNORE: bool = false,
         _1: u5 = 0,
@@ -1184,7 +1185,7 @@ pub const tc_cflag_t = switch (native_os) {
 };
 
 pub const tc_lflag_t = switch (native_os) {
-    .linux => std.os.linux.tc_lflag_t,
+    .linux => linux.tc_lflag_t,
     .macos, .ios, .tvos, .watchos => packed struct(u64) {
         ECHOKE: bool = false,
         ECHOE: bool = false,
@@ -1310,7 +1311,7 @@ pub const tc_lflag_t = switch (native_os) {
 };
 
 pub const speed_t = switch (native_os) {
-    .linux => std.os.linux.speed_t,
+    .linux => linux.speed_t,
     .macos, .ios, .tvos, .watchos, .openbsd => enum(u64) {
         B0 = 0,
         B50 = 50,
@@ -1605,14 +1606,6 @@ pub const stat = switch (native_os) {
     else => private.stat,
 };
 
-pub fn getErrno(rc: anytype) c.E {
-    if (rc == -1) {
-        return @enumFromInt(c._errno().*);
-    } else {
-        return .SUCCESS;
-    }
-}
-
 pub extern "c" var environ: [*:null]?[*:0]u8;
 
 pub extern "c" fn fopen(noalias filename: [*:0]const u8, noalias modes: [*:0]const u8) ?*FILE;
@@ -1905,10 +1898,10 @@ pub extern "c" fn if_nametoindex([*:0]const u8) c_int;
 pub const getcontext = if (builtin.target.isAndroid())
     @compileError("android bionic libc does not implement getcontext")
 else if (native_os == .linux and builtin.target.isMusl())
-    std.os.linux.getcontext
+    linux.getcontext
 else
     struct {
-        extern fn getcontext(ucp: *std.os.ucontext_t) c_int;
+        extern fn getcontext(ucp: *std.posix.ucontext_t) c_int;
     }.getcontext;
 
 pub const max_align_t = if (native_abi == .msvc)
lib/std/child_process.zig
@@ -3,30 +3,31 @@ const builtin = @import("builtin");
 const unicode = std.unicode;
 const io = std.io;
 const fs = std.fs;
-const os = std.os;
 const process = std.process;
 const File = std.fs.File;
-const windows = os.windows;
-const linux = os.linux;
+const windows = std.os.windows;
+const linux = std.os.linux;
+const posix = std.posix;
 const mem = std.mem;
 const math = std.math;
 const debug = std.debug;
 const EnvMap = process.EnvMap;
 const maxInt = std.math.maxInt;
 const assert = std.debug.assert;
+const native_os = builtin.os.tag;
 
 pub const ChildProcess = struct {
-    pub const Id = switch (builtin.os.tag) {
+    pub const Id = switch (native_os) {
         .windows => windows.HANDLE,
         .wasi => void,
-        else => os.pid_t,
+        else => posix.pid_t,
     };
 
     /// Available after calling `spawn()`. This becomes `undefined` after calling `wait()`.
     /// On Windows this is the hProcess.
     /// On POSIX this is the pid.
     id: Id,
-    thread_handle: if (builtin.os.tag == .windows) windows.HANDLE else void,
+    thread_handle: if (native_os == .windows) windows.HANDLE else void,
 
     allocator: mem.Allocator,
 
@@ -46,10 +47,10 @@ pub const ChildProcess = struct {
     stderr_behavior: StdIo,
 
     /// Set to change the user id when spawning the child process.
-    uid: if (builtin.os.tag == .windows or builtin.os.tag == .wasi) void else ?os.uid_t,
+    uid: if (native_os == .windows or native_os == .wasi) void else ?posix.uid_t,
 
     /// Set to change the group id when spawning the child process.
-    gid: if (builtin.os.tag == .windows or builtin.os.tag == .wasi) void else ?os.gid_t,
+    gid: if (native_os == .windows or native_os == .wasi) void else ?posix.gid_t,
 
     /// Set to change the current working directory when spawning the child process.
     cwd: ?[]const u8,
@@ -58,7 +59,7 @@ pub const ChildProcess = struct {
     /// Once that is done, `cwd` will be deprecated in favor of this field.
     cwd_dir: ?fs.Dir = null,
 
-    err_pipe: ?if (builtin.os.tag == .windows) void else [2]os.fd_t,
+    err_pipe: ?if (native_os == .windows) void else [2]posix.fd_t,
 
     expand_arg0: Arg0Expand,
 
@@ -87,7 +88,7 @@ pub const ChildProcess = struct {
         /// Returns the peak resident set size of the child process, in bytes,
         /// if available.
         pub inline fn getMaxRss(rus: ResourceUsageStatistics) ?usize {
-            switch (builtin.os.tag) {
+            switch (native_os) {
                 .linux => {
                     if (rus.rusage) |ru| {
                         return @as(usize, @intCast(ru.maxrss)) * 1024;
@@ -114,14 +115,14 @@ pub const ChildProcess = struct {
             }
         }
 
-        const rusage_init = switch (builtin.os.tag) {
-            .linux, .macos, .ios => @as(?std.os.rusage, null),
+        const rusage_init = switch (native_os) {
+            .linux, .macos, .ios => @as(?posix.rusage, null),
             .windows => @as(?windows.VM_COUNTERS, null),
             else => {},
         };
     };
 
-    pub const Arg0Expand = os.Arg0Expand;
+    pub const Arg0Expand = posix.Arg0Expand;
 
     pub const SpawnError = error{
         OutOfMemory,
@@ -136,9 +137,9 @@ pub const ChildProcess = struct {
         /// Windows-only. `cwd` was provided, but the path did not exist when spawning the child process.
         CurrentWorkingDirectoryUnlinked,
     } ||
-        os.ExecveError ||
-        os.SetIdError ||
-        os.ChangeCurDirError ||
+        posix.ExecveError ||
+        posix.SetIdError ||
+        posix.ChangeCurDirError ||
         windows.CreateProcessError ||
         windows.GetProcessMemoryInfoError ||
         windows.WaitForSingleObjectError;
@@ -168,8 +169,8 @@ pub const ChildProcess = struct {
             .term = null,
             .env_map = null,
             .cwd = null,
-            .uid = if (builtin.os.tag == .windows or builtin.os.tag == .wasi) {} else null,
-            .gid = if (builtin.os.tag == .windows or builtin.os.tag == .wasi) {} else null,
+            .uid = if (native_os == .windows or native_os == .wasi) {} else null,
+            .gid = if (native_os == .windows or native_os == .wasi) {} else null,
             .stdin = null,
             .stdout = null,
             .stderr = null,
@@ -193,7 +194,7 @@ pub const ChildProcess = struct {
             @compileError("the target operating system cannot spawn processes");
         }
 
-        if (builtin.os.tag == .windows) {
+        if (native_os == .windows) {
             return self.spawnWindows();
         } else {
             return self.spawnPosix();
@@ -207,7 +208,7 @@ pub const ChildProcess = struct {
 
     /// Forcibly terminates child process and then cleans up all resources.
     pub fn kill(self: *ChildProcess) !Term {
-        if (builtin.os.tag == .windows) {
+        if (native_os == .windows) {
             return self.killWindows(1);
         } else {
             return self.killPosix();
@@ -241,7 +242,7 @@ pub const ChildProcess = struct {
             self.cleanupStreams();
             return term;
         }
-        os.kill(self.id, os.SIG.TERM) catch |err| switch (err) {
+        posix.kill(self.id, posix.SIG.TERM) catch |err| switch (err) {
             error.ProcessNotFound => return error.AlreadyTerminated,
             else => return err,
         };
@@ -251,7 +252,7 @@ pub const ChildProcess = struct {
 
     /// Blocks until child process terminates and then cleans up all resources.
     pub fn wait(self: *ChildProcess) !Term {
-        const term = if (builtin.os.tag == .windows)
+        const term = if (native_os == .windows)
             try self.waitWindows()
         else
             try self.waitPosix();
@@ -318,7 +319,7 @@ pub const ChildProcess = struct {
         stderr.* = fifoToOwnedArrayList(poller.fifo(.stderr));
     }
 
-    pub const RunError = os.GetCwdError || os.ReadError || SpawnError || os.PollError || error{
+    pub const RunError = posix.GetCwdError || posix.ReadError || SpawnError || posix.PollError || error{
         StdoutStreamTooLong,
         StderrStreamTooLong,
     };
@@ -396,19 +397,19 @@ pub const ChildProcess = struct {
             self.resource_usage_statistics.rusage = try windows.GetProcessMemoryInfo(self.id);
         }
 
-        os.close(self.id);
-        os.close(self.thread_handle);
+        posix.close(self.id);
+        posix.close(self.thread_handle);
         self.cleanupStreams();
         return result;
     }
 
     fn waitUnwrapped(self: *ChildProcess) !void {
-        const res: os.WaitPidResult = res: {
+        const res: posix.WaitPidResult = res: {
             if (self.request_resource_usage_statistics) {
-                switch (builtin.os.tag) {
+                switch (native_os) {
                     .linux, .macos, .ios => {
-                        var ru: std.os.rusage = undefined;
-                        const res = os.wait4(self.id, 0, &ru);
+                        var ru: posix.rusage = undefined;
+                        const res = posix.wait4(self.id, 0, &ru);
                         self.resource_usage_statistics.rusage = ru;
                         break :res res;
                     },
@@ -416,7 +417,7 @@ pub const ChildProcess = struct {
                 }
             }
 
-            break :res os.waitpid(self.id, 0);
+            break :res posix.waitpid(self.id, 0);
         };
         const status = res.status;
         self.cleanupStreams();
@@ -446,20 +447,20 @@ pub const ChildProcess = struct {
         if (self.err_pipe) |err_pipe| {
             defer destroyPipe(err_pipe);
 
-            if (builtin.os.tag == .linux) {
-                var fd = [1]std.os.pollfd{std.os.pollfd{
+            if (native_os == .linux) {
+                var fd = [1]posix.pollfd{posix.pollfd{
                     .fd = err_pipe[0],
-                    .events = std.os.POLL.IN,
+                    .events = posix.POLL.IN,
                     .revents = undefined,
                 }};
 
                 // Check if the eventfd buffer stores a non-zero value by polling
                 // it, that's the error code returned by the child process.
-                _ = std.os.poll(&fd, 0) catch unreachable;
+                _ = posix.poll(&fd, 0) catch unreachable;
 
                 // According to eventfd(2) the descriptor is readable if the counter
                 // has a value greater than 0
-                if ((fd[0].revents & std.os.POLL.IN) != 0) {
+                if ((fd[0].revents & posix.POLL.IN) != 0) {
                     const err_int = try readIntFd(err_pipe[0]);
                     return @as(SpawnError, @errorCast(@errorFromInt(err_int)));
                 }
@@ -483,36 +484,36 @@ pub const ChildProcess = struct {
     }
 
     fn statusToTerm(status: u32) Term {
-        return if (os.W.IFEXITED(status))
-            Term{ .Exited = os.W.EXITSTATUS(status) }
-        else if (os.W.IFSIGNALED(status))
-            Term{ .Signal = os.W.TERMSIG(status) }
-        else if (os.W.IFSTOPPED(status))
-            Term{ .Stopped = os.W.STOPSIG(status) }
+        return if (posix.W.IFEXITED(status))
+            Term{ .Exited = posix.W.EXITSTATUS(status) }
+        else if (posix.W.IFSIGNALED(status))
+            Term{ .Signal = posix.W.TERMSIG(status) }
+        else if (posix.W.IFSTOPPED(status))
+            Term{ .Stopped = posix.W.STOPSIG(status) }
         else
             Term{ .Unknown = status };
     }
 
     fn spawnPosix(self: *ChildProcess) SpawnError!void {
-        const pipe_flags: os.O = .{};
-        const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try os.pipe2(pipe_flags) else undefined;
+        const pipe_flags: posix.O = .{};
+        const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try posix.pipe2(pipe_flags) else undefined;
         errdefer if (self.stdin_behavior == StdIo.Pipe) {
             destroyPipe(stdin_pipe);
         };
 
-        const stdout_pipe = if (self.stdout_behavior == StdIo.Pipe) try os.pipe2(pipe_flags) else undefined;
+        const stdout_pipe = if (self.stdout_behavior == StdIo.Pipe) try posix.pipe2(pipe_flags) else undefined;
         errdefer if (self.stdout_behavior == StdIo.Pipe) {
             destroyPipe(stdout_pipe);
         };
 
-        const stderr_pipe = if (self.stderr_behavior == StdIo.Pipe) try os.pipe2(pipe_flags) else undefined;
+        const stderr_pipe = if (self.stderr_behavior == StdIo.Pipe) try posix.pipe2(pipe_flags) else undefined;
         errdefer if (self.stderr_behavior == StdIo.Pipe) {
             destroyPipe(stderr_pipe);
         };
 
         const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore);
         const dev_null_fd = if (any_ignore)
-            os.openZ("/dev/null", .{ .ACCMODE = .RDWR }, 0) catch |err| switch (err) {
+            posix.openZ("/dev/null", .{ .ACCMODE = .RDWR }, 0) catch |err| switch (err) {
                 error.PathAlreadyExists => unreachable,
                 error.NoSpaceLeft => unreachable,
                 error.FileTooBig => unreachable,
@@ -526,7 +527,7 @@ pub const ChildProcess = struct {
         else
             undefined;
         defer {
-            if (any_ignore) os.close(dev_null_fd);
+            if (any_ignore) posix.close(dev_null_fd);
         }
 
         var arena_allocator = std.heap.ArenaAllocator.init(self.allocator);
@@ -554,7 +555,7 @@ pub const ChildProcess = struct {
             } else if (builtin.output_mode == .Exe) {
                 // Then we have Zig start code and this works.
                 // TODO type-safety for null-termination of `os.environ`.
-                break :m @as([*:null]const ?[*:0]const u8, @ptrCast(os.environ.ptr));
+                break :m @as([*:null]const ?[*:0]const u8, @ptrCast(std.os.environ.ptr));
             } else {
                 // TODO come up with a solution for this.
                 @compileError("missing std lib enhancement: ChildProcess implementation has no way to collect the environment variables to forward to the child process");
@@ -564,60 +565,60 @@ pub const ChildProcess = struct {
         // This pipe is used to communicate errors between the time of fork
         // and execve from the child process to the parent process.
         const err_pipe = blk: {
-            if (builtin.os.tag == .linux) {
-                const fd = try os.eventfd(0, linux.EFD.CLOEXEC);
+            if (native_os == .linux) {
+                const fd = try posix.eventfd(0, linux.EFD.CLOEXEC);
                 // There's no distinction between the readable and the writeable
                 // end with eventfd
-                break :blk [2]os.fd_t{ fd, fd };
+                break :blk [2]posix.fd_t{ fd, fd };
             } else {
-                break :blk try os.pipe2(.{ .CLOEXEC = true });
+                break :blk try posix.pipe2(.{ .CLOEXEC = true });
             }
         };
         errdefer destroyPipe(err_pipe);
 
-        const pid_result = try os.fork();
+        const pid_result = try posix.fork();
         if (pid_result == 0) {
             // we are the child
-            setUpChildIo(self.stdin_behavior, stdin_pipe[0], os.STDIN_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err);
-            setUpChildIo(self.stdout_behavior, stdout_pipe[1], os.STDOUT_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err);
-            setUpChildIo(self.stderr_behavior, stderr_pipe[1], os.STDERR_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err);
+            setUpChildIo(self.stdin_behavior, stdin_pipe[0], posix.STDIN_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err);
+            setUpChildIo(self.stdout_behavior, stdout_pipe[1], posix.STDOUT_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err);
+            setUpChildIo(self.stderr_behavior, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err);
 
             if (self.stdin_behavior == .Pipe) {
-                os.close(stdin_pipe[0]);
-                os.close(stdin_pipe[1]);
+                posix.close(stdin_pipe[0]);
+                posix.close(stdin_pipe[1]);
             }
             if (self.stdout_behavior == .Pipe) {
-                os.close(stdout_pipe[0]);
-                os.close(stdout_pipe[1]);
+                posix.close(stdout_pipe[0]);
+                posix.close(stdout_pipe[1]);
             }
             if (self.stderr_behavior == .Pipe) {
-                os.close(stderr_pipe[0]);
-                os.close(stderr_pipe[1]);
+                posix.close(stderr_pipe[0]);
+                posix.close(stderr_pipe[1]);
             }
 
             if (self.cwd_dir) |cwd| {
-                os.fchdir(cwd.fd) catch |err| forkChildErrReport(err_pipe[1], err);
+                posix.fchdir(cwd.fd) catch |err| forkChildErrReport(err_pipe[1], err);
             } else if (self.cwd) |cwd| {
-                os.chdir(cwd) catch |err| forkChildErrReport(err_pipe[1], err);
+                posix.chdir(cwd) catch |err| forkChildErrReport(err_pipe[1], err);
             }
 
             if (self.gid) |gid| {
-                os.setregid(gid, gid) catch |err| forkChildErrReport(err_pipe[1], err);
+                posix.setregid(gid, gid) catch |err| forkChildErrReport(err_pipe[1], err);
             }
 
             if (self.uid) |uid| {
-                os.setreuid(uid, uid) catch |err| forkChildErrReport(err_pipe[1], err);
+                posix.setreuid(uid, uid) catch |err| forkChildErrReport(err_pipe[1], err);
             }
 
             const err = switch (self.expand_arg0) {
-                .expand => os.execvpeZ_expandArg0(.expand, argv_buf.ptr[0].?, argv_buf.ptr, envp),
-                .no_expand => os.execvpeZ_expandArg0(.no_expand, argv_buf.ptr[0].?, argv_buf.ptr, envp),
+                .expand => posix.execvpeZ_expandArg0(.expand, argv_buf.ptr[0].?, argv_buf.ptr, envp),
+                .no_expand => posix.execvpeZ_expandArg0(.no_expand, argv_buf.ptr[0].?, argv_buf.ptr, envp),
             };
             forkChildErrReport(err_pipe[1], err);
         }
 
         // we are the parent
-        const pid = @as(i32, @intCast(pid_result));
+        const pid: i32 = @intCast(pid_result);
         if (self.stdin_behavior == StdIo.Pipe) {
             self.stdin = File{ .handle = stdin_pipe[1] };
         } else {
@@ -639,13 +640,13 @@ pub const ChildProcess = struct {
         self.term = null;
 
         if (self.stdin_behavior == StdIo.Pipe) {
-            os.close(stdin_pipe[0]);
+            posix.close(stdin_pipe[0]);
         }
         if (self.stdout_behavior == StdIo.Pipe) {
-            os.close(stdout_pipe[1]);
+            posix.close(stdout_pipe[1]);
         }
         if (self.stderr_behavior == StdIo.Pipe) {
-            os.close(stderr_pipe[1]);
+            posix.close(stderr_pipe[1]);
         }
     }
 
@@ -679,7 +680,7 @@ pub const ChildProcess = struct {
         else
             undefined;
         defer {
-            if (any_ignore) os.close(nul_handle);
+            if (any_ignore) posix.close(nul_handle);
         }
 
         var g_hChildStd_IN_Rd: ?windows.HANDLE = null;
@@ -821,8 +822,8 @@ pub const ChildProcess = struct {
         defer self.allocator.free(cmd_line_w);
 
         run: {
-            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{};
+            const PATH: [:0]const u16 = std.process.getenvW(unicode.utf8ToUtf16LeStringLiteral("PATH")) orelse &[_:0]u16{};
+            const PATHEXT: [:0]const u16 = std.process.getenvW(unicode.utf8ToUtf16LeStringLiteral("PATHEXT")) orelse &[_:0]u16{};
 
             var app_buf = std.ArrayListUnmanaged(u16){};
             defer app_buf.deinit(self.allocator);
@@ -905,22 +906,22 @@ pub const ChildProcess = struct {
         self.term = null;
 
         if (self.stdin_behavior == StdIo.Pipe) {
-            os.close(g_hChildStd_IN_Rd.?);
+            posix.close(g_hChildStd_IN_Rd.?);
         }
         if (self.stderr_behavior == StdIo.Pipe) {
-            os.close(g_hChildStd_ERR_Wr.?);
+            posix.close(g_hChildStd_ERR_Wr.?);
         }
         if (self.stdout_behavior == StdIo.Pipe) {
-            os.close(g_hChildStd_OUT_Wr.?);
+            posix.close(g_hChildStd_OUT_Wr.?);
         }
     }
 
     fn setUpChildIo(stdio: StdIo, pipe_fd: i32, std_fileno: i32, dev_null_fd: i32) !void {
         switch (stdio) {
-            .Pipe => try os.dup2(pipe_fd, std_fileno),
-            .Close => os.close(std_fileno),
+            .Pipe => try posix.dup2(pipe_fd, std_fileno),
+            .Close => posix.close(std_fileno),
             .Inherit => {},
-            .Ignore => try os.dup2(dev_null_fd, std_fileno),
+            .Ignore => try posix.dup2(dev_null_fd, std_fileno),
         }
     }
 };
@@ -987,7 +988,7 @@ fn windowsCreateProcessPathExt(
 
     // This 2048 is arbitrary, we just want it to be large enough to get multiple FILE_DIRECTORY_INFORMATION entries
     // returned per NtQueryDirectoryFile call.
-    var file_information_buf: [2048]u8 align(@alignOf(os.windows.FILE_DIRECTORY_INFORMATION)) = undefined;
+    var file_information_buf: [2048]u8 align(@alignOf(windows.FILE_DIRECTORY_INFORMATION)) = undefined;
     const file_info_maximum_single_entry_size = @sizeOf(windows.FILE_DIRECTORY_INFORMATION) + (windows.NAME_MAX * 2);
     if (file_information_buf.len < file_info_maximum_single_entry_size) {
         @compileError("file_information_buf must be large enough to contain at least one maximum size FILE_DIRECTORY_INFORMATION entry");
@@ -1391,8 +1392,8 @@ fn testArgvToCommandLineWindows(argv: []const []const u8, expected_cmd_line: []c
 }
 
 fn windowsDestroyPipe(rd: ?windows.HANDLE, wr: ?windows.HANDLE) void {
-    if (rd) |h| os.close(h);
-    if (wr) |h| os.close(h);
+    if (rd) |h| posix.close(h);
+    if (wr) |h| posix.close(h);
 }
 
 fn windowsMakePipeIn(rd: *?windows.HANDLE, wr: *?windows.HANDLE, sattr: *const windows.SECURITY_ATTRIBUTES) !void {
@@ -1443,7 +1444,7 @@ fn windowsMakeAsyncPipe(rd: *?windows.HANDLE, wr: *?windows.HANDLE, sattr: *cons
             else => |err| return windows.unexpectedError(err),
         }
     }
-    errdefer os.close(read_handle);
+    errdefer posix.close(read_handle);
 
     var sattr_copy = sattr.*;
     const write_handle = windows.kernel32.CreateFileW(
@@ -1460,7 +1461,7 @@ fn windowsMakeAsyncPipe(rd: *?windows.HANDLE, wr: *?windows.HANDLE, sattr: *cons
             else => |err| return windows.unexpectedError(err),
         }
     }
-    errdefer os.close(write_handle);
+    errdefer posix.close(write_handle);
 
     try windows.SetHandleInformation(read_handle, windows.HANDLE_FLAG_INHERIT, 0);
 
@@ -1468,9 +1469,9 @@ fn windowsMakeAsyncPipe(rd: *?windows.HANDLE, wr: *?windows.HANDLE, sattr: *cons
     wr.* = write_handle;
 }
 
-fn destroyPipe(pipe: [2]os.fd_t) void {
-    os.close(pipe[0]);
-    if (pipe[0] != pipe[1]) os.close(pipe[1]);
+fn destroyPipe(pipe: [2]posix.fd_t) void {
+    posix.close(pipe[0]);
+    if (pipe[0] != pipe[1]) posix.close(pipe[1]);
 }
 
 // Child of fork calls this to report an error to the fork parent.
@@ -1485,7 +1486,7 @@ fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn {
         // The _exit(2) function does nothing but make the exit syscall, unlike exit(3)
         std.c._exit(1);
     }
-    os.exit(1);
+    posix.exit(1);
 }
 
 const ErrInt = std.meta.Int(.unsigned, @sizeOf(anyerror) * 8);
lib/std/debug.zig
@@ -3,7 +3,7 @@ const builtin = @import("builtin");
 const math = std.math;
 const mem = std.mem;
 const io = std.io;
-const os = std.os;
+const posix = std.posix;
 const fs = std.fs;
 const testing = std.testing;
 const elf = std.elf;
@@ -34,7 +34,7 @@ pub const sys_can_stack_trace = switch (builtin.cpu.arch) {
     // "Non-Emscripten WebAssembly hasn't implemented __builtin_return_address".
     .wasm32,
     .wasm64,
-    => builtin.os.tag == .emscripten,
+    => native_os == .emscripten,
 
     // `@returnAddress()` is unsupported in LLVM 13.
     .bpfel,
@@ -192,8 +192,8 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
     }
 }
 
-pub const have_ucontext = @hasDecl(os.system, "ucontext_t") and
-    (builtin.os.tag != .linux or switch (builtin.cpu.arch) {
+pub const have_ucontext = @hasDecl(posix.system, "ucontext_t") and
+    (native_os != .linux or switch (builtin.cpu.arch) {
     .mips, .mipsel, .mips64, .mips64el, .riscv64 => false,
     else => true,
 });
@@ -203,9 +203,9 @@ pub const have_ucontext = @hasDecl(os.system, "ucontext_t") and
 /// use internal pointers within this structure. To make a copy, use `copyContext`.
 pub const ThreadContext = blk: {
     if (native_os == .windows) {
-        break :blk std.os.windows.CONTEXT;
+        break :blk windows.CONTEXT;
     } else if (have_ucontext) {
-        break :blk os.ucontext_t;
+        break :blk posix.ucontext_t;
     } else {
         break :blk void;
     }
@@ -228,9 +228,9 @@ pub fn relocateContext(context: *ThreadContext) void {
     };
 }
 
-pub const have_getcontext = @hasDecl(os.system, "getcontext") and
-    builtin.os.tag != .openbsd and
-    (builtin.os.tag != .linux or switch (builtin.cpu.arch) {
+pub const have_getcontext = @hasDecl(posix.system, "getcontext") and
+    native_os != .openbsd and
+    (native_os != .linux or switch (builtin.cpu.arch) {
     .x86,
     .x86_64,
     => true,
@@ -249,7 +249,7 @@ pub inline fn getContext(context: *ThreadContext) bool {
         return true;
     }
 
-    const result = have_getcontext and os.system.getcontext(context) == 0;
+    const result = have_getcontext and posix.system.getcontext(context) == 0;
     if (native_os == .macos) {
         assert(context.mcsize == @sizeOf(std.c.mcontext_t));
 
@@ -470,12 +470,12 @@ pub fn panicImpl(trace: ?*const std.builtin.StackTrace, first_trace_addr: ?usize
 
                 const stderr = io.getStdErr().writer();
                 if (builtin.single_threaded) {
-                    stderr.print("panic: ", .{}) catch os.abort();
+                    stderr.print("panic: ", .{}) catch posix.abort();
                 } else {
                     const current_thread_id = std.Thread.getCurrentId();
-                    stderr.print("thread {} panic: ", .{current_thread_id}) catch os.abort();
+                    stderr.print("thread {} panic: ", .{current_thread_id}) catch posix.abort();
                 }
-                stderr.print("{s}\n", .{msg}) catch os.abort();
+                stderr.print("{s}\n", .{msg}) catch posix.abort();
                 if (trace) |t| {
                     dumpStackTrace(t.*);
                 }
@@ -491,14 +491,14 @@ pub fn panicImpl(trace: ?*const std.builtin.StackTrace, first_trace_addr: ?usize
             // we're still holding the mutex but that's fine as we're going to
             // call abort()
             const stderr = io.getStdErr().writer();
-            stderr.print("Panicked during a panic. Aborting.\n", .{}) catch os.abort();
+            stderr.print("Panicked during a panic. Aborting.\n", .{}) catch posix.abort();
         },
         else => {
             // Panicked while printing "Panicked during a panic."
         },
     };
 
-    os.abort();
+    posix.abort();
 }
 
 /// Must be called only after adding 1 to `panicking`. There are three callsites.
@@ -584,7 +584,7 @@ pub const StackIterator = struct {
         };
     }
 
-    pub fn initWithContext(first_address: ?usize, debug_info: *DebugInfo, context: *const os.ucontext_t) !StackIterator {
+    pub fn initWithContext(first_address: ?usize, debug_info: *DebugInfo, context: *const posix.ucontext_t) !StackIterator {
         // The implementation of DWARF unwinding on aarch64-macos is not complete. However, Apple mandates that
         // the frame pointer register is always used, so on this platform we can safely use the FP-based unwinder.
         if (comptime builtin.target.isDarwin() and native_arch == .aarch64) {
@@ -668,12 +668,11 @@ pub const StackIterator = struct {
         const aligned_memory = @as([*]align(mem.page_size) u8, @ptrFromInt(aligned_address))[0..mem.page_size];
 
         if (native_os == .windows) {
-            const w = os.windows;
-            var memory_info: w.MEMORY_BASIC_INFORMATION = undefined;
+            var memory_info: windows.MEMORY_BASIC_INFORMATION = undefined;
 
             // The only error this function can throw is ERROR_INVALID_PARAMETER.
             // supply an address that invalid i'll be thrown.
-            const rc = w.VirtualQuery(aligned_memory, &memory_info, aligned_memory.len) catch {
+            const rc = windows.VirtualQuery(aligned_memory, &memory_info, aligned_memory.len) catch {
                 return false;
             };
 
@@ -683,17 +682,15 @@ pub const StackIterator = struct {
             }
 
             // Free pages cannot be read, they are unmapped
-            if (memory_info.State == w.MEM_FREE) {
+            if (memory_info.State == windows.MEM_FREE) {
                 return false;
             }
 
             return true;
-        } else if (@hasDecl(os.system, "msync") and native_os != .wasi and native_os != .emscripten) {
-            os.msync(aligned_memory, os.MSF.ASYNC) catch |err| {
+        } else if (@hasDecl(posix.system, "msync") and native_os != .wasi and native_os != .emscripten) {
+            posix.msync(aligned_memory, posix.MSF.ASYNC) catch |err| {
                 switch (err) {
-                    os.MSyncError.UnmappedMemory => {
-                        return false;
-                    },
+                    error.UnmappedMemory => return false,
                     else => unreachable,
                 }
             };
@@ -1296,7 +1293,7 @@ pub fn readElfDebugInfo(
                 }
 
                 var cwd_buf: [fs.MAX_PATH_BYTES]u8 = undefined;
-                const cwd_path = os.realpath(".", &cwd_buf) catch break :blk;
+                const cwd_path = posix.realpath(".", &cwd_buf) catch break :blk;
 
                 // <global debug directory>/<absolute folder of current binary>/<gnu_debuglink>
                 for (global_debug_directories) |global_directory| {
@@ -1651,15 +1648,15 @@ fn mapWholeFile(file: File) ![]align(mem.page_size) const u8 {
         defer file.close();
 
         const file_len = math.cast(usize, try file.getEndPos()) orelse math.maxInt(usize);
-        const mapped_mem = try os.mmap(
+        const mapped_mem = try posix.mmap(
             null,
             file_len,
-            os.PROT.READ,
+            posix.PROT.READ,
             .{ .TYPE = .SHARED },
             file.handle,
             0,
         );
-        errdefer os.munmap(mapped_mem);
+        errdefer posix.munmap(mapped_mem);
 
         return mapped_mem;
     }
@@ -1997,8 +1994,8 @@ pub const DebugInfo = struct {
         } = .{ .address = address };
         const CtxTy = @TypeOf(ctx);
 
-        if (os.dl_iterate_phdr(&ctx, error{Found}, struct {
-            fn callback(info: *os.dl_phdr_info, size: usize, context: *CtxTy) !void {
+        if (posix.dl_iterate_phdr(&ctx, error{Found}, struct {
+            fn callback(info: *posix.dl_phdr_info, size: usize, context: *CtxTy) !void {
                 _ = size;
                 if (context.address < info.dlpi_addr) return;
                 const phdrs = info.dlpi_phdr[0..info.dlpi_phnum];
@@ -2036,8 +2033,8 @@ pub const DebugInfo = struct {
         } = .{ .address = address };
         const CtxTy = @TypeOf(ctx);
 
-        if (os.dl_iterate_phdr(&ctx, error{Found}, struct {
-            fn callback(info: *os.dl_phdr_info, size: usize, context: *CtxTy) !void {
+        if (posix.dl_iterate_phdr(&ctx, error{Found}, struct {
+            fn callback(info: *posix.dl_phdr_info, size: usize, context: *CtxTy) !void {
                 _ = size;
                 // The base address is too high
                 if (context.address < info.dlpi_addr)
@@ -2159,7 +2156,7 @@ pub const ModuleDebugInfo = switch (native_os) {
             }
             self.ofiles.deinit();
             allocator.free(self.symbols);
-            os.munmap(self.mapped_memory);
+            posix.munmap(self.mapped_memory);
         }
 
         fn loadOFile(self: *@This(), allocator: mem.Allocator, o_file_path: []const u8) !*OFileInfo {
@@ -2433,8 +2430,8 @@ pub const ModuleDebugInfo = switch (native_os) {
 
         pub fn deinit(self: *@This(), allocator: mem.Allocator) void {
             self.dwarf.deinit(allocator);
-            os.munmap(self.mapped_memory);
-            if (self.external_mapped_memory) |m| os.munmap(m);
+            posix.munmap(self.mapped_memory);
+            if (self.external_mapped_memory) |m| posix.munmap(m);
         }
 
         pub fn getSymbolAtAddress(self: *@This(), allocator: mem.Allocator, address: usize) !SymbolInfo {
@@ -2514,7 +2511,7 @@ pub const have_segfault_handling_support = switch (native_os) {
     .windows,
     => true,
 
-    .freebsd, .openbsd => @hasDecl(os.system, "ucontext_t"),
+    .freebsd, .openbsd => @hasDecl(std.c, "ucontext_t"),
     else => false,
 };
 
@@ -2529,11 +2526,11 @@ pub fn maybeEnableSegfaultHandler() void {
 
 var windows_segfault_handle: ?windows.HANDLE = null;
 
-pub fn updateSegfaultHandler(act: ?*const os.Sigaction) error{OperationNotSupported}!void {
-    try os.sigaction(os.SIG.SEGV, act, null);
-    try os.sigaction(os.SIG.ILL, act, null);
-    try os.sigaction(os.SIG.BUS, act, null);
-    try os.sigaction(os.SIG.FPE, act, null);
+pub fn updateSegfaultHandler(act: ?*const posix.Sigaction) error{OperationNotSupported}!void {
+    try posix.sigaction(posix.SIG.SEGV, act, null);
+    try posix.sigaction(posix.SIG.ILL, act, null);
+    try posix.sigaction(posix.SIG.BUS, act, null);
+    try posix.sigaction(posix.SIG.FPE, act, null);
 }
 
 /// Attaches a global SIGSEGV handler which calls `@panic("segmentation fault");`
@@ -2545,10 +2542,10 @@ pub fn attachSegfaultHandler() void {
         windows_segfault_handle = windows.kernel32.AddVectoredExceptionHandler(0, handleSegfaultWindows);
         return;
     }
-    var act = os.Sigaction{
+    var act = posix.Sigaction{
         .handler = .{ .sigaction = handleSegfaultPosix },
-        .mask = os.empty_sigset,
-        .flags = (os.SA.SIGINFO | os.SA.RESTART | os.SA.RESETHAND),
+        .mask = posix.empty_sigset,
+        .flags = (posix.SA.SIGINFO | posix.SA.RESTART | posix.SA.RESETHAND),
     };
 
     updateSegfaultHandler(&act) catch {
@@ -2564,16 +2561,16 @@ fn resetSegfaultHandler() void {
         }
         return;
     }
-    var act = os.Sigaction{
-        .handler = .{ .handler = os.SIG.DFL },
-        .mask = os.empty_sigset,
+    var act = posix.Sigaction{
+        .handler = .{ .handler = posix.SIG.DFL },
+        .mask = posix.empty_sigset,
         .flags = 0,
     };
     // To avoid a double-panic, do nothing if an error happens here.
     updateSegfaultHandler(&act) catch {};
 }
 
-fn handleSegfaultPosix(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const anyopaque) callconv(.C) noreturn {
+fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*const anyopaque) callconv(.C) noreturn {
     // Reset to the default handler so that if a segfault happens in this handler it will crash
     // the process. Also when this handler returns, the original instruction will be repeated
     // and the resulting segfault will crash the process rather than continually dump stack traces.
@@ -2612,13 +2609,13 @@ fn handleSegfaultPosix(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const any
     // We cannot allow the signal handler to return because when it runs the original instruction
     // again, the memory may be mapped and undefined behavior would occur rather than repeating
     // the segfault. So we simply abort here.
-    os.abort();
+    posix.abort();
 }
 
 fn dumpSegfaultInfoPosix(sig: i32, code: i32, addr: usize, ctx_ptr: ?*const anyopaque) void {
     const stderr = io.getStdErr().writer();
     _ = switch (sig) {
-        os.SIG.SEGV => if (native_arch == .x86_64 and native_os == .linux and code == 128) // SI_KERNEL
+        posix.SIG.SEGV => if (native_arch == .x86_64 and native_os == .linux and code == 128) // SI_KERNEL
             // x86_64 doesn't have a full 64-bit virtual address space.
             // Addresses outside of that address space are non-canonical
             // and the CPU won't provide the faulting address to us.
@@ -2629,11 +2626,11 @@ fn dumpSegfaultInfoPosix(sig: i32, code: i32, addr: usize, ctx_ptr: ?*const anyo
             stderr.print("General protection exception (no address available)\n", .{})
         else
             stderr.print("Segmentation fault at address 0x{x}\n", .{addr}),
-        os.SIG.ILL => stderr.print("Illegal instruction at address 0x{x}\n", .{addr}),
-        os.SIG.BUS => stderr.print("Bus error at address 0x{x}\n", .{addr}),
-        os.SIG.FPE => stderr.print("Arithmetic exception at address 0x{x}\n", .{addr}),
+        posix.SIG.ILL => stderr.print("Illegal instruction at address 0x{x}\n", .{addr}),
+        posix.SIG.BUS => stderr.print("Bus error at address 0x{x}\n", .{addr}),
+        posix.SIG.FPE => stderr.print("Arithmetic exception at address 0x{x}\n", .{addr}),
         else => unreachable,
-    } catch os.abort();
+    } catch posix.abort();
 
     switch (native_arch) {
         .x86,
@@ -2641,7 +2638,7 @@ fn dumpSegfaultInfoPosix(sig: i32, code: i32, addr: usize, ctx_ptr: ?*const anyo
         .arm,
         .aarch64,
         => {
-            const ctx: *const os.ucontext_t = @ptrCast(@alignCast(ctx_ptr));
+            const ctx: *const posix.ucontext_t = @ptrCast(@alignCast(ctx_ptr));
             dumpStackTraceFromBase(ctx);
         },
         else => {},
@@ -2684,7 +2681,7 @@ fn handleSegfaultWindowsExtra(
                 dumpSegfaultInfoWindows(info, msg, label);
             },
         };
-        os.abort();
+        posix.abort();
     } else {
         switch (msg) {
             0 => panicImpl(null, exception_address, "{s}", label.?),
@@ -2707,7 +2704,7 @@ fn dumpSegfaultInfoWindows(info: *windows.EXCEPTION_POINTERS, msg: u8, label: ?[
         1 => stderr.print("Segmentation fault at address 0x{x}\n", .{info.ExceptionRecord.ExceptionInformation[1]}),
         2 => stderr.print("Illegal instruction at address 0x{x}\n", .{info.ContextRecord.getRegs().ip}),
         else => unreachable,
-    } catch os.abort();
+    } catch posix.abort();
 
     dumpStackTraceFromBase(info.ContextRecord);
 }
@@ -2722,9 +2719,9 @@ pub fn dumpStackPointerAddr(prefix: []const u8) void {
 test "manage resources correctly" {
     if (builtin.strip_debug_info) return error.SkipZigTest;
 
-    if (builtin.os.tag == .wasi) return error.SkipZigTest;
+    if (native_os == .wasi) return error.SkipZigTest;
 
-    if (builtin.os.tag == .windows) {
+    if (native_os == .windows) {
         // https://github.com/ziglang/zig/issues/13963
         return error.SkipZigTest;
     }
lib/std/dwarf.zig
@@ -2188,12 +2188,12 @@ pub fn openDwarfDebugInfo(di: *DwarfInfo, allocator: mem.Allocator) !void {
 /// This function is to make it handy to comment out the return and make it
 /// into a crash when working on this file.
 fn badDwarf() error{InvalidDebugInfo} {
-    //std.os.abort(); // can be handy to uncomment when working on this file
+    //if (true) @panic("badDwarf"); // can be handy to uncomment when working on this file
     return error.InvalidDebugInfo;
 }
 
 fn missingDwarf() error{MissingDebugInfo} {
-    //std.os.abort(); // can be handy to uncomment when working on this file
+    //if (true) @panic("missingDwarf"); // can be handy to uncomment when working on this file
     return error.MissingDebugInfo;
 }
 
lib/std/dynamic_library.zig
@@ -1,16 +1,16 @@
 const std = @import("std.zig");
 const builtin = @import("builtin");
 const mem = std.mem;
-const os = std.os;
 const testing = std.testing;
 const elf = std.elf;
 const windows = std.os.windows;
-const system = std.os.system;
+const native_os = builtin.os.tag;
+const posix = std.posix;
 
 /// Cross-platform dynamic library loading and symbol lookup.
 /// Platform-specific functionality is available through the `inner` field.
 pub const DynLib = struct {
-    const InnerType = switch (builtin.os.tag) {
+    const InnerType = switch (native_os) {
         .linux => if (!builtin.link_libc or builtin.abi == .musl and builtin.link_mode == .static)
             ElfDynLib
         else
@@ -125,7 +125,7 @@ pub fn linkmap_iterator(phdrs: []elf.Phdr) error{InvalidExe}!LinkMap.Iterator {
 pub const ElfDynLib = struct {
     strings: [*:0]u8,
     syms: [*]elf.Sym,
-    hashtab: [*]os.Elf_Symndx,
+    hashtab: [*]posix.Elf_Symndx,
     versym: ?[*]u16,
     verdef: ?*elf.Verdef,
     memory: []align(mem.page_size) u8,
@@ -138,27 +138,27 @@ pub const ElfDynLib = struct {
         ElfStringSectionNotFound,
         ElfSymSectionNotFound,
         ElfHashTableNotFound,
-    } || os.OpenError || os.MMapError;
+    } || posix.OpenError || posix.MMapError;
 
     /// Trusts the file. Malicious file will be able to execute arbitrary code.
     pub fn open(path: []const u8) Error!ElfDynLib {
-        const fd = try os.open(path, .{ .ACCMODE = .RDONLY, .CLOEXEC = true }, 0);
-        defer os.close(fd);
+        const fd = try posix.open(path, .{ .ACCMODE = .RDONLY, .CLOEXEC = true }, 0);
+        defer posix.close(fd);
 
-        const stat = try os.fstat(fd);
+        const stat = try posix.fstat(fd);
         const size = std.math.cast(usize, stat.size) orelse return error.FileTooBig;
 
         // This one is to read the ELF info. We do more mmapping later
         // corresponding to the actual LOAD sections.
-        const file_bytes = try os.mmap(
+        const file_bytes = try posix.mmap(
             null,
             mem.alignForward(usize, size, mem.page_size),
-            os.PROT.READ,
+            posix.PROT.READ,
             .{ .TYPE = .PRIVATE },
             fd,
             0,
         );
-        defer os.munmap(file_bytes);
+        defer posix.munmap(file_bytes);
 
         const eh = @as(*elf.Ehdr, @ptrCast(file_bytes.ptr));
         if (!mem.eql(u8, eh.e_ident[0..4], elf.MAGIC)) return error.NotElfFile;
@@ -188,15 +188,15 @@ pub const ElfDynLib = struct {
         const dynv = maybe_dynv orelse return error.MissingDynamicLinkingInformation;
 
         // Reserve the entire range (with no permissions) so that we can do MAP.FIXED below.
-        const all_loaded_mem = try os.mmap(
+        const all_loaded_mem = try posix.mmap(
             null,
             virt_addr_end,
-            os.PROT.NONE,
+            posix.PROT.NONE,
             .{ .TYPE = .PRIVATE, .ANONYMOUS = true },
             -1,
             0,
         );
-        errdefer os.munmap(all_loaded_mem);
+        errdefer posix.munmap(all_loaded_mem);
 
         const base = @intFromPtr(all_loaded_mem.ptr);
 
@@ -220,7 +220,7 @@ pub const ElfDynLib = struct {
                         const prot = elfToMmapProt(ph.p_flags);
                         if ((ph.p_flags & elf.PF_W) == 0) {
                             // If it does not need write access, it can be mapped from the fd.
-                            _ = try os.mmap(
+                            _ = try posix.mmap(
                                 ptr,
                                 extended_memsz,
                                 prot,
@@ -229,7 +229,7 @@ pub const ElfDynLib = struct {
                                 ph.p_offset - extra_bytes,
                             );
                         } else {
-                            const sect_mem = try os.mmap(
+                            const sect_mem = try posix.mmap(
                                 ptr,
                                 extended_memsz,
                                 prot,
@@ -247,7 +247,7 @@ pub const ElfDynLib = struct {
 
         var maybe_strings: ?[*:0]u8 = null;
         var maybe_syms: ?[*]elf.Sym = null;
-        var maybe_hashtab: ?[*]os.Elf_Symndx = null;
+        var maybe_hashtab: ?[*]posix.Elf_Symndx = null;
         var maybe_versym: ?[*]u16 = null;
         var maybe_verdef: ?*elf.Verdef = null;
 
@@ -258,7 +258,7 @@ pub const ElfDynLib = struct {
                 switch (dynv[i]) {
                     elf.DT_STRTAB => maybe_strings = @as([*:0]u8, @ptrFromInt(p)),
                     elf.DT_SYMTAB => maybe_syms = @as([*]elf.Sym, @ptrFromInt(p)),
-                    elf.DT_HASH => maybe_hashtab = @as([*]os.Elf_Symndx, @ptrFromInt(p)),
+                    elf.DT_HASH => maybe_hashtab = @as([*]posix.Elf_Symndx, @ptrFromInt(p)),
                     elf.DT_VERSYM => maybe_versym = @as([*]u16, @ptrFromInt(p)),
                     elf.DT_VERDEF => maybe_verdef = @as(*elf.Verdef, @ptrFromInt(p)),
                     else => {},
@@ -283,7 +283,7 @@ pub const ElfDynLib = struct {
 
     /// Trusts the file
     pub fn close(self: *ElfDynLib) void {
-        os.munmap(self.memory);
+        posix.munmap(self.memory);
         self.* = undefined;
     }
 
@@ -320,10 +320,10 @@ pub const ElfDynLib = struct {
     }
 
     fn elfToMmapProt(elf_prot: u64) u32 {
-        var result: u32 = os.PROT.NONE;
-        if ((elf_prot & elf.PF_R) != 0) result |= os.PROT.READ;
-        if ((elf_prot & elf.PF_W) != 0) result |= os.PROT.WRITE;
-        if ((elf_prot & elf.PF_X) != 0) result |= os.PROT.EXEC;
+        var result: u32 = posix.PROT.NONE;
+        if ((elf_prot & elf.PF_R) != 0) result |= posix.PROT.READ;
+        if ((elf_prot & elf.PF_W) != 0) result |= posix.PROT.WRITE;
+        if ((elf_prot & elf.PF_X) != 0) result |= posix.PROT.EXEC;
         return result;
     }
 };
@@ -343,7 +343,7 @@ fn checkver(def_arg: *elf.Verdef, vsym_arg: i32, vername: []const u8, strings: [
 }
 
 test "ElfDynLib" {
-    if (builtin.os.tag != .linux) {
+    if (native_os != .linux) {
         return error.SkipZigTest;
     }
 
@@ -419,20 +419,20 @@ pub const DlDynLib = struct {
     handle: *anyopaque,
 
     pub fn open(path: []const u8) Error!DlDynLib {
-        const path_c = try os.toPosixPath(path);
+        const path_c = try posix.toPosixPath(path);
         return openZ(&path_c);
     }
 
     pub fn openZ(path_c: [*:0]const u8) Error!DlDynLib {
         return .{
-            .handle = system.dlopen(path_c, system.RTLD.LAZY) orelse {
+            .handle = std.c.dlopen(path_c, std.c.RTLD.LAZY) orelse {
                 return error.FileNotFound;
             },
         };
     }
 
     pub fn close(self: *DlDynLib) void {
-        switch (std.os.errno(system.dlclose(self.handle))) {
+        switch (posix.errno(std.c.dlclose(self.handle))) {
             .SUCCESS => return,
             else => unreachable,
         }
@@ -442,7 +442,7 @@ pub const DlDynLib = struct {
     pub fn lookup(self: *DlDynLib, comptime T: type, name: [:0]const u8) ?T {
         // dlsym (and other dl-functions) secretly take shadow parameter - return address on stack
         // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66826
-        if (@call(.never_tail, system.dlsym, .{ self.handle, name.ptr })) |symbol| {
+        if (@call(.never_tail, std.c.dlsym, .{ self.handle, name.ptr })) |symbol| {
             return @as(T, @ptrCast(@alignCast(symbol)));
         } else {
             return null;
@@ -453,12 +453,12 @@ pub const DlDynLib = struct {
     /// Returns human readable string describing most recent error than occurred from `lookup`
     /// or `null` if no error has occurred since initialization or when `getError` was last called.
     pub fn getError() ?[:0]const u8 {
-        return mem.span(system.dlerror());
+        return mem.span(std.c.dlerror());
     }
 };
 
 test "dynamic_library" {
-    const libname = switch (builtin.os.tag) {
+    const libname = switch (native_os) {
         .linux, .freebsd, .openbsd, .solaris, .illumos => "invalid_so.so",
         .windows => "invalid_dll.dll",
         .macos, .tvos, .watchos, .ios => "invalid_dylib.dylib",
lib/std/fs.zig
@@ -3,21 +3,23 @@
 const std = @import("std.zig");
 const builtin = @import("builtin");
 const root = @import("root");
-const os = std.os;
 const mem = std.mem;
 const base64 = std.base64;
 const crypto = std.crypto;
 const Allocator = std.mem.Allocator;
 const assert = std.debug.assert;
+const native_os = builtin.os.tag;
+const posix = std.posix;
+const windows = std.os.windows;
 
-const is_darwin = builtin.os.tag.isDarwin();
+const is_darwin = native_os.isDarwin();
 
 pub const AtomicFile = @import("fs/AtomicFile.zig");
 pub const Dir = @import("fs/Dir.zig");
 pub const File = @import("fs/File.zig");
 pub const path = @import("fs/path.zig");
 
-pub const has_executable_bit = switch (builtin.os.tag) {
+pub const has_executable_bit = switch (native_os) {
     .windows, .wasi => false,
     else => true,
 };
@@ -26,36 +28,43 @@ pub const wasi = @import("fs/wasi.zig");
 
 // TODO audit these APIs with respect to Dir and absolute paths
 
-pub const realpath = os.realpath;
-pub const realpathZ = os.realpathZ;
-pub const realpathW = os.realpathW;
+pub const realpath = posix.realpath;
+pub const realpathZ = posix.realpathZ;
+pub const realpathW = posix.realpathW;
 
 pub const getAppDataDir = @import("fs/get_app_data_dir.zig").getAppDataDir;
 pub const GetAppDataDirError = @import("fs/get_app_data_dir.zig").GetAppDataDirError;
 
-/// This represents the maximum size of a `[]u8` file path that the
-/// operating system will accept. Paths, including those returned from file
-/// system operations, may be longer than this length, but such paths cannot
-/// be successfully passed back in other file system operations. However,
-/// all path components returned by file system operations are assumed to
-/// fit into a `u8` array of this length.
+/// Deprecated: use `max_path_bytes`.
+pub const MAX_PATH_BYTES = max_path_bytes;
+
+/// The maximum length of a file path that the operating system will accept.
+///
+/// Paths, including those returned from file system operations, may be longer
+/// than this length, but such paths cannot be successfully passed back in
+/// other file system operations. However, all path components returned by file
+/// system operations are assumed to fit into a `u8` array of this length.
+///
 /// The byte count includes room for a null sentinel byte.
-/// On Windows, `[]u8` file paths are encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// On WASI, `[]u8` file paths are encoded as valid UTF-8.
-/// On other platforms, `[]u8` file paths are opaque sequences of bytes with no particular encoding.
-pub const MAX_PATH_BYTES = switch (builtin.os.tag) {
-    .linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .haiku, .solaris, .illumos, .plan9, .emscripten => os.PATH_MAX,
+///
+/// * On Windows, `[]u8` file paths are encoded as
+///   [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// * On WASI, `[]u8` file paths are encoded as valid UTF-8.
+/// * On other platforms, `[]u8` file paths are opaque sequences of bytes with
+///   no particular encoding.
+pub const max_path_bytes = switch (native_os) {
+    .linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .haiku, .solaris, .illumos, .plan9, .emscripten => posix.PATH_MAX,
     // Each WTF-16LE code unit may be expanded to 3 WTF-8 bytes.
     // If it would require 4 WTF-8 bytes, then there would be a surrogate
     // pair in the WTF-16LE, and we (over)account 3 bytes for it that way.
     // +1 for the null byte at the end, which can be encoded in 1 byte.
-    .windows => os.windows.PATH_MAX_WIDE * 3 + 1,
+    .windows => windows.PATH_MAX_WIDE * 3 + 1,
     // TODO work out what a reasonable value we should use here
     .wasi => 4096,
     else => if (@hasDecl(root, "os") and @hasDecl(root.os, "PATH_MAX"))
         root.os.PATH_MAX
     else
-        @compileError("PATH_MAX not implemented for " ++ @tagName(builtin.os.tag)),
+        @compileError("PATH_MAX not implemented for " ++ @tagName(native_os)),
 };
 
 /// This represents the maximum size of a `[]u8` file name component that
@@ -66,22 +75,22 @@ pub const MAX_PATH_BYTES = switch (builtin.os.tag) {
 /// On Windows, `[]u8` file name components are encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
 /// On WASI, file name components are encoded as valid UTF-8.
 /// On other platforms, `[]u8` components are an opaque sequence of bytes with no particular encoding.
-pub const MAX_NAME_BYTES = switch (builtin.os.tag) {
-    .linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .solaris, .illumos => os.NAME_MAX,
+pub const MAX_NAME_BYTES = switch (native_os) {
+    .linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .solaris, .illumos => posix.NAME_MAX,
     // Haiku's NAME_MAX includes the null terminator, so subtract one.
-    .haiku => os.NAME_MAX - 1,
+    .haiku => posix.NAME_MAX - 1,
     // Each WTF-16LE character may be expanded to 3 WTF-8 bytes.
     // If it would require 4 WTF-8 bytes, then there would be a surrogate
     // pair in the WTF-16LE, and we (over)account 3 bytes for it that way.
-    .windows => os.windows.NAME_MAX * 3,
+    .windows => windows.NAME_MAX * 3,
     // For WASI, the MAX_NAME will depend on the host OS, so it needs to be
     // as large as the largest MAX_NAME_BYTES (Windows) in order to work on any host OS.
     // TODO determine if this is a reasonable approach
-    .wasi => os.windows.NAME_MAX * 3,
+    .wasi => windows.NAME_MAX * 3,
     else => if (@hasDecl(root, "os") and @hasDecl(root.os, "NAME_MAX"))
         root.os.NAME_MAX
     else
-        @compileError("NAME_MAX not implemented for " ++ @tagName(builtin.os.tag)),
+        @compileError("NAME_MAX not implemented for " ++ @tagName(native_os)),
 };
 
 pub const base64_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".*;
@@ -167,19 +176,19 @@ pub fn copyFileAbsolute(
 /// On other platforms, `absolute_path` is an opaque sequence of bytes with no particular encoding.
 pub fn makeDirAbsolute(absolute_path: []const u8) !void {
     assert(path.isAbsolute(absolute_path));
-    return os.mkdir(absolute_path, Dir.default_mode);
+    return posix.mkdir(absolute_path, Dir.default_mode);
 }
 
 /// Same as `makeDirAbsolute` except the parameter is null-terminated.
 pub fn makeDirAbsoluteZ(absolute_path_z: [*:0]const u8) !void {
     assert(path.isAbsoluteZ(absolute_path_z));
-    return os.mkdirZ(absolute_path_z, Dir.default_mode);
+    return posix.mkdirZ(absolute_path_z, Dir.default_mode);
 }
 
 /// Same as `makeDirAbsolute` except the parameter is a null-terminated WTF-16 LE-encoded string.
 pub fn makeDirAbsoluteW(absolute_path_w: [*:0]const u16) !void {
     assert(path.isAbsoluteWindowsW(absolute_path_w));
-    return os.mkdirW(absolute_path_w, Dir.default_mode);
+    return posix.mkdirW(absolute_path_w, Dir.default_mode);
 }
 
 /// Same as `Dir.deleteDir` except the path is absolute.
@@ -188,19 +197,19 @@ pub fn makeDirAbsoluteW(absolute_path_w: [*:0]const u16) !void {
 /// On other platforms, `dir_path` is an opaque sequence of bytes with no particular encoding.
 pub fn deleteDirAbsolute(dir_path: []const u8) !void {
     assert(path.isAbsolute(dir_path));
-    return os.rmdir(dir_path);
+    return posix.rmdir(dir_path);
 }
 
 /// Same as `deleteDirAbsolute` except the path parameter is null-terminated.
 pub fn deleteDirAbsoluteZ(dir_path: [*:0]const u8) !void {
     assert(path.isAbsoluteZ(dir_path));
-    return os.rmdirZ(dir_path);
+    return posix.rmdirZ(dir_path);
 }
 
 /// Same as `deleteDirAbsolute` except the path parameter is WTF-16 and target OS is assumed Windows.
 pub fn deleteDirAbsoluteW(dir_path: [*:0]const u16) !void {
     assert(path.isAbsoluteWindowsW(dir_path));
-    return os.rmdirW(dir_path);
+    return posix.rmdirW(dir_path);
 }
 
 /// Same as `Dir.rename` except the paths are absolute.
@@ -210,49 +219,49 @@ pub fn deleteDirAbsoluteW(dir_path: [*:0]const u16) !void {
 pub fn renameAbsolute(old_path: []const u8, new_path: []const u8) !void {
     assert(path.isAbsolute(old_path));
     assert(path.isAbsolute(new_path));
-    return os.rename(old_path, new_path);
+    return posix.rename(old_path, new_path);
 }
 
 /// Same as `renameAbsolute` except the path parameters are null-terminated.
 pub fn renameAbsoluteZ(old_path: [*:0]const u8, new_path: [*:0]const u8) !void {
     assert(path.isAbsoluteZ(old_path));
     assert(path.isAbsoluteZ(new_path));
-    return os.renameZ(old_path, new_path);
+    return posix.renameZ(old_path, new_path);
 }
 
 /// Same as `renameAbsolute` except the path parameters are WTF-16 and target OS is assumed Windows.
 pub fn renameAbsoluteW(old_path: [*:0]const u16, new_path: [*:0]const u16) !void {
     assert(path.isAbsoluteWindowsW(old_path));
     assert(path.isAbsoluteWindowsW(new_path));
-    return os.renameW(old_path, new_path);
+    return posix.renameW(old_path, new_path);
 }
 
 /// Same as `Dir.rename`, except `new_sub_path` is relative to `new_dir`
 pub fn rename(old_dir: Dir, old_sub_path: []const u8, new_dir: Dir, new_sub_path: []const u8) !void {
-    return os.renameat(old_dir.fd, old_sub_path, new_dir.fd, new_sub_path);
+    return posix.renameat(old_dir.fd, old_sub_path, new_dir.fd, new_sub_path);
 }
 
 /// Same as `rename` except the parameters are null-terminated.
 pub fn renameZ(old_dir: Dir, old_sub_path_z: [*:0]const u8, new_dir: Dir, new_sub_path_z: [*:0]const u8) !void {
-    return os.renameatZ(old_dir.fd, old_sub_path_z, new_dir.fd, new_sub_path_z);
+    return posix.renameatZ(old_dir.fd, old_sub_path_z, new_dir.fd, new_sub_path_z);
 }
 
 /// Same as `rename` except the parameters are WTF16LE, NT prefixed.
 /// This function is Windows-only.
 pub fn renameW(old_dir: Dir, old_sub_path_w: []const u16, new_dir: Dir, new_sub_path_w: []const u16) !void {
-    return os.renameatW(old_dir.fd, old_sub_path_w, new_dir.fd, new_sub_path_w);
+    return posix.renameatW(old_dir.fd, old_sub_path_w, new_dir.fd, new_sub_path_w);
 }
 
 /// Returns a handle to the current working directory. It is not opened with iteration capability.
 /// Closing the returned `Dir` is checked illegal behavior. Iterating over the result is illegal behavior.
 /// On POSIX targets, this function is comptime-callable.
 pub fn cwd() Dir {
-    if (builtin.os.tag == .windows) {
-        return .{ .fd = os.windows.peb().ProcessParameters.CurrentDirectory.Handle };
-    } else if (builtin.os.tag == .wasi) {
+    if (native_os == .windows) {
+        return .{ .fd = windows.peb().ProcessParameters.CurrentDirectory.Handle };
+    } else if (native_os == .wasi) {
         return .{ .fd = std.options.wasiCwd() };
     } else {
-        return .{ .fd = os.AT.FDCWD };
+        return .{ .fd = posix.AT.FDCWD };
     }
 }
 
@@ -412,20 +421,20 @@ pub fn deleteTreeAbsolute(absolute_path: []const u8) !void {
 /// On other platforms, `pathname` is an opaque sequence of bytes with no particular encoding.
 pub fn readLinkAbsolute(pathname: []const u8, buffer: *[MAX_PATH_BYTES]u8) ![]u8 {
     assert(path.isAbsolute(pathname));
-    return os.readlink(pathname, buffer);
+    return posix.readlink(pathname, buffer);
 }
 
 /// Windows-only. Same as `readlinkW`, except the path parameter is null-terminated, WTF16
 /// encoded.
 pub fn readlinkAbsoluteW(pathname_w: [*:0]const u16, buffer: *[MAX_PATH_BYTES]u8) ![]u8 {
     assert(path.isAbsoluteWindowsW(pathname_w));
-    return os.readlinkW(pathname_w, buffer);
+    return posix.readlinkW(pathname_w, buffer);
 }
 
 /// Same as `readLink`, except the path parameter is null-terminated.
 pub fn readLinkAbsoluteZ(pathname_c: [*:0]const u8, buffer: *[MAX_PATH_BYTES]u8) ![]u8 {
     assert(path.isAbsoluteZ(pathname_c));
-    return os.readlinkZ(pathname_c, buffer);
+    return posix.readlinkZ(pathname_c, buffer);
 }
 
 /// Creates a symbolic link named `sym_link_path` which contains the string `target_path`.
@@ -443,12 +452,12 @@ pub fn symLinkAbsolute(
 ) !void {
     assert(path.isAbsolute(target_path));
     assert(path.isAbsolute(sym_link_path));
-    if (builtin.os.tag == .windows) {
-        const target_path_w = try os.windows.sliceToPrefixedFileW(null, target_path);
-        const sym_link_path_w = try os.windows.sliceToPrefixedFileW(null, sym_link_path);
-        return os.windows.CreateSymbolicLink(null, sym_link_path_w.span(), target_path_w.span(), flags.is_directory);
+    if (native_os == .windows) {
+        const target_path_w = try windows.sliceToPrefixedFileW(null, target_path);
+        const sym_link_path_w = try windows.sliceToPrefixedFileW(null, sym_link_path);
+        return windows.CreateSymbolicLink(null, sym_link_path_w.span(), target_path_w.span(), flags.is_directory);
     }
-    return os.symlink(target_path, sym_link_path);
+    return posix.symlink(target_path, sym_link_path);
 }
 
 /// Windows-only. Same as `symLinkAbsolute` except the parameters are null-terminated, WTF16 LE encoded.
@@ -462,7 +471,7 @@ pub fn symLinkAbsoluteW(
 ) !void {
     assert(path.isAbsoluteWindowsWTF16(target_path_w));
     assert(path.isAbsoluteWindowsWTF16(sym_link_path_w));
-    return os.windows.CreateSymbolicLink(null, sym_link_path_w, target_path_w, flags.is_directory);
+    return windows.CreateSymbolicLink(null, sym_link_path_w, target_path_w, flags.is_directory);
 }
 
 /// Same as `symLinkAbsolute` except the parameters are null-terminated pointers.
@@ -474,27 +483,27 @@ pub fn symLinkAbsoluteZ(
 ) !void {
     assert(path.isAbsoluteZ(target_path_c));
     assert(path.isAbsoluteZ(sym_link_path_c));
-    if (builtin.os.tag == .windows) {
-        const target_path_w = try os.windows.cStrToPrefixedFileW(null, target_path_c);
-        const sym_link_path_w = try os.windows.cStrToPrefixedFileW(null, sym_link_path_c);
-        return os.windows.CreateSymbolicLink(null, sym_link_path_w.span(), target_path_w.span(), flags.is_directory);
+    if (native_os == .windows) {
+        const target_path_w = try windows.cStrToPrefixedFileW(null, target_path_c);
+        const sym_link_path_w = try windows.cStrToPrefixedFileW(null, sym_link_path_c);
+        return windows.CreateSymbolicLink(null, sym_link_path_w.span(), target_path_w.span(), flags.is_directory);
     }
-    return os.symlinkZ(target_path_c, sym_link_path_c);
+    return posix.symlinkZ(target_path_c, sym_link_path_c);
 }
 
-pub const OpenSelfExeError = os.OpenError || SelfExePathError || os.FlockError;
+pub const OpenSelfExeError = posix.OpenError || SelfExePathError || posix.FlockError;
 
 pub fn openSelfExe(flags: File.OpenFlags) OpenSelfExeError!File {
-    if (builtin.os.tag == .linux) {
+    if (native_os == .linux) {
         return openFileAbsoluteZ("/proc/self/exe", flags);
     }
-    if (builtin.os.tag == .windows) {
+    if (native_os == .windows) {
         // If ImagePathName is a symlink, then it will contain the path of the symlink,
         // not the path that the symlink points to. However, because we are opening
         // the file, we can let the openFileW call follow the symlink for us.
-        const image_path_unicode_string = &os.windows.peb().ProcessParameters.ImagePathName;
+        const image_path_unicode_string = &windows.peb().ProcessParameters.ImagePathName;
         const image_path_name = image_path_unicode_string.Buffer.?[0 .. image_path_unicode_string.Length / 2 :0];
-        const prefixed_path_w = try os.windows.wToPrefixedFileW(null, image_path_name);
+        const prefixed_path_w = try windows.wToPrefixedFileW(null, image_path_name);
         return cwd().openFileW(prefixed_path_w.span(), flags);
     }
     // Use of MAX_PATH_BYTES here is valid as the resulting path is immediately
@@ -505,7 +514,7 @@ pub fn openSelfExe(flags: File.OpenFlags) OpenSelfExeError!File {
     return openFileAbsoluteZ(buf[0..self_exe_path.len :0].ptr, flags);
 }
 
-// This is os.ReadLinkError || os.RealPathError with impossible errors excluded
+// This is `posix.ReadLinkError || posix.RealPathError` with impossible errors excluded
 pub const SelfExePathError = error{
     FileNotFound,
     AccessDenied,
@@ -542,7 +551,7 @@ pub const SelfExePathError = error{
     /// On Windows, the volume does not contain a recognized file system. File
     /// system drivers might not be loaded, or the volume may be corrupt.
     UnrecognizedVolume,
-} || os.SysCtlError;
+} || posix.SysCtlError;
 
 /// `selfExePath` except allocates the result on the heap.
 /// Caller owns returned memory.
@@ -580,7 +589,7 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
         if (rc != 0) return error.NameTooLong;
 
         var real_path_buf: [MAX_PATH_BYTES]u8 = undefined;
-        const real_path = std.os.realpathZ(&symlink_path_buf, &real_path_buf) catch |err| switch (err) {
+        const real_path = std.posix.realpathZ(&symlink_path_buf, &real_path_buf) catch |err| switch (err) {
             error.InvalidWtf8 => unreachable, // Windows-only
             error.NetworkNotFound => unreachable, // Windows-only
             else => |e| return e,
@@ -590,15 +599,15 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
         @memcpy(result, real_path);
         return result;
     }
-    switch (builtin.os.tag) {
-        .linux => return os.readlinkZ("/proc/self/exe", out_buffer) catch |err| switch (err) {
+    switch (native_os) {
+        .linux => return posix.readlinkZ("/proc/self/exe", out_buffer) catch |err| switch (err) {
             error.InvalidUtf8 => unreachable, // WASI-only
             error.InvalidWtf8 => unreachable, // Windows-only
             error.UnsupportedReparsePointType => unreachable, // Windows-only
             error.NetworkNotFound => unreachable, // Windows-only
             else => |e| return e,
         },
-        .solaris, .illumos => return os.readlinkZ("/proc/self/path/a.out", out_buffer) catch |err| switch (err) {
+        .solaris, .illumos => return posix.readlinkZ("/proc/self/path/a.out", out_buffer) catch |err| switch (err) {
             error.InvalidUtf8 => unreachable, // WASI-only
             error.InvalidWtf8 => unreachable, // Windows-only
             error.UnsupportedReparsePointType => unreachable, // Windows-only
@@ -606,29 +615,29 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
             else => |e| return e,
         },
         .freebsd, .dragonfly => {
-            var mib = [4]c_int{ os.CTL.KERN, os.KERN.PROC, os.KERN.PROC_PATHNAME, -1 };
+            var mib = [4]c_int{ posix.CTL.KERN, posix.KERN.PROC, posix.KERN.PROC_PATHNAME, -1 };
             var out_len: usize = out_buffer.len;
-            try os.sysctl(&mib, out_buffer.ptr, &out_len, null, 0);
+            try posix.sysctl(&mib, out_buffer.ptr, &out_len, null, 0);
             // TODO could this slice from 0 to out_len instead?
             return mem.sliceTo(out_buffer, 0);
         },
         .netbsd => {
-            var mib = [4]c_int{ os.CTL.KERN, os.KERN.PROC_ARGS, -1, os.KERN.PROC_PATHNAME };
+            var mib = [4]c_int{ posix.CTL.KERN, posix.KERN.PROC_ARGS, -1, posix.KERN.PROC_PATHNAME };
             var out_len: usize = out_buffer.len;
-            try os.sysctl(&mib, out_buffer.ptr, &out_len, null, 0);
+            try posix.sysctl(&mib, out_buffer.ptr, &out_len, null, 0);
             // TODO could this slice from 0 to out_len instead?
             return mem.sliceTo(out_buffer, 0);
         },
         .openbsd, .haiku => {
             // OpenBSD doesn't support getting the path of a running process, so try to guess it
-            if (os.argv.len == 0)
+            if (std.os.argv.len == 0)
                 return error.FileNotFound;
 
-            const argv0 = mem.span(os.argv[0]);
+            const argv0 = mem.span(std.os.argv[0]);
             if (mem.indexOf(u8, argv0, "/") != null) {
                 // argv[0] is a path (relative or absolute): use realpath(3) directly
                 var real_path_buf: [MAX_PATH_BYTES]u8 = undefined;
-                const real_path = os.realpathZ(os.argv[0], &real_path_buf) catch |err| switch (err) {
+                const real_path = posix.realpathZ(std.os.argv[0], &real_path_buf) catch |err| switch (err) {
                     error.InvalidWtf8 => unreachable, // Windows-only
                     error.NetworkNotFound => unreachable, // Windows-only
                     else => |e| return e,
@@ -640,17 +649,17 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
                 return result;
             } else if (argv0.len != 0) {
                 // argv[0] is not empty (and not a path): search it inside PATH
-                const PATH = std.os.getenvZ("PATH") orelse return error.FileNotFound;
+                const PATH = posix.getenvZ("PATH") orelse return error.FileNotFound;
                 var path_it = mem.tokenizeScalar(u8, PATH, path.delimiter);
                 while (path_it.next()) |a_path| {
                     var resolved_path_buf: [MAX_PATH_BYTES - 1:0]u8 = undefined;
                     const resolved_path = std.fmt.bufPrintZ(&resolved_path_buf, "{s}/{s}", .{
                         a_path,
-                        os.argv[0],
+                        std.os.argv[0],
                     }) catch continue;
 
                     var real_path_buf: [MAX_PATH_BYTES]u8 = undefined;
-                    if (os.realpathZ(resolved_path, &real_path_buf)) |real_path| {
+                    if (posix.realpathZ(resolved_path, &real_path_buf)) |real_path| {
                         // found a file, and hope it is the right file
                         if (real_path.len > out_buffer.len)
                             return error.NameTooLong;
@@ -663,13 +672,13 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
             return error.FileNotFound;
         },
         .windows => {
-            const image_path_unicode_string = &os.windows.peb().ProcessParameters.ImagePathName;
+            const image_path_unicode_string = &windows.peb().ProcessParameters.ImagePathName;
             const image_path_name = image_path_unicode_string.Buffer.?[0 .. image_path_unicode_string.Length / 2 :0];
 
             // If ImagePathName is a symlink, then it will contain the path of the
             // symlink, not the path that the symlink points to. We want the path
             // that the symlink points to, though, so we need to get the realpath.
-            const pathname_w = try os.windows.wToPrefixedFileW(null, image_path_name);
+            const pathname_w = try windows.wToPrefixedFileW(null, image_path_name);
             return std.fs.cwd().realpathW(pathname_w.span(), out_buffer) catch |err| switch (err) {
                 error.InvalidWtf8 => unreachable,
                 else => |e| return e,
@@ -718,11 +727,11 @@ pub fn realpathAlloc(allocator: Allocator, pathname: []const u8) ![]u8 {
     // paths. musl supports passing NULL but restricts the output to PATH_MAX
     // anyway.
     var buf: [MAX_PATH_BYTES]u8 = undefined;
-    return allocator.dupe(u8, try os.realpath(pathname, &buf));
+    return allocator.dupe(u8, try posix.realpath(pathname, &buf));
 }
 
 test {
-    if (builtin.os.tag != .wasi) {
+    if (native_os != .wasi) {
         _ = &makeDirAbsolute;
         _ = &makeDirAbsoluteZ;
         _ = &copyFileAbsolute;
lib/std/heap.zig
@@ -4,9 +4,9 @@ const root = @import("root");
 const assert = std.debug.assert;
 const testing = std.testing;
 const mem = std.mem;
-const os = std.os;
 const c = std.c;
 const Allocator = std.mem.Allocator;
+const windows = std.os.windows;
 
 pub const LoggingAllocator = @import("heap/logging_allocator.zig").LoggingAllocator;
 pub const loggingAllocator = @import("heap/logging_allocator.zig").loggingAllocator;
@@ -263,7 +263,7 @@ pub const HeapAllocator = switch (builtin.os.tag) {
     .windows => struct {
         heap_handle: ?HeapHandle,
 
-        const HeapHandle = os.windows.HANDLE;
+        const HeapHandle = windows.HANDLE;
 
         pub fn init() HeapAllocator {
             return HeapAllocator{
@@ -284,7 +284,7 @@ pub const HeapAllocator = switch (builtin.os.tag) {
 
         pub fn deinit(self: *HeapAllocator) void {
             if (self.heap_handle) |heap_handle| {
-                os.windows.HeapDestroy(heap_handle);
+                windows.HeapDestroy(heap_handle);
             }
         }
 
@@ -305,13 +305,13 @@ pub const HeapAllocator = switch (builtin.os.tag) {
             const amt = n + ptr_align - 1 + @sizeOf(usize);
             const optional_heap_handle = @atomicLoad(?HeapHandle, &self.heap_handle, .seq_cst);
             const heap_handle = optional_heap_handle orelse blk: {
-                const options = if (builtin.single_threaded) os.windows.HEAP_NO_SERIALIZE else 0;
-                const hh = os.windows.kernel32.HeapCreate(options, amt, 0) orelse return null;
+                const options = if (builtin.single_threaded) windows.HEAP_NO_SERIALIZE else 0;
+                const hh = windows.kernel32.HeapCreate(options, amt, 0) orelse return null;
                 const other_hh = @cmpxchgStrong(?HeapHandle, &self.heap_handle, null, hh, .seq_cst, .seq_cst) orelse break :blk hh;
-                os.windows.HeapDestroy(hh);
+                windows.HeapDestroy(hh);
                 break :blk other_hh.?; // can't be null because of the cmpxchg
             };
-            const ptr = os.windows.kernel32.HeapAlloc(heap_handle, 0, amt) orelse return null;
+            const ptr = windows.kernel32.HeapAlloc(heap_handle, 0, amt) orelse return null;
             const root_addr = @intFromPtr(ptr);
             const aligned_addr = mem.alignForward(usize, root_addr, ptr_align);
             const buf = @as([*]u8, @ptrFromInt(aligned_addr))[0..n];
@@ -333,9 +333,9 @@ pub const HeapAllocator = switch (builtin.os.tag) {
             const root_addr = getRecordPtr(buf).*;
             const align_offset = @intFromPtr(buf.ptr) - root_addr;
             const amt = align_offset + new_size + @sizeOf(usize);
-            const new_ptr = os.windows.kernel32.HeapReAlloc(
+            const new_ptr = windows.kernel32.HeapReAlloc(
                 self.heap_handle.?,
-                os.windows.HEAP_REALLOC_IN_PLACE_ONLY,
+                windows.HEAP_REALLOC_IN_PLACE_ONLY,
                 @as(*anyopaque, @ptrFromInt(root_addr)),
                 amt,
             ) orelse return false;
@@ -353,7 +353,7 @@ pub const HeapAllocator = switch (builtin.os.tag) {
             _ = log2_buf_align;
             _ = return_address;
             const self: *HeapAllocator = @ptrCast(@alignCast(ctx));
-            os.windows.HeapFree(self.heap_handle.?, 0, @as(*anyopaque, @ptrFromInt(getRecordPtr(buf).*)));
+            windows.HeapFree(self.heap_handle.?, 0, @as(*anyopaque, @ptrFromInt(getRecordPtr(buf).*)));
         }
     },
     else => @compileError("Unsupported OS"),
lib/std/io.zig
@@ -2,74 +2,76 @@ const std = @import("std.zig");
 const builtin = @import("builtin");
 const root = @import("root");
 const c = std.c;
+const is_windows = builtin.os.tag == .windows;
+const windows = std.os.windows;
+const posix = std.posix;
 
 const math = std.math;
 const assert = std.debug.assert;
-const os = std.os;
 const fs = std.fs;
 const mem = std.mem;
 const meta = std.meta;
 const File = std.fs.File;
 const Allocator = std.mem.Allocator;
 
-fn getStdOutHandle() os.fd_t {
-    if (builtin.os.tag == .windows) {
+fn getStdOutHandle() posix.fd_t {
+    if (is_windows) {
         if (builtin.zig_backend == .stage2_aarch64) {
             // TODO: this is just a temporary workaround until we advance aarch64 backend further along.
-            return os.windows.GetStdHandle(os.windows.STD_OUTPUT_HANDLE) catch os.windows.INVALID_HANDLE_VALUE;
+            return windows.GetStdHandle(windows.STD_OUTPUT_HANDLE) catch windows.INVALID_HANDLE_VALUE;
         }
-        return os.windows.peb().ProcessParameters.hStdOutput;
+        return windows.peb().ProcessParameters.hStdOutput;
     }
 
     if (@hasDecl(root, "os") and @hasDecl(root.os, "io") and @hasDecl(root.os.io, "getStdOutHandle")) {
         return root.os.io.getStdOutHandle();
     }
 
-    return os.STDOUT_FILENO;
+    return posix.STDOUT_FILENO;
 }
 
 pub fn getStdOut() File {
-    return File{ .handle = getStdOutHandle() };
+    return .{ .handle = getStdOutHandle() };
 }
 
-fn getStdErrHandle() os.fd_t {
-    if (builtin.os.tag == .windows) {
+fn getStdErrHandle() posix.fd_t {
+    if (is_windows) {
         if (builtin.zig_backend == .stage2_aarch64) {
             // TODO: this is just a temporary workaround until we advance aarch64 backend further along.
-            return os.windows.GetStdHandle(os.windows.STD_ERROR_HANDLE) catch os.windows.INVALID_HANDLE_VALUE;
+            return windows.GetStdHandle(windows.STD_ERROR_HANDLE) catch windows.INVALID_HANDLE_VALUE;
         }
-        return os.windows.peb().ProcessParameters.hStdError;
+        return windows.peb().ProcessParameters.hStdError;
     }
 
     if (@hasDecl(root, "os") and @hasDecl(root.os, "io") and @hasDecl(root.os.io, "getStdErrHandle")) {
         return root.os.io.getStdErrHandle();
     }
 
-    return os.STDERR_FILENO;
+    return posix.STDERR_FILENO;
 }
 
 pub fn getStdErr() File {
-    return File{ .handle = getStdErrHandle() };
+    return .{ .handle = getStdErrHandle() };
 }
 
-fn getStdInHandle() os.fd_t {
-    if (builtin.os.tag == .windows) {
+fn getStdInHandle() posix.fd_t {
+    if (is_windows) {
         if (builtin.zig_backend == .stage2_aarch64) {
             // TODO: this is just a temporary workaround until we advance aarch64 backend further along.
-            return os.windows.GetStdHandle(os.windows.STD_INPUT_HANDLE) catch os.windows.INVALID_HANDLE_VALUE;
+            return windows.GetStdHandle(windows.STD_INPUT_HANDLE) catch windows.INVALID_HANDLE_VALUE;
         }
-        return os.windows.peb().ProcessParameters.hStdInput;
+        return windows.peb().ProcessParameters.hStdInput;
     }
 
     if (@hasDecl(root, "os") and @hasDecl(root.os, "io") and @hasDecl(root.os.io, "getStdInHandle")) {
         return root.os.io.getStdInHandle();
     }
 
-    return os.STDIN_FILENO;
+    return posix.STDIN_FILENO;
 }
 
 pub fn getStdIn() File {
-    return File{ .handle = getStdInHandle() };
+    return .{ .handle = getStdInHandle() };
 }
 
 pub fn GenericReader(
@@ -434,10 +436,10 @@ pub fn poll(
     const enum_fields = @typeInfo(StreamEnum).Enum.fields;
     var result: Poller(StreamEnum) = undefined;
 
-    if (builtin.os.tag == .windows) result.windows = .{
+    if (is_windows) result.windows = .{
         .first_read_done = false,
-        .overlapped = [1]os.windows.OVERLAPPED{
-            mem.zeroes(os.windows.OVERLAPPED),
+        .overlapped = [1]windows.OVERLAPPED{
+            mem.zeroes(windows.OVERLAPPED),
         } ** enum_fields.len,
         .active = .{
             .count = 0,
@@ -453,12 +455,12 @@ pub fn poll(
             .head = 0,
             .count = 0,
         };
-        if (builtin.os.tag == .windows) {
+        if (is_windows) {
             result.windows.active.handles_buf[i] = @field(files, enum_fields[i].name).handle;
         } else {
             result.poll_fds[i] = .{
                 .fd = @field(files, enum_fields[i].name).handle,
-                .events = os.POLL.IN,
+                .events = posix.POLL.IN,
                 .revents = undefined,
             };
         }
@@ -471,16 +473,16 @@ pub const PollFifo = std.fifo.LinearFifo(u8, .Dynamic);
 pub fn Poller(comptime StreamEnum: type) type {
     return struct {
         const enum_fields = @typeInfo(StreamEnum).Enum.fields;
-        const PollFd = if (builtin.os.tag == .windows) void else std.os.pollfd;
+        const PollFd = if (is_windows) void else posix.pollfd;
 
         fifos: [enum_fields.len]PollFifo,
         poll_fds: [enum_fields.len]PollFd,
-        windows: if (builtin.os.tag == .windows) struct {
+        windows: if (is_windows) struct {
             first_read_done: bool,
-            overlapped: [enum_fields.len]os.windows.OVERLAPPED,
+            overlapped: [enum_fields.len]windows.OVERLAPPED,
             active: struct {
                 count: math.IntFittingRange(0, enum_fields.len),
-                handles_buf: [enum_fields.len]os.windows.HANDLE,
+                handles_buf: [enum_fields.len]windows.HANDLE,
                 stream_map: [enum_fields.len]StreamEnum,
 
                 pub fn removeAt(self: *@This(), index: u32) void {
@@ -497,10 +499,10 @@ pub fn Poller(comptime StreamEnum: type) type {
         const Self = @This();
 
         pub fn deinit(self: *Self) void {
-            if (builtin.os.tag == .windows) {
+            if (is_windows) {
                 // cancel any pending IO to prevent clobbering OVERLAPPED value
                 for (self.windows.active.handles_buf[0..self.windows.active.count]) |h| {
-                    _ = os.windows.kernel32.CancelIo(h);
+                    _ = windows.kernel32.CancelIo(h);
                 }
             }
             inline for (&self.fifos) |*q| q.deinit();
@@ -508,7 +510,7 @@ pub fn Poller(comptime StreamEnum: type) type {
         }
 
         pub fn poll(self: *Self) !bool {
-            if (builtin.os.tag == .windows) {
+            if (is_windows) {
                 return pollWindows(self, null);
             } else {
                 return pollPosix(self, null);
@@ -516,7 +518,7 @@ pub fn Poller(comptime StreamEnum: type) type {
         }
 
         pub fn pollTimeout(self: *Self, nanoseconds: u64) !bool {
-            if (builtin.os.tag == .windows) {
+            if (is_windows) {
                 return pollWindows(self, nanoseconds);
             } else {
                 return pollPosix(self, nanoseconds);
@@ -554,39 +556,39 @@ pub fn Poller(comptime StreamEnum: type) type {
             while (true) {
                 if (self.windows.active.count == 0) return false;
 
-                const status = os.windows.kernel32.WaitForMultipleObjects(
+                const status = windows.kernel32.WaitForMultipleObjects(
                     self.windows.active.count,
                     &self.windows.active.handles_buf,
                     0,
                     if (nanoseconds) |ns|
-                        @min(std.math.cast(u32, ns / std.time.ns_per_ms) orelse (os.windows.INFINITE - 1), os.windows.INFINITE - 1)
+                        @min(std.math.cast(u32, ns / std.time.ns_per_ms) orelse (windows.INFINITE - 1), windows.INFINITE - 1)
                     else
-                        os.windows.INFINITE,
+                        windows.INFINITE,
                 );
-                if (status == os.windows.WAIT_FAILED)
-                    return os.windows.unexpectedError(os.windows.kernel32.GetLastError());
-                if (status == os.windows.WAIT_TIMEOUT)
+                if (status == windows.WAIT_FAILED)
+                    return windows.unexpectedError(windows.kernel32.GetLastError());
+                if (status == windows.WAIT_TIMEOUT)
                     return true;
 
-                if (status < os.windows.WAIT_OBJECT_0 or status > os.windows.WAIT_OBJECT_0 + enum_fields.len - 1)
+                if (status < windows.WAIT_OBJECT_0 or status > windows.WAIT_OBJECT_0 + enum_fields.len - 1)
                     unreachable;
 
-                const active_idx = status - os.windows.WAIT_OBJECT_0;
+                const active_idx = status - windows.WAIT_OBJECT_0;
 
                 const handle = self.windows.active.handles_buf[active_idx];
                 const stream_idx = @intFromEnum(self.windows.active.stream_map[active_idx]);
                 var read_bytes: u32 = undefined;
-                if (0 == os.windows.kernel32.GetOverlappedResult(
+                if (0 == windows.kernel32.GetOverlappedResult(
                     handle,
                     &self.windows.overlapped[stream_idx],
                     &read_bytes,
                     0,
-                )) switch (os.windows.kernel32.GetLastError()) {
+                )) switch (windows.kernel32.GetLastError()) {
                     .BROKEN_PIPE => {
                         self.windows.active.removeAt(active_idx);
                         continue;
                     },
-                    else => |err| return os.windows.unexpectedError(err),
+                    else => |err| return windows.unexpectedError(err),
                 };
 
                 self.fifos[stream_idx].update(read_bytes);
@@ -611,9 +613,9 @@ pub fn Poller(comptime StreamEnum: type) type {
             // allocate grows exponentially.
             const bump_amt = 512;
 
-            const err_mask = os.POLL.ERR | os.POLL.NVAL | os.POLL.HUP;
+            const err_mask = posix.POLL.ERR | posix.POLL.NVAL | posix.POLL.HUP;
 
-            const events_len = try os.poll(&self.poll_fds, if (nanoseconds) |ns|
+            const events_len = try posix.poll(&self.poll_fds, if (nanoseconds) |ns|
                 std.math.cast(i32, ns / std.time.ns_per_ms) orelse std.math.maxInt(i32)
             else
                 -1);
@@ -629,9 +631,9 @@ pub fn Poller(comptime StreamEnum: type) type {
                 // conditions.
                 // It's still possible to read after a POLL.HUP is received,
                 // always check if there's some data waiting to be read first.
-                if (poll_fd.revents & os.POLL.IN != 0) {
+                if (poll_fd.revents & posix.POLL.IN != 0) {
                     const buf = try q.writableWithSize(bump_amt);
-                    const amt = try os.read(poll_fd.fd, buf);
+                    const amt = try posix.read(poll_fd.fd, buf);
                     q.update(amt);
                     if (amt == 0) {
                         // Remove the fd when the EOF condition is met.
@@ -652,19 +654,19 @@ pub fn Poller(comptime StreamEnum: type) type {
 }
 
 fn windowsAsyncRead(
-    handle: os.windows.HANDLE,
-    overlapped: *os.windows.OVERLAPPED,
+    handle: windows.HANDLE,
+    overlapped: *windows.OVERLAPPED,
     fifo: *PollFifo,
     bump_amt: usize,
 ) !enum { pending, closed } {
     while (true) {
         const buf = try fifo.writableWithSize(bump_amt);
         var read_bytes: u32 = undefined;
-        const read_result = os.windows.kernel32.ReadFile(handle, buf.ptr, math.cast(u32, buf.len) orelse math.maxInt(u32), &read_bytes, overlapped);
-        if (read_result == 0) return switch (os.windows.kernel32.GetLastError()) {
+        const read_result = windows.kernel32.ReadFile(handle, buf.ptr, math.cast(u32, buf.len) orelse math.maxInt(u32), &read_bytes, overlapped);
+        if (read_result == 0) return switch (windows.kernel32.GetLastError()) {
             .IO_PENDING => .pending,
             .BROKEN_PIPE => .closed,
-            else => |err| os.windows.unexpectedError(err),
+            else => |err| windows.unexpectedError(err),
         };
         fifo.update(read_bytes);
     }
lib/std/net.zig
@@ -5,15 +5,16 @@ const builtin = @import("builtin");
 const assert = std.debug.assert;
 const net = @This();
 const mem = std.mem;
-const os = std.os;
 const posix = std.posix;
 const fs = std.fs;
 const io = std.io;
 const native_endian = builtin.target.cpu.arch.endian();
+const native_os = builtin.os.tag;
+const windows = std.os.windows;
 
 // Windows 10 added support for unix sockets in build 17063, redstone 4 is the
 // first release to support them.
-pub const has_unix_sockets = switch (builtin.os.tag) {
+pub const has_unix_sockets = switch (native_os) {
     .windows => builtin.os.version_range.windows.isAtLeast(.win10_rs4) orelse false,
     else => true,
 };
@@ -28,14 +29,14 @@ pub const IPParseError = error{
 pub const IPv4ParseError = IPParseError || error{NonCanonical};
 
 pub const IPv6ParseError = IPParseError || error{InvalidIpv4Mapping};
-pub const IPv6InterfaceError = os.SocketError || os.IoCtl_SIOCGIFINDEX_Error || error{NameTooLong};
+pub const IPv6InterfaceError = posix.SocketError || posix.IoCtl_SIOCGIFINDEX_Error || error{NameTooLong};
 pub const IPv6ResolveError = IPv6ParseError || IPv6InterfaceError;
 
 pub const Address = extern union {
-    any: os.sockaddr,
+    any: posix.sockaddr,
     in: Ip4Address,
     in6: Ip6Address,
-    un: if (has_unix_sockets) os.sockaddr.un else void,
+    un: if (has_unix_sockets) posix.sockaddr.un else void,
 
     /// Parse the given IP address string into an Address value.
     /// It is recommended to use `resolveIp` instead, to handle
@@ -85,38 +86,38 @@ pub const Address = extern union {
         return error.InvalidIPAddressFormat;
     }
 
-    pub fn parseExpectingFamily(name: []const u8, family: os.sa_family_t, port: u16) !Address {
+    pub fn parseExpectingFamily(name: []const u8, family: posix.sa_family_t, port: u16) !Address {
         switch (family) {
-            os.AF.INET => return parseIp4(name, port),
-            os.AF.INET6 => return parseIp6(name, port),
-            os.AF.UNSPEC => return parseIp(name, port),
+            posix.AF.INET => return parseIp4(name, port),
+            posix.AF.INET6 => return parseIp6(name, port),
+            posix.AF.UNSPEC => return parseIp(name, port),
             else => unreachable,
         }
     }
 
     pub fn parseIp6(buf: []const u8, port: u16) IPv6ParseError!Address {
-        return Address{ .in6 = try Ip6Address.parse(buf, port) };
+        return .{ .in6 = try Ip6Address.parse(buf, port) };
     }
 
     pub fn resolveIp6(buf: []const u8, port: u16) IPv6ResolveError!Address {
-        return Address{ .in6 = try Ip6Address.resolve(buf, port) };
+        return .{ .in6 = try Ip6Address.resolve(buf, port) };
     }
 
     pub fn parseIp4(buf: []const u8, port: u16) IPv4ParseError!Address {
-        return Address{ .in = try Ip4Address.parse(buf, port) };
+        return .{ .in = try Ip4Address.parse(buf, port) };
     }
 
     pub fn initIp4(addr: [4]u8, port: u16) Address {
-        return Address{ .in = Ip4Address.init(addr, port) };
+        return .{ .in = Ip4Address.init(addr, port) };
     }
 
     pub fn initIp6(addr: [16]u8, port: u16, flowinfo: u32, scope_id: u32) Address {
-        return Address{ .in6 = Ip6Address.init(addr, port, flowinfo, scope_id) };
+        return .{ .in6 = Ip6Address.init(addr, port, flowinfo, scope_id) };
     }
 
     pub fn initUnix(path: []const u8) !Address {
-        var sock_addr = os.sockaddr.un{
-            .family = os.AF.UNIX,
+        var sock_addr = posix.sockaddr.un{
+            .family = posix.AF.UNIX,
             .path = undefined,
         };
 
@@ -133,8 +134,8 @@ pub const Address = extern union {
     /// Asserts that the address is ip4 or ip6.
     pub fn getPort(self: Address) u16 {
         return switch (self.any.family) {
-            os.AF.INET => self.in.getPort(),
-            os.AF.INET6 => self.in6.getPort(),
+            posix.AF.INET => self.in.getPort(),
+            posix.AF.INET6 => self.in6.getPort(),
             else => unreachable,
         };
     }
@@ -143,8 +144,8 @@ pub const Address = extern union {
     /// Asserts that the address is ip4 or ip6.
     pub fn setPort(self: *Address, port: u16) void {
         switch (self.any.family) {
-            os.AF.INET => self.in.setPort(port),
-            os.AF.INET6 => self.in6.setPort(port),
+            posix.AF.INET => self.in.setPort(port),
+            posix.AF.INET6 => self.in6.setPort(port),
             else => unreachable,
         }
     }
@@ -152,10 +153,10 @@ pub const Address = extern union {
     /// Asserts that `addr` is an IP address.
     /// This function will read past the end of the pointer, with a size depending
     /// on the address family.
-    pub fn initPosix(addr: *align(4) const os.sockaddr) Address {
+    pub fn initPosix(addr: *align(4) const posix.sockaddr) Address {
         switch (addr.family) {
-            os.AF.INET => return Address{ .in = Ip4Address{ .sa = @as(*const os.sockaddr.in, @ptrCast(addr)).* } },
-            os.AF.INET6 => return Address{ .in6 = Ip6Address{ .sa = @as(*const os.sockaddr.in6, @ptrCast(addr)).* } },
+            posix.AF.INET => return Address{ .in = Ip4Address{ .sa = @as(*const posix.sockaddr.in, @ptrCast(addr)).* } },
+            posix.AF.INET6 => return Address{ .in6 = Ip6Address{ .sa = @as(*const posix.sockaddr.in6, @ptrCast(addr)).* } },
             else => unreachable,
         }
     }
@@ -168,9 +169,9 @@ pub const Address = extern union {
     ) !void {
         if (fmt.len != 0) std.fmt.invalidFmtError(fmt, self);
         switch (self.any.family) {
-            os.AF.INET => try self.in.format(fmt, options, out_stream),
-            os.AF.INET6 => try self.in6.format(fmt, options, out_stream),
-            os.AF.UNIX => {
+            posix.AF.INET => try self.in.format(fmt, options, out_stream),
+            posix.AF.INET6 => try self.in6.format(fmt, options, out_stream),
+            posix.AF.UNIX => {
                 if (!has_unix_sockets) {
                     unreachable;
                 }
@@ -187,11 +188,11 @@ pub const Address = extern union {
         return mem.eql(u8, a_bytes, b_bytes);
     }
 
-    pub fn getOsSockLen(self: Address) os.socklen_t {
+    pub fn getOsSockLen(self: Address) posix.socklen_t {
         switch (self.any.family) {
-            os.AF.INET => return self.in.getOsSockLen(),
-            os.AF.INET6 => return self.in6.getOsSockLen(),
-            os.AF.UNIX => {
+            posix.AF.INET => return self.in.getOsSockLen(),
+            posix.AF.INET6 => return self.in6.getOsSockLen(),
+            posix.AF.UNIX => {
                 if (!has_unix_sockets) {
                     unreachable;
                 }
@@ -204,7 +205,7 @@ pub const Address = extern union {
                 // provide the full buffer size (e.g. getsockname, getpeername, recvfrom, accept).
                 //
                 // To access the path, std.mem.sliceTo(&address.un.path, 0) should be used.
-                return @as(os.socklen_t, @intCast(@sizeOf(os.sockaddr.un)));
+                return @as(posix.socklen_t, @intCast(@sizeOf(posix.sockaddr.un)));
             },
 
             else => unreachable,
@@ -247,7 +248,7 @@ pub const Address = extern union {
                 posix.SO.REUSEADDR,
                 &mem.toBytes(@as(c_int, 1)),
             );
-            switch (builtin.os.tag) {
+            switch (native_os) {
                 .windows => {},
                 else => try posix.setsockopt(
                     sockfd,
@@ -267,7 +268,7 @@ pub const Address = extern union {
 };
 
 pub const Ip4Address = extern struct {
-    sa: os.sockaddr.in,
+    sa: posix.sockaddr.in,
 
     pub fn parse(buf: []const u8, port: u16) IPv4ParseError!Ip4Address {
         var result = Ip4Address{
@@ -330,7 +331,7 @@ pub const Ip4Address = extern struct {
 
     pub fn init(addr: [4]u8, port: u16) Ip4Address {
         return Ip4Address{
-            .sa = os.sockaddr.in{
+            .sa = posix.sockaddr.in{
                 .port = mem.nativeToBig(u16, port),
                 .addr = @as(*align(1) const u32, @ptrCast(&addr)).*,
             },
@@ -367,21 +368,21 @@ pub const Ip4Address = extern struct {
         });
     }
 
-    pub fn getOsSockLen(self: Ip4Address) os.socklen_t {
+    pub fn getOsSockLen(self: Ip4Address) posix.socklen_t {
         _ = self;
-        return @sizeOf(os.sockaddr.in);
+        return @sizeOf(posix.sockaddr.in);
     }
 };
 
 pub const Ip6Address = extern struct {
-    sa: os.sockaddr.in6,
+    sa: posix.sockaddr.in6,
 
     /// Parse a given IPv6 address string into an Address.
     /// Assumes the Scope ID of the address is fully numeric.
     /// For non-numeric addresses, see `resolveIp6`.
     pub fn parse(buf: []const u8, port: u16) IPv6ParseError!Ip6Address {
         var result = Ip6Address{
-            .sa = os.sockaddr.in6{
+            .sa = posix.sockaddr.in6{
                 .scope_id = 0,
                 .port = mem.nativeToBig(u16, port),
                 .flowinfo = 0,
@@ -499,7 +500,7 @@ pub const Ip6Address = extern struct {
     pub fn resolve(buf: []const u8, port: u16) IPv6ResolveError!Ip6Address {
         // TODO: Unify the implementations of resolveIp6 and parseIp6.
         var result = Ip6Address{
-            .sa = os.sockaddr.in6{
+            .sa = posix.sockaddr.in6{
                 .scope_id = 0,
                 .port = mem.nativeToBig(u16, port),
                 .flowinfo = 0,
@@ -516,7 +517,7 @@ pub const Ip6Address = extern struct {
         var abbrv = false;
 
         var scope_id = false;
-        var scope_id_value: [os.IFNAMESIZE - 1]u8 = undefined;
+        var scope_id_value: [posix.IFNAMESIZE - 1]u8 = undefined;
         var scope_id_index: usize = 0;
 
         for (buf, 0..) |c, i| {
@@ -632,7 +633,7 @@ pub const Ip6Address = extern struct {
 
     pub fn init(addr: [16]u8, port: u16, flowinfo: u32, scope_id: u32) Ip6Address {
         return Ip6Address{
-            .sa = os.sockaddr.in6{
+            .sa = posix.sockaddr.in6{
                 .addr = addr,
                 .port = mem.nativeToBig(u16, port),
                 .flowinfo = flowinfo,
@@ -702,51 +703,51 @@ pub const Ip6Address = extern struct {
         try std.fmt.format(out_stream, "]:{}", .{port});
     }
 
-    pub fn getOsSockLen(self: Ip6Address) os.socklen_t {
+    pub fn getOsSockLen(self: Ip6Address) posix.socklen_t {
         _ = self;
-        return @sizeOf(os.sockaddr.in6);
+        return @sizeOf(posix.sockaddr.in6);
     }
 };
 
 pub fn connectUnixSocket(path: []const u8) !Stream {
     const opt_non_block = 0;
-    const sockfd = try os.socket(
-        os.AF.UNIX,
-        os.SOCK.STREAM | os.SOCK.CLOEXEC | opt_non_block,
+    const sockfd = try posix.socket(
+        posix.AF.UNIX,
+        posix.SOCK.STREAM | posix.SOCK.CLOEXEC | opt_non_block,
         0,
     );
     errdefer Stream.close(.{ .handle = sockfd });
 
     var addr = try std.net.Address.initUnix(path);
-    try os.connect(sockfd, &addr.any, addr.getOsSockLen());
+    try posix.connect(sockfd, &addr.any, addr.getOsSockLen());
 
-    return Stream{ .handle = sockfd };
+    return .{ .handle = sockfd };
 }
 
 fn if_nametoindex(name: []const u8) IPv6InterfaceError!u32 {
-    if (builtin.target.os.tag == .linux) {
-        var ifr: os.ifreq = undefined;
-        const sockfd = try os.socket(os.AF.UNIX, os.SOCK.DGRAM | os.SOCK.CLOEXEC, 0);
+    if (native_os == .linux) {
+        var ifr: posix.ifreq = undefined;
+        const sockfd = try posix.socket(posix.AF.UNIX, posix.SOCK.DGRAM | posix.SOCK.CLOEXEC, 0);
         defer Stream.close(.{ .handle = sockfd });
 
         @memcpy(ifr.ifrn.name[0..name.len], name);
         ifr.ifrn.name[name.len] = 0;
 
         // TODO investigate if this needs to be integrated with evented I/O.
-        try os.ioctl_SIOCGIFINDEX(sockfd, &ifr);
+        try posix.ioctl_SIOCGIFINDEX(sockfd, &ifr);
 
-        return @as(u32, @bitCast(ifr.ifru.ivalue));
+        return @bitCast(ifr.ifru.ivalue);
     }
 
-    if (comptime builtin.target.os.tag.isDarwin()) {
-        if (name.len >= os.IFNAMESIZE)
+    if (native_os.isDarwin()) {
+        if (name.len >= posix.IFNAMESIZE)
             return error.NameTooLong;
 
-        var if_name: [os.IFNAMESIZE:0]u8 = undefined;
+        var if_name: [posix.IFNAMESIZE:0]u8 = undefined;
         @memcpy(if_name[0..name.len], name);
         if_name[name.len] = 0;
         const if_slice = if_name[0..name.len :0];
-        const index = os.system.if_nametoindex(if_slice);
+        const index = std.c.if_nametoindex(if_slice);
         if (index == 0)
             return error.InterfaceNotFound;
         return @as(u32, @bitCast(index));
@@ -786,24 +787,24 @@ pub fn tcpConnectToHost(allocator: mem.Allocator, name: []const u8, port: u16) T
             else => return err,
         };
     }
-    return std.os.ConnectError.ConnectionRefused;
+    return posix.ConnectError.ConnectionRefused;
 }
 
-pub const TcpConnectToAddressError = std.os.SocketError || std.os.ConnectError;
+pub const TcpConnectToAddressError = posix.SocketError || posix.ConnectError;
 
 pub fn tcpConnectToAddress(address: Address) TcpConnectToAddressError!Stream {
     const nonblock = 0;
-    const sock_flags = os.SOCK.STREAM | nonblock |
-        (if (builtin.target.os.tag == .windows) 0 else os.SOCK.CLOEXEC);
-    const sockfd = try os.socket(address.any.family, sock_flags, os.IPPROTO.TCP);
+    const sock_flags = posix.SOCK.STREAM | nonblock |
+        (if (native_os == .windows) 0 else posix.SOCK.CLOEXEC);
+    const sockfd = try posix.socket(address.any.family, sock_flags, posix.IPPROTO.TCP);
     errdefer Stream.close(.{ .handle = sockfd });
 
-    try os.connect(sockfd, &address.any, address.getOsSockLen());
+    try posix.connect(sockfd, &address.any, address.getOsSockLen());
 
     return Stream{ .handle = sockfd };
 }
 
-const GetAddressListError = std.mem.Allocator.Error || std.fs.File.OpenError || std.fs.File.ReadError || std.os.SocketError || std.os.BindError || std.os.SetSockOptError || error{
+const GetAddressListError = std.mem.Allocator.Error || std.fs.File.OpenError || std.fs.File.ReadError || posix.SocketError || posix.BindError || posix.SetSockOptError || error{
     // TODO: break this up into error sets from the various underlying functions
 
     TemporaryNameServerFailure,
@@ -844,30 +845,30 @@ pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) Get
     const arena = result.arena.allocator();
     errdefer result.deinit();
 
-    if (builtin.target.os.tag == .windows) {
+    if (native_os == .windows) {
         const name_c = try allocator.dupeZ(u8, name);
         defer allocator.free(name_c);
 
         const port_c = try std.fmt.allocPrintZ(allocator, "{}", .{port});
         defer allocator.free(port_c);
 
-        const ws2_32 = os.windows.ws2_32;
-        const hints = os.addrinfo{
+        const ws2_32 = windows.ws2_32;
+        const hints = posix.addrinfo{
             .flags = ws2_32.AI.NUMERICSERV,
-            .family = os.AF.UNSPEC,
-            .socktype = os.SOCK.STREAM,
-            .protocol = os.IPPROTO.TCP,
+            .family = posix.AF.UNSPEC,
+            .socktype = posix.SOCK.STREAM,
+            .protocol = posix.IPPROTO.TCP,
             .canonname = null,
             .addr = null,
             .addrlen = 0,
             .next = null,
         };
-        var res: ?*os.addrinfo = null;
+        var res: ?*posix.addrinfo = null;
         var first = true;
         while (true) {
             const rc = ws2_32.getaddrinfo(name_c.ptr, port_c.ptr, &hints, &res);
-            switch (@as(os.windows.ws2_32.WinsockError, @enumFromInt(@as(u16, @intCast(rc))))) {
-                @as(os.windows.ws2_32.WinsockError, @enumFromInt(0)) => break,
+            switch (@as(windows.ws2_32.WinsockError, @enumFromInt(@as(u16, @intCast(rc))))) {
+                @as(windows.ws2_32.WinsockError, @enumFromInt(0)) => break,
                 .WSATRY_AGAIN => return error.TemporaryNameServerFailure,
                 .WSANO_RECOVERY => return error.NameServerFailure,
                 .WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported,
@@ -879,10 +880,10 @@ pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) Get
                 .WSANOTINITIALISED => {
                     if (!first) return error.Unexpected;
                     first = false;
-                    try os.windows.callWSAStartup();
+                    try windows.callWSAStartup();
                     continue;
                 },
-                else => |err| return os.windows.unexpectedWSAError(err),
+                else => |err| return windows.unexpectedWSAError(err),
             }
         }
         defer ws2_32.freeaddrinfo(res);
@@ -923,18 +924,18 @@ pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) Get
         const port_c = try std.fmt.allocPrintZ(allocator, "{}", .{port});
         defer allocator.free(port_c);
 
-        const sys = if (builtin.target.os.tag == .windows) os.windows.ws2_32 else os.system;
-        const hints = os.addrinfo{
+        const sys = if (native_os == .windows) windows.ws2_32 else posix.system;
+        const hints = posix.addrinfo{
             .flags = sys.AI.NUMERICSERV,
-            .family = os.AF.UNSPEC,
-            .socktype = os.SOCK.STREAM,
-            .protocol = os.IPPROTO.TCP,
+            .family = posix.AF.UNSPEC,
+            .socktype = posix.SOCK.STREAM,
+            .protocol = posix.IPPROTO.TCP,
             .canonname = null,
             .addr = null,
             .addrlen = 0,
             .next = null,
         };
-        var res: ?*os.addrinfo = null;
+        var res: ?*posix.addrinfo = null;
         switch (sys.getaddrinfo(name_c.ptr, port_c.ptr, &hints, &res)) {
             @as(sys.EAI, @enumFromInt(0)) => {},
             .ADDRFAMILY => return error.HostLacksNetworkAddresses,
@@ -947,8 +948,8 @@ pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) Get
             .NONAME => return error.UnknownHostName,
             .SERVICE => return error.ServiceUnavailable,
             .SOCKTYPE => unreachable, // Invalid socket type requested in hints
-            .SYSTEM => switch (os.errno(-1)) {
-                else => |e| return os.unexpectedErrno(e),
+            .SYSTEM => switch (posix.errno(-1)) {
+                else => |e| return posix.unexpectedErrno(e),
             },
             else => unreachable,
         }
@@ -983,9 +984,9 @@ pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) Get
         return result;
     }
 
-    if (builtin.target.os.tag == .linux) {
+    if (native_os == .linux) {
         const flags = std.c.AI.NUMERICSERV;
-        const family = os.AF.UNSPEC;
+        const family = posix.AF.UNSPEC;
         var lookup_addrs = std.ArrayList(LookupAddr).init(allocator);
         defer lookup_addrs.deinit();
 
@@ -1026,7 +1027,7 @@ fn linuxLookupName(
     addrs: *std.ArrayList(LookupAddr),
     canon: *std.ArrayList(u8),
     opt_name: ?[]const u8,
-    family: os.sa_family_t,
+    family: posix.sa_family_t,
     flags: u32,
     port: u16,
 ) !void {
@@ -1066,9 +1067,9 @@ fn linuxLookupName(
 
     // No further processing is needed if there are fewer than 2
     // results or if there are only IPv4 results.
-    if (addrs.items.len == 1 or family == os.AF.INET) return;
+    if (addrs.items.len == 1 or family == posix.AF.INET) return;
     const all_ip4 = for (addrs.items) |addr| {
-        if (addr.addr.any.family != os.AF.INET) break false;
+        if (addr.addr.any.family != posix.AF.INET) break false;
     } else true;
     if (all_ip4) return;
 
@@ -1081,42 +1082,42 @@ fn linuxLookupName(
     // A more idiomatic "ziggy" implementation would be welcome.
     for (addrs.items, 0..) |*addr, i| {
         var key: i32 = 0;
-        var sa6: os.sockaddr.in6 = undefined;
-        @memset(@as([*]u8, @ptrCast(&sa6))[0..@sizeOf(os.sockaddr.in6)], 0);
-        var da6 = os.sockaddr.in6{
-            .family = os.AF.INET6,
+        var sa6: posix.sockaddr.in6 = undefined;
+        @memset(@as([*]u8, @ptrCast(&sa6))[0..@sizeOf(posix.sockaddr.in6)], 0);
+        var da6 = posix.sockaddr.in6{
+            .family = posix.AF.INET6,
             .scope_id = addr.addr.in6.sa.scope_id,
             .port = 65535,
             .flowinfo = 0,
             .addr = [1]u8{0} ** 16,
         };
-        var sa4: os.sockaddr.in = undefined;
-        @memset(@as([*]u8, @ptrCast(&sa4))[0..@sizeOf(os.sockaddr.in)], 0);
-        var da4 = os.sockaddr.in{
-            .family = os.AF.INET,
+        var sa4: posix.sockaddr.in = undefined;
+        @memset(@as([*]u8, @ptrCast(&sa4))[0..@sizeOf(posix.sockaddr.in)], 0);
+        var da4 = posix.sockaddr.in{
+            .family = posix.AF.INET,
             .port = 65535,
             .addr = 0,
             .zero = [1]u8{0} ** 8,
         };
-        var sa: *align(4) os.sockaddr = undefined;
-        var da: *align(4) os.sockaddr = undefined;
-        var salen: os.socklen_t = undefined;
-        var dalen: os.socklen_t = undefined;
-        if (addr.addr.any.family == os.AF.INET6) {
+        var sa: *align(4) posix.sockaddr = undefined;
+        var da: *align(4) posix.sockaddr = undefined;
+        var salen: posix.socklen_t = undefined;
+        var dalen: posix.socklen_t = undefined;
+        if (addr.addr.any.family == posix.AF.INET6) {
             da6.addr = addr.addr.in6.sa.addr;
             da = @ptrCast(&da6);
-            dalen = @sizeOf(os.sockaddr.in6);
+            dalen = @sizeOf(posix.sockaddr.in6);
             sa = @ptrCast(&sa6);
-            salen = @sizeOf(os.sockaddr.in6);
+            salen = @sizeOf(posix.sockaddr.in6);
         } else {
             sa6.addr[0..12].* = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff".*;
             da6.addr[0..12].* = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff".*;
             mem.writeInt(u32, da6.addr[12..], addr.addr.in.sa.addr, native_endian);
             da4.addr = addr.addr.in.sa.addr;
             da = @ptrCast(&da4);
-            dalen = @sizeOf(os.sockaddr.in);
+            dalen = @sizeOf(posix.sockaddr.in);
             sa = @ptrCast(&sa4);
-            salen = @sizeOf(os.sockaddr.in);
+            salen = @sizeOf(posix.sockaddr.in);
         }
         const dpolicy = policyOf(da6.addr);
         const dscope: i32 = scopeOf(da6.addr);
@@ -1124,13 +1125,13 @@ fn linuxLookupName(
         const dprec: i32 = dpolicy.prec;
         const MAXADDRS = 3;
         var prefixlen: i32 = 0;
-        const sock_flags = os.SOCK.DGRAM | os.SOCK.CLOEXEC;
-        if (os.socket(addr.addr.any.family, sock_flags, os.IPPROTO.UDP)) |fd| syscalls: {
+        const sock_flags = posix.SOCK.DGRAM | posix.SOCK.CLOEXEC;
+        if (posix.socket(addr.addr.any.family, sock_flags, posix.IPPROTO.UDP)) |fd| syscalls: {
             defer Stream.close(.{ .handle = fd });
-            os.connect(fd, da, dalen) catch break :syscalls;
+            posix.connect(fd, da, dalen) catch break :syscalls;
             key |= DAS_USABLE;
-            os.getsockname(fd, sa, &salen) catch break :syscalls;
-            if (addr.addr.any.family == os.AF.INET) {
+            posix.getsockname(fd, sa, &salen) catch break :syscalls;
+            if (addr.addr.any.family == posix.AF.INET) {
                 mem.writeInt(u32, sa6.addr[12..16], sa4.addr, native_endian);
             }
             if (dscope == @as(i32, scopeOf(sa6.addr))) key |= DAS_MATCHINGSCOPE;
@@ -1267,28 +1268,28 @@ fn addrCmpLessThan(context: void, b: LookupAddr, a: LookupAddr) bool {
 
 fn linuxLookupNameFromNull(
     addrs: *std.ArrayList(LookupAddr),
-    family: os.sa_family_t,
+    family: posix.sa_family_t,
     flags: u32,
     port: u16,
 ) !void {
     if ((flags & std.c.AI.PASSIVE) != 0) {
-        if (family != os.AF.INET6) {
+        if (family != posix.AF.INET6) {
             (try addrs.addOne()).* = LookupAddr{
                 .addr = Address.initIp4([1]u8{0} ** 4, port),
             };
         }
-        if (family != os.AF.INET) {
+        if (family != posix.AF.INET) {
             (try addrs.addOne()).* = LookupAddr{
                 .addr = Address.initIp6([1]u8{0} ** 16, port, 0, 0),
             };
         }
     } else {
-        if (family != os.AF.INET6) {
+        if (family != posix.AF.INET6) {
             (try addrs.addOne()).* = LookupAddr{
                 .addr = Address.initIp4([4]u8{ 127, 0, 0, 1 }, port),
             };
         }
-        if (family != os.AF.INET) {
+        if (family != posix.AF.INET) {
             (try addrs.addOne()).* = LookupAddr{
                 .addr = Address.initIp6(([1]u8{0} ** 15) ++ [1]u8{1}, port, 0, 0),
             };
@@ -1300,7 +1301,7 @@ fn linuxLookupNameFromHosts(
     addrs: *std.ArrayList(LookupAddr),
     canon: *std.ArrayList(u8),
     name: []const u8,
-    family: os.sa_family_t,
+    family: posix.sa_family_t,
     port: u16,
 ) !void {
     const file = fs.openFileAbsoluteZ("/etc/hosts", .{}) catch |err| switch (err) {
@@ -1374,7 +1375,7 @@ fn linuxLookupNameFromDnsSearch(
     addrs: *std.ArrayList(LookupAddr),
     canon: *std.ArrayList(u8),
     name: []const u8,
-    family: os.sa_family_t,
+    family: posix.sa_family_t,
     port: u16,
 ) !void {
     var rc: ResolvConf = undefined;
@@ -1429,7 +1430,7 @@ fn linuxLookupNameFromDns(
     addrs: *std.ArrayList(LookupAddr),
     canon: *std.ArrayList(u8),
     name: []const u8,
-    family: os.sa_family_t,
+    family: posix.sa_family_t,
     rc: ResolvConf,
     port: u16,
 ) !void {
@@ -1439,12 +1440,12 @@ fn linuxLookupNameFromDns(
         .port = port,
     };
     const AfRr = struct {
-        af: os.sa_family_t,
+        af: posix.sa_family_t,
         rr: u8,
     };
     const afrrs = [_]AfRr{
-        AfRr{ .af = os.AF.INET6, .rr = os.RR.A },
-        AfRr{ .af = os.AF.INET, .rr = os.RR.AAAA },
+        AfRr{ .af = posix.AF.INET6, .rr = posix.RR.A },
+        AfRr{ .af = posix.AF.INET, .rr = posix.RR.AAAA },
     };
     var qbuf: [2][280]u8 = undefined;
     var abuf: [2][512]u8 = undefined;
@@ -1454,7 +1455,7 @@ fn linuxLookupNameFromDns(
 
     for (afrrs) |afrr| {
         if (family != afrr.af) {
-            const len = os.res_mkquery(0, name, 1, afrr.rr, &[_]u8{}, null, &qbuf[nq]);
+            const len = posix.res_mkquery(0, name, 1, afrr.rr, &[_]u8{}, null, &qbuf[nq]);
             qp[nq] = qbuf[nq][0..len];
             nq += 1;
         }
@@ -1582,8 +1583,8 @@ fn resMSendRc(
     const timeout = 1000 * rc.timeout;
     const attempts = rc.attempts;
 
-    var sl: os.socklen_t = @sizeOf(os.sockaddr.in);
-    var family: os.sa_family_t = os.AF.INET;
+    var sl: posix.socklen_t = @sizeOf(posix.sockaddr.in);
+    var family: posix.sa_family_t = posix.AF.INET;
 
     var ns_list = std.ArrayList(Address).init(rc.ns.allocator);
     defer ns_list.deinit();
@@ -1594,18 +1595,18 @@ fn resMSendRc(
     for (rc.ns.items, 0..) |iplit, i| {
         ns[i] = iplit.addr;
         assert(ns[i].getPort() == 53);
-        if (iplit.addr.any.family != os.AF.INET) {
-            family = os.AF.INET6;
+        if (iplit.addr.any.family != posix.AF.INET) {
+            family = posix.AF.INET6;
         }
     }
 
-    const flags = os.SOCK.DGRAM | os.SOCK.CLOEXEC | os.SOCK.NONBLOCK;
-    const fd = os.socket(family, flags, 0) catch |err| switch (err) {
+    const flags = posix.SOCK.DGRAM | posix.SOCK.CLOEXEC | posix.SOCK.NONBLOCK;
+    const fd = posix.socket(family, flags, 0) catch |err| switch (err) {
         error.AddressFamilyNotSupported => blk: {
             // Handle case where system lacks IPv6 support
-            if (family == os.AF.INET6) {
-                family = os.AF.INET;
-                break :blk try os.socket(os.AF.INET, flags, 0);
+            if (family == posix.AF.INET6) {
+                family = posix.AF.INET;
+                break :blk try posix.socket(posix.AF.INET, flags, 0);
             }
             return err;
         },
@@ -1618,33 +1619,33 @@ fn resMSendRc(
     // packet which is up to the caller to interpret.
 
     // Convert any IPv4 addresses in a mixed environment to v4-mapped
-    if (family == os.AF.INET6) {
-        try os.setsockopt(
+    if (family == posix.AF.INET6) {
+        try posix.setsockopt(
             fd,
-            os.SOL.IPV6,
-            os.linux.IPV6.V6ONLY,
+            posix.SOL.IPV6,
+            std.os.linux.IPV6.V6ONLY,
             &mem.toBytes(@as(c_int, 0)),
         );
         for (0..ns.len) |i| {
-            if (ns[i].any.family != os.AF.INET) continue;
+            if (ns[i].any.family != posix.AF.INET) continue;
             mem.writeInt(u32, ns[i].in6.sa.addr[12..], ns[i].in.sa.addr, native_endian);
             ns[i].in6.sa.addr[0..12].* = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff".*;
-            ns[i].any.family = os.AF.INET6;
+            ns[i].any.family = posix.AF.INET6;
             ns[i].in6.sa.flowinfo = 0;
             ns[i].in6.sa.scope_id = 0;
         }
-        sl = @sizeOf(os.sockaddr.in6);
+        sl = @sizeOf(posix.sockaddr.in6);
     }
 
     // Get local address and open/bind a socket
     var sa: Address = undefined;
     @memset(@as([*]u8, @ptrCast(&sa))[0..@sizeOf(Address)], 0);
     sa.any.family = family;
-    try os.bind(fd, &sa.any, sl);
+    try posix.bind(fd, &sa.any, sl);
 
-    var pfd = [1]os.pollfd{os.pollfd{
+    var pfd = [1]posix.pollfd{posix.pollfd{
         .fd = fd,
-        .events = os.POLL.IN,
+        .events = posix.POLL.IN,
         .revents = undefined,
     }};
     const retry_interval = timeout / attempts;
@@ -1663,7 +1664,7 @@ fn resMSendRc(
                 if (answers[i].len == 0) {
                     var j: usize = 0;
                     while (j < ns.len) : (j += 1) {
-                        _ = os.sendto(fd, queries[i], os.MSG.NOSIGNAL, &ns[j].any, sl) catch undefined;
+                        _ = posix.sendto(fd, queries[i], posix.MSG.NOSIGNAL, &ns[j].any, sl) catch undefined;
                     }
                 }
             }
@@ -1673,12 +1674,12 @@ fn resMSendRc(
 
         // Wait for a response, or until time to retry
         const clamped_timeout = @min(@as(u31, std.math.maxInt(u31)), t1 + retry_interval - t2);
-        const nevents = os.poll(&pfd, clamped_timeout) catch 0;
+        const nevents = posix.poll(&pfd, clamped_timeout) catch 0;
         if (nevents == 0) continue;
 
         while (true) {
             var sl_copy = sl;
-            const rlen = os.recvfrom(fd, answer_bufs[next], 0, &sa.any, &sl_copy) catch break;
+            const rlen = posix.recvfrom(fd, answer_bufs[next], 0, &sa.any, &sl_copy) catch break;
 
             // Ignore non-identifiable packets
             if (rlen < 4) continue;
@@ -1704,7 +1705,7 @@ fn resMSendRc(
                 0, 3 => {},
                 2 => if (servfail_retry != 0) {
                     servfail_retry -= 1;
-                    _ = os.sendto(fd, queries[i], os.MSG.NOSIGNAL, &ns[j].any, sl) catch undefined;
+                    _ = posix.sendto(fd, queries[i], posix.MSG.NOSIGNAL, &ns[j].any, sl) catch undefined;
                 },
                 else => continue,
             }
@@ -1758,24 +1759,24 @@ fn dnsParse(
 
 fn dnsParseCallback(ctx: dpc_ctx, rr: u8, data: []const u8, packet: []const u8) !void {
     switch (rr) {
-        os.RR.A => {
+        posix.RR.A => {
             if (data.len != 4) return error.InvalidDnsARecord;
             const new_addr = try ctx.addrs.addOne();
             new_addr.* = LookupAddr{
                 .addr = Address.initIp4(data[0..4].*, ctx.port),
             };
         },
-        os.RR.AAAA => {
+        posix.RR.AAAA => {
             if (data.len != 16) return error.InvalidDnsAAAARecord;
             const new_addr = try ctx.addrs.addOne();
             new_addr.* = LookupAddr{
                 .addr = Address.initIp6(data[0..16].*, ctx.port, 0, 0),
             };
         },
-        os.RR.CNAME => {
+        posix.RR.CNAME => {
             var tmp: [256]u8 = undefined;
             // Returns len of compressed name. strlen to get canon name.
-            _ = try os.dn_expand(packet, data, &tmp);
+            _ = try posix.dn_expand(packet, data, &tmp);
             const canon_name = mem.sliceTo(&tmp, 0);
             if (isValidHostName(canon_name)) {
                 ctx.canon.items.len = 0;
@@ -1792,14 +1793,14 @@ pub const Stream = struct {
     handle: posix.socket_t,
 
     pub fn close(s: Stream) void {
-        switch (builtin.os.tag) {
-            .windows => std.os.windows.closesocket(s.handle) catch unreachable,
+        switch (native_os) {
+            .windows => windows.closesocket(s.handle) catch unreachable,
             else => posix.close(s.handle),
         }
     }
 
-    pub const ReadError = os.ReadError;
-    pub const WriteError = os.WriteError;
+    pub const ReadError = posix.ReadError;
+    pub const WriteError = posix.WriteError;
 
     pub const Reader = io.Reader(Stream, ReadError, read);
     pub const Writer = io.Writer(Stream, WriteError, write);
@@ -1813,22 +1814,22 @@ pub const Stream = struct {
     }
 
     pub fn read(self: Stream, buffer: []u8) ReadError!usize {
-        if (builtin.os.tag == .windows) {
-            return os.windows.ReadFile(self.handle, buffer, null);
+        if (native_os == .windows) {
+            return windows.ReadFile(self.handle, buffer, null);
         }
 
-        return os.read(self.handle, buffer);
+        return posix.read(self.handle, buffer);
     }
 
-    pub fn readv(s: Stream, iovecs: []const os.iovec) ReadError!usize {
-        if (builtin.os.tag == .windows) {
+    pub fn readv(s: Stream, iovecs: []const posix.iovec) ReadError!usize {
+        if (native_os == .windows) {
             // TODO improve this to use ReadFileScatter
             if (iovecs.len == 0) return @as(usize, 0);
             const first = iovecs[0];
-            return os.windows.ReadFile(s.handle, first.iov_base[0..first.iov_len], null);
+            return windows.ReadFile(s.handle, first.iov_base[0..first.iov_len], null);
         }
 
-        return os.readv(s.handle, iovecs);
+        return posix.readv(s.handle, iovecs);
     }
 
     /// Returns the number of bytes read. If the number read is smaller than
@@ -1858,11 +1859,11 @@ pub const Stream = struct {
     /// file system thread instead of non-blocking. It needs to be reworked to properly
     /// use non-blocking I/O.
     pub fn write(self: Stream, buffer: []const u8) WriteError!usize {
-        if (builtin.os.tag == .windows) {
-            return os.windows.WriteFile(self.handle, buffer, null);
+        if (native_os == .windows) {
+            return windows.WriteFile(self.handle, buffer, null);
         }
 
-        return os.write(self.handle, buffer);
+        return posix.write(self.handle, buffer);
     }
 
     pub fn writeAll(self: Stream, bytes: []const u8) WriteError!void {
@@ -1874,15 +1875,15 @@ pub const Stream = struct {
 
     /// See https://github.com/ziglang/zig/issues/7699
     /// See equivalent function: `std.fs.File.writev`.
-    pub fn writev(self: Stream, iovecs: []const os.iovec_const) WriteError!usize {
-        return os.writev(self.handle, iovecs);
+    pub fn writev(self: Stream, iovecs: []const posix.iovec_const) WriteError!usize {
+        return posix.writev(self.handle, iovecs);
     }
 
     /// The `iovecs` parameter is mutable because this function needs to mutate the fields in
     /// order to handle partial writes from the underlying OS layer.
     /// See https://github.com/ziglang/zig/issues/7699
     /// See equivalent function: `std.fs.File.writevAll`.
-    pub fn writevAll(self: Stream, iovecs: []os.iovec_const) WriteError!void {
+    pub fn writevAll(self: Stream, iovecs: []posix.iovec_const) WriteError!void {
         if (iovecs.len == 0) return;
 
         var i: usize = 0;
lib/std/os.zig
@@ -11,8 +11,6 @@
 //!   On Linux libc can be side-stepped by using `std.os.linux` directly.
 //! * For Windows, this file represents the API that libc would provide for
 //!   Windows. For thin wrappers around Windows-specific APIs, see `std.os.windows`.
-//! Note: The Zig standard library does not support POSIX thread cancellation, and
-//! in general EINTR is handled by trying again.
 
 const root = @import("root");
 const std = @import("std.zig");
@@ -25,14 +23,6 @@ const fs = std.fs;
 const dl = @import("dynamic_library.zig");
 const MAX_PATH_BYTES = std.fs.MAX_PATH_BYTES;
 
-pub const darwin = std.c;
-pub const dragonfly = std.c;
-pub const freebsd = std.c;
-pub const haiku = std.c;
-pub const netbsd = std.c;
-pub const openbsd = std.c;
-pub const solaris = std.c;
-pub const illumos = std.c;
 pub const linux = @import("os/linux.zig");
 pub const plan9 = @import("os/plan9.zig");
 pub const uefi = @import("os/uefi.zig");
@@ -40,214 +30,15 @@ pub const wasi = @import("os/wasi.zig");
 pub const emscripten = @import("os/emscripten.zig");
 pub const windows = @import("os/windows.zig");
 
-comptime {
-    assert(@import("std") == std); // std lib tests require --zig-lib-dir
-}
-
 test {
-    _ = darwin;
     _ = linux;
     if (builtin.os.tag == .uefi) {
         _ = uefi;
     }
     _ = wasi;
     _ = windows;
-
-    _ = @import("os/test.zig");
 }
 
-/// Applications can override the `system` API layer in their root source file.
-/// Otherwise, when linking libc, this is the C API.
-/// When not linking libc, it is the OS-specific system interface.
-pub const system = if (@hasDecl(root, "os") and @hasDecl(root.os, "system") and root.os != @This())
-    root.os.system
-else if (use_libc)
-    std.c
-else switch (builtin.os.tag) {
-    .linux => linux,
-    .plan9 => plan9,
-    .uefi => uefi,
-    else => struct {},
-};
-
-/// Whether to use libc for the POSIX API layer.
-const use_libc = builtin.link_libc or switch (builtin.os.tag) {
-    .windows, .wasi => true,
-    else => false,
-};
-
-pub const AF = system.AF;
-pub const AF_SUN = system.AF_SUN;
-pub const ARCH = system.ARCH;
-pub const AT = system.AT;
-pub const AT_SUN = system.AT_SUN;
-pub const CLOCK = system.CLOCK;
-pub const CPU_COUNT = system.CPU_COUNT;
-pub const CTL = system.CTL;
-pub const DT = system.DT;
-pub const E = system.E;
-pub const Elf_Symndx = system.Elf_Symndx;
-pub const F = system.F;
-pub const FD_CLOEXEC = system.FD_CLOEXEC;
-pub const Flock = system.Flock;
-pub const HOST_NAME_MAX = system.HOST_NAME_MAX;
-pub const HW = system.HW;
-pub const IFNAMESIZE = system.IFNAMESIZE;
-pub const IOV_MAX = system.IOV_MAX;
-pub const IPPROTO = system.IPPROTO;
-pub const KERN = system.KERN;
-pub const Kevent = system.Kevent;
-pub const LOCK = system.LOCK;
-pub const MADV = system.MADV;
-pub const MAP = system.MAP;
-pub const MSF = system.MSF;
-pub const MAX_ADDR_LEN = system.MAX_ADDR_LEN;
-pub const MFD = system.MFD;
-pub const MMAP2_UNIT = system.MMAP2_UNIT;
-pub const MSG = system.MSG;
-pub const NAME_MAX = system.NAME_MAX;
-pub const O = system.O;
-pub const PATH_MAX = system.PATH_MAX;
-pub const POLL = system.POLL;
-pub const POSIX_FADV = system.POSIX_FADV;
-pub const PR = system.PR;
-pub const PROT = system.PROT;
-pub const REG = system.REG;
-pub const RLIM = system.RLIM;
-pub const RR = system.RR;
-pub const S = system.S;
-pub const SA = system.SA;
-pub const SC = system.SC;
-pub const _SC = system._SC;
-pub const SEEK = system.SEEK;
-pub const SHUT = system.SHUT;
-pub const SIG = system.SIG;
-pub const SIOCGIFINDEX = system.SIOCGIFINDEX;
-pub const SO = system.SO;
-pub const SOCK = system.SOCK;
-pub const SOL = system.SOL;
-pub const STDERR_FILENO = system.STDERR_FILENO;
-pub const STDIN_FILENO = system.STDIN_FILENO;
-pub const STDOUT_FILENO = system.STDOUT_FILENO;
-pub const SYS = system.SYS;
-pub const Sigaction = system.Sigaction;
-pub const Stat = system.Stat;
-pub const T = system.T;
-pub const TCSA = system.TCSA;
-pub const TCP = system.TCP;
-pub const VDSO = system.VDSO;
-pub const W = system.W;
-pub const addrinfo = system.addrinfo;
-pub const blkcnt_t = system.blkcnt_t;
-pub const blksize_t = system.blksize_t;
-pub const clock_t = system.clock_t;
-pub const cpu_set_t = system.cpu_set_t;
-pub const dev_t = system.dev_t;
-pub const dl_phdr_info = system.dl_phdr_info;
-pub const empty_sigset = system.empty_sigset;
-pub const filled_sigset = system.filled_sigset;
-pub const fd_t = system.fd_t;
-pub const gid_t = system.gid_t;
-pub const ifreq = system.ifreq;
-pub const ino_t = system.ino_t;
-pub const mcontext_t = system.mcontext_t;
-pub const mode_t = system.mode_t;
-pub const msghdr = system.msghdr;
-pub const msghdr_const = system.msghdr_const;
-pub const nfds_t = system.nfds_t;
-pub const nlink_t = system.nlink_t;
-pub const off_t = system.off_t;
-pub const pid_t = system.pid_t;
-pub const pollfd = system.pollfd;
-pub const port_t = system.port_t;
-pub const port_event = system.port_event;
-pub const port_notify = system.port_notify;
-pub const file_obj = system.file_obj;
-pub const rlim_t = system.rlim_t;
-pub const rlimit = system.rlimit;
-pub const rlimit_resource = system.rlimit_resource;
-pub const rusage = system.rusage;
-pub const sa_family_t = system.sa_family_t;
-pub const siginfo_t = system.siginfo_t;
-pub const sigset_t = system.sigset_t;
-pub const sockaddr = system.sockaddr;
-pub const socklen_t = system.socklen_t;
-pub const stack_t = system.stack_t;
-pub const time_t = system.time_t;
-pub const timespec = system.timespec;
-pub const timestamp_t = system.timestamp_t;
-pub const timeval = system.timeval;
-pub const timezone = system.timezone;
-pub const ucontext_t = system.ucontext_t;
-pub const uid_t = system.uid_t;
-pub const user_desc = system.user_desc;
-pub const utsname = system.utsname;
-pub const winsize = system.winsize;
-
-pub const termios = system.termios;
-pub const CSIZE = system.CSIZE;
-pub const NCCS = system.NCCS;
-pub const cc_t = system.cc_t;
-pub const V = system.V;
-pub const speed_t = system.speed_t;
-pub const tc_iflag_t = system.tc_iflag_t;
-pub const tc_oflag_t = system.tc_oflag_t;
-pub const tc_cflag_t = system.tc_cflag_t;
-pub const tc_lflag_t = system.tc_lflag_t;
-
-pub const F_OK = system.F_OK;
-pub const R_OK = system.R_OK;
-pub const W_OK = system.W_OK;
-pub const X_OK = system.X_OK;
-
-pub const iovec = extern struct {
-    iov_base: [*]u8,
-    iov_len: usize,
-};
-
-pub const iovec_const = extern struct {
-    iov_base: [*]const u8,
-    iov_len: usize,
-};
-
-pub const ACCMODE = enum(u2) {
-    RDONLY = 0,
-    WRONLY = 1,
-    RDWR = 2,
-};
-
-pub const LOG = struct {
-    /// system is unusable
-    pub const EMERG = 0;
-    /// action must be taken immediately
-    pub const ALERT = 1;
-    /// critical conditions
-    pub const CRIT = 2;
-    /// error conditions
-    pub const ERR = 3;
-    /// warning conditions
-    pub const WARNING = 4;
-    /// normal but significant condition
-    pub const NOTICE = 5;
-    /// informational
-    pub const INFO = 6;
-    /// debug-level messages
-    pub const DEBUG = 7;
-};
-
-/// An fd-relative file path
-///
-/// This is currently only used for WASI-specific functionality, but the concept
-/// is the same as the dirfd/pathname pairs in the `*at(...)` POSIX functions.
-pub const RelativePathWasi = struct {
-    /// Handle to directory
-    dir_fd: fd_t,
-    /// Path to resource within `dir_fd`.
-    relative_path: []const u8,
-};
-
-pub const socket_t = if (builtin.os.tag == .windows) windows.ws2_32.SOCKET else fd_t;
-
 /// See also `getenv`. Populated by startup code before main().
 /// TODO this is a footgun because the value will be undefined when using `zig build-lib`.
 /// https://github.com/ziglang/zig/issues/4524
@@ -262,7433 +53,184 @@ pub var argv: [][*:0]u8 = if (builtin.link_libc) undefined else switch (builtin.
     else => undefined,
 };
 
-pub const have_sigpipe_support = @hasDecl(@This(), "SIG") and @hasDecl(SIG, "PIPE");
-
-fn noopSigHandler(_: c_int) callconv(.C) void {}
-
-/// On default executed by posix startup code before main(), if SIGPIPE is supported.
-pub fn maybeIgnoreSigpipe() void {
-    if (have_sigpipe_support and !std.options.keep_sigpipe) {
-        const act = Sigaction{
-            // We set handler to a noop function instead of SIG.IGN so we don't leak our
-            // signal disposition to a child process
-            .handler = .{ .handler = noopSigHandler },
-            .mask = empty_sigset,
-            .flags = 0,
-        };
-        sigaction(SIG.PIPE, &act, null) catch |err|
-            std.debug.panic("failed to install noop SIGPIPE handler with '{s}'", .{@errorName(err)});
-    }
-}
-
-/// To obtain errno, call this function with the return value of the
-/// system function call. For some systems this will obtain the value directly
-/// from the return code; for others it will use a thread-local errno variable.
-/// Therefore, this function only returns a well-defined value when it is called
-/// directly after the system function call which one wants to learn the errno
-/// value of.
-pub const errno = system.getErrno;
-
-/// Closes the file descriptor.
-/// This function is not capable of returning any indication of failure. An
-/// application which wants to ensure writes have succeeded before closing
-/// must call `fsync` before `close`.
-/// Note: The Zig standard library does not support POSIX thread cancellation.
-pub fn close(fd: fd_t) void {
-    if (builtin.os.tag == .windows) {
-        return windows.CloseHandle(fd);
-    }
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        _ = wasi.fd_close(fd);
+/// Call from Windows-specific code if you already have a WTF-16LE encoded, null terminated string.
+/// Otherwise use `access` or `accessZ`.
+pub fn accessW(path: [*:0]const u16) windows.GetFileAttributesError!void {
+    const ret = try windows.GetFileAttributesW(path);
+    if (ret != windows.INVALID_FILE_ATTRIBUTES) {
         return;
     }
-    if (builtin.target.isDarwin()) {
-        // This avoids the EINTR problem.
-        switch (darwin.getErrno(darwin.@"close$NOCANCEL"(fd))) {
-            .BADF => unreachable, // Always a race condition.
-            else => return,
-        }
-    }
-    switch (errno(system.close(fd))) {
-        .BADF => unreachable, // Always a race condition.
-        .INTR => return, // This is still a success. See https://github.com/ziglang/zig/issues/2425
-        else => return,
+    switch (windows.kernel32.GetLastError()) {
+        .FILE_NOT_FOUND => return error.FileNotFound,
+        .PATH_NOT_FOUND => return error.FileNotFound,
+        .ACCESS_DENIED => return error.PermissionDenied,
+        else => |err| return windows.unexpectedError(err),
     }
 }
 
-pub const FChmodError = error{
-    AccessDenied,
-    InputOutput,
-    SymLinkLoop,
-    FileNotFound,
-    SystemResources,
-    ReadOnlyFileSystem,
-} || UnexpectedError;
-
-/// Changes the mode of the file referred to by the file descriptor.
-/// The process must have the correct privileges in order to do this
-/// successfully, or must have the effective user ID matching the owner
-/// of the file.
-pub fn fchmod(fd: fd_t, mode: mode_t) FChmodError!void {
-    if (!std.fs.has_executable_bit) @compileError("fchmod unsupported by target OS");
-
-    while (true) {
-        const res = system.fchmod(fd, mode);
+pub fn isGetFdPathSupportedOnTarget(os: std.Target.Os) bool {
+    return switch (os.tag) {
+        .windows,
+        .macos,
+        .ios,
+        .watchos,
+        .tvos,
+        .linux,
+        .solaris,
+        .illumos,
+        .freebsd,
+        => true,
 
-        switch (system.getErrno(res)) {
-            .SUCCESS => return,
-            .INTR => continue,
-            .BADF => unreachable,
-            .FAULT => unreachable,
-            .INVAL => unreachable,
-            .ACCES => return error.AccessDenied,
-            .IO => return error.InputOutput,
-            .LOOP => return error.SymLinkLoop,
-            .NOENT => return error.FileNotFound,
-            .NOMEM => return error.SystemResources,
-            .NOTDIR => return error.FileNotFound,
-            .PERM => return error.AccessDenied,
-            .ROFS => return error.ReadOnlyFileSystem,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
+        .dragonfly => os.version_range.semver.max.order(.{ .major = 6, .minor = 0, .patch = 0 }) != .lt,
+        .netbsd => os.version_range.semver.max.order(.{ .major = 10, .minor = 0, .patch = 0 }) != .lt,
+        else => false,
+    };
 }
 
-const FChmodAtError = FChmodError || error{
-    /// A component of `path` exceeded `NAME_MAX`, or the entire path exceeded
-    /// `PATH_MAX`.
-    NameTooLong,
-    /// `path` resolves to a symbolic link, and `AT.SYMLINK_NOFOLLOW` was set
-    /// in `flags`. This error only occurs on Linux, where changing the mode of
-    /// a symbolic link has no meaning and can cause undefined behaviour on
-    /// certain filesystems.
-    ///
-    /// The procfs fallback was used but procfs was not mounted.
-    OperationNotSupported,
-    /// The procfs fallback was used but the process exceeded its open file
-    /// limit.
-    ProcessFdQuotaExceeded,
-    /// The procfs fallback was used but the system exceeded it open file limit.
-    SystemFdQuotaExceeded,
-};
-
-var has_fchmodat2_syscall = std.atomic.Value(bool).init(true);
-
-/// Changes the `mode` of `path` relative to the directory referred to by
-/// `dirfd`. The process must have the correct privileges in order to do this
-/// successfully, or must have the effective user ID matching the owner of the
-/// file.
+/// Return canonical path of handle `fd`.
 ///
-/// On Linux the `fchmodat2` syscall will be used if available, otherwise a
-/// workaround using procfs will be employed. Changing the mode of a symbolic
-/// link with `AT.SYMLINK_NOFOLLOW` set will also return
-/// `OperationNotSupported`, as:
+/// This function is very host-specific and is not universally supported by all hosts.
+/// For example, while it generally works on Linux, macOS, FreeBSD or Windows, it is
+/// unsupported on WASI.
 ///
-///  1. Permissions on the link are ignored when resolving its target.
-///  2. This operation has been known to invoke undefined behaviour across
-///     different filesystems[1].
+/// * On Windows, the result is encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// * On other platforms, the result is an opaque sequence of bytes with no particular encoding.
 ///
-/// [1]: https://sourceware.org/legacy-ml/libc-alpha/2020-02/msg00467.html.
-pub inline fn fchmodat(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtError!void {
-    if (!std.fs.has_executable_bit) @compileError("fchmodat unsupported by target OS");
-
-    // No special handling for linux is needed if we can use the libc fallback
-    // or `flags` is empty. Glibc only added the fallback in 2.32.
-    const skip_fchmodat_fallback = builtin.os.tag != .linux or
-        std.c.versionCheck(.{ .major = 2, .minor = 32, .patch = 0 }) or
-        flags == 0;
-
-    // This function is marked inline so that when flags is comptime-known,
-    // skip_fchmodat_fallback will be comptime-known true.
-    if (skip_fchmodat_fallback)
-        return fchmodat1(dirfd, path, mode, flags);
-
-    return fchmodat2(dirfd, path, mode, flags);
-}
-
-fn fchmodat1(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtError!void {
-    const path_c = try toPosixPath(path);
-    while (true) {
-        const res = system.fchmodat(dirfd, &path_c, mode, flags);
-        switch (system.getErrno(res)) {
-            .SUCCESS => return,
-            .INTR => continue,
-            .BADF => unreachable,
-            .FAULT => unreachable,
-            .INVAL => unreachable,
-            .ACCES => return error.AccessDenied,
-            .IO => return error.InputOutput,
-            .LOOP => return error.SymLinkLoop,
-            .MFILE => return error.ProcessFdQuotaExceeded,
-            .NAMETOOLONG => return error.NameTooLong,
-            .NFILE => return error.SystemFdQuotaExceeded,
-            .NOENT => return error.FileNotFound,
-            .NOTDIR => return error.FileNotFound,
-            .NOMEM => return error.SystemResources,
-            .OPNOTSUPP => return error.OperationNotSupported,
-            .PERM => return error.AccessDenied,
-            .ROFS => return error.ReadOnlyFileSystem,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-fn fchmodat2(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtError!void {
-    const path_c = try toPosixPath(path);
-    const use_fchmodat2 = (builtin.os.isAtLeast(.linux, .{ .major = 6, .minor = 6, .patch = 0 }) orelse false) and
-        has_fchmodat2_syscall.load(.monotonic);
-    while (use_fchmodat2) {
-        // Later on this should be changed to `system.fchmodat2`
-        // when the musl/glibc add a wrapper.
-        const res = linux.fchmodat2(dirfd, &path_c, mode, flags);
-        switch (linux.getErrno(res)) {
-            .SUCCESS => return,
-            .INTR => continue,
-            .BADF => unreachable,
-            .FAULT => unreachable,
-            .INVAL => unreachable,
-            .ACCES => return error.AccessDenied,
-            .IO => return error.InputOutput,
-            .LOOP => return error.SymLinkLoop,
-            .NOENT => return error.FileNotFound,
-            .NOMEM => return error.SystemResources,
-            .NOTDIR => return error.FileNotFound,
-            .OPNOTSUPP => return error.OperationNotSupported,
-            .PERM => return error.AccessDenied,
-            .ROFS => return error.ReadOnlyFileSystem,
-
-            .NOSYS => { // Use fallback.
-                has_fchmodat2_syscall.store(false, .monotonic);
-                break;
-            },
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-
-    // Fallback to changing permissions using procfs:
-    //
-    // 1. Open `path` as a `PATH` descriptor.
-    // 2. Stat the fd and check if it isn't a symbolic link.
-    // 3. Generate the procfs reference to the fd via `/proc/self/fd/{fd}`.
-    // 4. Pass the procfs path to `chmod` with the `mode`.
-    var pathfd: fd_t = undefined;
-    while (true) {
-        const rc = system.openat(dirfd, &path_c, .{ .PATH = true, .NOFOLLOW = true, .CLOEXEC = true }, @as(mode_t, 0));
-        switch (system.getErrno(rc)) {
-            .SUCCESS => {
-                pathfd = @intCast(rc);
-                break;
-            },
-            .INTR => continue,
-            .FAULT => unreachable,
-            .INVAL => unreachable,
-            .ACCES => return error.AccessDenied,
-            .PERM => return error.AccessDenied,
-            .LOOP => return error.SymLinkLoop,
-            .MFILE => return error.ProcessFdQuotaExceeded,
-            .NAMETOOLONG => return error.NameTooLong,
-            .NFILE => return error.SystemFdQuotaExceeded,
-            .NOENT => return error.FileNotFound,
-            .NOMEM => return error.SystemResources,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-    defer close(pathfd);
-
-    const stat = fstatatZ(pathfd, "", AT.EMPTY_PATH) catch |err| switch (err) {
-        error.NameTooLong => unreachable,
-        error.FileNotFound => unreachable,
-        error.InvalidUtf8 => unreachable,
-        else => |e| return e,
-    };
-    if ((stat.mode & S.IFMT) == S.IFLNK)
-        return error.OperationNotSupported;
-
-    var procfs_buf: ["/proc/self/fd/-2147483648\x00".len]u8 = undefined;
-    const proc_path = std.fmt.bufPrintZ(procfs_buf[0..], "/proc/self/fd/{d}", .{pathfd}) catch unreachable;
-    while (true) {
-        const res = system.chmod(proc_path, mode);
-        switch (system.getErrno(res)) {
-            // Getting NOENT here means that procfs isn't mounted.
-            .NOENT => return error.OperationNotSupported,
-
-            .SUCCESS => return,
-            .INTR => continue,
-            .BADF => unreachable,
-            .FAULT => unreachable,
-            .INVAL => unreachable,
-            .ACCES => return error.AccessDenied,
-            .IO => return error.InputOutput,
-            .LOOP => return error.SymLinkLoop,
-            .NOMEM => return error.SystemResources,
-            .NOTDIR => return error.FileNotFound,
-            .PERM => return error.AccessDenied,
-            .ROFS => return error.ReadOnlyFileSystem,
-            else => |err| return unexpectedErrno(err),
-        }
+/// Calling this function is usually a bug.
+pub fn getFdPath(fd: std.posix.fd_t, out_buffer: *[MAX_PATH_BYTES]u8) std.posix.RealPathError![]u8 {
+    const posix = std.posix;
+    if (!comptime isGetFdPathSupportedOnTarget(builtin.os)) {
+        @compileError("querying for canonical path of a handle is unsupported on this host");
     }
-}
-
-pub const FChownError = error{
-    AccessDenied,
-    InputOutput,
-    SymLinkLoop,
-    FileNotFound,
-    SystemResources,
-    ReadOnlyFileSystem,
-} || UnexpectedError;
-
-/// Changes the owner and group of the file referred to by the file descriptor.
-/// The process must have the correct privileges in order to do this
-/// successfully. The group may be changed by the owner of the directory to
-/// any group of which the owner is a member. If the owner or group is
-/// specified as `null`, the ID is not changed.
-pub fn fchown(fd: fd_t, owner: ?uid_t, group: ?gid_t) FChownError!void {
     switch (builtin.os.tag) {
-        .windows, .wasi => @compileError("Unsupported OS"),
-        else => {},
-    }
-
-    while (true) {
-        const res = system.fchown(fd, owner orelse ~@as(uid_t, 0), group orelse ~@as(gid_t, 0));
-
-        switch (system.getErrno(res)) {
-            .SUCCESS => return,
-            .INTR => continue,
-            .BADF => unreachable, // Can be reached if the fd refers to a directory opened without `OpenDirOptions{ .iterate = true }`
-
-            .FAULT => unreachable,
-            .INVAL => unreachable,
-            .ACCES => return error.AccessDenied,
-            .IO => return error.InputOutput,
-            .LOOP => return error.SymLinkLoop,
-            .NOENT => return error.FileNotFound,
-            .NOMEM => return error.SystemResources,
-            .NOTDIR => return error.FileNotFound,
-            .PERM => return error.AccessDenied,
-            .ROFS => return error.ReadOnlyFileSystem,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-pub const RebootError = error{
-    PermissionDenied,
-} || UnexpectedError;
-
-pub const RebootCommand = switch (builtin.os.tag) {
-    .linux => union(linux.LINUX_REBOOT.CMD) {
-        RESTART: void,
-        HALT: void,
-        CAD_ON: void,
-        CAD_OFF: void,
-        POWER_OFF: void,
-        RESTART2: [*:0]const u8,
-        SW_SUSPEND: void,
-        KEXEC: void,
-    },
-    else => @compileError("Unsupported OS"),
-};
+        .windows => {
+            var wide_buf: [windows.PATH_MAX_WIDE]u16 = undefined;
+            const wide_slice = try windows.GetFinalPathNameByHandle(fd, .{}, wide_buf[0..]);
 
-pub fn reboot(cmd: RebootCommand) RebootError!void {
-    switch (builtin.os.tag) {
-        .linux => {
-            switch (system.getErrno(linux.reboot(
-                .MAGIC1,
-                .MAGIC2,
-                cmd,
-                switch (cmd) {
-                    .RESTART2 => |s| s,
-                    else => null,
-                },
-            ))) {
+            const end_index = std.unicode.wtf16LeToWtf8(out_buffer, wide_slice);
+            return out_buffer[0..end_index];
+        },
+        .macos, .ios, .watchos, .tvos => {
+            // On macOS, we can use F.GETPATH fcntl command to query the OS for
+            // the path to the file descriptor.
+            @memset(out_buffer[0..MAX_PATH_BYTES], 0);
+            switch (posix.errno(posix.system.fcntl(fd, posix.F.GETPATH, out_buffer))) {
                 .SUCCESS => {},
-                .PERM => return error.PermissionDenied,
-                else => |err| return std.os.unexpectedErrno(err),
-            }
-            switch (cmd) {
-                .CAD_OFF => {},
-                .CAD_ON => {},
-                .SW_SUSPEND => {},
-
-                .HALT => unreachable,
-                .KEXEC => unreachable,
-                .POWER_OFF => unreachable,
-                .RESTART => unreachable,
-                .RESTART2 => unreachable,
+                .BADF => return error.FileNotFound,
+                .NOSPC => return error.NameTooLong,
+                // TODO man pages for fcntl on macOS don't really tell you what
+                // errno values to expect when command is F.GETPATH...
+                else => |err| return posix.unexpectedErrno(err),
             }
+            const len = mem.indexOfScalar(u8, out_buffer[0..], 0) orelse MAX_PATH_BYTES;
+            return out_buffer[0..len];
         },
-        else => @compileError("Unsupported OS"),
-    }
-}
-
-pub const GetRandomError = OpenError;
+        .linux => {
+            var procfs_buf: ["/proc/self/fd/-2147483648\x00".len]u8 = undefined;
+            const proc_path = std.fmt.bufPrintZ(procfs_buf[0..], "/proc/self/fd/{d}", .{fd}) catch unreachable;
 
-/// Obtain a series of random bytes. These bytes can be used to seed user-space
-/// random number generators or for cryptographic purposes.
-/// When linking against libc, this calls the
-/// appropriate OS-specific library call. Otherwise it uses the zig standard
-/// library implementation.
-pub fn getrandom(buffer: []u8) GetRandomError!void {
-    if (builtin.os.tag == .windows) {
-        return windows.RtlGenRandom(buffer);
-    }
-    if (builtin.os.tag == .linux or builtin.os.tag == .freebsd) {
-        var buf = buffer;
-        const use_c = builtin.os.tag != .linux or
-            std.c.versionCheck(std.SemanticVersion{ .major = 2, .minor = 25, .patch = 0 });
+            const target = posix.readlinkZ(proc_path, out_buffer) catch |err| {
+                switch (err) {
+                    error.NotLink => unreachable,
+                    error.BadPathName => unreachable,
+                    error.InvalidUtf8 => unreachable, // WASI-only
+                    error.InvalidWtf8 => unreachable, // Windows-only
+                    error.UnsupportedReparsePointType => unreachable, // Windows-only
+                    error.NetworkNotFound => unreachable, // Windows-only
+                    else => |e| return e,
+                }
+            };
+            return target;
+        },
+        .solaris, .illumos => {
+            var procfs_buf: ["/proc/self/path/-2147483648\x00".len]u8 = undefined;
+            const proc_path = std.fmt.bufPrintZ(procfs_buf[0..], "/proc/self/path/{d}", .{fd}) catch unreachable;
 
-        while (buf.len != 0) {
-            const num_read: usize, const err = if (use_c) res: {
-                const rc = std.c.getrandom(buf.ptr, buf.len, 0);
-                break :res .{
-                    @bitCast(rc),
-                    std.c.getErrno(rc),
+            const target = posix.readlinkZ(proc_path, out_buffer) catch |err| switch (err) {
+                error.UnsupportedReparsePointType => unreachable,
+                error.NotLink => unreachable,
+                else => |e| return e,
+            };
+            return target;
+        },
+        .freebsd => {
+            if (comptime builtin.os.isAtLeast(.freebsd, .{ .major = 13, .minor = 0, .patch = 0 }) orelse false) {
+                var kfile: std.c.kinfo_file = undefined;
+                kfile.structsize = std.c.KINFO_FILE_SIZE;
+                switch (posix.errno(std.c.fcntl(fd, std.c.F.KINFO, @intFromPtr(&kfile)))) {
+                    .SUCCESS => {},
+                    .BADF => return error.FileNotFound,
+                    else => |err| return posix.unexpectedErrno(err),
+                }
+                const len = mem.indexOfScalar(u8, &kfile.path, 0) orelse MAX_PATH_BYTES;
+                if (len == 0) return error.NameTooLong;
+                const result = out_buffer[0..len];
+                @memcpy(result, kfile.path[0..len]);
+                return result;
+            } else {
+                // This fallback implementation reimplements libutil's `kinfo_getfile()`.
+                // The motivation is to avoid linking -lutil when building zig or general
+                // user executables.
+                var mib = [4]c_int{ posix.CTL.KERN, posix.KERN.PROC, posix.KERN.PROC_FILEDESC, std.c.getpid() };
+                var len: usize = undefined;
+                posix.sysctl(&mib, null, &len, null, 0) catch |err| switch (err) {
+                    error.PermissionDenied => unreachable,
+                    error.SystemResources => return error.SystemResources,
+                    error.NameTooLong => unreachable,
+                    error.UnknownName => unreachable,
+                    else => return error.Unexpected,
                 };
-            } else res: {
-                const rc = linux.getrandom(buf.ptr, buf.len, 0);
-                break :res .{
-                    rc,
-                    linux.getErrno(rc),
+                len = len * 4 / 3;
+                const buf = std.heap.c_allocator.alloc(u8, len) catch return error.SystemResources;
+                defer std.heap.c_allocator.free(buf);
+                len = buf.len;
+                posix.sysctl(&mib, &buf[0], &len, null, 0) catch |err| switch (err) {
+                    error.PermissionDenied => unreachable,
+                    error.SystemResources => return error.SystemResources,
+                    error.NameTooLong => unreachable,
+                    error.UnknownName => unreachable,
+                    else => return error.Unexpected,
                 };
-            };
-
-            switch (err) {
-                .SUCCESS => buf = buf[num_read..],
-                .INVAL => unreachable,
-                .FAULT => unreachable,
-                .INTR => continue,
-                .NOSYS => return getRandomBytesDevURandom(buf),
-                else => return unexpectedErrno(err),
+                var i: usize = 0;
+                while (i < len) {
+                    const kf: *align(1) std.c.kinfo_file = @ptrCast(&buf[i]);
+                    if (kf.fd == fd) {
+                        len = mem.indexOfScalar(u8, &kf.path, 0) orelse MAX_PATH_BYTES;
+                        if (len == 0) return error.NameTooLong;
+                        const result = out_buffer[0..len];
+                        @memcpy(result, kf.path[0..len]);
+                        return result;
+                    }
+                    i += @intCast(kf.structsize);
+                }
+                return error.FileNotFound;
             }
-        }
-        return;
-    }
-    if (builtin.os.tag == .emscripten) {
-        const err = std.c.getErrno(std.c.getentropy(buffer.ptr, buffer.len));
-        switch (err) {
-            .SUCCESS => return,
-            else => return unexpectedErrno(err),
-        }
-    }
-    switch (builtin.os.tag) {
-        .netbsd, .openbsd, .macos, .ios, .tvos, .watchos => {
-            system.arc4random_buf(buffer.ptr, buffer.len);
-            return;
         },
-        .wasi => switch (wasi.random_get(buffer.ptr, buffer.len)) {
-            .SUCCESS => return,
-            else => |err| return unexpectedErrno(err),
+        .dragonfly => {
+            @memset(out_buffer[0..MAX_PATH_BYTES], 0);
+            switch (posix.errno(std.c.fcntl(fd, posix.F.GETPATH, out_buffer))) {
+                .SUCCESS => {},
+                .BADF => return error.FileNotFound,
+                .RANGE => return error.NameTooLong,
+                else => |err| return posix.unexpectedErrno(err),
+            }
+            const len = mem.indexOfScalar(u8, out_buffer[0..], 0) orelse MAX_PATH_BYTES;
+            return out_buffer[0..len];
+        },
+        .netbsd => {
+            @memset(out_buffer[0..MAX_PATH_BYTES], 0);
+            switch (posix.errno(std.c.fcntl(fd, posix.F.GETPATH, out_buffer))) {
+                .SUCCESS => {},
+                .ACCES => return error.AccessDenied,
+                .BADF => return error.FileNotFound,
+                .NOENT => return error.FileNotFound,
+                .NOMEM => return error.SystemResources,
+                .RANGE => return error.NameTooLong,
+                else => |err| return posix.unexpectedErrno(err),
+            }
+            const len = mem.indexOfScalar(u8, out_buffer[0..], 0) orelse MAX_PATH_BYTES;
+            return out_buffer[0..len];
         },
-        else => return getRandomBytesDevURandom(buffer),
-    }
-}
-
-fn getRandomBytesDevURandom(buf: []u8) !void {
-    const fd = try openZ("/dev/urandom", .{ .ACCMODE = .RDONLY, .CLOEXEC = true }, 0);
-    defer close(fd);
-
-    const st = try fstat(fd);
-    if (!S.ISCHR(st.mode)) {
-        return error.NoDevice;
-    }
-
-    const file = std.fs.File{ .handle = fd };
-    const stream = file.reader();
-    stream.readNoEof(buf) catch return error.Unexpected;
-}
-
-/// Causes abnormal process termination.
-/// If linking against libc, this calls the abort() libc function. Otherwise
-/// it raises SIGABRT followed by SIGKILL and finally lo
-/// Invokes the current signal handler for SIGABRT, if any.
-pub fn abort() noreturn {
-    @setCold(true);
-    // MSVCRT abort() sometimes opens a popup window which is undesirable, so
-    // even when linking libc on Windows we use our own abort implementation.
-    // See https://github.com/ziglang/zig/issues/2071 for more details.
-    if (builtin.os.tag == .windows) {
-        if (builtin.mode == .Debug) {
-            @breakpoint();
-        }
-        windows.kernel32.ExitProcess(3);
-    }
-    if (!builtin.link_libc and builtin.os.tag == .linux) {
-        // The Linux man page says that the libc abort() function
-        // "first unblocks the SIGABRT signal", but this is a footgun
-        // for user-defined signal handlers that want to restore some state in
-        // some program sections and crash in others.
-        // So, the user-installed SIGABRT handler is run, if present.
-        raise(SIG.ABRT) catch {};
-
-        // Disable all signal handlers.
-        sigprocmask(SIG.BLOCK, &linux.all_mask, null);
-
-        // Only one thread may proceed to the rest of abort().
-        if (!builtin.single_threaded) {
-            const global = struct {
-                var abort_entered: bool = false;
-            };
-            while (@cmpxchgWeak(bool, &global.abort_entered, false, true, .seq_cst, .seq_cst)) |_| {}
-        }
-
-        // Install default handler so that the tkill below will terminate.
-        const sigact = Sigaction{
-            .handler = .{ .handler = SIG.DFL },
-            .mask = empty_sigset,
-            .flags = 0,
-        };
-        sigaction(SIG.ABRT, &sigact, null) catch |err| switch (err) {
-            error.OperationNotSupported => unreachable,
-        };
-
-        _ = linux.tkill(linux.gettid(), SIG.ABRT);
-
-        const sigabrtmask: linux.sigset_t = [_]u32{0} ** 31 ++ [_]u32{1 << (SIG.ABRT - 1)};
-        sigprocmask(SIG.UNBLOCK, &sigabrtmask, null);
-
-        // Beyond this point should be unreachable.
-        @as(*allowzero volatile u8, @ptrFromInt(0)).* = 0;
-        raise(SIG.KILL) catch {};
-        exit(127); // Pid 1 might not be signalled in some containers.
-    }
-    switch (builtin.os.tag) {
-        .uefi, .wasi, .emscripten, .cuda, .amdhsa => @trap(),
-        else => system.abort(),
-    }
-}
-
-pub const RaiseError = UnexpectedError;
-
-pub fn raise(sig: u8) RaiseError!void {
-    if (builtin.link_libc) {
-        switch (errno(system.raise(sig))) {
-            .SUCCESS => return,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-
-    if (builtin.os.tag == .linux) {
-        var set: sigset_t = undefined;
-        // block application signals
-        sigprocmask(SIG.BLOCK, &linux.app_mask, &set);
-
-        const tid = linux.gettid();
-        const rc = linux.tkill(tid, sig);
-
-        // restore signal mask
-        sigprocmask(SIG.SETMASK, &set, null);
-
-        switch (errno(rc)) {
-            .SUCCESS => return,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-
-    @compileError("std.os.raise unimplemented for this target");
-}
-
-pub const KillError = error{ ProcessNotFound, PermissionDenied } || UnexpectedError;
-
-pub fn kill(pid: pid_t, sig: u8) KillError!void {
-    switch (errno(system.kill(pid, sig))) {
-        .SUCCESS => return,
-        .INVAL => unreachable, // invalid signal
-        .PERM => return error.PermissionDenied,
-        .SRCH => return error.ProcessNotFound,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Exits the program cleanly with the specified status code.
-pub fn exit(status: u8) noreturn {
-    if (builtin.link_libc) {
-        system.exit(status);
-    }
-    if (builtin.os.tag == .windows) {
-        windows.kernel32.ExitProcess(status);
-    }
-    if (builtin.os.tag == .wasi) {
-        wasi.proc_exit(status);
-    }
-    if (builtin.os.tag == .linux and !builtin.single_threaded) {
-        linux.exit_group(status);
-    }
-    if (builtin.os.tag == .uefi) {
-        // exit() is only available if exitBootServices() has not been called yet.
-        // This call to exit should not fail, so we don't care about its return value.
-        if (uefi.system_table.boot_services) |bs| {
-            _ = bs.exit(uefi.handle, @enumFromInt(status), 0, null);
-        }
-        // If we can't exit, reboot the system instead.
-        uefi.system_table.runtime_services.resetSystem(.ResetCold, @enumFromInt(status), 0, null);
+        else => unreachable, // made unreachable by isGetFdPathSupportedOnTarget above
     }
-    system.exit(status);
 }
-
-pub const ReadError = error{
-    InputOutput,
-    SystemResources,
-    IsDir,
-    OperationAborted,
-    BrokenPipe,
-    ConnectionResetByPeer,
-    ConnectionTimedOut,
-    NotOpenForReading,
-    SocketNotConnected,
-
-    /// This error occurs when no global event loop is configured,
-    /// and reading from the file descriptor would block.
-    WouldBlock,
-
-    /// In WASI, this error occurs when the file descriptor does
-    /// not hold the required rights to read from it.
-    AccessDenied,
-} || UnexpectedError;
-
-/// Returns the number of bytes that were read, which can be less than
-/// buf.len. If 0 bytes were read, that means EOF.
-/// If `fd` is opened in non blocking mode, the function will return error.WouldBlock
-/// when EAGAIN is received.
-///
-/// Linux has a limit on how many bytes may be transferred in one `read` call, which is `0x7ffff000`
-/// on both 64-bit and 32-bit systems. This is due to using a signed C int as the return value, as
-/// well as stuffing the errno codes into the last `4096` values. This is noted on the `read` man page.
-/// The limit on Darwin is `0x7fffffff`, trying to read more than that returns EINVAL.
-/// The corresponding POSIX limit is `math.maxInt(isize)`.
-pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
-    if (buf.len == 0) return 0;
-    if (builtin.os.tag == .windows) {
-        return windows.ReadFile(fd, buf, null);
-    }
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        const iovs = [1]iovec{iovec{
-            .iov_base = buf.ptr,
-            .iov_len = buf.len,
-        }};
-
-        var nread: usize = undefined;
-        switch (wasi.fd_read(fd, &iovs, iovs.len, &nread)) {
-            .SUCCESS => return nread,
-            .INTR => unreachable,
-            .INVAL => unreachable,
-            .FAULT => unreachable,
-            .AGAIN => unreachable,
-            .BADF => return error.NotOpenForReading, // Can be a race condition.
-            .IO => return error.InputOutput,
-            .ISDIR => return error.IsDir,
-            .NOBUFS => return error.SystemResources,
-            .NOMEM => return error.SystemResources,
-            .NOTCONN => return error.SocketNotConnected,
-            .CONNRESET => return error.ConnectionResetByPeer,
-            .TIMEDOUT => return error.ConnectionTimedOut,
-            .NOTCAPABLE => return error.AccessDenied,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-
-    // Prevents EINVAL.
-    const max_count = switch (builtin.os.tag) {
-        .linux => 0x7ffff000,
-        .macos, .ios, .watchos, .tvos => math.maxInt(i32),
-        else => math.maxInt(isize),
-    };
-    while (true) {
-        const rc = system.read(fd, buf.ptr, @min(buf.len, max_count));
-        switch (errno(rc)) {
-            .SUCCESS => return @intCast(rc),
-            .INTR => continue,
-            .INVAL => unreachable,
-            .FAULT => unreachable,
-            .AGAIN => return error.WouldBlock,
-            .BADF => return error.NotOpenForReading, // Can be a race condition.
-            .IO => return error.InputOutput,
-            .ISDIR => return error.IsDir,
-            .NOBUFS => return error.SystemResources,
-            .NOMEM => return error.SystemResources,
-            .NOTCONN => return error.SocketNotConnected,
-            .CONNRESET => return error.ConnectionResetByPeer,
-            .TIMEDOUT => return error.ConnectionTimedOut,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-/// Number of bytes read is returned. Upon reading end-of-file, zero is returned.
-///
-/// For POSIX systems, if `fd` is opened in non blocking mode, the function will
-/// return error.WouldBlock when EAGAIN is received.
-/// On Windows, if the application has a global event loop enabled, I/O Completion Ports are
-/// used to perform the I/O. `error.WouldBlock` is not possible on Windows.
-///
-/// This operation is non-atomic on the following systems:
-/// * Windows
-/// On these systems, the read races with concurrent writes to the same file descriptor.
-///
-/// This function assumes that all vectors, including zero-length vectors, have
-/// a pointer within the address space of the application.
-pub fn readv(fd: fd_t, iov: []const iovec) ReadError!usize {
-    if (builtin.os.tag == .windows) {
-        // TODO improve this to use ReadFileScatter
-        if (iov.len == 0) return 0;
-        const first = iov[0];
-        return read(fd, first.iov_base[0..first.iov_len]);
-    }
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        var nread: usize = undefined;
-        switch (wasi.fd_read(fd, iov.ptr, iov.len, &nread)) {
-            .SUCCESS => return nread,
-            .INTR => unreachable,
-            .INVAL => unreachable,
-            .FAULT => unreachable,
-            .AGAIN => unreachable, // currently not support in WASI
-            .BADF => return error.NotOpenForReading, // can be a race condition
-            .IO => return error.InputOutput,
-            .ISDIR => return error.IsDir,
-            .NOBUFS => return error.SystemResources,
-            .NOMEM => return error.SystemResources,
-            .NOTCONN => return error.SocketNotConnected,
-            .CONNRESET => return error.ConnectionResetByPeer,
-            .TIMEDOUT => return error.ConnectionTimedOut,
-            .NOTCAPABLE => return error.AccessDenied,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-
-    while (true) {
-        const rc = system.readv(fd, iov.ptr, @min(iov.len, IOV_MAX));
-        switch (errno(rc)) {
-            .SUCCESS => return @intCast(rc),
-            .INTR => continue,
-            .INVAL => unreachable,
-            .FAULT => unreachable,
-            .AGAIN => return error.WouldBlock,
-            .BADF => return error.NotOpenForReading, // can be a race condition
-            .IO => return error.InputOutput,
-            .ISDIR => return error.IsDir,
-            .NOBUFS => return error.SystemResources,
-            .NOMEM => return error.SystemResources,
-            .NOTCONN => return error.SocketNotConnected,
-            .CONNRESET => return error.ConnectionResetByPeer,
-            .TIMEDOUT => return error.ConnectionTimedOut,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-pub const PReadError = ReadError || error{Unseekable};
-
-/// Number of bytes read is returned. Upon reading end-of-file, zero is returned.
-///
-/// Retries when interrupted by a signal.
-///
-/// For POSIX systems, if `fd` is opened in non blocking mode, the function will
-/// return error.WouldBlock when EAGAIN is received.
-/// On Windows, if the application has a global event loop enabled, I/O Completion Ports are
-/// used to perform the I/O. `error.WouldBlock` is not possible on Windows.
-///
-/// Linux has a limit on how many bytes may be transferred in one `pread` call, which is `0x7ffff000`
-/// on both 64-bit and 32-bit systems. This is due to using a signed C int as the return value, as
-/// well as stuffing the errno codes into the last `4096` values. This is noted on the `read` man page.
-/// The limit on Darwin is `0x7fffffff`, trying to read more than that returns EINVAL.
-/// The corresponding POSIX limit is `math.maxInt(isize)`.
-pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize {
-    if (buf.len == 0) return 0;
-    if (builtin.os.tag == .windows) {
-        return windows.ReadFile(fd, buf, offset);
-    }
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        const iovs = [1]iovec{iovec{
-            .iov_base = buf.ptr,
-            .iov_len = buf.len,
-        }};
-
-        var nread: usize = undefined;
-        switch (wasi.fd_pread(fd, &iovs, iovs.len, offset, &nread)) {
-            .SUCCESS => return nread,
-            .INTR => unreachable,
-            .INVAL => unreachable,
-            .FAULT => unreachable,
-            .AGAIN => unreachable,
-            .BADF => return error.NotOpenForReading, // Can be a race condition.
-            .IO => return error.InputOutput,
-            .ISDIR => return error.IsDir,
-            .NOBUFS => return error.SystemResources,
-            .NOMEM => return error.SystemResources,
-            .NOTCONN => return error.SocketNotConnected,
-            .CONNRESET => return error.ConnectionResetByPeer,
-            .TIMEDOUT => return error.ConnectionTimedOut,
-            .NXIO => return error.Unseekable,
-            .SPIPE => return error.Unseekable,
-            .OVERFLOW => return error.Unseekable,
-            .NOTCAPABLE => return error.AccessDenied,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-
-    // Prevent EINVAL.
-    const max_count = switch (builtin.os.tag) {
-        .linux => 0x7ffff000,
-        .macos, .ios, .watchos, .tvos => math.maxInt(i32),
-        else => math.maxInt(isize),
-    };
-
-    const pread_sym = if (lfs64_abi) system.pread64 else system.pread;
-    while (true) {
-        const rc = pread_sym(fd, buf.ptr, @min(buf.len, max_count), @bitCast(offset));
-        switch (errno(rc)) {
-            .SUCCESS => return @intCast(rc),
-            .INTR => continue,
-            .INVAL => unreachable,
-            .FAULT => unreachable,
-            .AGAIN => return error.WouldBlock,
-            .BADF => return error.NotOpenForReading, // Can be a race condition.
-            .IO => return error.InputOutput,
-            .ISDIR => return error.IsDir,
-            .NOBUFS => return error.SystemResources,
-            .NOMEM => return error.SystemResources,
-            .NOTCONN => return error.SocketNotConnected,
-            .CONNRESET => return error.ConnectionResetByPeer,
-            .TIMEDOUT => return error.ConnectionTimedOut,
-            .NXIO => return error.Unseekable,
-            .SPIPE => return error.Unseekable,
-            .OVERFLOW => return error.Unseekable,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-pub const TruncateError = error{
-    FileTooBig,
-    InputOutput,
-    FileBusy,
-
-    /// In WASI, this error occurs when the file descriptor does
-    /// not hold the required rights to call `ftruncate` on it.
-    AccessDenied,
-} || UnexpectedError;
-
-pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void {
-    if (builtin.os.tag == .windows) {
-        var io_status_block: windows.IO_STATUS_BLOCK = undefined;
-        var eof_info = windows.FILE_END_OF_FILE_INFORMATION{
-            .EndOfFile = @bitCast(length),
-        };
-
-        const rc = windows.ntdll.NtSetInformationFile(
-            fd,
-            &io_status_block,
-            &eof_info,
-            @sizeOf(windows.FILE_END_OF_FILE_INFORMATION),
-            .FileEndOfFileInformation,
-        );
-
-        switch (rc) {
-            .SUCCESS => return,
-            .INVALID_HANDLE => unreachable, // Handle not open for writing
-            .ACCESS_DENIED => return error.AccessDenied,
-            else => return windows.unexpectedStatus(rc),
-        }
-    }
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        switch (wasi.fd_filestat_set_size(fd, length)) {
-            .SUCCESS => return,
-            .INTR => unreachable,
-            .FBIG => return error.FileTooBig,
-            .IO => return error.InputOutput,
-            .PERM => return error.AccessDenied,
-            .TXTBSY => return error.FileBusy,
-            .BADF => unreachable, // Handle not open for writing
-            .INVAL => unreachable, // Handle not open for writing
-            .NOTCAPABLE => return error.AccessDenied,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-
-    const ftruncate_sym = if (lfs64_abi) system.ftruncate64 else system.ftruncate;
-    while (true) {
-        switch (errno(ftruncate_sym(fd, @bitCast(length)))) {
-            .SUCCESS => return,
-            .INTR => continue,
-            .FBIG => return error.FileTooBig,
-            .IO => return error.InputOutput,
-            .PERM => return error.AccessDenied,
-            .TXTBSY => return error.FileBusy,
-            .BADF => unreachable, // Handle not open for writing
-            .INVAL => unreachable, // Handle not open for writing
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-/// Number of bytes read is returned. Upon reading end-of-file, zero is returned.
-///
-/// Retries when interrupted by a signal.
-///
-/// For POSIX systems, if `fd` is opened in non blocking mode, the function will
-/// return error.WouldBlock when EAGAIN is received.
-/// On Windows, if the application has a global event loop enabled, I/O Completion Ports are
-/// used to perform the I/O. `error.WouldBlock` is not possible on Windows.
-///
-/// This operation is non-atomic on the following systems:
-/// * Darwin
-/// * Windows
-/// On these systems, the read races with concurrent writes to the same file descriptor.
-pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize {
-    const have_pread_but_not_preadv = switch (builtin.os.tag) {
-        .windows, .macos, .ios, .watchos, .tvos, .haiku => true,
-        else => false,
-    };
-    if (have_pread_but_not_preadv) {
-        // We could loop here; but proper usage of `preadv` must handle partial reads anyway.
-        // So we simply read into the first vector only.
-        if (iov.len == 0) return 0;
-        const first = iov[0];
-        return pread(fd, first.iov_base[0..first.iov_len], offset);
-    }
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        var nread: usize = undefined;
-        switch (wasi.fd_pread(fd, iov.ptr, iov.len, offset, &nread)) {
-            .SUCCESS => return nread,
-            .INTR => unreachable,
-            .INVAL => unreachable,
-            .FAULT => unreachable,
-            .AGAIN => unreachable,
-            .BADF => return error.NotOpenForReading, // can be a race condition
-            .IO => return error.InputOutput,
-            .ISDIR => return error.IsDir,
-            .NOBUFS => return error.SystemResources,
-            .NOMEM => return error.SystemResources,
-            .NOTCONN => return error.SocketNotConnected,
-            .CONNRESET => return error.ConnectionResetByPeer,
-            .TIMEDOUT => return error.ConnectionTimedOut,
-            .NXIO => return error.Unseekable,
-            .SPIPE => return error.Unseekable,
-            .OVERFLOW => return error.Unseekable,
-            .NOTCAPABLE => return error.AccessDenied,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-
-    const preadv_sym = if (lfs64_abi) system.preadv64 else system.preadv;
-    while (true) {
-        const rc = preadv_sym(fd, iov.ptr, @min(iov.len, IOV_MAX), @bitCast(offset));
-        switch (errno(rc)) {
-            .SUCCESS => return @bitCast(rc),
-            .INTR => continue,
-            .INVAL => unreachable,
-            .FAULT => unreachable,
-            .AGAIN => return error.WouldBlock,
-            .BADF => return error.NotOpenForReading, // can be a race condition
-            .IO => return error.InputOutput,
-            .ISDIR => return error.IsDir,
-            .NOBUFS => return error.SystemResources,
-            .NOMEM => return error.SystemResources,
-            .NOTCONN => return error.SocketNotConnected,
-            .CONNRESET => return error.ConnectionResetByPeer,
-            .TIMEDOUT => return error.ConnectionTimedOut,
-            .NXIO => return error.Unseekable,
-            .SPIPE => return error.Unseekable,
-            .OVERFLOW => return error.Unseekable,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-pub const WriteError = error{
-    DiskQuota,
-    FileTooBig,
-    InputOutput,
-    NoSpaceLeft,
-    DeviceBusy,
-    InvalidArgument,
-
-    /// In WASI, this error may occur when the file descriptor does
-    /// not hold the required rights to write to it.
-    AccessDenied,
-    BrokenPipe,
-    SystemResources,
-    OperationAborted,
-    NotOpenForWriting,
-
-    /// The process cannot access the file because another process has locked
-    /// a portion of the file. Windows-only.
-    LockViolation,
-
-    /// This error occurs when no global event loop is configured,
-    /// and reading from the file descriptor would block.
-    WouldBlock,
-
-    /// Connection reset by peer.
-    ConnectionResetByPeer,
-} || UnexpectedError;
-
-/// Write to a file descriptor.
-/// Retries when interrupted by a signal.
-/// Returns the number of bytes written. If nonzero bytes were supplied, this will be nonzero.
-///
-/// Note that a successful write() may transfer fewer than count bytes.  Such partial  writes  can
-/// occur  for  various reasons; for example, because there was insufficient space on the disk
-/// device to write all of the requested bytes, or because a blocked write() to a socket,  pipe,  or
-/// similar  was  interrupted by a signal handler after it had transferred some, but before it had
-/// transferred all of the requested bytes.  In the event of a partial write, the caller can  make
-/// another  write() call to transfer the remaining bytes.  The subsequent call will either
-/// transfer further bytes or may result in an error (e.g., if the disk is now full).
-///
-/// For POSIX systems, if `fd` is opened in non blocking mode, the function will
-/// return error.WouldBlock when EAGAIN is received.
-/// On Windows, if the application has a global event loop enabled, I/O Completion Ports are
-/// used to perform the I/O. `error.WouldBlock` is not possible on Windows.
-///
-/// Linux has a limit on how many bytes may be transferred in one `write` call, which is `0x7ffff000`
-/// on both 64-bit and 32-bit systems. This is due to using a signed C int as the return value, as
-/// well as stuffing the errno codes into the last `4096` values. This is noted on the `write` man page.
-/// The limit on Darwin is `0x7fffffff`, trying to read more than that returns EINVAL.
-/// The corresponding POSIX limit is `math.maxInt(isize)`.
-pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize {
-    if (bytes.len == 0) return 0;
-    if (builtin.os.tag == .windows) {
-        return windows.WriteFile(fd, bytes, null);
-    }
-
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        const ciovs = [_]iovec_const{iovec_const{
-            .iov_base = bytes.ptr,
-            .iov_len = bytes.len,
-        }};
-        var nwritten: usize = undefined;
-        switch (wasi.fd_write(fd, &ciovs, ciovs.len, &nwritten)) {
-            .SUCCESS => return nwritten,
-            .INTR => unreachable,
-            .INVAL => unreachable,
-            .FAULT => unreachable,
-            .AGAIN => unreachable,
-            .BADF => return error.NotOpenForWriting, // can be a race condition.
-            .DESTADDRREQ => unreachable, // `connect` was never called.
-            .DQUOT => return error.DiskQuota,
-            .FBIG => return error.FileTooBig,
-            .IO => return error.InputOutput,
-            .NOSPC => return error.NoSpaceLeft,
-            .PERM => return error.AccessDenied,
-            .PIPE => return error.BrokenPipe,
-            .NOTCAPABLE => return error.AccessDenied,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-
-    const max_count = switch (builtin.os.tag) {
-        .linux => 0x7ffff000,
-        .macos, .ios, .watchos, .tvos => math.maxInt(i32),
-        else => math.maxInt(isize),
-    };
-    while (true) {
-        const rc = system.write(fd, bytes.ptr, @min(bytes.len, max_count));
-        switch (errno(rc)) {
-            .SUCCESS => return @intCast(rc),
-            .INTR => continue,
-            .INVAL => return error.InvalidArgument,
-            .FAULT => unreachable,
-            .AGAIN => return error.WouldBlock,
-            .BADF => return error.NotOpenForWriting, // can be a race condition.
-            .DESTADDRREQ => unreachable, // `connect` was never called.
-            .DQUOT => return error.DiskQuota,
-            .FBIG => return error.FileTooBig,
-            .IO => return error.InputOutput,
-            .NOSPC => return error.NoSpaceLeft,
-            .PERM => return error.AccessDenied,
-            .PIPE => return error.BrokenPipe,
-            .CONNRESET => return error.ConnectionResetByPeer,
-            .BUSY => return error.DeviceBusy,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-/// Write multiple buffers to a file descriptor.
-/// Retries when interrupted by a signal.
-/// Returns the number of bytes written. If nonzero bytes were supplied, this will be nonzero.
-///
-/// Note that a successful write() may transfer fewer bytes than supplied.  Such partial  writes  can
-/// occur  for  various reasons; for example, because there was insufficient space on the disk
-/// device to write all of the requested bytes, or because a blocked write() to a socket,  pipe,  or
-/// similar  was  interrupted by a signal handler after it had transferred some, but before it had
-/// transferred all of the requested bytes.  In the event of a partial write, the caller can  make
-/// another  write() call to transfer the remaining bytes.  The subsequent call will either
-/// transfer further bytes or may result in an error (e.g., if the disk is now full).
-///
-/// For POSIX systems, if `fd` is opened in non blocking mode, the function will
-/// return error.WouldBlock when EAGAIN is received.
-/// On Windows, if the application has a global event loop enabled, I/O Completion Ports are
-/// used to perform the I/O. `error.WouldBlock` is not possible on Windows.
-///
-/// If `iov.len` is larger than `IOV_MAX`, a partial write will occur.
-///
-/// This function assumes that all vectors, including zero-length vectors, have
-/// a pointer within the address space of the application.
-pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!usize {
-    if (builtin.os.tag == .windows) {
-        // TODO improve this to use WriteFileScatter
-        if (iov.len == 0) return 0;
-        const first = iov[0];
-        return write(fd, first.iov_base[0..first.iov_len]);
-    }
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        var nwritten: usize = undefined;
-        switch (wasi.fd_write(fd, iov.ptr, iov.len, &nwritten)) {
-            .SUCCESS => return nwritten,
-            .INTR => unreachable,
-            .INVAL => unreachable,
-            .FAULT => unreachable,
-            .AGAIN => unreachable,
-            .BADF => return error.NotOpenForWriting, // can be a race condition.
-            .DESTADDRREQ => unreachable, // `connect` was never called.
-            .DQUOT => return error.DiskQuota,
-            .FBIG => return error.FileTooBig,
-            .IO => return error.InputOutput,
-            .NOSPC => return error.NoSpaceLeft,
-            .PERM => return error.AccessDenied,
-            .PIPE => return error.BrokenPipe,
-            .NOTCAPABLE => return error.AccessDenied,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-
-    while (true) {
-        const rc = system.writev(fd, iov.ptr, @min(iov.len, IOV_MAX));
-        switch (errno(rc)) {
-            .SUCCESS => return @intCast(rc),
-            .INTR => continue,
-            .INVAL => return error.InvalidArgument,
-            .FAULT => unreachable,
-            .AGAIN => return error.WouldBlock,
-            .BADF => return error.NotOpenForWriting, // Can be a race condition.
-            .DESTADDRREQ => unreachable, // `connect` was never called.
-            .DQUOT => return error.DiskQuota,
-            .FBIG => return error.FileTooBig,
-            .IO => return error.InputOutput,
-            .NOSPC => return error.NoSpaceLeft,
-            .PERM => return error.AccessDenied,
-            .PIPE => return error.BrokenPipe,
-            .CONNRESET => return error.ConnectionResetByPeer,
-            .BUSY => return error.DeviceBusy,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-pub const PWriteError = WriteError || error{Unseekable};
-
-/// Write to a file descriptor, with a position offset.
-/// Retries when interrupted by a signal.
-/// Returns the number of bytes written. If nonzero bytes were supplied, this will be nonzero.
-///
-/// Note that a successful write() may transfer fewer bytes than supplied.  Such partial  writes  can
-/// occur  for  various reasons; for example, because there was insufficient space on the disk
-/// device to write all of the requested bytes, or because a blocked write() to a socket,  pipe,  or
-/// similar  was  interrupted by a signal handler after it had transferred some, but before it had
-/// transferred all of the requested bytes.  In the event of a partial write, the caller can  make
-/// another  write() call to transfer the remaining bytes.  The subsequent call will either
-/// transfer further bytes or may result in an error (e.g., if the disk is now full).
-///
-/// For POSIX systems, if `fd` is opened in non blocking mode, the function will
-/// return error.WouldBlock when EAGAIN is received.
-/// On Windows, if the application has a global event loop enabled, I/O Completion Ports are
-/// used to perform the I/O. `error.WouldBlock` is not possible on Windows.
-///
-/// Linux has a limit on how many bytes may be transferred in one `pwrite` call, which is `0x7ffff000`
-/// on both 64-bit and 32-bit systems. This is due to using a signed C int as the return value, as
-/// well as stuffing the errno codes into the last `4096` values. This is noted on the `write` man page.
-/// The limit on Darwin is `0x7fffffff`, trying to write more than that returns EINVAL.
-/// The corresponding POSIX limit is `math.maxInt(isize)`.
-pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize {
-    if (bytes.len == 0) return 0;
-    if (builtin.os.tag == .windows) {
-        return windows.WriteFile(fd, bytes, offset);
-    }
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        const ciovs = [1]iovec_const{iovec_const{
-            .iov_base = bytes.ptr,
-            .iov_len = bytes.len,
-        }};
-
-        var nwritten: usize = undefined;
-        switch (wasi.fd_pwrite(fd, &ciovs, ciovs.len, offset, &nwritten)) {
-            .SUCCESS => return nwritten,
-            .INTR => unreachable,
-            .INVAL => unreachable,
-            .FAULT => unreachable,
-            .AGAIN => unreachable,
-            .BADF => return error.NotOpenForWriting, // can be a race condition.
-            .DESTADDRREQ => unreachable, // `connect` was never called.
-            .DQUOT => return error.DiskQuota,
-            .FBIG => return error.FileTooBig,
-            .IO => return error.InputOutput,
-            .NOSPC => return error.NoSpaceLeft,
-            .PERM => return error.AccessDenied,
-            .PIPE => return error.BrokenPipe,
-            .NXIO => return error.Unseekable,
-            .SPIPE => return error.Unseekable,
-            .OVERFLOW => return error.Unseekable,
-            .NOTCAPABLE => return error.AccessDenied,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-
-    // Prevent EINVAL.
-    const max_count = switch (builtin.os.tag) {
-        .linux => 0x7ffff000,
-        .macos, .ios, .watchos, .tvos => math.maxInt(i32),
-        else => math.maxInt(isize),
-    };
-
-    const pwrite_sym = if (lfs64_abi) system.pwrite64 else system.pwrite;
-    while (true) {
-        const rc = pwrite_sym(fd, bytes.ptr, @min(bytes.len, max_count), @bitCast(offset));
-        switch (errno(rc)) {
-            .SUCCESS => return @intCast(rc),
-            .INTR => continue,
-            .INVAL => return error.InvalidArgument,
-            .FAULT => unreachable,
-            .AGAIN => return error.WouldBlock,
-            .BADF => return error.NotOpenForWriting, // Can be a race condition.
-            .DESTADDRREQ => unreachable, // `connect` was never called.
-            .DQUOT => return error.DiskQuota,
-            .FBIG => return error.FileTooBig,
-            .IO => return error.InputOutput,
-            .NOSPC => return error.NoSpaceLeft,
-            .PERM => return error.AccessDenied,
-            .PIPE => return error.BrokenPipe,
-            .NXIO => return error.Unseekable,
-            .SPIPE => return error.Unseekable,
-            .OVERFLOW => return error.Unseekable,
-            .BUSY => return error.DeviceBusy,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-/// Write multiple buffers to a file descriptor, with a position offset.
-/// Retries when interrupted by a signal.
-/// Returns the number of bytes written. If nonzero bytes were supplied, this will be nonzero.
-///
-/// Note that a successful write() may transfer fewer than count bytes.  Such partial  writes  can
-/// occur  for  various reasons; for example, because there was insufficient space on the disk
-/// device to write all of the requested bytes, or because a blocked write() to a socket,  pipe,  or
-/// similar  was  interrupted by a signal handler after it had transferred some, but before it had
-/// transferred all of the requested bytes.  In the event of a partial write, the caller can  make
-/// another  write() call to transfer the remaining bytes.  The subsequent call will either
-/// transfer further bytes or may result in an error (e.g., if the disk is now full).
-///
-/// If `fd` is opened in non blocking mode, the function will
-/// return error.WouldBlock when EAGAIN is received.
-///
-/// The following systems do not have this syscall, and will return partial writes if more than one
-/// vector is provided:
-/// * Darwin
-/// * Windows
-///
-/// If `iov.len` is larger than `IOV_MAX`, a partial write will occur.
-pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usize {
-    const have_pwrite_but_not_pwritev = switch (builtin.os.tag) {
-        .windows, .macos, .ios, .watchos, .tvos, .haiku => true,
-        else => false,
-    };
-
-    if (have_pwrite_but_not_pwritev) {
-        // We could loop here; but proper usage of `pwritev` must handle partial writes anyway.
-        // So we simply write the first vector only.
-        if (iov.len == 0) return 0;
-        const first = iov[0];
-        return pwrite(fd, first.iov_base[0..first.iov_len], offset);
-    }
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        var nwritten: usize = undefined;
-        switch (wasi.fd_pwrite(fd, iov.ptr, iov.len, offset, &nwritten)) {
-            .SUCCESS => return nwritten,
-            .INTR => unreachable,
-            .INVAL => unreachable,
-            .FAULT => unreachable,
-            .AGAIN => unreachable,
-            .BADF => return error.NotOpenForWriting, // Can be a race condition.
-            .DESTADDRREQ => unreachable, // `connect` was never called.
-            .DQUOT => return error.DiskQuota,
-            .FBIG => return error.FileTooBig,
-            .IO => return error.InputOutput,
-            .NOSPC => return error.NoSpaceLeft,
-            .PERM => return error.AccessDenied,
-            .PIPE => return error.BrokenPipe,
-            .NXIO => return error.Unseekable,
-            .SPIPE => return error.Unseekable,
-            .OVERFLOW => return error.Unseekable,
-            .NOTCAPABLE => return error.AccessDenied,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-
-    const pwritev_sym = if (lfs64_abi) system.pwritev64 else system.pwritev;
-    while (true) {
-        const rc = pwritev_sym(fd, iov.ptr, @min(iov.len, IOV_MAX), @bitCast(offset));
-        switch (errno(rc)) {
-            .SUCCESS => return @intCast(rc),
-            .INTR => continue,
-            .INVAL => return error.InvalidArgument,
-            .FAULT => unreachable,
-            .AGAIN => return error.WouldBlock,
-            .BADF => return error.NotOpenForWriting, // Can be a race condition.
-            .DESTADDRREQ => unreachable, // `connect` was never called.
-            .DQUOT => return error.DiskQuota,
-            .FBIG => return error.FileTooBig,
-            .IO => return error.InputOutput,
-            .NOSPC => return error.NoSpaceLeft,
-            .PERM => return error.AccessDenied,
-            .PIPE => return error.BrokenPipe,
-            .NXIO => return error.Unseekable,
-            .SPIPE => return error.Unseekable,
-            .OVERFLOW => return error.Unseekable,
-            .BUSY => return error.DeviceBusy,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-pub const OpenError = error{
-    /// In WASI, this error may occur when the file descriptor does
-    /// not hold the required rights to open a new resource relative to it.
-    AccessDenied,
-    SymLinkLoop,
-    ProcessFdQuotaExceeded,
-    SystemFdQuotaExceeded,
-    NoDevice,
-    FileNotFound,
-
-    /// The path exceeded `MAX_PATH_BYTES` bytes.
-    NameTooLong,
-
-    /// Insufficient kernel memory was available, or
-    /// the named file is a FIFO and per-user hard limit on
-    /// memory allocation for pipes has been reached.
-    SystemResources,
-
-    /// The file is too large to be opened. This error is unreachable
-    /// for 64-bit targets, as well as when opening directories.
-    FileTooBig,
-
-    /// The path refers to directory but the `DIRECTORY` flag was not provided.
-    IsDir,
-
-    /// A new path cannot be created because the device has no room for the new file.
-    /// This error is only reachable when the `CREAT` flag is provided.
-    NoSpaceLeft,
-
-    /// A component used as a directory in the path was not, in fact, a directory, or
-    /// `DIRECTORY` was specified and the path was not a directory.
-    NotDir,
-
-    /// The path already exists and the `CREAT` and `EXCL` flags were provided.
-    PathAlreadyExists,
-    DeviceBusy,
-
-    /// The underlying filesystem does not support file locks
-    FileLocksNotSupported,
-
-    /// Path contains characters that are disallowed by the underlying filesystem.
-    BadPathName,
-
-    /// WASI-only; file paths must be valid UTF-8.
-    InvalidUtf8,
-
-    /// Windows-only; file paths provided by the user must be valid WTF-8.
-    /// https://simonsapin.github.io/wtf-8/
-    InvalidWtf8,
-
-    /// On Windows, `\\server` or `\\server\share` was not found.
-    NetworkNotFound,
-
-    /// One of these three things:
-    /// * pathname  refers to an executable image which is currently being
-    ///   executed and write access was requested.
-    /// * pathname refers to a file that is currently in  use  as  a  swap
-    ///   file, and the O_TRUNC flag was specified.
-    /// * pathname  refers  to  a file that is currently being read by the
-    ///   kernel (e.g., for module/firmware loading), and write access was
-    ///   requested.
-    FileBusy,
-
-    WouldBlock,
-} || UnexpectedError;
-
-/// Open and possibly create a file. Keeps trying if it gets interrupted.
-/// On Windows, `file_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// 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 `openZ`.
-pub fn open(file_path: []const u8, flags: O, perm: mode_t) OpenError!fd_t {
-    if (builtin.os.tag == .windows) {
-        @compileError("Windows does not support POSIX; use Windows-specific API or cross-platform std.fs API");
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return openat(AT.FDCWD, file_path, flags, perm);
-    }
-    const file_path_c = try toPosixPath(file_path);
-    return openZ(&file_path_c, flags, perm);
-}
-
-/// Open and possibly create a file. Keeps trying if it gets interrupted.
-/// On Windows, `file_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// 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 `open`.
-pub fn openZ(file_path: [*:0]const u8, flags: O, perm: mode_t) OpenError!fd_t {
-    if (builtin.os.tag == .windows) {
-        @compileError("Windows does not support POSIX; use Windows-specific API or cross-platform std.fs API");
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return open(mem.sliceTo(file_path, 0), flags, perm);
-    }
-
-    const open_sym = if (lfs64_abi) system.open64 else system.open;
-    while (true) {
-        const rc = open_sym(file_path, flags, perm);
-        switch (errno(rc)) {
-            .SUCCESS => return @intCast(rc),
-            .INTR => continue,
-
-            .FAULT => unreachable,
-            .INVAL => unreachable,
-            .ACCES => return error.AccessDenied,
-            .FBIG => return error.FileTooBig,
-            .OVERFLOW => return error.FileTooBig,
-            .ISDIR => return error.IsDir,
-            .LOOP => return error.SymLinkLoop,
-            .MFILE => return error.ProcessFdQuotaExceeded,
-            .NAMETOOLONG => return error.NameTooLong,
-            .NFILE => return error.SystemFdQuotaExceeded,
-            .NODEV => return error.NoDevice,
-            .NOENT => return error.FileNotFound,
-            .NOMEM => return error.SystemResources,
-            .NOSPC => return error.NoSpaceLeft,
-            .NOTDIR => return error.NotDir,
-            .PERM => return error.AccessDenied,
-            .EXIST => return error.PathAlreadyExists,
-            .BUSY => return error.DeviceBusy,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-/// 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://simonsapin.github.io/wtf-8/).
-/// 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 (builtin.os.tag == .windows) {
-        @compileError("Windows does not support POSIX; use Windows-specific API or cross-platform std.fs API");
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        // `mode` is ignored on WASI, which does not support unix-style file permissions
-        const opts = try openOptionsFromFlagsWasi(flags);
-        const fd = try openatWasi(
-            dir_fd,
-            file_path,
-            opts.lookup_flags,
-            opts.oflags,
-            opts.fs_flags,
-            opts.fs_rights_base,
-            opts.fs_rights_inheriting,
-        );
-        errdefer close(fd);
-
-        if (flags.write) {
-            const info = try fstat_wasi(fd);
-            if (info.filetype == .DIRECTORY)
-                return error.IsDir;
-        }
-
-        return fd;
-    }
-    const file_path_c = try toPosixPath(file_path);
-    return openatZ(dir_fd, &file_path_c, flags, mode);
-}
-
-pub const CommonOpenFlags = packed struct {
-    ACCMODE: ACCMODE = .RDONLY,
-    CREAT: bool = false,
-    EXCL: bool = false,
-    LARGEFILE: bool = false,
-    DIRECTORY: bool = false,
-    CLOEXEC: bool = false,
-    NONBLOCK: bool = false,
-
-    pub fn lower(cof: CommonOpenFlags) O {
-        if (builtin.os.tag == .wasi) return .{
-            .read = cof.ACCMODE != .WRONLY,
-            .write = cof.ACCMODE != .RDONLY,
-            .CREAT = cof.CREAT,
-            .EXCL = cof.EXCL,
-            .DIRECTORY = cof.DIRECTORY,
-            .NONBLOCK = cof.NONBLOCK,
-        };
-        var result: O = .{
-            .ACCMODE = cof.ACCMODE,
-            .CREAT = cof.CREAT,
-            .EXCL = cof.EXCL,
-            .DIRECTORY = cof.DIRECTORY,
-            .NONBLOCK = cof.NONBLOCK,
-            .CLOEXEC = cof.CLOEXEC,
-        };
-        if (@hasField(O, "LARGEFILE")) result.LARGEFILE = cof.LARGEFILE;
-        return result;
-    }
-};
-
-/// A struct to contain all lookup/rights flags accepted by `wasi.path_open`
-const WasiOpenOptions = struct {
-    oflags: wasi.oflags_t,
-    lookup_flags: wasi.lookupflags_t,
-    fs_rights_base: wasi.rights_t,
-    fs_rights_inheriting: wasi.rights_t,
-    fs_flags: wasi.fdflags_t,
-};
-
-/// Compute rights + flags corresponding to the provided POSIX access mode.
-fn openOptionsFromFlagsWasi(oflag: O) OpenError!WasiOpenOptions {
-    const w = std.os.wasi;
-
-    // Next, calculate the read/write rights to request, depending on the
-    // provided POSIX access mode
-    var rights: w.rights_t = .{};
-    if (oflag.read) {
-        rights.FD_READ = true;
-        rights.FD_READDIR = true;
-    }
-    if (oflag.write) {
-        rights.FD_DATASYNC = true;
-        rights.FD_WRITE = true;
-        rights.FD_ALLOCATE = true;
-        rights.FD_FILESTAT_SET_SIZE = true;
-    }
-
-    // https://github.com/ziglang/zig/issues/18882
-    const flag_bits: u32 = @bitCast(oflag);
-    const oflags_int: u16 = @as(u12, @truncate(flag_bits >> 12));
-    const fs_flags_int: u16 = @as(u12, @truncate(flag_bits));
-
-    return .{
-        // https://github.com/ziglang/zig/issues/18882
-        .oflags = @bitCast(oflags_int),
-        .lookup_flags = .{
-            .SYMLINK_FOLLOW = !oflag.NOFOLLOW,
-        },
-        .fs_rights_base = rights,
-        .fs_rights_inheriting = rights,
-        // https://github.com/ziglang/zig/issues/18882
-        .fs_flags = @bitCast(fs_flags_int),
-    };
-}
-
-/// Open and possibly create a file in WASI.
-pub fn openatWasi(
-    dir_fd: fd_t,
-    file_path: []const u8,
-    lookup_flags: wasi.lookupflags_t,
-    oflags: wasi.oflags_t,
-    fdflags: wasi.fdflags_t,
-    base: wasi.rights_t,
-    inheriting: wasi.rights_t,
-) OpenError!fd_t {
-    while (true) {
-        var fd: fd_t = undefined;
-        switch (wasi.path_open(dir_fd, lookup_flags, file_path.ptr, file_path.len, oflags, base, inheriting, fdflags, &fd)) {
-            .SUCCESS => return fd,
-            .INTR => continue,
-
-            .FAULT => unreachable,
-            .INVAL => unreachable,
-            .BADF => unreachable,
-            .ACCES => return error.AccessDenied,
-            .FBIG => return error.FileTooBig,
-            .OVERFLOW => return error.FileTooBig,
-            .ISDIR => return error.IsDir,
-            .LOOP => return error.SymLinkLoop,
-            .MFILE => return error.ProcessFdQuotaExceeded,
-            .NAMETOOLONG => return error.NameTooLong,
-            .NFILE => return error.SystemFdQuotaExceeded,
-            .NODEV => return error.NoDevice,
-            .NOENT => return error.FileNotFound,
-            .NOMEM => return error.SystemResources,
-            .NOSPC => return error.NoSpaceLeft,
-            .NOTDIR => return error.NotDir,
-            .PERM => return error.AccessDenied,
-            .EXIST => return error.PathAlreadyExists,
-            .BUSY => return error.DeviceBusy,
-            .NOTCAPABLE => return error.AccessDenied,
-            .ILSEQ => return error.InvalidUtf8,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-/// 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://simonsapin.github.io/wtf-8/).
-/// 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 (builtin.os.tag == .windows) {
-        @compileError("Windows does not support POSIX; use Windows-specific API or cross-platform std.fs API");
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return openat(dir_fd, mem.sliceTo(file_path, 0), flags, mode);
-    }
-
-    const openat_sym = if (lfs64_abi) system.openat64 else system.openat;
-    while (true) {
-        const rc = openat_sym(dir_fd, file_path, flags, mode);
-        switch (errno(rc)) {
-            .SUCCESS => return @intCast(rc),
-            .INTR => continue,
-
-            .FAULT => unreachable,
-            .INVAL => unreachable,
-            .BADF => unreachable,
-            .ACCES => return error.AccessDenied,
-            .FBIG => return error.FileTooBig,
-            .OVERFLOW => return error.FileTooBig,
-            .ISDIR => return error.IsDir,
-            .LOOP => return error.SymLinkLoop,
-            .MFILE => return error.ProcessFdQuotaExceeded,
-            .NAMETOOLONG => return error.NameTooLong,
-            .NFILE => return error.SystemFdQuotaExceeded,
-            .NODEV => return error.NoDevice,
-            .NOENT => return error.FileNotFound,
-            .NOMEM => return error.SystemResources,
-            .NOSPC => return error.NoSpaceLeft,
-            .NOTDIR => return error.NotDir,
-            .PERM => return error.AccessDenied,
-            .EXIST => return error.PathAlreadyExists,
-            .BUSY => return error.DeviceBusy,
-            .OPNOTSUPP => return error.FileLocksNotSupported,
-            .AGAIN => return error.WouldBlock,
-            .TXTBSY => return error.FileBusy,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-pub fn dup(old_fd: fd_t) !fd_t {
-    const rc = system.dup(old_fd);
-    return switch (errno(rc)) {
-        .SUCCESS => return @intCast(rc),
-        .MFILE => error.ProcessFdQuotaExceeded,
-        .BADF => unreachable, // invalid file descriptor
-        else => |err| return unexpectedErrno(err),
-    };
-}
-
-pub fn dup2(old_fd: fd_t, new_fd: fd_t) !void {
-    while (true) {
-        switch (errno(system.dup2(old_fd, new_fd))) {
-            .SUCCESS => return,
-            .BUSY, .INTR => continue,
-            .MFILE => return error.ProcessFdQuotaExceeded,
-            .INVAL => unreachable, // invalid parameters passed to dup2
-            .BADF => unreachable, // invalid file descriptor
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-pub const ExecveError = error{
-    SystemResources,
-    AccessDenied,
-    InvalidExe,
-    FileSystem,
-    IsDir,
-    FileNotFound,
-    NotDir,
-    FileBusy,
-    ProcessFdQuotaExceeded,
-    SystemFdQuotaExceeded,
-    NameTooLong,
-} || UnexpectedError;
-
-/// This function ignores PATH environment variable. See `execvpeZ` for that.
-pub fn execveZ(
-    path: [*:0]const u8,
-    child_argv: [*:null]const ?[*:0]const u8,
-    envp: [*:null]const ?[*:0]const u8,
-) ExecveError {
-    switch (errno(system.execve(path, child_argv, envp))) {
-        .SUCCESS => unreachable,
-        .FAULT => unreachable,
-        .@"2BIG" => return error.SystemResources,
-        .MFILE => return error.ProcessFdQuotaExceeded,
-        .NAMETOOLONG => return error.NameTooLong,
-        .NFILE => return error.SystemFdQuotaExceeded,
-        .NOMEM => return error.SystemResources,
-        .ACCES => return error.AccessDenied,
-        .PERM => return error.AccessDenied,
-        .INVAL => return error.InvalidExe,
-        .NOEXEC => return error.InvalidExe,
-        .IO => return error.FileSystem,
-        .LOOP => return error.FileSystem,
-        .ISDIR => return error.IsDir,
-        .NOENT => return error.FileNotFound,
-        .NOTDIR => return error.NotDir,
-        .TXTBSY => return error.FileBusy,
-        else => |err| switch (builtin.os.tag) {
-            .macos, .ios, .tvos, .watchos => switch (err) {
-                .BADEXEC => return error.InvalidExe,
-                .BADARCH => return error.InvalidExe,
-                else => return unexpectedErrno(err),
-            },
-            .linux => switch (err) {
-                .LIBBAD => return error.InvalidExe,
-                else => return unexpectedErrno(err),
-            },
-            else => return unexpectedErrno(err),
-        },
-    }
-}
-
-pub const Arg0Expand = enum {
-    expand,
-    no_expand,
-};
-
-/// Like `execvpeZ` except if `arg0_expand` is `.expand`, then `argv` is mutable,
-/// and `argv[0]` is expanded to be the same absolute path that is passed to the execve syscall.
-/// If this function returns with an error, `argv[0]` will be restored to the value it was when it was passed in.
-pub fn execvpeZ_expandArg0(
-    comptime arg0_expand: Arg0Expand,
-    file: [*:0]const u8,
-    child_argv: switch (arg0_expand) {
-        .expand => [*:null]?[*:0]const u8,
-        .no_expand => [*:null]const ?[*:0]const u8,
-    },
-    envp: [*:null]const ?[*:0]const u8,
-) ExecveError {
-    const file_slice = mem.sliceTo(file, 0);
-    if (mem.indexOfScalar(u8, file_slice, '/') != null) return execveZ(file, child_argv, envp);
-
-    const PATH = getenvZ("PATH") orelse "/usr/local/bin:/bin/:/usr/bin";
-    // Use of MAX_PATH_BYTES here is valid as the path_buf will be passed
-    // directly to the operating system in execveZ.
-    var path_buf: [MAX_PATH_BYTES]u8 = undefined;
-    var it = mem.tokenizeScalar(u8, PATH, ':');
-    var seen_eacces = false;
-    var err: ExecveError = error.FileNotFound;
-
-    // In case of expanding arg0 we must put it back if we return with an error.
-    const prev_arg0 = child_argv[0];
-    defer switch (arg0_expand) {
-        .expand => child_argv[0] = prev_arg0,
-        .no_expand => {},
-    };
-
-    while (it.next()) |search_path| {
-        const path_len = search_path.len + file_slice.len + 1;
-        if (path_buf.len < path_len + 1) return error.NameTooLong;
-        @memcpy(path_buf[0..search_path.len], search_path);
-        path_buf[search_path.len] = '/';
-        @memcpy(path_buf[search_path.len + 1 ..][0..file_slice.len], file_slice);
-        path_buf[path_len] = 0;
-        const full_path = path_buf[0..path_len :0].ptr;
-        switch (arg0_expand) {
-            .expand => child_argv[0] = full_path,
-            .no_expand => {},
-        }
-        err = execveZ(full_path, child_argv, envp);
-        switch (err) {
-            error.AccessDenied => seen_eacces = true,
-            error.FileNotFound, error.NotDir => {},
-            else => |e| return e,
-        }
-    }
-    if (seen_eacces) return error.AccessDenied;
-    return err;
-}
-
-/// This function also uses the PATH environment variable to get the full path to the executable.
-/// If `file` is an absolute path, this is the same as `execveZ`.
-pub fn execvpeZ(
-    file: [*:0]const u8,
-    argv_ptr: [*:null]const ?[*:0]const u8,
-    envp: [*:null]const ?[*:0]const u8,
-) ExecveError {
-    return execvpeZ_expandArg0(.no_expand, file, argv_ptr, envp);
-}
-
-/// Get an environment variable.
-/// See also `getenvZ`.
-pub fn getenv(key: []const u8) ?[:0]const u8 {
-    if (builtin.os.tag == .windows) {
-        @compileError("std.os.getenv is unavailable for Windows because environment strings are in WTF-16 format. See std.process.getEnvVarOwned for a cross-platform API or std.os.getenvW for a Windows-specific API.");
-    }
-    if (builtin.link_libc) {
-        var ptr = std.c.environ;
-        while (ptr[0]) |line| : (ptr += 1) {
-            var line_i: usize = 0;
-            while (line[line_i] != 0 and line[line_i] != '=') : (line_i += 1) {}
-            const this_key = line[0..line_i];
-
-            if (!mem.eql(u8, this_key, key)) continue;
-
-            return mem.sliceTo(line + line_i + 1, 0);
-        }
-        return null;
-    }
-    if (builtin.os.tag == .wasi) {
-        @compileError("std.os.getenv is unavailable for WASI. See std.process.getEnvMap or std.process.getEnvVarOwned for a cross-platform API.");
-    }
-    // The simplified start logic doesn't populate environ.
-    if (std.start.simplified_logic) return null;
-    // TODO see https://github.com/ziglang/zig/issues/4524
-    for (environ) |ptr| {
-        var line_i: usize = 0;
-        while (ptr[line_i] != 0 and ptr[line_i] != '=') : (line_i += 1) {}
-        const this_key = ptr[0..line_i];
-        if (!mem.eql(u8, key, this_key)) continue;
-
-        return mem.sliceTo(ptr + line_i + 1, 0);
-    }
-    return null;
-}
-
-/// Get an environment variable with a null-terminated name.
-/// See also `getenv`.
-pub fn getenvZ(key: [*:0]const u8) ?[:0]const u8 {
-    if (builtin.link_libc) {
-        const value = system.getenv(key) orelse return null;
-        return mem.sliceTo(value, 0);
-    }
-    if (builtin.os.tag == .windows) {
-        @compileError("std.os.getenvZ is unavailable for Windows because environment string is in WTF-16 format. See std.process.getEnvVarOwned for cross-platform API or std.os.getenvW for Windows-specific API.");
-    }
-    return getenv(mem.sliceTo(key, 0));
-}
-
-/// Windows-only. Get an environment variable with a null-terminated, WTF-16 encoded name.
-/// See also `getenv`.
-/// This function performs a Unicode-aware case-insensitive lookup using RtlEqualUnicodeString.
-pub fn getenvW(key: [*:0]const u16) ?[:0]const u16 {
-    if (builtin.os.tag != .windows) {
-        @compileError("std.os.getenvW is a Windows-only API");
-    }
-    const key_slice = mem.sliceTo(key, 0);
-    const ptr = windows.peb().ProcessParameters.Environment;
-    var i: usize = 0;
-    while (ptr[i] != 0) {
-        const key_start = i;
-
-        // There are some special environment variables that start with =,
-        // so we need a special case to not treat = as a key/value separator
-        // if it's the first character.
-        // https://devblogs.microsoft.com/oldnewthing/20100506-00/?p=14133
-        if (ptr[key_start] == '=') i += 1;
-
-        while (ptr[i] != 0 and ptr[i] != '=') : (i += 1) {}
-        const this_key = ptr[key_start..i];
-
-        if (ptr[i] == '=') i += 1;
-
-        const value_start = i;
-        while (ptr[i] != 0) : (i += 1) {}
-        const this_value = ptr[value_start..i :0];
-
-        if (windows.eqlIgnoreCaseWTF16(key_slice, this_key)) {
-            return this_value;
-        }
-
-        i += 1; // skip over null byte
-    }
-    return null;
-}
-
-pub const GetCwdError = error{
-    NameTooLong,
-    CurrentWorkingDirectoryUnlinked,
-} || UnexpectedError;
-
-/// The result is a slice of out_buffer, indexed from 0.
-pub fn getcwd(out_buffer: []u8) GetCwdError![]u8 {
-    if (builtin.os.tag == .windows) {
-        return windows.GetCurrentDirectory(out_buffer);
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        const path = ".";
-        if (out_buffer.len < path.len) return error.NameTooLong;
-        const result = out_buffer[0..path.len];
-        @memcpy(result, path);
-        return result;
-    }
-
-    const err: E = if (builtin.link_libc) err: {
-        const c_err = if (std.c.getcwd(out_buffer.ptr, out_buffer.len)) |_| 0 else std.c._errno().*;
-        break :err @enumFromInt(c_err);
-    } else err: {
-        break :err errno(system.getcwd(out_buffer.ptr, out_buffer.len));
-    };
-    switch (err) {
-        .SUCCESS => return mem.sliceTo(out_buffer, 0),
-        .FAULT => unreachable,
-        .INVAL => unreachable,
-        .NOENT => return error.CurrentWorkingDirectoryUnlinked,
-        .RANGE => return error.NameTooLong,
-        else => return unexpectedErrno(err),
-    }
-}
-
-pub const SymLinkError = error{
-    /// In WASI, this error may occur when the file descriptor does
-    /// not hold the required rights to create a new symbolic link relative to it.
-    AccessDenied,
-    DiskQuota,
-    PathAlreadyExists,
-    FileSystem,
-    SymLinkLoop,
-    FileNotFound,
-    SystemResources,
-    NoSpaceLeft,
-    ReadOnlyFileSystem,
-    NotDir,
-    NameTooLong,
-
-    /// WASI-only; file paths must be valid UTF-8.
-    InvalidUtf8,
-
-    /// Windows-only; file paths provided by the user must be valid WTF-8.
-    /// https://simonsapin.github.io/wtf-8/
-    InvalidWtf8,
-
-    BadPathName,
-} || UnexpectedError;
-
-/// Creates a symbolic link named `sym_link_path` which contains the string `target_path`.
-/// A symbolic link (also known as a soft link) may point to an existing file or to a nonexistent
-/// one; the latter case is known as a dangling link.
-/// On Windows, both paths should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// On WASI, both paths should be encoded as valid UTF-8.
-/// On other platforms, both paths are an opaque sequence of bytes with no particular encoding.
-/// If `sym_link_path` exists, it will not be overwritten.
-/// See also `symlinkZ.
-pub fn symlink(target_path: []const u8, sym_link_path: []const u8) SymLinkError!void {
-    if (builtin.os.tag == .windows) {
-        @compileError("symlink is not supported on Windows; use std.os.windows.CreateSymbolicLink instead");
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return symlinkat(target_path, wasi.AT.FDCWD, sym_link_path);
-    }
-    const target_path_c = try toPosixPath(target_path);
-    const sym_link_path_c = try toPosixPath(sym_link_path);
-    return symlinkZ(&target_path_c, &sym_link_path_c);
-}
-
-/// This is the same as `symlink` except the parameters are null-terminated pointers.
-/// See also `symlink`.
-pub fn symlinkZ(target_path: [*:0]const u8, sym_link_path: [*:0]const u8) SymLinkError!void {
-    if (builtin.os.tag == .windows) {
-        @compileError("symlink is not supported on Windows; use std.os.windows.CreateSymbolicLink instead");
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return symlinkatZ(target_path, fs.cwd().fd, sym_link_path);
-    }
-    switch (errno(system.symlink(target_path, sym_link_path))) {
-        .SUCCESS => return,
-        .FAULT => unreachable,
-        .INVAL => unreachable,
-        .ACCES => return error.AccessDenied,
-        .PERM => return error.AccessDenied,
-        .DQUOT => return error.DiskQuota,
-        .EXIST => return error.PathAlreadyExists,
-        .IO => return error.FileSystem,
-        .LOOP => return error.SymLinkLoop,
-        .NAMETOOLONG => return error.NameTooLong,
-        .NOENT => return error.FileNotFound,
-        .NOTDIR => return error.NotDir,
-        .NOMEM => return error.SystemResources,
-        .NOSPC => return error.NoSpaceLeft,
-        .ROFS => return error.ReadOnlyFileSystem,
-        .ILSEQ => |err| if (builtin.os.tag == .wasi)
-            return error.InvalidUtf8
-        else
-            return unexpectedErrno(err),
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Similar to `symlink`, however, creates a symbolic link named `sym_link_path` which contains the string
-/// `target_path` **relative** to `newdirfd` directory handle.
-/// A symbolic link (also known as a soft link) may point to an existing file or to a nonexistent
-/// one; the latter case is known as a dangling link.
-/// On Windows, both paths should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// On WASI, both paths should be encoded as valid UTF-8.
-/// On other platforms, both paths are an opaque sequence of bytes with no particular encoding.
-/// If `sym_link_path` exists, it will not be overwritten.
-/// See also `symlinkatWasi`, `symlinkatZ` and `symlinkatW`.
-pub fn symlinkat(target_path: []const u8, newdirfd: fd_t, sym_link_path: []const u8) SymLinkError!void {
-    if (builtin.os.tag == .windows) {
-        @compileError("symlinkat is not supported on Windows; use std.os.windows.CreateSymbolicLink instead");
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return symlinkatWasi(target_path, newdirfd, sym_link_path);
-    }
-    const target_path_c = try toPosixPath(target_path);
-    const sym_link_path_c = try toPosixPath(sym_link_path);
-    return symlinkatZ(&target_path_c, newdirfd, &sym_link_path_c);
-}
-
-/// WASI-only. The same as `symlinkat` but targeting WASI.
-/// See also `symlinkat`.
-pub fn symlinkatWasi(target_path: []const u8, newdirfd: fd_t, sym_link_path: []const u8) SymLinkError!void {
-    switch (wasi.path_symlink(target_path.ptr, target_path.len, newdirfd, sym_link_path.ptr, sym_link_path.len)) {
-        .SUCCESS => {},
-        .FAULT => unreachable,
-        .INVAL => unreachable,
-        .BADF => unreachable,
-        .ACCES => return error.AccessDenied,
-        .PERM => return error.AccessDenied,
-        .DQUOT => return error.DiskQuota,
-        .EXIST => return error.PathAlreadyExists,
-        .IO => return error.FileSystem,
-        .LOOP => return error.SymLinkLoop,
-        .NAMETOOLONG => return error.NameTooLong,
-        .NOENT => return error.FileNotFound,
-        .NOTDIR => return error.NotDir,
-        .NOMEM => return error.SystemResources,
-        .NOSPC => return error.NoSpaceLeft,
-        .ROFS => return error.ReadOnlyFileSystem,
-        .NOTCAPABLE => return error.AccessDenied,
-        .ILSEQ => return error.InvalidUtf8,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// The same as `symlinkat` except the parameters are null-terminated pointers.
-/// See also `symlinkat`.
-pub fn symlinkatZ(target_path: [*:0]const u8, newdirfd: fd_t, sym_link_path: [*:0]const u8) SymLinkError!void {
-    if (builtin.os.tag == .windows) {
-        @compileError("symlinkat is not supported on Windows; use std.os.windows.CreateSymbolicLink instead");
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return symlinkat(mem.sliceTo(target_path, 0), newdirfd, mem.sliceTo(sym_link_path, 0));
-    }
-    switch (errno(system.symlinkat(target_path, newdirfd, sym_link_path))) {
-        .SUCCESS => return,
-        .FAULT => unreachable,
-        .INVAL => unreachable,
-        .ACCES => return error.AccessDenied,
-        .PERM => return error.AccessDenied,
-        .DQUOT => return error.DiskQuota,
-        .EXIST => return error.PathAlreadyExists,
-        .IO => return error.FileSystem,
-        .LOOP => return error.SymLinkLoop,
-        .NAMETOOLONG => return error.NameTooLong,
-        .NOENT => return error.FileNotFound,
-        .NOTDIR => return error.NotDir,
-        .NOMEM => return error.SystemResources,
-        .NOSPC => return error.NoSpaceLeft,
-        .ROFS => return error.ReadOnlyFileSystem,
-        .ILSEQ => |err| if (builtin.os.tag == .wasi)
-            return error.InvalidUtf8
-        else
-            return unexpectedErrno(err),
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub const LinkError = UnexpectedError || error{
-    AccessDenied,
-    DiskQuota,
-    PathAlreadyExists,
-    FileSystem,
-    SymLinkLoop,
-    LinkQuotaExceeded,
-    NameTooLong,
-    FileNotFound,
-    SystemResources,
-    NoSpaceLeft,
-    ReadOnlyFileSystem,
-    NotSameFileSystem,
-
-    /// WASI-only; file paths must be valid UTF-8.
-    InvalidUtf8,
-};
-
-/// On WASI, both paths should be encoded as valid UTF-8.
-/// On other platforms, both paths are an opaque sequence of bytes with no particular encoding.
-pub fn linkZ(oldpath: [*:0]const u8, newpath: [*:0]const u8, flags: i32) LinkError!void {
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return link(mem.sliceTo(oldpath, 0), mem.sliceTo(newpath, 0), flags);
-    }
-    switch (errno(system.link(oldpath, newpath, flags))) {
-        .SUCCESS => return,
-        .ACCES => return error.AccessDenied,
-        .DQUOT => return error.DiskQuota,
-        .EXIST => return error.PathAlreadyExists,
-        .FAULT => unreachable,
-        .IO => return error.FileSystem,
-        .LOOP => return error.SymLinkLoop,
-        .MLINK => return error.LinkQuotaExceeded,
-        .NAMETOOLONG => return error.NameTooLong,
-        .NOENT => return error.FileNotFound,
-        .NOMEM => return error.SystemResources,
-        .NOSPC => return error.NoSpaceLeft,
-        .PERM => return error.AccessDenied,
-        .ROFS => return error.ReadOnlyFileSystem,
-        .XDEV => return error.NotSameFileSystem,
-        .INVAL => unreachable,
-        .ILSEQ => |err| if (builtin.os.tag == .wasi)
-            return error.InvalidUtf8
-        else
-            return unexpectedErrno(err),
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// On WASI, both paths should be encoded as valid UTF-8.
-/// On other platforms, both paths are an opaque sequence of bytes with no particular encoding.
-pub fn link(oldpath: []const u8, newpath: []const u8, flags: i32) LinkError!void {
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return linkat(wasi.AT.FDCWD, oldpath, wasi.AT.FDCWD, newpath, flags) catch |err| switch (err) {
-            error.NotDir => unreachable, // link() does not support directories
-            else => |e| return e,
-        };
-    }
-    const old = try toPosixPath(oldpath);
-    const new = try toPosixPath(newpath);
-    return try linkZ(&old, &new, flags);
-}
-
-pub const LinkatError = LinkError || error{NotDir};
-
-/// On WASI, both paths should be encoded as valid UTF-8.
-/// On other platforms, both paths are an opaque sequence of bytes with no particular encoding.
-pub fn linkatZ(
-    olddir: fd_t,
-    oldpath: [*:0]const u8,
-    newdir: fd_t,
-    newpath: [*:0]const u8,
-    flags: i32,
-) LinkatError!void {
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return linkat(olddir, mem.sliceTo(oldpath, 0), newdir, mem.sliceTo(newpath, 0), flags);
-    }
-    switch (errno(system.linkat(olddir, oldpath, newdir, newpath, flags))) {
-        .SUCCESS => return,
-        .ACCES => return error.AccessDenied,
-        .DQUOT => return error.DiskQuota,
-        .EXIST => return error.PathAlreadyExists,
-        .FAULT => unreachable,
-        .IO => return error.FileSystem,
-        .LOOP => return error.SymLinkLoop,
-        .MLINK => return error.LinkQuotaExceeded,
-        .NAMETOOLONG => return error.NameTooLong,
-        .NOENT => return error.FileNotFound,
-        .NOMEM => return error.SystemResources,
-        .NOSPC => return error.NoSpaceLeft,
-        .NOTDIR => return error.NotDir,
-        .PERM => return error.AccessDenied,
-        .ROFS => return error.ReadOnlyFileSystem,
-        .XDEV => return error.NotSameFileSystem,
-        .INVAL => unreachable,
-        .ILSEQ => |err| if (builtin.os.tag == .wasi)
-            return error.InvalidUtf8
-        else
-            return unexpectedErrno(err),
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// On WASI, both paths should be encoded as valid UTF-8.
-/// On other platforms, both paths are an opaque sequence of bytes with no particular encoding.
-pub fn linkat(
-    olddir: fd_t,
-    oldpath: []const u8,
-    newdir: fd_t,
-    newpath: []const u8,
-    flags: i32,
-) LinkatError!void {
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        const old: RelativePathWasi = .{ .dir_fd = olddir, .relative_path = oldpath };
-        const new: RelativePathWasi = .{ .dir_fd = newdir, .relative_path = newpath };
-        const old_flags: wasi.lookupflags_t = .{
-            .SYMLINK_FOLLOW = (flags & AT.SYMLINK_FOLLOW) != 0,
-        };
-        switch (wasi.path_link(
-            old.dir_fd,
-            old_flags,
-            old.relative_path.ptr,
-            old.relative_path.len,
-            new.dir_fd,
-            new.relative_path.ptr,
-            new.relative_path.len,
-        )) {
-            .SUCCESS => return,
-            .ACCES => return error.AccessDenied,
-            .DQUOT => return error.DiskQuota,
-            .EXIST => return error.PathAlreadyExists,
-            .FAULT => unreachable,
-            .IO => return error.FileSystem,
-            .LOOP => return error.SymLinkLoop,
-            .MLINK => return error.LinkQuotaExceeded,
-            .NAMETOOLONG => return error.NameTooLong,
-            .NOENT => return error.FileNotFound,
-            .NOMEM => return error.SystemResources,
-            .NOSPC => return error.NoSpaceLeft,
-            .NOTDIR => return error.NotDir,
-            .PERM => return error.AccessDenied,
-            .ROFS => return error.ReadOnlyFileSystem,
-            .XDEV => return error.NotSameFileSystem,
-            .INVAL => unreachable,
-            .ILSEQ => return error.InvalidUtf8,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-    const old = try toPosixPath(oldpath);
-    const new = try toPosixPath(newpath);
-    return try linkatZ(olddir, &old, newdir, &new, flags);
-}
-
-pub const UnlinkError = error{
-    FileNotFound,
-
-    /// In WASI, this error may occur when the file descriptor does
-    /// not hold the required rights to unlink a resource by path relative to it.
-    AccessDenied,
-    FileBusy,
-    FileSystem,
-    IsDir,
-    SymLinkLoop,
-    NameTooLong,
-    NotDir,
-    SystemResources,
-    ReadOnlyFileSystem,
-
-    /// WASI-only; file paths must be valid UTF-8.
-    InvalidUtf8,
-
-    /// Windows-only; file paths provided by the user must be valid WTF-8.
-    /// https://simonsapin.github.io/wtf-8/
-    InvalidWtf8,
-
-    /// On Windows, file paths cannot contain these characters:
-    /// '/', '*', '?', '"', '<', '>', '|'
-    BadPathName,
-
-    /// On Windows, `\\server` or `\\server\share` was not found.
-    NetworkNotFound,
-} || UnexpectedError;
-
-/// Delete a name and possibly the file it refers to.
-/// On Windows, `file_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// 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 `unlinkZ`.
-pub fn unlink(file_path: []const u8) UnlinkError!void {
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return unlinkat(wasi.AT.FDCWD, file_path, 0) catch |err| switch (err) {
-            error.DirNotEmpty => unreachable, // only occurs when targeting directories
-            else => |e| return e,
-        };
-    } else if (builtin.os.tag == .windows) {
-        const file_path_w = try windows.sliceToPrefixedFileW(null, file_path);
-        return unlinkW(file_path_w.span());
-    } else {
-        const file_path_c = try toPosixPath(file_path);
-        return unlinkZ(&file_path_c);
-    }
-}
-
-/// Same as `unlink` except the parameter is null terminated.
-pub fn unlinkZ(file_path: [*:0]const u8) UnlinkError!void {
-    if (builtin.os.tag == .windows) {
-        const file_path_w = try windows.cStrToPrefixedFileW(null, file_path);
-        return unlinkW(file_path_w.span());
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return unlink(mem.sliceTo(file_path, 0));
-    }
-    switch (errno(system.unlink(file_path))) {
-        .SUCCESS => return,
-        .ACCES => return error.AccessDenied,
-        .PERM => return error.AccessDenied,
-        .BUSY => return error.FileBusy,
-        .FAULT => unreachable,
-        .INVAL => unreachable,
-        .IO => return error.FileSystem,
-        .ISDIR => return error.IsDir,
-        .LOOP => return error.SymLinkLoop,
-        .NAMETOOLONG => return error.NameTooLong,
-        .NOENT => return error.FileNotFound,
-        .NOTDIR => return error.NotDir,
-        .NOMEM => return error.SystemResources,
-        .ROFS => return error.ReadOnlyFileSystem,
-        .ILSEQ => |err| if (builtin.os.tag == .wasi)
-            return error.InvalidUtf8
-        else
-            return unexpectedErrno(err),
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Windows-only. Same as `unlink` except the parameter is null-terminated, WTF16 LE encoded.
-pub fn unlinkW(file_path_w: []const u16) UnlinkError!void {
-    windows.DeleteFile(file_path_w, .{ .dir = std.fs.cwd().fd }) catch |err| switch (err) {
-        error.DirNotEmpty => unreachable, // we're not passing .remove_dir = true
-        else => |e| return e,
-    };
-}
-
-pub const UnlinkatError = UnlinkError || error{
-    /// When passing `AT.REMOVEDIR`, this error occurs when the named directory is not empty.
-    DirNotEmpty,
-};
-
-/// Delete a file name and possibly the file it refers to, based on an open directory handle.
-/// On Windows, `file_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// 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.
-/// Asserts that the path parameter has no null bytes.
-pub fn unlinkat(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!void {
-    if (builtin.os.tag == .windows) {
-        const file_path_w = try windows.sliceToPrefixedFileW(dirfd, file_path);
-        return unlinkatW(dirfd, file_path_w.span(), flags);
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return unlinkatWasi(dirfd, file_path, flags);
-    } else {
-        const file_path_c = try toPosixPath(file_path);
-        return unlinkatZ(dirfd, &file_path_c, flags);
-    }
-}
-
-/// WASI-only. Same as `unlinkat` but targeting WASI.
-/// See also `unlinkat`.
-pub fn unlinkatWasi(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!void {
-    const remove_dir = (flags & AT.REMOVEDIR) != 0;
-    const res = if (remove_dir)
-        wasi.path_remove_directory(dirfd, file_path.ptr, file_path.len)
-    else
-        wasi.path_unlink_file(dirfd, file_path.ptr, file_path.len);
-    switch (res) {
-        .SUCCESS => return,
-        .ACCES => return error.AccessDenied,
-        .PERM => return error.AccessDenied,
-        .BUSY => return error.FileBusy,
-        .FAULT => unreachable,
-        .IO => return error.FileSystem,
-        .ISDIR => return error.IsDir,
-        .LOOP => return error.SymLinkLoop,
-        .NAMETOOLONG => return error.NameTooLong,
-        .NOENT => return error.FileNotFound,
-        .NOTDIR => return error.NotDir,
-        .NOMEM => return error.SystemResources,
-        .ROFS => return error.ReadOnlyFileSystem,
-        .NOTEMPTY => return error.DirNotEmpty,
-        .NOTCAPABLE => return error.AccessDenied,
-        .ILSEQ => return error.InvalidUtf8,
-
-        .INVAL => unreachable, // invalid flags, or pathname has . as last component
-        .BADF => unreachable, // always a race condition
-
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Same as `unlinkat` but `file_path` is a null-terminated string.
-pub fn unlinkatZ(dirfd: fd_t, file_path_c: [*:0]const u8, flags: u32) UnlinkatError!void {
-    if (builtin.os.tag == .windows) {
-        const file_path_w = try windows.cStrToPrefixedFileW(dirfd, file_path_c);
-        return unlinkatW(dirfd, file_path_w.span(), flags);
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return unlinkat(dirfd, mem.sliceTo(file_path_c, 0), flags);
-    }
-    switch (errno(system.unlinkat(dirfd, file_path_c, flags))) {
-        .SUCCESS => return,
-        .ACCES => return error.AccessDenied,
-        .PERM => return error.AccessDenied,
-        .BUSY => return error.FileBusy,
-        .FAULT => unreachable,
-        .IO => return error.FileSystem,
-        .ISDIR => return error.IsDir,
-        .LOOP => return error.SymLinkLoop,
-        .NAMETOOLONG => return error.NameTooLong,
-        .NOENT => return error.FileNotFound,
-        .NOTDIR => return error.NotDir,
-        .NOMEM => return error.SystemResources,
-        .ROFS => return error.ReadOnlyFileSystem,
-        .EXIST => return error.DirNotEmpty,
-        .NOTEMPTY => return error.DirNotEmpty,
-        .ILSEQ => |err| if (builtin.os.tag == .wasi)
-            return error.InvalidUtf8
-        else
-            return unexpectedErrno(err),
-
-        .INVAL => unreachable, // invalid flags, or pathname has . as last component
-        .BADF => unreachable, // always a race condition
-
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Same as `unlinkat` but `sub_path_w` is WTF16LE, NT prefixed. Windows only.
-pub fn unlinkatW(dirfd: fd_t, sub_path_w: []const u16, flags: u32) UnlinkatError!void {
-    const remove_dir = (flags & AT.REMOVEDIR) != 0;
-    return windows.DeleteFile(sub_path_w, .{ .dir = dirfd, .remove_dir = remove_dir });
-}
-
-pub const RenameError = error{
-    /// In WASI, this error may occur when the file descriptor does
-    /// not hold the required rights to rename a resource by path relative to it.
-    ///
-    /// On Windows, this error may be returned instead of PathAlreadyExists when
-    /// renaming a directory over an existing directory.
-    AccessDenied,
-    FileBusy,
-    DiskQuota,
-    IsDir,
-    SymLinkLoop,
-    LinkQuotaExceeded,
-    NameTooLong,
-    FileNotFound,
-    NotDir,
-    SystemResources,
-    NoSpaceLeft,
-    PathAlreadyExists,
-    ReadOnlyFileSystem,
-    RenameAcrossMountPoints,
-    /// WASI-only; file paths must be valid UTF-8.
-    InvalidUtf8,
-    /// Windows-only; file paths provided by the user must be valid WTF-8.
-    /// https://simonsapin.github.io/wtf-8/
-    InvalidWtf8,
-    BadPathName,
-    NoDevice,
-    SharingViolation,
-    PipeBusy,
-    /// On Windows, `\\server` or `\\server\share` was not found.
-    NetworkNotFound,
-    /// On Windows, antivirus software is enabled by default. It can be
-    /// disabled, but Windows Update sometimes ignores the user's preference
-    /// and re-enables it. When enabled, antivirus software on Windows
-    /// intercepts file system operations and makes them significantly slower
-    /// in addition to possibly failing with this error code.
-    AntivirusInterference,
-} || UnexpectedError;
-
-/// Change the name or location of a file.
-/// On Windows, both paths should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// On WASI, both paths should be encoded as valid UTF-8.
-/// On other platforms, both paths are an opaque sequence of bytes with no particular encoding.
-pub fn rename(old_path: []const u8, new_path: []const u8) RenameError!void {
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return renameat(wasi.AT.FDCWD, old_path, wasi.AT.FDCWD, new_path);
-    } else if (builtin.os.tag == .windows) {
-        const old_path_w = try windows.sliceToPrefixedFileW(null, old_path);
-        const new_path_w = try windows.sliceToPrefixedFileW(null, new_path);
-        return renameW(old_path_w.span().ptr, new_path_w.span().ptr);
-    } else {
-        const old_path_c = try toPosixPath(old_path);
-        const new_path_c = try toPosixPath(new_path);
-        return renameZ(&old_path_c, &new_path_c);
-    }
-}
-
-/// Same as `rename` except the parameters are null-terminated.
-pub fn renameZ(old_path: [*:0]const u8, new_path: [*:0]const u8) RenameError!void {
-    if (builtin.os.tag == .windows) {
-        const old_path_w = try windows.cStrToPrefixedFileW(null, old_path);
-        const new_path_w = try windows.cStrToPrefixedFileW(null, new_path);
-        return renameW(old_path_w.span().ptr, new_path_w.span().ptr);
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return rename(mem.sliceTo(old_path, 0), mem.sliceTo(new_path, 0));
-    }
-    switch (errno(system.rename(old_path, new_path))) {
-        .SUCCESS => return,
-        .ACCES => return error.AccessDenied,
-        .PERM => return error.AccessDenied,
-        .BUSY => return error.FileBusy,
-        .DQUOT => return error.DiskQuota,
-        .FAULT => unreachable,
-        .INVAL => unreachable,
-        .ISDIR => return error.IsDir,
-        .LOOP => return error.SymLinkLoop,
-        .MLINK => return error.LinkQuotaExceeded,
-        .NAMETOOLONG => return error.NameTooLong,
-        .NOENT => return error.FileNotFound,
-        .NOTDIR => return error.NotDir,
-        .NOMEM => return error.SystemResources,
-        .NOSPC => return error.NoSpaceLeft,
-        .EXIST => return error.PathAlreadyExists,
-        .NOTEMPTY => return error.PathAlreadyExists,
-        .ROFS => return error.ReadOnlyFileSystem,
-        .XDEV => return error.RenameAcrossMountPoints,
-        .ILSEQ => |err| if (builtin.os.tag == .wasi)
-            return error.InvalidUtf8
-        else
-            return unexpectedErrno(err),
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Same as `rename` except the parameters are null-terminated and WTF16LE encoded.
-/// Assumes target is Windows.
-pub fn renameW(old_path: [*:0]const u16, new_path: [*:0]const u16) RenameError!void {
-    const flags = windows.MOVEFILE_REPLACE_EXISTING | windows.MOVEFILE_WRITE_THROUGH;
-    return windows.MoveFileExW(old_path, new_path, flags);
-}
-
-/// Change the name or location of a file based on an open directory handle.
-/// On Windows, both paths should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// On WASI, both paths should be encoded as valid UTF-8.
-/// On other platforms, both paths are an opaque sequence of bytes with no particular encoding.
-pub fn renameat(
-    old_dir_fd: fd_t,
-    old_path: []const u8,
-    new_dir_fd: fd_t,
-    new_path: []const u8,
-) RenameError!void {
-    if (builtin.os.tag == .windows) {
-        const old_path_w = try windows.sliceToPrefixedFileW(old_dir_fd, old_path);
-        const new_path_w = try windows.sliceToPrefixedFileW(new_dir_fd, new_path);
-        return renameatW(old_dir_fd, old_path_w.span(), new_dir_fd, new_path_w.span(), windows.TRUE);
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        const old: RelativePathWasi = .{ .dir_fd = old_dir_fd, .relative_path = old_path };
-        const new: RelativePathWasi = .{ .dir_fd = new_dir_fd, .relative_path = new_path };
-        return renameatWasi(old, new);
-    } else {
-        const old_path_c = try toPosixPath(old_path);
-        const new_path_c = try toPosixPath(new_path);
-        return renameatZ(old_dir_fd, &old_path_c, new_dir_fd, &new_path_c);
-    }
-}
-
-/// WASI-only. Same as `renameat` expect targeting WASI.
-/// See also `renameat`.
-pub fn renameatWasi(old: RelativePathWasi, new: RelativePathWasi) RenameError!void {
-    switch (wasi.path_rename(old.dir_fd, old.relative_path.ptr, old.relative_path.len, new.dir_fd, new.relative_path.ptr, new.relative_path.len)) {
-        .SUCCESS => return,
-        .ACCES => return error.AccessDenied,
-        .PERM => return error.AccessDenied,
-        .BUSY => return error.FileBusy,
-        .DQUOT => return error.DiskQuota,
-        .FAULT => unreachable,
-        .INVAL => unreachable,
-        .ISDIR => return error.IsDir,
-        .LOOP => return error.SymLinkLoop,
-        .MLINK => return error.LinkQuotaExceeded,
-        .NAMETOOLONG => return error.NameTooLong,
-        .NOENT => return error.FileNotFound,
-        .NOTDIR => return error.NotDir,
-        .NOMEM => return error.SystemResources,
-        .NOSPC => return error.NoSpaceLeft,
-        .EXIST => return error.PathAlreadyExists,
-        .NOTEMPTY => return error.PathAlreadyExists,
-        .ROFS => return error.ReadOnlyFileSystem,
-        .XDEV => return error.RenameAcrossMountPoints,
-        .NOTCAPABLE => return error.AccessDenied,
-        .ILSEQ => return error.InvalidUtf8,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Same as `renameat` except the parameters are null-terminated.
-pub fn renameatZ(
-    old_dir_fd: fd_t,
-    old_path: [*:0]const u8,
-    new_dir_fd: fd_t,
-    new_path: [*:0]const u8,
-) RenameError!void {
-    if (builtin.os.tag == .windows) {
-        const old_path_w = try windows.cStrToPrefixedFileW(old_dir_fd, old_path);
-        const new_path_w = try windows.cStrToPrefixedFileW(new_dir_fd, new_path);
-        return renameatW(old_dir_fd, old_path_w.span(), new_dir_fd, new_path_w.span(), windows.TRUE);
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return renameat(old_dir_fd, mem.sliceTo(old_path, 0), new_dir_fd, mem.sliceTo(new_path, 0));
-    }
-
-    switch (errno(system.renameat(old_dir_fd, old_path, new_dir_fd, new_path))) {
-        .SUCCESS => return,
-        .ACCES => return error.AccessDenied,
-        .PERM => return error.AccessDenied,
-        .BUSY => return error.FileBusy,
-        .DQUOT => return error.DiskQuota,
-        .FAULT => unreachable,
-        .INVAL => unreachable,
-        .ISDIR => return error.IsDir,
-        .LOOP => return error.SymLinkLoop,
-        .MLINK => return error.LinkQuotaExceeded,
-        .NAMETOOLONG => return error.NameTooLong,
-        .NOENT => return error.FileNotFound,
-        .NOTDIR => return error.NotDir,
-        .NOMEM => return error.SystemResources,
-        .NOSPC => return error.NoSpaceLeft,
-        .EXIST => return error.PathAlreadyExists,
-        .NOTEMPTY => return error.PathAlreadyExists,
-        .ROFS => return error.ReadOnlyFileSystem,
-        .XDEV => return error.RenameAcrossMountPoints,
-        .ILSEQ => |err| if (builtin.os.tag == .wasi)
-            return error.InvalidUtf8
-        else
-            return unexpectedErrno(err),
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Same as `renameat` but Windows-only and the path parameters are
-/// [WTF-16](https://simonsapin.github.io/wtf-8/#potentially-ill-formed-utf-16) encoded.
-pub fn renameatW(
-    old_dir_fd: fd_t,
-    old_path_w: []const u16,
-    new_dir_fd: fd_t,
-    new_path_w: []const u16,
-    ReplaceIfExists: windows.BOOLEAN,
-) RenameError!void {
-    const src_fd = windows.OpenFile(old_path_w, .{
-        .dir = old_dir_fd,
-        .access_mask = windows.SYNCHRONIZE | windows.GENERIC_WRITE | windows.DELETE,
-        .creation = windows.FILE_OPEN,
-        .filter = .any, // This function is supposed to rename both files and directories.
-        .follow_symlinks = false,
-    }) catch |err| switch (err) {
-        error.WouldBlock => unreachable, // Not possible without `.share_access_nonblocking = true`.
-        else => |e| return e,
-    };
-    defer windows.CloseHandle(src_fd);
-
-    var need_fallback = true;
-    var rc: windows.NTSTATUS = undefined;
-    // FILE_RENAME_INFORMATION_EX and FILE_RENAME_POSIX_SEMANTICS require >= win10_rs1,
-    // but FILE_RENAME_IGNORE_READONLY_ATTRIBUTE requires >= win10_rs5. We check >= rs5 here
-    // so that we only use POSIX_SEMANTICS when we know IGNORE_READONLY_ATTRIBUTE will also be
-    // supported in order to avoid either (1) using a redundant call that we can know in advance will return
-    // STATUS_NOT_SUPPORTED or (2) only setting IGNORE_READONLY_ATTRIBUTE when >= rs5
-    // and therefore having different behavior when the Windows version is >= rs1 but < rs5.
-    if (builtin.target.os.isAtLeast(.windows, .win10_rs5) orelse false) {
-        const struct_buf_len = @sizeOf(windows.FILE_RENAME_INFORMATION_EX) + (MAX_PATH_BYTES - 1);
-        var rename_info_buf: [struct_buf_len]u8 align(@alignOf(windows.FILE_RENAME_INFORMATION_EX)) = undefined;
-        const struct_len = @sizeOf(windows.FILE_RENAME_INFORMATION_EX) - 1 + new_path_w.len * 2;
-        if (struct_len > struct_buf_len) return error.NameTooLong;
-
-        const rename_info: *windows.FILE_RENAME_INFORMATION_EX = @ptrCast(&rename_info_buf);
-        var io_status_block: windows.IO_STATUS_BLOCK = undefined;
-
-        var flags: windows.ULONG = windows.FILE_RENAME_POSIX_SEMANTICS | windows.FILE_RENAME_IGNORE_READONLY_ATTRIBUTE;
-        if (ReplaceIfExists == windows.TRUE) flags |= windows.FILE_RENAME_REPLACE_IF_EXISTS;
-        rename_info.* = .{
-            .Flags = flags,
-            .RootDirectory = if (std.fs.path.isAbsoluteWindowsWTF16(new_path_w)) null else new_dir_fd,
-            .FileNameLength = @intCast(new_path_w.len * 2), // already checked error.NameTooLong
-            .FileName = undefined,
-        };
-        @memcpy((&rename_info.FileName).ptr, new_path_w);
-        rc = windows.ntdll.NtSetInformationFile(
-            src_fd,
-            &io_status_block,
-            rename_info,
-            @intCast(struct_len), // already checked for error.NameTooLong
-            .FileRenameInformationEx,
-        );
-        switch (rc) {
-            .SUCCESS => return,
-            // INVALID_PARAMETER here means that the filesystem does not support FileRenameInformationEx
-            .INVALID_PARAMETER => {},
-            .DIRECTORY_NOT_EMPTY => return error.PathAlreadyExists,
-            .FILE_IS_A_DIRECTORY => return error.IsDir,
-            .NOT_A_DIRECTORY => return error.NotDir,
-            // For all other statuses, fall down to the switch below to handle them.
-            else => need_fallback = false,
-        }
-    }
-
-    if (need_fallback) {
-        const struct_buf_len = @sizeOf(windows.FILE_RENAME_INFORMATION) + (MAX_PATH_BYTES - 1);
-        var rename_info_buf: [struct_buf_len]u8 align(@alignOf(windows.FILE_RENAME_INFORMATION)) = undefined;
-        const struct_len = @sizeOf(windows.FILE_RENAME_INFORMATION) - 1 + new_path_w.len * 2;
-        if (struct_len > struct_buf_len) return error.NameTooLong;
-
-        const rename_info: *windows.FILE_RENAME_INFORMATION = @ptrCast(&rename_info_buf);
-        var io_status_block: windows.IO_STATUS_BLOCK = undefined;
-
-        rename_info.* = .{
-            .Flags = ReplaceIfExists,
-            .RootDirectory = if (std.fs.path.isAbsoluteWindowsWTF16(new_path_w)) null else new_dir_fd,
-            .FileNameLength = @intCast(new_path_w.len * 2), // already checked error.NameTooLong
-            .FileName = undefined,
-        };
-        @memcpy((&rename_info.FileName).ptr, new_path_w);
-
-        rc =
-            windows.ntdll.NtSetInformationFile(
-            src_fd,
-            &io_status_block,
-            rename_info,
-            @intCast(struct_len), // already checked for error.NameTooLong
-            .FileRenameInformation,
-        );
-    }
-
-    switch (rc) {
-        .SUCCESS => {},
-        .INVALID_HANDLE => unreachable,
-        .INVALID_PARAMETER => unreachable,
-        .OBJECT_PATH_SYNTAX_BAD => unreachable,
-        .ACCESS_DENIED => return error.AccessDenied,
-        .OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
-        .OBJECT_PATH_NOT_FOUND => return error.FileNotFound,
-        .NOT_SAME_DEVICE => return error.RenameAcrossMountPoints,
-        .OBJECT_NAME_COLLISION => return error.PathAlreadyExists,
-        else => return windows.unexpectedStatus(rc),
-    }
-}
-
-/// On Windows, `sub_dir_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// On WASI, `sub_dir_path` should be encoded as valid UTF-8.
-/// On other platforms, `sub_dir_path` is an opaque sequence of bytes with no particular encoding.
-pub fn mkdirat(dir_fd: fd_t, sub_dir_path: []const u8, mode: u32) MakeDirError!void {
-    if (builtin.os.tag == .windows) {
-        const sub_dir_path_w = try windows.sliceToPrefixedFileW(dir_fd, sub_dir_path);
-        return mkdiratW(dir_fd, sub_dir_path_w.span(), mode);
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return mkdiratWasi(dir_fd, sub_dir_path, mode);
-    } else {
-        const sub_dir_path_c = try toPosixPath(sub_dir_path);
-        return mkdiratZ(dir_fd, &sub_dir_path_c, mode);
-    }
-}
-
-pub fn mkdiratWasi(dir_fd: fd_t, sub_dir_path: []const u8, mode: u32) MakeDirError!void {
-    _ = mode;
-    switch (wasi.path_create_directory(dir_fd, sub_dir_path.ptr, sub_dir_path.len)) {
-        .SUCCESS => return,
-        .ACCES => return error.AccessDenied,
-        .BADF => unreachable,
-        .PERM => return error.AccessDenied,
-        .DQUOT => return error.DiskQuota,
-        .EXIST => return error.PathAlreadyExists,
-        .FAULT => unreachable,
-        .LOOP => return error.SymLinkLoop,
-        .MLINK => return error.LinkQuotaExceeded,
-        .NAMETOOLONG => return error.NameTooLong,
-        .NOENT => return error.FileNotFound,
-        .NOMEM => return error.SystemResources,
-        .NOSPC => return error.NoSpaceLeft,
-        .NOTDIR => return error.NotDir,
-        .ROFS => return error.ReadOnlyFileSystem,
-        .NOTCAPABLE => return error.AccessDenied,
-        .ILSEQ => return error.InvalidUtf8,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Same as `mkdirat` except the parameters are null-terminated.
-pub fn mkdiratZ(dir_fd: fd_t, sub_dir_path: [*:0]const u8, mode: u32) MakeDirError!void {
-    if (builtin.os.tag == .windows) {
-        const sub_dir_path_w = try windows.cStrToPrefixedFileW(dir_fd, sub_dir_path);
-        return mkdiratW(dir_fd, sub_dir_path_w.span(), mode);
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return mkdirat(dir_fd, mem.sliceTo(sub_dir_path, 0), mode);
-    }
-    switch (errno(system.mkdirat(dir_fd, sub_dir_path, mode))) {
-        .SUCCESS => return,
-        .ACCES => return error.AccessDenied,
-        .BADF => unreachable,
-        .PERM => return error.AccessDenied,
-        .DQUOT => return error.DiskQuota,
-        .EXIST => return error.PathAlreadyExists,
-        .FAULT => unreachable,
-        .LOOP => return error.SymLinkLoop,
-        .MLINK => return error.LinkQuotaExceeded,
-        .NAMETOOLONG => return error.NameTooLong,
-        .NOENT => return error.FileNotFound,
-        .NOMEM => return error.SystemResources,
-        .NOSPC => return error.NoSpaceLeft,
-        .NOTDIR => return error.NotDir,
-        .ROFS => return error.ReadOnlyFileSystem,
-        // dragonfly: when dir_fd is unlinked from filesystem
-        .NOTCONN => return error.FileNotFound,
-        .ILSEQ => |err| if (builtin.os.tag == .wasi)
-            return error.InvalidUtf8
-        else
-            return unexpectedErrno(err),
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Windows-only. Same as `mkdirat` except the parameter WTF16 LE encoded.
-pub fn mkdiratW(dir_fd: fd_t, sub_path_w: []const u16, mode: u32) MakeDirError!void {
-    _ = mode;
-    const sub_dir_handle = windows.OpenFile(sub_path_w, .{
-        .dir = dir_fd,
-        .access_mask = windows.GENERIC_READ | windows.SYNCHRONIZE,
-        .creation = windows.FILE_CREATE,
-        .filter = .dir_only,
-    }) catch |err| switch (err) {
-        error.IsDir => return error.Unexpected,
-        error.PipeBusy => return error.Unexpected,
-        error.WouldBlock => return error.Unexpected,
-        error.AntivirusInterference => return error.Unexpected,
-        else => |e| return e,
-    };
-    windows.CloseHandle(sub_dir_handle);
-}
-
-pub const MakeDirError = error{
-    /// In WASI, this error may occur when the file descriptor does
-    /// not hold the required rights to create a new directory relative to it.
-    AccessDenied,
-    DiskQuota,
-    PathAlreadyExists,
-    SymLinkLoop,
-    LinkQuotaExceeded,
-    NameTooLong,
-    FileNotFound,
-    SystemResources,
-    NoSpaceLeft,
-    NotDir,
-    ReadOnlyFileSystem,
-    /// WASI-only; file paths must be valid UTF-8.
-    InvalidUtf8,
-    /// Windows-only; file paths provided by the user must be valid WTF-8.
-    /// https://simonsapin.github.io/wtf-8/
-    InvalidWtf8,
-    BadPathName,
-    NoDevice,
-    /// On Windows, `\\server` or `\\server\share` was not found.
-    NetworkNotFound,
-} || UnexpectedError;
-
-/// Create a directory.
-/// `mode` is ignored on Windows and WASI.
-/// On Windows, `dir_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// On WASI, `dir_path` should be encoded as valid UTF-8.
-/// On other platforms, `dir_path` is an opaque sequence of bytes with no particular encoding.
-pub fn mkdir(dir_path: []const u8, mode: u32) MakeDirError!void {
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return mkdirat(wasi.AT.FDCWD, dir_path, mode);
-    } else if (builtin.os.tag == .windows) {
-        const dir_path_w = try windows.sliceToPrefixedFileW(null, dir_path);
-        return mkdirW(dir_path_w.span(), mode);
-    } else {
-        const dir_path_c = try toPosixPath(dir_path);
-        return mkdirZ(&dir_path_c, mode);
-    }
-}
-
-/// Same as `mkdir` but the parameter is null-terminated.
-/// On Windows, `dir_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// On WASI, `dir_path` should be encoded as valid UTF-8.
-/// On other platforms, `dir_path` is an opaque sequence of bytes with no particular encoding.
-pub fn mkdirZ(dir_path: [*:0]const u8, mode: u32) MakeDirError!void {
-    if (builtin.os.tag == .windows) {
-        const dir_path_w = try windows.cStrToPrefixedFileW(null, dir_path);
-        return mkdirW(dir_path_w.span(), mode);
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return mkdir(mem.sliceTo(dir_path, 0), mode);
-    }
-    switch (errno(system.mkdir(dir_path, mode))) {
-        .SUCCESS => return,
-        .ACCES => return error.AccessDenied,
-        .PERM => return error.AccessDenied,
-        .DQUOT => return error.DiskQuota,
-        .EXIST => return error.PathAlreadyExists,
-        .FAULT => unreachable,
-        .LOOP => return error.SymLinkLoop,
-        .MLINK => return error.LinkQuotaExceeded,
-        .NAMETOOLONG => return error.NameTooLong,
-        .NOENT => return error.FileNotFound,
-        .NOMEM => return error.SystemResources,
-        .NOSPC => return error.NoSpaceLeft,
-        .NOTDIR => return error.NotDir,
-        .ROFS => return error.ReadOnlyFileSystem,
-        .ILSEQ => |err| if (builtin.os.tag == .wasi)
-            return error.InvalidUtf8
-        else
-            return unexpectedErrno(err),
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Windows-only. Same as `mkdir` but the parameters is WTF16LE encoded.
-pub fn mkdirW(dir_path_w: []const u16, mode: u32) MakeDirError!void {
-    _ = mode;
-    const sub_dir_handle = windows.OpenFile(dir_path_w, .{
-        .dir = std.fs.cwd().fd,
-        .access_mask = windows.GENERIC_READ | windows.SYNCHRONIZE,
-        .creation = windows.FILE_CREATE,
-        .filter = .dir_only,
-    }) catch |err| switch (err) {
-        error.IsDir => return error.Unexpected,
-        error.PipeBusy => return error.Unexpected,
-        error.WouldBlock => return error.Unexpected,
-        error.AntivirusInterference => return error.Unexpected,
-        else => |e| return e,
-    };
-    windows.CloseHandle(sub_dir_handle);
-}
-
-pub const DeleteDirError = error{
-    AccessDenied,
-    FileBusy,
-    SymLinkLoop,
-    NameTooLong,
-    FileNotFound,
-    SystemResources,
-    NotDir,
-    DirNotEmpty,
-    ReadOnlyFileSystem,
-    /// WASI-only; file paths must be valid UTF-8.
-    InvalidUtf8,
-    /// Windows-only; file paths provided by the user must be valid WTF-8.
-    /// https://simonsapin.github.io/wtf-8/
-    InvalidWtf8,
-    BadPathName,
-    /// On Windows, `\\server` or `\\server\share` was not found.
-    NetworkNotFound,
-} || UnexpectedError;
-
-/// Deletes an empty directory.
-/// On Windows, `dir_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// On WASI, `dir_path` should be encoded as valid UTF-8.
-/// On other platforms, `dir_path` is an opaque sequence of bytes with no particular encoding.
-pub fn rmdir(dir_path: []const u8) DeleteDirError!void {
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return unlinkat(wasi.AT.FDCWD, dir_path, AT.REMOVEDIR) catch |err| switch (err) {
-            error.FileSystem => unreachable, // only occurs when targeting files
-            error.IsDir => unreachable, // only occurs when targeting files
-            else => |e| return e,
-        };
-    } else if (builtin.os.tag == .windows) {
-        const dir_path_w = try windows.sliceToPrefixedFileW(null, dir_path);
-        return rmdirW(dir_path_w.span());
-    } else {
-        const dir_path_c = try toPosixPath(dir_path);
-        return rmdirZ(&dir_path_c);
-    }
-}
-
-/// Same as `rmdir` except the parameter is null-terminated.
-/// On Windows, `dir_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// On WASI, `dir_path` should be encoded as valid UTF-8.
-/// On other platforms, `dir_path` is an opaque sequence of bytes with no particular encoding.
-pub fn rmdirZ(dir_path: [*:0]const u8) DeleteDirError!void {
-    if (builtin.os.tag == .windows) {
-        const dir_path_w = try windows.cStrToPrefixedFileW(null, dir_path);
-        return rmdirW(dir_path_w.span());
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return rmdir(mem.sliceTo(dir_path, 0));
-    }
-    switch (errno(system.rmdir(dir_path))) {
-        .SUCCESS => return,
-        .ACCES => return error.AccessDenied,
-        .PERM => return error.AccessDenied,
-        .BUSY => return error.FileBusy,
-        .FAULT => unreachable,
-        .INVAL => return error.BadPathName,
-        .LOOP => return error.SymLinkLoop,
-        .NAMETOOLONG => return error.NameTooLong,
-        .NOENT => return error.FileNotFound,
-        .NOMEM => return error.SystemResources,
-        .NOTDIR => return error.NotDir,
-        .EXIST => return error.DirNotEmpty,
-        .NOTEMPTY => return error.DirNotEmpty,
-        .ROFS => return error.ReadOnlyFileSystem,
-        .ILSEQ => |err| if (builtin.os.tag == .wasi)
-            return error.InvalidUtf8
-        else
-            return unexpectedErrno(err),
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Windows-only. Same as `rmdir` except the parameter is WTF-16 LE encoded.
-pub fn rmdirW(dir_path_w: []const u16) DeleteDirError!void {
-    return windows.DeleteFile(dir_path_w, .{ .dir = std.fs.cwd().fd, .remove_dir = true }) catch |err| switch (err) {
-        error.IsDir => unreachable,
-        else => |e| return e,
-    };
-}
-
-pub const ChangeCurDirError = error{
-    AccessDenied,
-    FileSystem,
-    SymLinkLoop,
-    NameTooLong,
-    FileNotFound,
-    SystemResources,
-    NotDir,
-    BadPathName,
-    /// WASI-only; file paths must be valid UTF-8.
-    InvalidUtf8,
-    /// Windows-only; file paths provided by the user must be valid WTF-8.
-    /// https://simonsapin.github.io/wtf-8/
-    InvalidWtf8,
-} || UnexpectedError;
-
-/// Changes the current working directory of the calling process.
-/// On Windows, `dir_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// On WASI, `dir_path` should be encoded as valid UTF-8.
-/// On other platforms, `dir_path` is an opaque sequence of bytes with no particular encoding.
-pub fn chdir(dir_path: []const u8) ChangeCurDirError!void {
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        @compileError("WASI does not support os.chdir");
-    } else if (builtin.os.tag == .windows) {
-        var wtf16_dir_path: [windows.PATH_MAX_WIDE]u16 = undefined;
-        const len = try std.unicode.wtf8ToWtf16Le(wtf16_dir_path[0..], dir_path);
-        if (len > wtf16_dir_path.len) return error.NameTooLong;
-        return chdirW(wtf16_dir_path[0..len]);
-    } else {
-        const dir_path_c = try toPosixPath(dir_path);
-        return chdirZ(&dir_path_c);
-    }
-}
-
-/// Same as `chdir` except the parameter is null-terminated.
-/// On Windows, `dir_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// On WASI, `dir_path` should be encoded as valid UTF-8.
-/// On other platforms, `dir_path` is an opaque sequence of bytes with no particular encoding.
-pub fn chdirZ(dir_path: [*:0]const u8) ChangeCurDirError!void {
-    if (builtin.os.tag == .windows) {
-        var wtf16_dir_path: [windows.PATH_MAX_WIDE]u16 = undefined;
-        const len = try std.unicode.wtf8ToWtf16Le(wtf16_dir_path[0..], mem.span(dir_path));
-        if (len > wtf16_dir_path.len) return error.NameTooLong;
-        return chdirW(wtf16_dir_path[0..len]);
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return chdir(mem.span(dir_path));
-    }
-    switch (errno(system.chdir(dir_path))) {
-        .SUCCESS => return,
-        .ACCES => return error.AccessDenied,
-        .FAULT => unreachable,
-        .IO => return error.FileSystem,
-        .LOOP => return error.SymLinkLoop,
-        .NAMETOOLONG => return error.NameTooLong,
-        .NOENT => return error.FileNotFound,
-        .NOMEM => return error.SystemResources,
-        .NOTDIR => return error.NotDir,
-        .ILSEQ => |err| if (builtin.os.tag == .wasi)
-            return error.InvalidUtf8
-        else
-            return unexpectedErrno(err),
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Windows-only. Same as `chdir` except the parameter is WTF16 LE encoded.
-pub fn chdirW(dir_path: []const u16) ChangeCurDirError!void {
-    windows.SetCurrentDirectory(dir_path) catch |err| switch (err) {
-        error.NoDevice => return error.FileSystem,
-        else => |e| return e,
-    };
-}
-
-pub const FchdirError = error{
-    AccessDenied,
-    NotDir,
-    FileSystem,
-} || UnexpectedError;
-
-pub fn fchdir(dirfd: fd_t) FchdirError!void {
-    if (dirfd == AT.FDCWD) return;
-    while (true) {
-        switch (errno(system.fchdir(dirfd))) {
-            .SUCCESS => return,
-            .ACCES => return error.AccessDenied,
-            .BADF => unreachable,
-            .NOTDIR => return error.NotDir,
-            .INTR => continue,
-            .IO => return error.FileSystem,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-pub const ReadLinkError = error{
-    /// In WASI, this error may occur when the file descriptor does
-    /// not hold the required rights to read value of a symbolic link relative to it.
-    AccessDenied,
-    FileSystem,
-    SymLinkLoop,
-    NameTooLong,
-    FileNotFound,
-    SystemResources,
-    NotLink,
-    NotDir,
-    /// WASI-only; file paths must be valid UTF-8.
-    InvalidUtf8,
-    /// Windows-only; file paths provided by the user must be valid WTF-8.
-    /// https://simonsapin.github.io/wtf-8/
-    InvalidWtf8,
-    BadPathName,
-    /// Windows-only. This error may occur if the opened reparse point is
-    /// of unsupported type.
-    UnsupportedReparsePointType,
-    /// On Windows, `\\server` or `\\server\share` was not found.
-    NetworkNotFound,
-} || UnexpectedError;
-
-/// Read value of a symbolic link.
-/// On Windows, `file_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// 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.
-/// The return value is a slice of `out_buffer` from index 0.
-/// On Windows, the result is encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// On WASI, the result is encoded as UTF-8.
-/// On other platforms, the result is an opaque sequence of bytes with no particular encoding.
-pub fn readlink(file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 {
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return readlinkat(wasi.AT.FDCWD, file_path, out_buffer);
-    } else if (builtin.os.tag == .windows) {
-        const file_path_w = try windows.sliceToPrefixedFileW(null, file_path);
-        return readlinkW(file_path_w.span(), out_buffer);
-    } else {
-        const file_path_c = try toPosixPath(file_path);
-        return readlinkZ(&file_path_c, out_buffer);
-    }
-}
-
-/// Windows-only. Same as `readlink` except `file_path` is WTF16 LE encoded.
-/// The result is encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// See also `readlinkZ`.
-pub fn readlinkW(file_path: []const u16, out_buffer: []u8) ReadLinkError![]u8 {
-    return windows.ReadLink(std.fs.cwd().fd, file_path, out_buffer);
-}
-
-/// Same as `readlink` except `file_path` is null-terminated.
-pub fn readlinkZ(file_path: [*:0]const u8, out_buffer: []u8) ReadLinkError![]u8 {
-    if (builtin.os.tag == .windows) {
-        const file_path_w = try windows.cStrToPrefixedFileW(null, file_path);
-        return readlinkW(file_path_w.span(), out_buffer);
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return readlink(mem.sliceTo(file_path, 0), out_buffer);
-    }
-    const rc = system.readlink(file_path, out_buffer.ptr, out_buffer.len);
-    switch (errno(rc)) {
-        .SUCCESS => return out_buffer[0..@bitCast(rc)],
-        .ACCES => return error.AccessDenied,
-        .FAULT => unreachable,
-        .INVAL => return error.NotLink,
-        .IO => return error.FileSystem,
-        .LOOP => return error.SymLinkLoop,
-        .NAMETOOLONG => return error.NameTooLong,
-        .NOENT => return error.FileNotFound,
-        .NOMEM => return error.SystemResources,
-        .NOTDIR => return error.NotDir,
-        .ILSEQ => |err| if (builtin.os.tag == .wasi)
-            return error.InvalidUtf8
-        else
-            return unexpectedErrno(err),
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Similar to `readlink` except reads value of a symbolink link **relative** to `dirfd` directory handle.
-/// On Windows, `file_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// 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.
-/// The return value is a slice of `out_buffer` from index 0.
-/// On Windows, the result is encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// On WASI, the result is encoded as UTF-8.
-/// On other platforms, the result is an opaque sequence of bytes with no particular encoding.
-/// See also `readlinkatWasi`, `realinkatZ` and `realinkatW`.
-pub fn readlinkat(dirfd: fd_t, file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 {
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return readlinkatWasi(dirfd, file_path, out_buffer);
-    }
-    if (builtin.os.tag == .windows) {
-        const file_path_w = try windows.sliceToPrefixedFileW(dirfd, file_path);
-        return readlinkatW(dirfd, file_path_w.span(), out_buffer);
-    }
-    const file_path_c = try toPosixPath(file_path);
-    return readlinkatZ(dirfd, &file_path_c, out_buffer);
-}
-
-/// WASI-only. Same as `readlinkat` but targets WASI.
-/// See also `readlinkat`.
-pub fn readlinkatWasi(dirfd: fd_t, file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 {
-    var bufused: usize = undefined;
-    switch (wasi.path_readlink(dirfd, file_path.ptr, file_path.len, out_buffer.ptr, out_buffer.len, &bufused)) {
-        .SUCCESS => return out_buffer[0..bufused],
-        .ACCES => return error.AccessDenied,
-        .FAULT => unreachable,
-        .INVAL => return error.NotLink,
-        .IO => return error.FileSystem,
-        .LOOP => return error.SymLinkLoop,
-        .NAMETOOLONG => return error.NameTooLong,
-        .NOENT => return error.FileNotFound,
-        .NOMEM => return error.SystemResources,
-        .NOTDIR => return error.NotDir,
-        .NOTCAPABLE => return error.AccessDenied,
-        .ILSEQ => return error.InvalidUtf8,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Windows-only. Same as `readlinkat` except `file_path` is null-terminated, WTF16 LE encoded.
-/// The result is encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// See also `readlinkat`.
-pub fn readlinkatW(dirfd: fd_t, file_path: []const u16, out_buffer: []u8) ReadLinkError![]u8 {
-    return windows.ReadLink(dirfd, file_path, out_buffer);
-}
-
-/// Same as `readlinkat` except `file_path` is null-terminated.
-/// See also `readlinkat`.
-pub fn readlinkatZ(dirfd: fd_t, file_path: [*:0]const u8, out_buffer: []u8) ReadLinkError![]u8 {
-    if (builtin.os.tag == .windows) {
-        const file_path_w = try windows.cStrToPrefixedFileW(dirfd, file_path);
-        return readlinkatW(dirfd, file_path_w.span(), out_buffer);
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return readlinkat(dirfd, mem.sliceTo(file_path, 0), out_buffer);
-    }
-    const rc = system.readlinkat(dirfd, file_path, out_buffer.ptr, out_buffer.len);
-    switch (errno(rc)) {
-        .SUCCESS => return out_buffer[0..@bitCast(rc)],
-        .ACCES => return error.AccessDenied,
-        .FAULT => unreachable,
-        .INVAL => return error.NotLink,
-        .IO => return error.FileSystem,
-        .LOOP => return error.SymLinkLoop,
-        .NAMETOOLONG => return error.NameTooLong,
-        .NOENT => return error.FileNotFound,
-        .NOMEM => return error.SystemResources,
-        .NOTDIR => return error.NotDir,
-        .ILSEQ => |err| if (builtin.os.tag == .wasi)
-            return error.InvalidUtf8
-        else
-            return unexpectedErrno(err),
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub const SetEidError = error{
-    InvalidUserId,
-    PermissionDenied,
-} || UnexpectedError;
-
-pub const SetIdError = error{ResourceLimitReached} || SetEidError;
-
-pub fn setuid(uid: uid_t) SetIdError!void {
-    switch (errno(system.setuid(uid))) {
-        .SUCCESS => return,
-        .AGAIN => return error.ResourceLimitReached,
-        .INVAL => return error.InvalidUserId,
-        .PERM => return error.PermissionDenied,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub fn seteuid(uid: uid_t) SetEidError!void {
-    switch (errno(system.seteuid(uid))) {
-        .SUCCESS => return,
-        .INVAL => return error.InvalidUserId,
-        .PERM => return error.PermissionDenied,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub fn setreuid(ruid: uid_t, euid: uid_t) SetIdError!void {
-    switch (errno(system.setreuid(ruid, euid))) {
-        .SUCCESS => return,
-        .AGAIN => return error.ResourceLimitReached,
-        .INVAL => return error.InvalidUserId,
-        .PERM => return error.PermissionDenied,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub fn setgid(gid: gid_t) SetIdError!void {
-    switch (errno(system.setgid(gid))) {
-        .SUCCESS => return,
-        .AGAIN => return error.ResourceLimitReached,
-        .INVAL => return error.InvalidUserId,
-        .PERM => return error.PermissionDenied,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub fn setegid(uid: uid_t) SetEidError!void {
-    switch (errno(system.setegid(uid))) {
-        .SUCCESS => return,
-        .INVAL => return error.InvalidUserId,
-        .PERM => return error.PermissionDenied,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub fn setregid(rgid: gid_t, egid: gid_t) SetIdError!void {
-    switch (errno(system.setregid(rgid, egid))) {
-        .SUCCESS => return,
-        .AGAIN => return error.ResourceLimitReached,
-        .INVAL => return error.InvalidUserId,
-        .PERM => return error.PermissionDenied,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Test whether a file descriptor refers to a terminal.
-pub fn isatty(handle: fd_t) bool {
-    if (builtin.os.tag == .windows) {
-        if (isCygwinPty(handle))
-            return true;
-
-        var out: windows.DWORD = undefined;
-        return windows.kernel32.GetConsoleMode(handle, &out) != 0;
-    }
-    if (builtin.link_libc) {
-        return system.isatty(handle) != 0;
-    }
-    if (builtin.os.tag == .wasi) {
-        var statbuf: wasi.fdstat_t = undefined;
-        const err = wasi.fd_fdstat_get(handle, &statbuf);
-        if (err != .SUCCESS)
-            return false;
-
-        // A tty is a character device that we can't seek or tell on.
-        if (statbuf.fs_filetype != .CHARACTER_DEVICE)
-            return false;
-        if (statbuf.fs_rights_base.FD_SEEK or statbuf.fs_rights_base.FD_TELL)
-            return false;
-
-        return true;
-    }
-    if (builtin.os.tag == .linux) {
-        while (true) {
-            var wsz: linux.winsize = undefined;
-            const fd: usize = @bitCast(@as(isize, handle));
-            const rc = linux.syscall3(.ioctl, fd, linux.T.IOCGWINSZ, @intFromPtr(&wsz));
-            switch (linux.getErrno(rc)) {
-                .SUCCESS => return true,
-                .INTR => continue,
-                else => return false,
-            }
-        }
-    }
-    return system.isatty(handle) != 0;
-}
-
-pub fn isCygwinPty(handle: fd_t) bool {
-    if (builtin.os.tag != .windows) return false;
-
-    // If this is a MSYS2/cygwin pty, then it will be a named pipe with a name in one of these formats:
-    //   msys-[...]-ptyN-[...]
-    //   cygwin-[...]-ptyN-[...]
-    //
-    // Example: msys-1888ae32e00d56aa-pty0-to-master
-
-    // First, just check that the handle is a named pipe.
-    // This allows us to avoid the more costly NtQueryInformationFile call
-    // for handles that aren't named pipes.
-    {
-        var io_status: windows.IO_STATUS_BLOCK = undefined;
-        var device_info: windows.FILE_FS_DEVICE_INFORMATION = undefined;
-        const rc = windows.ntdll.NtQueryVolumeInformationFile(handle, &io_status, &device_info, @sizeOf(windows.FILE_FS_DEVICE_INFORMATION), .FileFsDeviceInformation);
-        switch (rc) {
-            .SUCCESS => {},
-            else => return false,
-        }
-        if (device_info.DeviceType != windows.FILE_DEVICE_NAMED_PIPE) return false;
-    }
-
-    const name_bytes_offset = @offsetOf(windows.FILE_NAME_INFO, "FileName");
-    // `NAME_MAX` UTF-16 code units (2 bytes each)
-    // Note: This buffer may not be long enough to handle *all* possible paths (PATH_MAX_WIDE would be necessary for that),
-    //       but because we only care about certain paths and we know they must be within a reasonable length,
-    //       we can use this smaller buffer and just return false on any error from NtQueryInformationFile.
-    const num_name_bytes = windows.MAX_PATH * 2;
-    var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = [_]u8{0} ** (name_bytes_offset + num_name_bytes);
-
-    var io_status_block: windows.IO_STATUS_BLOCK = undefined;
-    const rc = windows.ntdll.NtQueryInformationFile(handle, &io_status_block, &name_info_bytes, @intCast(name_info_bytes.len), .FileNameInformation);
-    switch (rc) {
-        .SUCCESS => {},
-        .INVALID_PARAMETER => unreachable,
-        else => return false,
-    }
-
-    const name_info: *const windows.FILE_NAME_INFO = @ptrCast(&name_info_bytes);
-    const name_bytes = name_info_bytes[name_bytes_offset .. name_bytes_offset + name_info.FileNameLength];
-    const name_wide = mem.bytesAsSlice(u16, name_bytes);
-    // Note: The name we get from NtQueryInformationFile will be prefixed with a '\', e.g. \msys-1888ae32e00d56aa-pty0-to-master
-    return (mem.startsWith(u16, name_wide, &[_]u16{ '\\', 'm', 's', 'y', 's', '-' }) or
-        mem.startsWith(u16, name_wide, &[_]u16{ '\\', 'c', 'y', 'g', 'w', 'i', 'n', '-' })) and
-        mem.indexOf(u16, name_wide, &[_]u16{ '-', 'p', 't', 'y' }) != null;
-}
-
-pub const SocketError = error{
-    /// Permission to create a socket of the specified type and/or
-    /// proโ€tocol is denied.
-    PermissionDenied,
-
-    /// The implementation does not support the specified address family.
-    AddressFamilyNotSupported,
-
-    /// Unknown protocol, or protocol family not available.
-    ProtocolFamilyNotAvailable,
-
-    /// The per-process limit on the number of open file descriptors has been reached.
-    ProcessFdQuotaExceeded,
-
-    /// The system-wide limit on the total number of open files has been reached.
-    SystemFdQuotaExceeded,
-
-    /// Insufficient memory is available. The socket cannot be created until sufficient
-    /// resources are freed.
-    SystemResources,
-
-    /// The protocol type or the specified protocol is not supported within this domain.
-    ProtocolNotSupported,
-
-    /// The socket type is not supported by the protocol.
-    SocketTypeNotSupported,
-} || UnexpectedError;
-
-pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t {
-    if (builtin.os.tag == .windows) {
-        // NOTE: windows translates the SOCK.NONBLOCK/SOCK.CLOEXEC flags into
-        // windows-analagous operations
-        const filtered_sock_type = socket_type & ~@as(u32, SOCK.NONBLOCK | SOCK.CLOEXEC);
-        const flags: u32 = if ((socket_type & SOCK.CLOEXEC) != 0)
-            windows.ws2_32.WSA_FLAG_NO_HANDLE_INHERIT
-        else
-            0;
-        const rc = try windows.WSASocketW(
-            @bitCast(domain),
-            @bitCast(filtered_sock_type),
-            @bitCast(protocol),
-            null,
-            0,
-            flags,
-        );
-        errdefer windows.closesocket(rc) catch unreachable;
-        if ((socket_type & SOCK.NONBLOCK) != 0) {
-            var mode: c_ulong = 1; // nonblocking
-            if (windows.ws2_32.SOCKET_ERROR == windows.ws2_32.ioctlsocket(rc, windows.ws2_32.FIONBIO, &mode)) {
-                switch (windows.ws2_32.WSAGetLastError()) {
-                    // have not identified any error codes that should be handled yet
-                    else => unreachable,
-                }
-            }
-        }
-        return rc;
-    }
-
-    const have_sock_flags = !builtin.target.isDarwin();
-    const filtered_sock_type = if (!have_sock_flags)
-        socket_type & ~@as(u32, SOCK.NONBLOCK | SOCK.CLOEXEC)
-    else
-        socket_type;
-    const rc = system.socket(domain, filtered_sock_type, protocol);
-    switch (errno(rc)) {
-        .SUCCESS => {
-            const fd: fd_t = @intCast(rc);
-            errdefer close(fd);
-            if (!have_sock_flags) {
-                try setSockFlags(fd, socket_type);
-            }
-            return fd;
-        },
-        .ACCES => return error.PermissionDenied,
-        .AFNOSUPPORT => return error.AddressFamilyNotSupported,
-        .INVAL => return error.ProtocolFamilyNotAvailable,
-        .MFILE => return error.ProcessFdQuotaExceeded,
-        .NFILE => return error.SystemFdQuotaExceeded,
-        .NOBUFS => return error.SystemResources,
-        .NOMEM => return error.SystemResources,
-        .PROTONOSUPPORT => return error.ProtocolNotSupported,
-        .PROTOTYPE => return error.SocketTypeNotSupported,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub const ShutdownError = error{
-    ConnectionAborted,
-
-    /// Connection was reset by peer, application should close socket as it is no longer usable.
-    ConnectionResetByPeer,
-    BlockingOperationInProgress,
-
-    /// The network subsystem has failed.
-    NetworkSubsystemFailed,
-
-    /// The socket is not connected (connection-oriented sockets only).
-    SocketNotConnected,
-    SystemResources,
-} || UnexpectedError;
-
-pub const ShutdownHow = enum { recv, send, both };
-
-/// Shutdown socket send/receive operations
-pub fn shutdown(sock: socket_t, how: ShutdownHow) ShutdownError!void {
-    if (builtin.os.tag == .windows) {
-        const result = windows.ws2_32.shutdown(sock, switch (how) {
-            .recv => windows.ws2_32.SD_RECEIVE,
-            .send => windows.ws2_32.SD_SEND,
-            .both => windows.ws2_32.SD_BOTH,
-        });
-        if (0 != result) switch (windows.ws2_32.WSAGetLastError()) {
-            .WSAECONNABORTED => return error.ConnectionAborted,
-            .WSAECONNRESET => return error.ConnectionResetByPeer,
-            .WSAEINPROGRESS => return error.BlockingOperationInProgress,
-            .WSAEINVAL => unreachable,
-            .WSAENETDOWN => return error.NetworkSubsystemFailed,
-            .WSAENOTCONN => return error.SocketNotConnected,
-            .WSAENOTSOCK => unreachable,
-            .WSANOTINITIALISED => unreachable,
-            else => |err| return windows.unexpectedWSAError(err),
-        };
-    } else {
-        const rc = system.shutdown(sock, switch (how) {
-            .recv => SHUT.RD,
-            .send => SHUT.WR,
-            .both => SHUT.RDWR,
-        });
-        switch (errno(rc)) {
-            .SUCCESS => return,
-            .BADF => unreachable,
-            .INVAL => unreachable,
-            .NOTCONN => return error.SocketNotConnected,
-            .NOTSOCK => unreachable,
-            .NOBUFS => return error.SystemResources,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-pub const BindError = error{
-    /// The address is protected, and the user is not the superuser.
-    /// For UNIX domain sockets: Search permission is denied on  a  component
-    /// of  the  path  prefix.
-    AccessDenied,
-
-    /// The given address is already in use, or in the case of Internet domain sockets,
-    /// The  port number was specified as zero in the socket
-    /// address structure, but, upon attempting to bind to  an  ephemeral  port,  it  was
-    /// determined  that  all  port  numbers in the ephemeral port range are currently in
-    /// use.  See the discussion of /proc/sys/net/ipv4/ip_local_port_range ip(7).
-    AddressInUse,
-
-    /// A nonexistent interface was requested or the requested address was not local.
-    AddressNotAvailable,
-
-    /// The address is not valid for the address family of socket.
-    AddressFamilyNotSupported,
-
-    /// Too many symbolic links were encountered in resolving addr.
-    SymLinkLoop,
-
-    /// addr is too long.
-    NameTooLong,
-
-    /// A component in the directory prefix of the socket pathname does not exist.
-    FileNotFound,
-
-    /// Insufficient kernel memory was available.
-    SystemResources,
-
-    /// A component of the path prefix is not a directory.
-    NotDir,
-
-    /// The socket inode would reside on a read-only filesystem.
-    ReadOnlyFileSystem,
-
-    /// The network subsystem has failed.
-    NetworkSubsystemFailed,
-
-    FileDescriptorNotASocket,
-
-    AlreadyBound,
-} || UnexpectedError;
-
-/// addr is `*const T` where T is one of the sockaddr
-pub fn bind(sock: socket_t, addr: *const sockaddr, len: socklen_t) BindError!void {
-    if (builtin.os.tag == .windows) {
-        const rc = windows.bind(sock, addr, len);
-        if (rc == windows.ws2_32.SOCKET_ERROR) {
-            switch (windows.ws2_32.WSAGetLastError()) {
-                .WSANOTINITIALISED => unreachable, // not initialized WSA
-                .WSAEACCES => return error.AccessDenied,
-                .WSAEADDRINUSE => return error.AddressInUse,
-                .WSAEADDRNOTAVAIL => return error.AddressNotAvailable,
-                .WSAENOTSOCK => return error.FileDescriptorNotASocket,
-                .WSAEFAULT => unreachable, // invalid pointers
-                .WSAEINVAL => return error.AlreadyBound,
-                .WSAENOBUFS => return error.SystemResources,
-                .WSAENETDOWN => return error.NetworkSubsystemFailed,
-                else => |err| return windows.unexpectedWSAError(err),
-            }
-            unreachable;
-        }
-        return;
-    } else {
-        const rc = system.bind(sock, addr, len);
-        switch (errno(rc)) {
-            .SUCCESS => return,
-            .ACCES, .PERM => return error.AccessDenied,
-            .ADDRINUSE => return error.AddressInUse,
-            .BADF => unreachable, // always a race condition if this error is returned
-            .INVAL => unreachable, // invalid parameters
-            .NOTSOCK => unreachable, // invalid `sockfd`
-            .AFNOSUPPORT => return error.AddressFamilyNotSupported,
-            .ADDRNOTAVAIL => return error.AddressNotAvailable,
-            .FAULT => unreachable, // invalid `addr` pointer
-            .LOOP => return error.SymLinkLoop,
-            .NAMETOOLONG => return error.NameTooLong,
-            .NOENT => return error.FileNotFound,
-            .NOMEM => return error.SystemResources,
-            .NOTDIR => return error.NotDir,
-            .ROFS => return error.ReadOnlyFileSystem,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-    unreachable;
-}
-
-pub const ListenError = error{
-    /// Another socket is already listening on the same port.
-    /// For Internet domain sockets, the  socket referred to by sockfd had not previously
-    /// been bound to an address and, upon attempting to bind it to an ephemeral port, it
-    /// was determined that all port numbers in the ephemeral port range are currently in
-    /// use.  See the discussion of /proc/sys/net/ipv4/ip_local_port_range in ip(7).
-    AddressInUse,
-
-    /// The file descriptor sockfd does not refer to a socket.
-    FileDescriptorNotASocket,
-
-    /// The socket is not of a type that supports the listen() operation.
-    OperationNotSupported,
-
-    /// The network subsystem has failed.
-    NetworkSubsystemFailed,
-
-    /// Ran out of system resources
-    /// On Windows it can either run out of socket descriptors or buffer space
-    SystemResources,
-
-    /// Already connected
-    AlreadyConnected,
-
-    /// Socket has not been bound yet
-    SocketNotBound,
-} || UnexpectedError;
-
-pub fn listen(sock: socket_t, backlog: u31) ListenError!void {
-    if (builtin.os.tag == .windows) {
-        const rc = windows.listen(sock, backlog);
-        if (rc == windows.ws2_32.SOCKET_ERROR) {
-            switch (windows.ws2_32.WSAGetLastError()) {
-                .WSANOTINITIALISED => unreachable, // not initialized WSA
-                .WSAENETDOWN => return error.NetworkSubsystemFailed,
-                .WSAEADDRINUSE => return error.AddressInUse,
-                .WSAEISCONN => return error.AlreadyConnected,
-                .WSAEINVAL => return error.SocketNotBound,
-                .WSAEMFILE, .WSAENOBUFS => return error.SystemResources,
-                .WSAENOTSOCK => return error.FileDescriptorNotASocket,
-                .WSAEOPNOTSUPP => return error.OperationNotSupported,
-                .WSAEINPROGRESS => unreachable,
-                else => |err| return windows.unexpectedWSAError(err),
-            }
-        }
-        return;
-    } else {
-        const rc = system.listen(sock, backlog);
-        switch (errno(rc)) {
-            .SUCCESS => return,
-            .ADDRINUSE => return error.AddressInUse,
-            .BADF => unreachable,
-            .NOTSOCK => return error.FileDescriptorNotASocket,
-            .OPNOTSUPP => return error.OperationNotSupported,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-pub const AcceptError = error{
-    ConnectionAborted,
-
-    /// The file descriptor sockfd does not refer to a socket.
-    FileDescriptorNotASocket,
-
-    /// The per-process limit on the number of open file descriptors has been reached.
-    ProcessFdQuotaExceeded,
-
-    /// The system-wide limit on the total number of open files has been reached.
-    SystemFdQuotaExceeded,
-
-    /// Not enough free memory.  This often means that the memory allocation  is  limited
-    /// by the socket buffer limits, not by the system memory.
-    SystemResources,
-
-    /// Socket is not listening for new connections.
-    SocketNotListening,
-
-    ProtocolFailure,
-
-    /// Firewall rules forbid connection.
-    BlockedByFirewall,
-
-    /// This error occurs when no global event loop is configured,
-    /// and accepting from the socket would block.
-    WouldBlock,
-
-    /// An incoming connection was indicated, but was subsequently terminated by the
-    /// remote peer prior to accepting the call.
-    ConnectionResetByPeer,
-
-    /// The network subsystem has failed.
-    NetworkSubsystemFailed,
-
-    /// The referenced socket is not a type that supports connection-oriented service.
-    OperationNotSupported,
-} || UnexpectedError;
-
-/// Accept a connection on a socket.
-/// If `sockfd` is opened in non blocking mode, the function will
-/// return error.WouldBlock when EAGAIN is received.
-pub fn accept(
-    /// This argument is a socket that has been created with `socket`, bound to a local address
-    /// with `bind`, and is listening for connections after a `listen`.
-    sock: socket_t,
-    /// This argument is a pointer to a sockaddr structure.  This structure is filled in with  the
-    /// address  of  the  peer  socket, as known to the communications layer.  The exact format of the
-    /// address returned addr is determined by the socket's address  family  (see  `socket`  and  the
-    /// respective  protocol  man  pages).
-    addr: ?*sockaddr,
-    /// This argument is a value-result argument: the caller must initialize it to contain  the
-    /// size (in bytes) of the structure pointed to by addr; on return it will contain the actual size
-    /// of the peer address.
-    ///
-    /// The returned address is truncated if the buffer provided is too small; in this  case,  `addr_size`
-    /// will return a value greater than was supplied to the call.
-    addr_size: ?*socklen_t,
-    /// The following values can be bitwise ORed in flags to obtain different behavior:
-    /// * `SOCK.NONBLOCK` - Set the `NONBLOCK` file status flag on the open file description (see `open`)
-    ///   referred  to by the new file descriptor.  Using this flag saves extra calls to `fcntl` to achieve
-    ///   the same result.
-    /// * `SOCK.CLOEXEC`  - Set the close-on-exec (`FD_CLOEXEC`) flag on the new file descriptor.   See  the
-    ///   description  of the `CLOEXEC` flag in `open` for reasons why this may be useful.
-    flags: u32,
-) AcceptError!socket_t {
-    const have_accept4 = !(builtin.target.isDarwin() or builtin.os.tag == .windows);
-    assert(0 == (flags & ~@as(u32, SOCK.NONBLOCK | SOCK.CLOEXEC))); // Unsupported flag(s)
-
-    const accepted_sock: socket_t = while (true) {
-        const rc = if (have_accept4)
-            system.accept4(sock, addr, addr_size, flags)
-        else if (builtin.os.tag == .windows)
-            windows.accept(sock, addr, addr_size)
-        else
-            system.accept(sock, addr, addr_size);
-
-        if (builtin.os.tag == .windows) {
-            if (rc == windows.ws2_32.INVALID_SOCKET) {
-                switch (windows.ws2_32.WSAGetLastError()) {
-                    .WSANOTINITIALISED => unreachable, // not initialized WSA
-                    .WSAECONNRESET => return error.ConnectionResetByPeer,
-                    .WSAEFAULT => unreachable,
-                    .WSAEINVAL => return error.SocketNotListening,
-                    .WSAEMFILE => return error.ProcessFdQuotaExceeded,
-                    .WSAENETDOWN => return error.NetworkSubsystemFailed,
-                    .WSAENOBUFS => return error.FileDescriptorNotASocket,
-                    .WSAEOPNOTSUPP => return error.OperationNotSupported,
-                    .WSAEWOULDBLOCK => return error.WouldBlock,
-                    else => |err| return windows.unexpectedWSAError(err),
-                }
-            } else {
-                break rc;
-            }
-        } else {
-            switch (errno(rc)) {
-                .SUCCESS => break @intCast(rc),
-                .INTR => continue,
-                .AGAIN => return error.WouldBlock,
-                .BADF => unreachable, // always a race condition
-                .CONNABORTED => return error.ConnectionAborted,
-                .FAULT => unreachable,
-                .INVAL => return error.SocketNotListening,
-                .NOTSOCK => unreachable,
-                .MFILE => return error.ProcessFdQuotaExceeded,
-                .NFILE => return error.SystemFdQuotaExceeded,
-                .NOBUFS => return error.SystemResources,
-                .NOMEM => return error.SystemResources,
-                .OPNOTSUPP => unreachable,
-                .PROTO => return error.ProtocolFailure,
-                .PERM => return error.BlockedByFirewall,
-                else => |err| return unexpectedErrno(err),
-            }
-        }
-    };
-
-    errdefer switch (builtin.os.tag) {
-        .windows => windows.closesocket(accepted_sock) catch unreachable,
-        else => close(accepted_sock),
-    };
-    if (!have_accept4) {
-        try setSockFlags(accepted_sock, flags);
-    }
-    return accepted_sock;
-}
-
-pub const EpollCreateError = error{
-    /// The  per-user   limit   on   the   number   of   epoll   instances   imposed   by
-    /// /proc/sys/fs/epoll/max_user_instances  was encountered.  See epoll(7) for further
-    /// details.
-    /// Or, The per-process limit on the number of open file descriptors has been reached.
-    ProcessFdQuotaExceeded,
-
-    /// The system-wide limit on the total number of open files has been reached.
-    SystemFdQuotaExceeded,
-
-    /// There was insufficient memory to create the kernel object.
-    SystemResources,
-} || UnexpectedError;
-
-pub fn epoll_create1(flags: u32) EpollCreateError!i32 {
-    const rc = system.epoll_create1(flags);
-    switch (errno(rc)) {
-        .SUCCESS => return @intCast(rc),
-        else => |err| return unexpectedErrno(err),
-
-        .INVAL => unreachable,
-        .MFILE => return error.ProcessFdQuotaExceeded,
-        .NFILE => return error.SystemFdQuotaExceeded,
-        .NOMEM => return error.SystemResources,
-    }
-}
-
-pub const EpollCtlError = error{
-    /// op was EPOLL_CTL_ADD, and the supplied file descriptor fd is  already  registered
-    /// with this epoll instance.
-    FileDescriptorAlreadyPresentInSet,
-
-    /// fd refers to an epoll instance and this EPOLL_CTL_ADD operation would result in a
-    /// circular loop of epoll instances monitoring one another.
-    OperationCausesCircularLoop,
-
-    /// op was EPOLL_CTL_MOD or EPOLL_CTL_DEL, and fd is not registered with  this  epoll
-    /// instance.
-    FileDescriptorNotRegistered,
-
-    /// There was insufficient memory to handle the requested op control operation.
-    SystemResources,
-
-    /// The  limit  imposed  by /proc/sys/fs/epoll/max_user_watches was encountered while
-    /// trying to register (EPOLL_CTL_ADD) a new file descriptor on  an  epoll  instance.
-    /// See epoll(7) for further details.
-    UserResourceLimitReached,
-
-    /// The target file fd does not support epoll.  This error can occur if fd refers to,
-    /// for example, a regular file or a directory.
-    FileDescriptorIncompatibleWithEpoll,
-} || UnexpectedError;
-
-pub fn epoll_ctl(epfd: i32, op: u32, fd: i32, event: ?*linux.epoll_event) EpollCtlError!void {
-    const rc = system.epoll_ctl(epfd, op, fd, event);
-    switch (errno(rc)) {
-        .SUCCESS => return,
-        else => |err| return unexpectedErrno(err),
-
-        .BADF => unreachable, // always a race condition if this happens
-        .EXIST => return error.FileDescriptorAlreadyPresentInSet,
-        .INVAL => unreachable,
-        .LOOP => return error.OperationCausesCircularLoop,
-        .NOENT => return error.FileDescriptorNotRegistered,
-        .NOMEM => return error.SystemResources,
-        .NOSPC => return error.UserResourceLimitReached,
-        .PERM => return error.FileDescriptorIncompatibleWithEpoll,
-    }
-}
-
-/// Waits for an I/O event on an epoll file descriptor.
-/// Returns the number of file descriptors ready for the requested I/O,
-/// or zero if no file descriptor became ready during the requested timeout milliseconds.
-pub fn epoll_wait(epfd: i32, events: []linux.epoll_event, timeout: i32) usize {
-    while (true) {
-        // TODO get rid of the @intCast
-        const rc = system.epoll_wait(epfd, events.ptr, @intCast(events.len), timeout);
-        switch (errno(rc)) {
-            .SUCCESS => return @intCast(rc),
-            .INTR => continue,
-            .BADF => unreachable,
-            .FAULT => unreachable,
-            .INVAL => unreachable,
-            else => unreachable,
-        }
-    }
-}
-
-pub const EventFdError = error{
-    SystemResources,
-    ProcessFdQuotaExceeded,
-    SystemFdQuotaExceeded,
-} || UnexpectedError;
-
-pub fn eventfd(initval: u32, flags: u32) EventFdError!i32 {
-    const rc = system.eventfd(initval, flags);
-    switch (errno(rc)) {
-        .SUCCESS => return @intCast(rc),
-        else => |err| return unexpectedErrno(err),
-
-        .INVAL => unreachable, // invalid parameters
-        .MFILE => return error.ProcessFdQuotaExceeded,
-        .NFILE => return error.SystemFdQuotaExceeded,
-        .NODEV => return error.SystemResources,
-        .NOMEM => return error.SystemResources,
-    }
-}
-
-pub const GetSockNameError = error{
-    /// Insufficient resources were available in the system to perform the operation.
-    SystemResources,
-
-    /// The network subsystem has failed.
-    NetworkSubsystemFailed,
-
-    /// Socket hasn't been bound yet
-    SocketNotBound,
-
-    FileDescriptorNotASocket,
-} || UnexpectedError;
-
-pub fn getsockname(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSockNameError!void {
-    if (builtin.os.tag == .windows) {
-        const rc = windows.getsockname(sock, addr, addrlen);
-        if (rc == windows.ws2_32.SOCKET_ERROR) {
-            switch (windows.ws2_32.WSAGetLastError()) {
-                .WSANOTINITIALISED => unreachable,
-                .WSAENETDOWN => return error.NetworkSubsystemFailed,
-                .WSAEFAULT => unreachable, // addr or addrlen have invalid pointers or addrlen points to an incorrect value
-                .WSAENOTSOCK => return error.FileDescriptorNotASocket,
-                .WSAEINVAL => return error.SocketNotBound,
-                else => |err| return windows.unexpectedWSAError(err),
-            }
-        }
-        return;
-    } else {
-        const rc = system.getsockname(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,
-        }
-    }
-}
-
-pub fn getpeername(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSockNameError!void {
-    if (builtin.os.tag == .windows) {
-        const rc = windows.getpeername(sock, addr, addrlen);
-        if (rc == windows.ws2_32.SOCKET_ERROR) {
-            switch (windows.ws2_32.WSAGetLastError()) {
-                .WSANOTINITIALISED => unreachable,
-                .WSAENETDOWN => return error.NetworkSubsystemFailed,
-                .WSAEFAULT => unreachable, // addr or addrlen have invalid pointers or addrlen points to an incorrect value
-                .WSAENOTSOCK => return error.FileDescriptorNotASocket,
-                .WSAEINVAL => return error.SocketNotBound,
-                else => |err| return windows.unexpectedWSAError(err),
-            }
-        }
-        return;
-    } else {
-        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,
-        }
-    }
-}
-
-pub const ConnectError = error{
-    /// For UNIX domain sockets, which are identified by pathname: Write permission is denied on  the  socket
-    /// file,  or  search  permission  is  denied  for  one of the directories in the path prefix.
-    /// or
-    /// The user tried to connect to a broadcast address without having the socket broadcast flag enabled  or
-    /// the connection request failed because of a local firewall rule.
-    PermissionDenied,
-
-    /// Local address is already in use.
-    AddressInUse,
-
-    /// (Internet  domain  sockets)  The  socket  referred  to  by sockfd had not previously been bound to an
-    /// address and, upon attempting to bind it to an ephemeral port, it was determined that all port numbers
-    /// in    the    ephemeral    port    range    are   currently   in   use.    See   the   discussion   of
-    /// /proc/sys/net/ipv4/ip_local_port_range in ip(7).
-    AddressNotAvailable,
-
-    /// The passed address didn't have the correct address family in its sa_family field.
-    AddressFamilyNotSupported,
-
-    /// Insufficient entries in the routing cache.
-    SystemResources,
-
-    /// A connect() on a stream socket found no one listening on the remote address.
-    ConnectionRefused,
-
-    /// Network is unreachable.
-    NetworkUnreachable,
-
-    /// Timeout  while  attempting  connection.   The server may be too busy to accept new connections.  Note
-    /// that for IP sockets the timeout may be very long when syncookies are enabled on the server.
-    ConnectionTimedOut,
-
-    /// This error occurs when no global event loop is configured,
-    /// and connecting to the socket would block.
-    WouldBlock,
-
-    /// The given path for the unix socket does not exist.
-    FileNotFound,
-
-    /// Connection was reset by peer before connect could complete.
-    ConnectionResetByPeer,
-
-    /// Socket is non-blocking and already has a pending connection in progress.
-    ConnectionPending,
-} || UnexpectedError;
-
-/// Initiate a connection on a socket.
-/// If `sockfd` is opened in non blocking mode, the function will
-/// return error.WouldBlock when EAGAIN or EINPROGRESS is received.
-pub fn connect(sock: socket_t, sock_addr: *const sockaddr, len: socklen_t) ConnectError!void {
-    if (builtin.os.tag == .windows) {
-        const rc = windows.ws2_32.connect(sock, sock_addr, @intCast(len));
-        if (rc == 0) return;
-        switch (windows.ws2_32.WSAGetLastError()) {
-            .WSAEADDRINUSE => return error.AddressInUse,
-            .WSAEADDRNOTAVAIL => return error.AddressNotAvailable,
-            .WSAECONNREFUSED => return error.ConnectionRefused,
-            .WSAECONNRESET => return error.ConnectionResetByPeer,
-            .WSAETIMEDOUT => return error.ConnectionTimedOut,
-            .WSAEHOSTUNREACH, // TODO: should we return NetworkUnreachable in this case as well?
-            .WSAENETUNREACH,
-            => return error.NetworkUnreachable,
-            .WSAEFAULT => unreachable,
-            .WSAEINVAL => unreachable,
-            .WSAEISCONN => unreachable,
-            .WSAENOTSOCK => unreachable,
-            .WSAEWOULDBLOCK => return error.WouldBlock,
-            .WSAEACCES => unreachable,
-            .WSAENOBUFS => return error.SystemResources,
-            .WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported,
-            else => |err| return windows.unexpectedWSAError(err),
-        }
-        return;
-    }
-
-    while (true) {
-        switch (errno(system.connect(sock, sock_addr, len))) {
-            .SUCCESS => return,
-            .ACCES => return error.PermissionDenied,
-            .PERM => return error.PermissionDenied,
-            .ADDRINUSE => return error.AddressInUse,
-            .ADDRNOTAVAIL => return error.AddressNotAvailable,
-            .AFNOSUPPORT => return error.AddressFamilyNotSupported,
-            .AGAIN, .INPROGRESS => return error.WouldBlock,
-            .ALREADY => return error.ConnectionPending,
-            .BADF => unreachable, // sockfd is not a valid open file descriptor.
-            .CONNREFUSED => return error.ConnectionRefused,
-            .CONNRESET => return error.ConnectionResetByPeer,
-            .FAULT => unreachable, // The socket structure address is outside the user's address space.
-            .INTR => continue,
-            .ISCONN => unreachable, // The socket is already connected.
-            .HOSTUNREACH => return error.NetworkUnreachable,
-            .NETUNREACH => return error.NetworkUnreachable,
-            .NOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
-            .PROTOTYPE => unreachable, // The socket type does not support the requested communications protocol.
-            .TIMEDOUT => return error.ConnectionTimedOut,
-            .NOENT => return error.FileNotFound, // Returned when socket is AF.UNIX and the given path does not exist.
-            .CONNABORTED => unreachable, // Tried to reuse socket that previously received error.ConnectionRefused.
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-pub fn getsockoptError(sockfd: fd_t) ConnectError!void {
-    var err_code: i32 = undefined;
-    var size: u32 = @sizeOf(u32);
-    const rc = system.getsockopt(sockfd, SOL.SOCKET, SO.ERROR, @ptrCast(&err_code), &size);
-    assert(size == 4);
-    switch (errno(rc)) {
-        .SUCCESS => switch (@as(E, @enumFromInt(err_code))) {
-            .SUCCESS => return,
-            .ACCES => return error.PermissionDenied,
-            .PERM => return error.PermissionDenied,
-            .ADDRINUSE => return error.AddressInUse,
-            .ADDRNOTAVAIL => return error.AddressNotAvailable,
-            .AFNOSUPPORT => return error.AddressFamilyNotSupported,
-            .AGAIN => return error.SystemResources,
-            .ALREADY => return error.ConnectionPending,
-            .BADF => unreachable, // sockfd is not a valid open file descriptor.
-            .CONNREFUSED => return error.ConnectionRefused,
-            .FAULT => unreachable, // The socket structure address is outside the user's address space.
-            .ISCONN => unreachable, // The socket is already connected.
-            .HOSTUNREACH => return error.NetworkUnreachable,
-            .NETUNREACH => return error.NetworkUnreachable,
-            .NOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
-            .PROTOTYPE => unreachable, // The socket type does not support the requested communications protocol.
-            .TIMEDOUT => return error.ConnectionTimedOut,
-            .CONNRESET => return error.ConnectionResetByPeer,
-            else => |err| return unexpectedErrno(err),
-        },
-        .BADF => unreachable, // The argument sockfd is not a valid file descriptor.
-        .FAULT => unreachable, // The address pointed to by optval or optlen is not in a valid part of the process address space.
-        .INVAL => unreachable,
-        .NOPROTOOPT => unreachable, // The option is unknown at the level indicated.
-        .NOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub const WaitPidResult = struct {
-    pid: pid_t,
-    status: u32,
-};
-
-/// Use this version of the `waitpid` wrapper if you spawned your child process using explicit
-/// `fork` and `execve` method.
-pub fn waitpid(pid: pid_t, flags: u32) WaitPidResult {
-    var status: if (builtin.link_libc) c_int else u32 = undefined;
-    while (true) {
-        const rc = system.waitpid(pid, &status, @intCast(flags));
-        switch (errno(rc)) {
-            .SUCCESS => return .{
-                .pid = @intCast(rc),
-                .status = @bitCast(status),
-            },
-            .INTR => continue,
-            .CHILD => unreachable, // The process specified does not exist. It would be a race condition to handle this error.
-            .INVAL => unreachable, // Invalid flags.
-            else => unreachable,
-        }
-    }
-}
-
-pub fn wait4(pid: pid_t, flags: u32, ru: ?*rusage) WaitPidResult {
-    var status: if (builtin.link_libc) c_int else u32 = undefined;
-    while (true) {
-        const rc = system.wait4(pid, &status, @intCast(flags), ru);
-        switch (errno(rc)) {
-            .SUCCESS => return .{
-                .pid = @intCast(rc),
-                .status = @bitCast(status),
-            },
-            .INTR => continue,
-            .CHILD => unreachable, // The process specified does not exist. It would be a race condition to handle this error.
-            .INVAL => unreachable, // Invalid flags.
-            else => unreachable,
-        }
-    }
-}
-
-pub const FStatError = error{
-    SystemResources,
-
-    /// In WASI, this error may occur when the file descriptor does
-    /// not hold the required rights to get its filestat information.
-    AccessDenied,
-} || UnexpectedError;
-
-/// Return information about a file descriptor.
-pub fn fstat(fd: fd_t) FStatError!Stat {
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return Stat.fromFilestat(try fstat_wasi(fd));
-    }
-    if (builtin.os.tag == .windows) {
-        @compileError("fstat is not yet implemented on Windows");
-    }
-
-    const fstat_sym = if (lfs64_abi) system.fstat64 else system.fstat;
-    var stat = mem.zeroes(Stat);
-    switch (errno(fstat_sym(fd, &stat))) {
-        .SUCCESS => return stat,
-        .INVAL => unreachable,
-        .BADF => unreachable, // Always a race condition.
-        .NOMEM => return error.SystemResources,
-        .ACCES => return error.AccessDenied,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub fn fstat_wasi(fd: fd_t) FStatError!wasi.filestat_t {
-    var stat: wasi.filestat_t = undefined;
-    switch (wasi.fd_filestat_get(fd, &stat)) {
-        .SUCCESS => return stat,
-        .INVAL => unreachable,
-        .BADF => unreachable, // Always a race condition.
-        .NOMEM => return error.SystemResources,
-        .ACCES => return error.AccessDenied,
-        .NOTCAPABLE => return error.AccessDenied,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub const FStatAtError = FStatError || error{
-    NameTooLong,
-    FileNotFound,
-    SymLinkLoop,
-    /// WASI-only; file paths must be valid UTF-8.
-    InvalidUtf8,
-};
-
-/// Similar to `fstat`, but returns stat of a resource pointed to by `pathname`
-/// which is relative to `dirfd` handle.
-/// On WASI, `pathname` should be encoded as valid UTF-8.
-/// On other platforms, `pathname` is an opaque sequence of bytes with no particular encoding.
-/// See also `fstatatZ` and `fstatat_wasi`.
-pub fn fstatat(dirfd: fd_t, pathname: []const u8, flags: u32) FStatAtError!Stat {
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        const filestat = try fstatat_wasi(dirfd, pathname, .{
-            .SYMLINK_FOLLOW = (flags & AT.SYMLINK_NOFOLLOW) == 0,
-        });
-        return Stat.fromFilestat(filestat);
-    } else if (builtin.os.tag == .windows) {
-        @compileError("fstatat is not yet implemented on Windows");
-    } else {
-        const pathname_c = try toPosixPath(pathname);
-        return fstatatZ(dirfd, &pathname_c, flags);
-    }
-}
-
-/// WASI-only. Same as `fstatat` but targeting WASI.
-/// `pathname` should be encoded as valid UTF-8.
-/// See also `fstatat`.
-pub fn fstatat_wasi(dirfd: fd_t, pathname: []const u8, flags: wasi.lookupflags_t) FStatAtError!wasi.filestat_t {
-    var stat: wasi.filestat_t = undefined;
-    switch (wasi.path_filestat_get(dirfd, flags, pathname.ptr, pathname.len, &stat)) {
-        .SUCCESS => return stat,
-        .INVAL => unreachable,
-        .BADF => unreachable, // Always a race condition.
-        .NOMEM => return error.SystemResources,
-        .ACCES => return error.AccessDenied,
-        .FAULT => unreachable,
-        .NAMETOOLONG => return error.NameTooLong,
-        .NOENT => return error.FileNotFound,
-        .NOTDIR => return error.FileNotFound,
-        .NOTCAPABLE => return error.AccessDenied,
-        .ILSEQ => return error.InvalidUtf8,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Same as `fstatat` but `pathname` is null-terminated.
-/// See also `fstatat`.
-pub fn fstatatZ(dirfd: fd_t, pathname: [*:0]const u8, flags: u32) FStatAtError!Stat {
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        const filestat = try fstatat_wasi(dirfd, mem.sliceTo(pathname, 0), .{
-            .SYMLINK_FOLLOW = (flags & AT.SYMLINK_NOFOLLOW) == 0,
-        });
-        return Stat.fromFilestat(filestat);
-    }
-
-    const fstatat_sym = if (lfs64_abi) system.fstatat64 else system.fstatat;
-    var stat = mem.zeroes(Stat);
-    switch (errno(fstatat_sym(dirfd, pathname, &stat, flags))) {
-        .SUCCESS => return stat,
-        .INVAL => unreachable,
-        .BADF => unreachable, // Always a race condition.
-        .NOMEM => return error.SystemResources,
-        .ACCES => return error.AccessDenied,
-        .PERM => return error.AccessDenied,
-        .FAULT => unreachable,
-        .NAMETOOLONG => return error.NameTooLong,
-        .LOOP => return error.SymLinkLoop,
-        .NOENT => return error.FileNotFound,
-        .NOTDIR => return error.FileNotFound,
-        .ILSEQ => |err| if (builtin.os.tag == .wasi)
-            return error.InvalidUtf8
-        else
-            return unexpectedErrno(err),
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub const KQueueError = error{
-    /// The per-process limit on the number of open file descriptors has been reached.
-    ProcessFdQuotaExceeded,
-
-    /// The system-wide limit on the total number of open files has been reached.
-    SystemFdQuotaExceeded,
-} || UnexpectedError;
-
-pub fn kqueue() KQueueError!i32 {
-    const rc = system.kqueue();
-    switch (errno(rc)) {
-        .SUCCESS => return @intCast(rc),
-        .MFILE => return error.ProcessFdQuotaExceeded,
-        .NFILE => return error.SystemFdQuotaExceeded,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub const KEventError = error{
-    /// The process does not have permission to register a filter.
-    AccessDenied,
-
-    /// The event could not be found to be modified or deleted.
-    EventNotFound,
-
-    /// No memory was available to register the event.
-    SystemResources,
-
-    /// The specified process to attach to does not exist.
-    ProcessNotFound,
-
-    /// changelist or eventlist had too many items on it.
-    /// TODO remove this possibility
-    Overflow,
-};
-
-pub fn kevent(
-    kq: i32,
-    changelist: []const Kevent,
-    eventlist: []Kevent,
-    timeout: ?*const timespec,
-) KEventError!usize {
-    while (true) {
-        const rc = system.kevent(
-            kq,
-            changelist.ptr,
-            math.cast(c_int, changelist.len) orelse return error.Overflow,
-            eventlist.ptr,
-            math.cast(c_int, eventlist.len) orelse return error.Overflow,
-            timeout,
-        );
-        switch (errno(rc)) {
-            .SUCCESS => return @intCast(rc),
-            .ACCES => return error.AccessDenied,
-            .FAULT => unreachable,
-            .BADF => unreachable, // Always a race condition.
-            .INTR => continue,
-            .INVAL => unreachable,
-            .NOENT => return error.EventNotFound,
-            .NOMEM => return error.SystemResources,
-            .SRCH => return error.ProcessNotFound,
-            else => unreachable,
-        }
-    }
-}
-
-pub const INotifyInitError = error{
-    ProcessFdQuotaExceeded,
-    SystemFdQuotaExceeded,
-    SystemResources,
-} || UnexpectedError;
-
-/// initialize an inotify instance
-pub fn inotify_init1(flags: u32) INotifyInitError!i32 {
-    const rc = system.inotify_init1(flags);
-    switch (errno(rc)) {
-        .SUCCESS => return @intCast(rc),
-        .INVAL => unreachable,
-        .MFILE => return error.ProcessFdQuotaExceeded,
-        .NFILE => return error.SystemFdQuotaExceeded,
-        .NOMEM => return error.SystemResources,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub const INotifyAddWatchError = error{
-    AccessDenied,
-    NameTooLong,
-    FileNotFound,
-    SystemResources,
-    UserResourceLimitReached,
-    NotDir,
-    WatchAlreadyExists,
-} || UnexpectedError;
-
-/// add a watch to an initialized inotify instance
-pub fn inotify_add_watch(inotify_fd: i32, pathname: []const u8, mask: u32) INotifyAddWatchError!i32 {
-    const pathname_c = try toPosixPath(pathname);
-    return inotify_add_watchZ(inotify_fd, &pathname_c, mask);
-}
-
-/// Same as `inotify_add_watch` except pathname is null-terminated.
-pub fn inotify_add_watchZ(inotify_fd: i32, pathname: [*:0]const u8, mask: u32) INotifyAddWatchError!i32 {
-    const rc = system.inotify_add_watch(inotify_fd, pathname, mask);
-    switch (errno(rc)) {
-        .SUCCESS => return @intCast(rc),
-        .ACCES => return error.AccessDenied,
-        .BADF => unreachable,
-        .FAULT => unreachable,
-        .INVAL => unreachable,
-        .NAMETOOLONG => return error.NameTooLong,
-        .NOENT => return error.FileNotFound,
-        .NOMEM => return error.SystemResources,
-        .NOSPC => return error.UserResourceLimitReached,
-        .NOTDIR => return error.NotDir,
-        .EXIST => return error.WatchAlreadyExists,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// remove an existing watch from an inotify instance
-pub fn inotify_rm_watch(inotify_fd: i32, wd: i32) void {
-    switch (errno(system.inotify_rm_watch(inotify_fd, wd))) {
-        .SUCCESS => return,
-        .BADF => unreachable,
-        .INVAL => unreachable,
-        else => unreachable,
-    }
-}
-
-pub const FanotifyInitError = error{
-    ProcessFdQuotaExceeded,
-    SystemFdQuotaExceeded,
-    SystemResources,
-    OperationNotSupported,
-    PermissionDenied,
-} || UnexpectedError;
-
-pub fn fanotify_init(flags: u32, event_f_flags: u32) FanotifyInitError!i32 {
-    const rc = system.fanotify_init(flags, event_f_flags);
-    switch (errno(rc)) {
-        .SUCCESS => return @intCast(rc),
-        .INVAL => unreachable,
-        .MFILE => return error.ProcessFdQuotaExceeded,
-        .NFILE => return error.SystemFdQuotaExceeded,
-        .NOMEM => return error.SystemResources,
-        .NOSYS => return error.OperationNotSupported,
-        .PERM => return error.PermissionDenied,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub const FanotifyMarkError = error{
-    MarkAlreadyExists,
-    IsDir,
-    NotAssociatedWithFileSystem,
-    FileNotFound,
-    SystemResources,
-    UserMarkQuotaExceeded,
-    NotImplemented,
-    NotDir,
-    OperationNotSupported,
-    PermissionDenied,
-    NotSameFileSystem,
-    NameTooLong,
-} || UnexpectedError;
-
-pub fn fanotify_mark(fanotify_fd: i32, flags: u32, mask: u64, dirfd: i32, pathname: ?[]const u8) FanotifyMarkError!void {
-    if (pathname) |path| {
-        const path_c = try toPosixPath(path);
-        return fanotify_markZ(fanotify_fd, flags, mask, dirfd, &path_c);
-    }
-
-    return fanotify_markZ(fanotify_fd, flags, mask, dirfd, null);
-}
-
-pub fn fanotify_markZ(fanotify_fd: i32, flags: u32, mask: u64, dirfd: i32, pathname: ?[*:0]const u8) FanotifyMarkError!void {
-    const rc = system.fanotify_mark(fanotify_fd, flags, mask, dirfd, pathname);
-    switch (errno(rc)) {
-        .SUCCESS => return,
-        .BADF => unreachable,
-        .EXIST => return error.MarkAlreadyExists,
-        .INVAL => unreachable,
-        .ISDIR => return error.IsDir,
-        .NODEV => return error.NotAssociatedWithFileSystem,
-        .NOENT => return error.FileNotFound,
-        .NOMEM => return error.SystemResources,
-        .NOSPC => return error.UserMarkQuotaExceeded,
-        .NOSYS => return error.NotImplemented,
-        .NOTDIR => return error.NotDir,
-        .OPNOTSUPP => return error.OperationNotSupported,
-        .PERM => return error.PermissionDenied,
-        .XDEV => return error.NotSameFileSystem,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub const MProtectError = error{
-    /// The memory cannot be given the specified access.  This can happen, for example, if you
-    /// mmap(2)  a  file  to  which  you have read-only access, then ask mprotect() to mark it
-    /// PROT_WRITE.
-    AccessDenied,
-
-    /// Changing  the  protection  of a memory region would result in the total number of mapโ€
-    /// pings with distinct attributes (e.g., read versus read/write protection) exceeding the
-    /// allowed maximum.  (For example, making the protection of a range PROT_READ in the midโ€
-    /// dle of a region currently protected as PROT_READ|PROT_WRITE would result in three mapโ€
-    /// pings: two read/write mappings at each end and a read-only mapping in the middle.)
-    OutOfMemory,
-} || UnexpectedError;
-
-/// `memory.len` must be page-aligned.
-pub fn mprotect(memory: []align(mem.page_size) u8, protection: u32) MProtectError!void {
-    assert(mem.isAligned(memory.len, mem.page_size));
-    if (builtin.os.tag == .windows) {
-        const win_prot: windows.DWORD = switch (@as(u3, @truncate(protection))) {
-            0b000 => windows.PAGE_NOACCESS,
-            0b001 => windows.PAGE_READONLY,
-            0b010 => unreachable, // +w -r not allowed
-            0b011 => windows.PAGE_READWRITE,
-            0b100 => windows.PAGE_EXECUTE,
-            0b101 => windows.PAGE_EXECUTE_READ,
-            0b110 => unreachable, // +w -r not allowed
-            0b111 => windows.PAGE_EXECUTE_READWRITE,
-        };
-        var old: windows.DWORD = undefined;
-        windows.VirtualProtect(memory.ptr, memory.len, win_prot, &old) catch |err| switch (err) {
-            error.InvalidAddress => return error.AccessDenied,
-            error.Unexpected => return error.Unexpected,
-        };
-    } else {
-        switch (errno(system.mprotect(memory.ptr, memory.len, protection))) {
-            .SUCCESS => return,
-            .INVAL => unreachable,
-            .ACCES => return error.AccessDenied,
-            .NOMEM => return error.OutOfMemory,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-pub const ForkError = error{SystemResources} || UnexpectedError;
-
-pub fn fork() ForkError!pid_t {
-    const rc = system.fork();
-    switch (errno(rc)) {
-        .SUCCESS => return @intCast(rc),
-        .AGAIN => return error.SystemResources,
-        .NOMEM => return error.SystemResources,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub const MMapError = error{
-    /// The underlying filesystem of the specified file does not support memory mapping.
-    MemoryMappingNotSupported,
-
-    /// A file descriptor refers to a non-regular file. Or a file mapping was requested,
-    /// but the file descriptor is not open for reading. Or `MAP.SHARED` was requested
-    /// and `PROT_WRITE` is set, but the file descriptor is not open in `RDWR` mode.
-    /// Or `PROT_WRITE` is set, but the file is append-only.
-    AccessDenied,
-
-    /// The `prot` argument asks for `PROT_EXEC` but the mapped area belongs to a file on
-    /// a filesystem that was mounted no-exec.
-    PermissionDenied,
-    LockedMemoryLimitExceeded,
-    ProcessFdQuotaExceeded,
-    SystemFdQuotaExceeded,
-    OutOfMemory,
-} || UnexpectedError;
-
-/// Map files or devices into memory.
-/// `length` does not need to be aligned.
-/// Use of a mapped region can result in these signals:
-/// * SIGSEGV - Attempted write into a region mapped as read-only.
-/// * SIGBUS - Attempted  access to a portion of the buffer that does not correspond to the file
-pub fn mmap(
-    ptr: ?[*]align(mem.page_size) u8,
-    length: usize,
-    prot: u32,
-    flags: system.MAP,
-    fd: fd_t,
-    offset: u64,
-) MMapError![]align(mem.page_size) u8 {
-    const mmap_sym = if (lfs64_abi) system.mmap64 else system.mmap;
-    const rc = mmap_sym(ptr, length, prot, @bitCast(flags), fd, @bitCast(offset));
-    const err: E = if (builtin.link_libc) blk: {
-        if (rc != std.c.MAP_FAILED) return @as([*]align(mem.page_size) u8, @ptrCast(@alignCast(rc)))[0..length];
-        break :blk @enumFromInt(system._errno().*);
-    } else blk: {
-        const err = errno(rc);
-        if (err == .SUCCESS) return @as([*]align(mem.page_size) u8, @ptrFromInt(rc))[0..length];
-        break :blk err;
-    };
-    switch (err) {
-        .SUCCESS => unreachable,
-        .TXTBSY => return error.AccessDenied,
-        .ACCES => return error.AccessDenied,
-        .PERM => return error.PermissionDenied,
-        .AGAIN => return error.LockedMemoryLimitExceeded,
-        .BADF => unreachable, // Always a race condition.
-        .OVERFLOW => unreachable, // The number of pages used for length + offset would overflow.
-        .NODEV => return error.MemoryMappingNotSupported,
-        .INVAL => unreachable, // Invalid parameters to mmap()
-        .MFILE => return error.ProcessFdQuotaExceeded,
-        .NFILE => return error.SystemFdQuotaExceeded,
-        .NOMEM => return error.OutOfMemory,
-        else => return unexpectedErrno(err),
-    }
-}
-
-/// Deletes the mappings for the specified address range, causing
-/// further references to addresses within the range to generate invalid memory references.
-/// Note that while POSIX allows unmapping a region in the middle of an existing mapping,
-/// Zig's munmap function does not, for two reasons:
-/// * It violates the Zig principle that resource deallocation must succeed.
-/// * The Windows function, VirtualFree, has this restriction.
-pub fn munmap(memory: []align(mem.page_size) const u8) void {
-    switch (errno(system.munmap(memory.ptr, memory.len))) {
-        .SUCCESS => return,
-        .INVAL => unreachable, // Invalid parameters.
-        .NOMEM => unreachable, // Attempted to unmap a region in the middle of an existing mapping.
-        else => unreachable,
-    }
-}
-
-pub const MSyncError = error{
-    UnmappedMemory,
-} || UnexpectedError;
-
-pub fn msync(memory: []align(mem.page_size) u8, flags: i32) MSyncError!void {
-    switch (errno(system.msync(memory.ptr, memory.len, flags))) {
-        .SUCCESS => return,
-        .NOMEM => return error.UnmappedMemory, // Unsuccessful, provided pointer does not point mapped memory
-        .INVAL => unreachable, // Invalid parameters.
-        else => unreachable,
-    }
-}
-
-pub const AccessError = error{
-    PermissionDenied,
-    FileNotFound,
-    NameTooLong,
-    InputOutput,
-    SystemResources,
-    BadPathName,
-    FileBusy,
-    SymLinkLoop,
-    ReadOnlyFileSystem,
-    /// WASI-only; file paths must be valid UTF-8.
-    InvalidUtf8,
-    /// Windows-only; file paths provided by the user must be valid WTF-8.
-    /// https://simonsapin.github.io/wtf-8/
-    InvalidWtf8,
-} || UnexpectedError;
-
-/// check user's permissions for a file
-/// On Windows, `path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// On WASI, `path` should be encoded as valid UTF-8.
-/// On other platforms, `path` is an opaque sequence of bytes with no particular encoding.
-/// TODO currently this assumes `mode` is `F.OK` on Windows.
-pub fn access(path: []const u8, mode: u32) AccessError!void {
-    if (builtin.os.tag == .windows) {
-        const path_w = windows.sliceToPrefixedFileW(null, path) catch |err| switch (err) {
-            error.AccessDenied => return error.PermissionDenied,
-            else => |e| return e,
-        };
-        _ = try windows.GetFileAttributesW(path_w.span().ptr);
-        return;
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return faccessat(wasi.AT.FDCWD, path, mode, 0);
-    }
-    const path_c = try toPosixPath(path);
-    return accessZ(&path_c, mode);
-}
-
-/// Same as `access` except `path` is null-terminated.
-pub fn accessZ(path: [*:0]const u8, mode: u32) AccessError!void {
-    if (builtin.os.tag == .windows) {
-        const path_w = windows.cStrToPrefixedFileW(null, path) catch |err| switch (err) {
-            error.AccessDenied => return error.PermissionDenied,
-            else => |e| return e,
-        };
-        _ = try windows.GetFileAttributesW(path_w.span().ptr);
-        return;
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return access(mem.sliceTo(path, 0), mode);
-    }
-    switch (errno(system.access(path, mode))) {
-        .SUCCESS => return,
-        .ACCES => return error.PermissionDenied,
-        .ROFS => return error.ReadOnlyFileSystem,
-        .LOOP => return error.SymLinkLoop,
-        .TXTBSY => return error.FileBusy,
-        .NOTDIR => return error.FileNotFound,
-        .NOENT => return error.FileNotFound,
-        .NAMETOOLONG => return error.NameTooLong,
-        .INVAL => unreachable,
-        .FAULT => unreachable,
-        .IO => return error.InputOutput,
-        .NOMEM => return error.SystemResources,
-        .ILSEQ => |err| if (builtin.os.tag == .wasi)
-            return error.InvalidUtf8
-        else
-            return unexpectedErrno(err),
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Call from Windows-specific code if you already have a WTF-16LE encoded, null terminated string.
-/// Otherwise use `access` or `accessZ`.
-/// TODO currently this ignores `mode`.
-pub fn accessW(path: [*:0]const u16, mode: u32) windows.GetFileAttributesError!void {
-    _ = mode;
-    const ret = try windows.GetFileAttributesW(path);
-    if (ret != windows.INVALID_FILE_ATTRIBUTES) {
-        return;
-    }
-    switch (windows.kernel32.GetLastError()) {
-        .FILE_NOT_FOUND => return error.FileNotFound,
-        .PATH_NOT_FOUND => return error.FileNotFound,
-        .ACCESS_DENIED => return error.PermissionDenied,
-        else => |err| return windows.unexpectedError(err),
-    }
-}
-
-/// Check user's permissions for a file, based on an open directory handle.
-/// On Windows, `path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// On WASI, `path` should be encoded as valid UTF-8.
-/// On other platforms, `path` is an opaque sequence of bytes with no particular encoding.
-/// TODO currently this ignores `mode` and `flags` on Windows.
-pub fn faccessat(dirfd: fd_t, path: []const u8, mode: u32, flags: u32) AccessError!void {
-    if (builtin.os.tag == .windows) {
-        const path_w = try windows.sliceToPrefixedFileW(dirfd, path);
-        return faccessatW(dirfd, path_w.span().ptr, mode, flags);
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        const resolved: RelativePathWasi = .{ .dir_fd = dirfd, .relative_path = path };
-
-        const st = blk: {
-            break :blk fstatat_wasi(dirfd, path, .{
-                .SYMLINK_FOLLOW = (flags & AT.SYMLINK_NOFOLLOW) == 0,
-            });
-        } catch |err| switch (err) {
-            error.AccessDenied => return error.PermissionDenied,
-            else => |e| return e,
-        };
-
-        if (mode != F_OK) {
-            var directory: wasi.fdstat_t = undefined;
-            if (wasi.fd_fdstat_get(resolved.dir_fd, &directory) != .SUCCESS) {
-                return error.PermissionDenied;
-            }
-
-            var rights: wasi.rights_t = .{};
-            if (mode & R_OK != 0) {
-                if (st.filetype == .DIRECTORY) {
-                    rights.FD_READDIR = true;
-                } else {
-                    rights.FD_READ = true;
-                }
-            }
-            if (mode & W_OK != 0) {
-                rights.FD_WRITE = true;
-            }
-            // No validation for X_OK
-
-            // https://github.com/ziglang/zig/issues/18882
-            const rights_int: u64 = @bitCast(rights);
-            const inheriting_int: u64 = @bitCast(directory.fs_rights_inheriting);
-            if ((rights_int & inheriting_int) != rights_int) {
-                return error.PermissionDenied;
-            }
-        }
-        return;
-    }
-    const path_c = try toPosixPath(path);
-    return faccessatZ(dirfd, &path_c, mode, flags);
-}
-
-/// Same as `faccessat` except the path parameter is null-terminated.
-pub fn faccessatZ(dirfd: fd_t, path: [*:0]const u8, mode: u32, flags: u32) AccessError!void {
-    if (builtin.os.tag == .windows) {
-        const path_w = try windows.cStrToPrefixedFileW(dirfd, path);
-        return faccessatW(dirfd, path_w.span().ptr, mode, flags);
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return faccessat(dirfd, mem.sliceTo(path, 0), mode, flags);
-    }
-    switch (errno(system.faccessat(dirfd, path, mode, flags))) {
-        .SUCCESS => return,
-        .ACCES => return error.PermissionDenied,
-        .ROFS => return error.ReadOnlyFileSystem,
-        .LOOP => return error.SymLinkLoop,
-        .TXTBSY => return error.FileBusy,
-        .NOTDIR => return error.FileNotFound,
-        .NOENT => return error.FileNotFound,
-        .NAMETOOLONG => return error.NameTooLong,
-        .INVAL => unreachable,
-        .FAULT => unreachable,
-        .IO => return error.InputOutput,
-        .NOMEM => return error.SystemResources,
-        .ILSEQ => |err| if (builtin.os.tag == .wasi)
-            return error.InvalidUtf8
-        else
-            return unexpectedErrno(err),
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Same as `faccessat` except asserts the target is Windows and the path parameter
-/// is NtDll-prefixed, null-terminated, WTF-16 encoded.
-/// TODO currently this ignores `mode` and `flags`
-pub fn faccessatW(dirfd: fd_t, sub_path_w: [*:0]const u16, mode: u32, flags: u32) AccessError!void {
-    _ = mode;
-    _ = flags;
-    if (sub_path_w[0] == '.' and sub_path_w[1] == 0) {
-        return;
-    }
-    if (sub_path_w[0] == '.' and sub_path_w[1] == '.' and sub_path_w[2] == 0) {
-        return;
-    }
-
-    const path_len_bytes = math.cast(u16, mem.sliceTo(sub_path_w, 0).len * 2) orelse return error.NameTooLong;
-    var nt_name = windows.UNICODE_STRING{
-        .Length = path_len_bytes,
-        .MaximumLength = path_len_bytes,
-        .Buffer = @constCast(sub_path_w),
-    };
-    var attr = windows.OBJECT_ATTRIBUTES{
-        .Length = @sizeOf(windows.OBJECT_ATTRIBUTES),
-        .RootDirectory = if (std.fs.path.isAbsoluteWindowsW(sub_path_w)) null else dirfd,
-        .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here.
-        .ObjectName = &nt_name,
-        .SecurityDescriptor = null,
-        .SecurityQualityOfService = null,
-    };
-    var basic_info: windows.FILE_BASIC_INFORMATION = undefined;
-    switch (windows.ntdll.NtQueryAttributesFile(&attr, &basic_info)) {
-        .SUCCESS => return,
-        .OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
-        .OBJECT_PATH_NOT_FOUND => return error.FileNotFound,
-        .OBJECT_NAME_INVALID => unreachable,
-        .INVALID_PARAMETER => unreachable,
-        .ACCESS_DENIED => return error.PermissionDenied,
-        .OBJECT_PATH_SYNTAX_BAD => unreachable,
-        else => |rc| return windows.unexpectedStatus(rc),
-    }
-}
-
-pub const PipeError = error{
-    SystemFdQuotaExceeded,
-    ProcessFdQuotaExceeded,
-} || UnexpectedError;
-
-/// Creates a unidirectional data channel that can be used for interprocess communication.
-pub fn pipe() PipeError![2]fd_t {
-    var fds: [2]fd_t = undefined;
-    switch (errno(system.pipe(&fds))) {
-        .SUCCESS => return fds,
-        .INVAL => unreachable, // Invalid parameters to pipe()
-        .FAULT => unreachable, // Invalid fds pointer
-        .NFILE => return error.SystemFdQuotaExceeded,
-        .MFILE => return error.ProcessFdQuotaExceeded,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub fn pipe2(flags: O) PipeError![2]fd_t {
-    if (@hasDecl(system, "pipe2")) {
-        var fds: [2]fd_t = undefined;
-        switch (errno(system.pipe2(&fds, flags))) {
-            .SUCCESS => return fds,
-            .INVAL => unreachable, // Invalid flags
-            .FAULT => unreachable, // Invalid fds pointer
-            .NFILE => return error.SystemFdQuotaExceeded,
-            .MFILE => return error.ProcessFdQuotaExceeded,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-
-    const fds: [2]fd_t = try pipe();
-    errdefer {
-        close(fds[0]);
-        close(fds[1]);
-    }
-
-    // https://github.com/ziglang/zig/issues/18882
-    if (@as(u32, @bitCast(flags)) == 0)
-        return fds;
-
-    // CLOEXEC is special, it's a file descriptor flag and must be set using
-    // F.SETFD.
-    if (flags.CLOEXEC) {
-        for (fds) |fd| {
-            switch (errno(system.fcntl(fd, F.SETFD, @as(u32, FD_CLOEXEC)))) {
-                .SUCCESS => {},
-                .INVAL => unreachable, // Invalid flags
-                .BADF => unreachable, // Always a race condition
-                else => |err| return unexpectedErrno(err),
-            }
-        }
-    }
-
-    const new_flags: u32 = f: {
-        var new_flags = flags;
-        new_flags.CLOEXEC = false;
-        break :f @bitCast(new_flags);
-    };
-    // Set every other flag affecting the file status using F.SETFL.
-    if (new_flags != 0) {
-        for (fds) |fd| {
-            switch (errno(system.fcntl(fd, F.SETFL, new_flags))) {
-                .SUCCESS => {},
-                .INVAL => unreachable, // Invalid flags
-                .BADF => unreachable, // Always a race condition
-                else => |err| return unexpectedErrno(err),
-            }
-        }
-    }
-
-    return fds;
-}
-
-pub const SysCtlError = error{
-    PermissionDenied,
-    SystemResources,
-    NameTooLong,
-    UnknownName,
-} || UnexpectedError;
-
-pub fn sysctl(
-    name: []const c_int,
-    oldp: ?*anyopaque,
-    oldlenp: ?*usize,
-    newp: ?*anyopaque,
-    newlen: usize,
-) SysCtlError!void {
-    if (builtin.os.tag == .wasi) {
-        @panic("unsupported"); // TODO should be compile error, not panic
-    }
-    if (builtin.os.tag == .haiku) {
-        @panic("unsupported"); // TODO should be compile error, not panic
-    }
-
-    const name_len = math.cast(c_uint, name.len) orelse return error.NameTooLong;
-    switch (errno(system.sysctl(name.ptr, name_len, oldp, oldlenp, newp, newlen))) {
-        .SUCCESS => return,
-        .FAULT => unreachable,
-        .PERM => return error.PermissionDenied,
-        .NOMEM => return error.SystemResources,
-        .NOENT => return error.UnknownName,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub fn sysctlbynameZ(
-    name: [*:0]const u8,
-    oldp: ?*anyopaque,
-    oldlenp: ?*usize,
-    newp: ?*anyopaque,
-    newlen: usize,
-) SysCtlError!void {
-    if (builtin.os.tag == .wasi) {
-        @panic("unsupported"); // TODO should be compile error, not panic
-    }
-    if (builtin.os.tag == .haiku) {
-        @panic("unsupported"); // TODO should be compile error, not panic
-    }
-
-    switch (errno(system.sysctlbyname(name, oldp, oldlenp, newp, newlen))) {
-        .SUCCESS => return,
-        .FAULT => unreachable,
-        .PERM => return error.PermissionDenied,
-        .NOMEM => return error.SystemResources,
-        .NOENT => return error.UnknownName,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub fn gettimeofday(tv: ?*timeval, tz: ?*timezone) void {
-    switch (errno(system.gettimeofday(tv, tz))) {
-        .SUCCESS => return,
-        .INVAL => unreachable,
-        else => unreachable,
-    }
-}
-
-pub const SeekError = error{
-    Unseekable,
-
-    /// In WASI, this error may occur when the file descriptor does
-    /// not hold the required rights to seek on it.
-    AccessDenied,
-} || UnexpectedError;
-
-/// Repositions read/write file offset relative to the beginning.
-pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {
-    if (builtin.os.tag == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
-        var result: u64 = undefined;
-        switch (errno(system.llseek(fd, offset, &result, SEEK.SET))) {
-            .SUCCESS => return,
-            .BADF => unreachable, // always a race condition
-            .INVAL => return error.Unseekable,
-            .OVERFLOW => return error.Unseekable,
-            .SPIPE => return error.Unseekable,
-            .NXIO => return error.Unseekable,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-    if (builtin.os.tag == .windows) {
-        return windows.SetFilePointerEx_BEGIN(fd, offset);
-    }
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        var new_offset: wasi.filesize_t = undefined;
-        switch (wasi.fd_seek(fd, @bitCast(offset), .SET, &new_offset)) {
-            .SUCCESS => return,
-            .BADF => unreachable, // always a race condition
-            .INVAL => return error.Unseekable,
-            .OVERFLOW => return error.Unseekable,
-            .SPIPE => return error.Unseekable,
-            .NXIO => return error.Unseekable,
-            .NOTCAPABLE => return error.AccessDenied,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-
-    const lseek_sym = if (lfs64_abi) system.lseek64 else system.lseek;
-    switch (errno(lseek_sym(fd, @bitCast(offset), SEEK.SET))) {
-        .SUCCESS => return,
-        .BADF => unreachable, // always a race condition
-        .INVAL => return error.Unseekable,
-        .OVERFLOW => return error.Unseekable,
-        .SPIPE => return error.Unseekable,
-        .NXIO => return error.Unseekable,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Repositions read/write file offset relative to the current offset.
-pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {
-    if (builtin.os.tag == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
-        var result: u64 = undefined;
-        switch (errno(system.llseek(fd, @bitCast(offset), &result, SEEK.CUR))) {
-            .SUCCESS => return,
-            .BADF => unreachable, // always a race condition
-            .INVAL => return error.Unseekable,
-            .OVERFLOW => return error.Unseekable,
-            .SPIPE => return error.Unseekable,
-            .NXIO => return error.Unseekable,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-    if (builtin.os.tag == .windows) {
-        return windows.SetFilePointerEx_CURRENT(fd, offset);
-    }
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        var new_offset: wasi.filesize_t = undefined;
-        switch (wasi.fd_seek(fd, offset, .CUR, &new_offset)) {
-            .SUCCESS => return,
-            .BADF => unreachable, // always a race condition
-            .INVAL => return error.Unseekable,
-            .OVERFLOW => return error.Unseekable,
-            .SPIPE => return error.Unseekable,
-            .NXIO => return error.Unseekable,
-            .NOTCAPABLE => return error.AccessDenied,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-    const lseek_sym = if (lfs64_abi) system.lseek64 else system.lseek;
-    switch (errno(lseek_sym(fd, @bitCast(offset), SEEK.CUR))) {
-        .SUCCESS => return,
-        .BADF => unreachable, // always a race condition
-        .INVAL => return error.Unseekable,
-        .OVERFLOW => return error.Unseekable,
-        .SPIPE => return error.Unseekable,
-        .NXIO => return error.Unseekable,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Repositions read/write file offset relative to the end.
-pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {
-    if (builtin.os.tag == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
-        var result: u64 = undefined;
-        switch (errno(system.llseek(fd, @bitCast(offset), &result, SEEK.END))) {
-            .SUCCESS => return,
-            .BADF => unreachable, // always a race condition
-            .INVAL => return error.Unseekable,
-            .OVERFLOW => return error.Unseekable,
-            .SPIPE => return error.Unseekable,
-            .NXIO => return error.Unseekable,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-    if (builtin.os.tag == .windows) {
-        return windows.SetFilePointerEx_END(fd, offset);
-    }
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        var new_offset: wasi.filesize_t = undefined;
-        switch (wasi.fd_seek(fd, offset, .END, &new_offset)) {
-            .SUCCESS => return,
-            .BADF => unreachable, // always a race condition
-            .INVAL => return error.Unseekable,
-            .OVERFLOW => return error.Unseekable,
-            .SPIPE => return error.Unseekable,
-            .NXIO => return error.Unseekable,
-            .NOTCAPABLE => return error.AccessDenied,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-    const lseek_sym = if (lfs64_abi) system.lseek64 else system.lseek;
-    switch (errno(lseek_sym(fd, @bitCast(offset), SEEK.END))) {
-        .SUCCESS => return,
-        .BADF => unreachable, // always a race condition
-        .INVAL => return error.Unseekable,
-        .OVERFLOW => return error.Unseekable,
-        .SPIPE => return error.Unseekable,
-        .NXIO => return error.Unseekable,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Returns the read/write file offset relative to the beginning.
-pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 {
-    if (builtin.os.tag == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
-        var result: u64 = undefined;
-        switch (errno(system.llseek(fd, 0, &result, SEEK.CUR))) {
-            .SUCCESS => return result,
-            .BADF => unreachable, // always a race condition
-            .INVAL => return error.Unseekable,
-            .OVERFLOW => return error.Unseekable,
-            .SPIPE => return error.Unseekable,
-            .NXIO => return error.Unseekable,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-    if (builtin.os.tag == .windows) {
-        return windows.SetFilePointerEx_CURRENT_get(fd);
-    }
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        var new_offset: wasi.filesize_t = undefined;
-        switch (wasi.fd_seek(fd, 0, .CUR, &new_offset)) {
-            .SUCCESS => return new_offset,
-            .BADF => unreachable, // always a race condition
-            .INVAL => return error.Unseekable,
-            .OVERFLOW => return error.Unseekable,
-            .SPIPE => return error.Unseekable,
-            .NXIO => return error.Unseekable,
-            .NOTCAPABLE => return error.AccessDenied,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-    const lseek_sym = if (lfs64_abi) system.lseek64 else system.lseek;
-    const rc = lseek_sym(fd, 0, SEEK.CUR);
-    switch (errno(rc)) {
-        .SUCCESS => return @bitCast(rc),
-        .BADF => unreachable, // always a race condition
-        .INVAL => return error.Unseekable,
-        .OVERFLOW => return error.Unseekable,
-        .SPIPE => return error.Unseekable,
-        .NXIO => return error.Unseekable,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub const FcntlError = error{
-    PermissionDenied,
-    FileBusy,
-    ProcessFdQuotaExceeded,
-    Locked,
-    DeadLock,
-    LockedRegionLimitExceeded,
-} || UnexpectedError;
-
-pub fn fcntl(fd: fd_t, cmd: i32, arg: usize) FcntlError!usize {
-    while (true) {
-        const rc = system.fcntl(fd, cmd, arg);
-        switch (errno(rc)) {
-            .SUCCESS => return @intCast(rc),
-            .INTR => continue,
-            .AGAIN, .ACCES => return error.Locked,
-            .BADF => unreachable,
-            .BUSY => return error.FileBusy,
-            .INVAL => unreachable, // invalid parameters
-            .PERM => return error.PermissionDenied,
-            .MFILE => return error.ProcessFdQuotaExceeded,
-            .NOTDIR => unreachable, // invalid parameter
-            .DEADLK => return error.DeadLock,
-            .NOLCK => return error.LockedRegionLimitExceeded,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-fn setSockFlags(sock: socket_t, flags: u32) !void {
-    if ((flags & SOCK.CLOEXEC) != 0) {
-        if (builtin.os.tag == .windows) {
-            // TODO: Find out if this is supported for sockets
-        } else {
-            var fd_flags = fcntl(sock, F.GETFD, 0) catch |err| switch (err) {
-                error.FileBusy => unreachable,
-                error.Locked => unreachable,
-                error.PermissionDenied => unreachable,
-                error.DeadLock => unreachable,
-                error.LockedRegionLimitExceeded => unreachable,
-                else => |e| return e,
-            };
-            fd_flags |= FD_CLOEXEC;
-            _ = fcntl(sock, F.SETFD, fd_flags) catch |err| switch (err) {
-                error.FileBusy => unreachable,
-                error.Locked => unreachable,
-                error.PermissionDenied => unreachable,
-                error.DeadLock => unreachable,
-                error.LockedRegionLimitExceeded => unreachable,
-                else => |e| return e,
-            };
-        }
-    }
-    if ((flags & SOCK.NONBLOCK) != 0) {
-        if (builtin.os.tag == .windows) {
-            var mode: c_ulong = 1;
-            if (windows.ws2_32.ioctlsocket(sock, windows.ws2_32.FIONBIO, &mode) == windows.ws2_32.SOCKET_ERROR) {
-                switch (windows.ws2_32.WSAGetLastError()) {
-                    .WSANOTINITIALISED => unreachable,
-                    .WSAENETDOWN => return error.NetworkSubsystemFailed,
-                    .WSAENOTSOCK => return error.FileDescriptorNotASocket,
-                    // TODO: handle more errors
-                    else => |err| return windows.unexpectedWSAError(err),
-                }
-            }
-        } else {
-            var fl_flags = fcntl(sock, F.GETFL, 0) catch |err| switch (err) {
-                error.FileBusy => unreachable,
-                error.Locked => unreachable,
-                error.PermissionDenied => unreachable,
-                error.DeadLock => unreachable,
-                error.LockedRegionLimitExceeded => unreachable,
-                else => |e| return e,
-            };
-            fl_flags |= 1 << @bitOffsetOf(O, "NONBLOCK");
-            _ = fcntl(sock, F.SETFL, fl_flags) catch |err| switch (err) {
-                error.FileBusy => unreachable,
-                error.Locked => unreachable,
-                error.PermissionDenied => unreachable,
-                error.DeadLock => unreachable,
-                error.LockedRegionLimitExceeded => unreachable,
-                else => |e| return e,
-            };
-        }
-    }
-}
-
-pub const FlockError = error{
-    WouldBlock,
-
-    /// The kernel ran out of memory for allocating file locks
-    SystemResources,
-
-    /// The underlying filesystem does not support file locks
-    FileLocksNotSupported,
-} || UnexpectedError;
-
-/// Depending on the operating system `flock` may or may not interact with
-/// `fcntl` locks made by other processes.
-pub fn flock(fd: fd_t, operation: i32) FlockError!void {
-    while (true) {
-        const rc = system.flock(fd, operation);
-        switch (errno(rc)) {
-            .SUCCESS => return,
-            .BADF => unreachable,
-            .INTR => continue,
-            .INVAL => unreachable, // invalid parameters
-            .NOLCK => return error.SystemResources,
-            .AGAIN => return error.WouldBlock, // TODO: integrate with async instead of just returning an error
-            .OPNOTSUPP => return error.FileLocksNotSupported,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-pub const RealPathError = error{
-    FileNotFound,
-    AccessDenied,
-    NameTooLong,
-    NotSupported,
-    NotDir,
-    SymLinkLoop,
-    InputOutput,
-    FileTooBig,
-    IsDir,
-    ProcessFdQuotaExceeded,
-    SystemFdQuotaExceeded,
-    NoDevice,
-    SystemResources,
-    NoSpaceLeft,
-    FileSystem,
-    BadPathName,
-    DeviceBusy,
-
-    SharingViolation,
-    PipeBusy,
-
-    /// Windows-only; file paths provided by the user must be valid WTF-8.
-    /// https://simonsapin.github.io/wtf-8/
-    InvalidWtf8,
-
-    /// On Windows, `\\server` or `\\server\share` was not found.
-    NetworkNotFound,
-
-    PathAlreadyExists,
-
-    /// On Windows, antivirus software is enabled by default. It can be
-    /// disabled, but Windows Update sometimes ignores the user's preference
-    /// and re-enables it. When enabled, antivirus software on Windows
-    /// intercepts file system operations and makes them significantly slower
-    /// in addition to possibly failing with this error code.
-    AntivirusInterference,
-
-    /// On Windows, the volume does not contain a recognized file system. File
-    /// system drivers might not be loaded, or the volume may be corrupt.
-    UnrecognizedVolume,
-} || UnexpectedError;
-
-/// Return the canonicalized absolute pathname.
-/// Expands all symbolic links and resolves references to `.`, `..`, and
-/// extra `/` characters in `pathname`.
-/// On Windows, `pathname` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// On other platforms, `pathname` is an opaque sequence of bytes with no particular encoding.
-/// The return value is a slice of `out_buffer`, but not necessarily from the beginning.
-/// See also `realpathZ` and `realpathW`.
-/// On Windows, the result is encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// On other platforms, the result is an opaque sequence of bytes with no particular encoding.
-/// Calling this function is usually a bug.
-pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
-    if (builtin.os.tag == .windows) {
-        const pathname_w = try windows.sliceToPrefixedFileW(null, pathname);
-        return realpathW(pathname_w.span(), out_buffer);
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        @compileError("WASI does not support os.realpath");
-    }
-    const pathname_c = try toPosixPath(pathname);
-    return realpathZ(&pathname_c, out_buffer);
-}
-
-/// Same as `realpath` except `pathname` is null-terminated.
-/// Calling this function is usually a bug.
-pub fn realpathZ(pathname: [*:0]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
-    if (builtin.os.tag == .windows) {
-        const pathname_w = try windows.cStrToPrefixedFileW(null, pathname);
-        return realpathW(pathname_w.span(), out_buffer);
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        return realpath(mem.sliceTo(pathname, 0), out_buffer);
-    }
-    if (!builtin.link_libc) {
-        const flags: O = switch (builtin.os.tag) {
-            .linux => .{
-                .NONBLOCK = true,
-                .CLOEXEC = true,
-                .PATH = true,
-            },
-            else => .{
-                .NONBLOCK = true,
-                .CLOEXEC = true,
-            },
-        };
-        const fd = openZ(pathname, flags, 0) catch |err| switch (err) {
-            error.FileLocksNotSupported => unreachable,
-            error.WouldBlock => unreachable,
-            error.FileBusy => unreachable, // not asking for write permissions
-            error.InvalidUtf8 => unreachable, // WASI-only
-            else => |e| return e,
-        };
-        defer close(fd);
-
-        return getFdPath(fd, out_buffer);
-    }
-    const result_path = std.c.realpath(pathname, out_buffer) orelse switch (@as(E, @enumFromInt(std.c._errno().*))) {
-        .SUCCESS => unreachable,
-        .INVAL => unreachable,
-        .BADF => unreachable,
-        .FAULT => unreachable,
-        .ACCES => return error.AccessDenied,
-        .NOENT => return error.FileNotFound,
-        .OPNOTSUPP => return error.NotSupported,
-        .NOTDIR => return error.NotDir,
-        .NAMETOOLONG => return error.NameTooLong,
-        .LOOP => return error.SymLinkLoop,
-        .IO => return error.InputOutput,
-        else => |err| return unexpectedErrno(err),
-    };
-    return mem.sliceTo(result_path, 0);
-}
-
-/// Same as `realpath` except `pathname` is WTF16LE-encoded.
-/// The result is encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// Calling this function is usually a bug.
-pub fn realpathW(pathname: []const u16, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
-    const w = windows;
-
-    const dir = std.fs.cwd().fd;
-    const access_mask = w.GENERIC_READ | w.SYNCHRONIZE;
-    const share_access = w.FILE_SHARE_READ;
-    const creation = w.FILE_OPEN;
-    const h_file = blk: {
-        const res = w.OpenFile(pathname, .{
-            .dir = dir,
-            .access_mask = access_mask,
-            .share_access = share_access,
-            .creation = creation,
-            .filter = .any,
-        }) catch |err| switch (err) {
-            error.WouldBlock => unreachable,
-            else => |e| return e,
-        };
-        break :blk res;
-    };
-    defer w.CloseHandle(h_file);
-
-    return getFdPath(h_file, out_buffer);
-}
-
-pub fn isGetFdPathSupportedOnTarget(os: std.Target.Os) bool {
-    return switch (os.tag) {
-        .windows,
-        .macos,
-        .ios,
-        .watchos,
-        .tvos,
-        .linux,
-        .solaris,
-        .illumos,
-        .freebsd,
-        => true,
-
-        .dragonfly => os.version_range.semver.max.order(.{ .major = 6, .minor = 0, .patch = 0 }) != .lt,
-        .netbsd => os.version_range.semver.max.order(.{ .major = 10, .minor = 0, .patch = 0 }) != .lt,
-        else => false,
-    };
-}
-
-/// Return canonical path of handle `fd`.
-/// This function is very host-specific and is not universally supported by all hosts.
-/// For example, while it generally works on Linux, macOS, FreeBSD or Windows, it is
-/// unsupported on WASI.
-/// On Windows, the result is encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
-/// On other platforms, the result is an opaque sequence of bytes with no particular encoding.
-/// Calling this function is usually a bug.
-pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
-    if (!comptime isGetFdPathSupportedOnTarget(builtin.os)) {
-        @compileError("querying for canonical path of a handle is unsupported on this host");
-    }
-    switch (builtin.os.tag) {
-        .windows => {
-            var wide_buf: [windows.PATH_MAX_WIDE]u16 = undefined;
-            const wide_slice = try windows.GetFinalPathNameByHandle(fd, .{}, wide_buf[0..]);
-
-            const end_index = std.unicode.wtf16LeToWtf8(out_buffer, wide_slice);
-            return out_buffer[0..end_index];
-        },
-        .macos, .ios, .watchos, .tvos => {
-            // On macOS, we can use F.GETPATH fcntl command to query the OS for
-            // the path to the file descriptor.
-            @memset(out_buffer[0..MAX_PATH_BYTES], 0);
-            switch (errno(system.fcntl(fd, F.GETPATH, out_buffer))) {
-                .SUCCESS => {},
-                .BADF => return error.FileNotFound,
-                .NOSPC => return error.NameTooLong,
-                // TODO man pages for fcntl on macOS don't really tell you what
-                // errno values to expect when command is F.GETPATH...
-                else => |err| return unexpectedErrno(err),
-            }
-            const len = mem.indexOfScalar(u8, out_buffer[0..], 0) orelse MAX_PATH_BYTES;
-            return out_buffer[0..len];
-        },
-        .linux => {
-            var procfs_buf: ["/proc/self/fd/-2147483648\x00".len]u8 = undefined;
-            const proc_path = std.fmt.bufPrintZ(procfs_buf[0..], "/proc/self/fd/{d}", .{fd}) catch unreachable;
-
-            const target = readlinkZ(proc_path, out_buffer) catch |err| {
-                switch (err) {
-                    error.NotLink => unreachable,
-                    error.BadPathName => unreachable,
-                    error.InvalidUtf8 => unreachable, // WASI-only
-                    error.InvalidWtf8 => unreachable, // Windows-only
-                    error.UnsupportedReparsePointType => unreachable, // Windows-only
-                    error.NetworkNotFound => unreachable, // Windows-only
-                    else => |e| return e,
-                }
-            };
-            return target;
-        },
-        .solaris, .illumos => {
-            var procfs_buf: ["/proc/self/path/-2147483648\x00".len]u8 = undefined;
-            const proc_path = std.fmt.bufPrintZ(procfs_buf[0..], "/proc/self/path/{d}", .{fd}) catch unreachable;
-
-            const target = readlinkZ(proc_path, out_buffer) catch |err| switch (err) {
-                error.UnsupportedReparsePointType => unreachable,
-                error.NotLink => unreachable,
-                else => |e| return e,
-            };
-            return target;
-        },
-        .freebsd => {
-            if (comptime builtin.os.isAtLeast(.freebsd, .{ .major = 13, .minor = 0, .patch = 0 }) orelse false) {
-                var kfile: system.kinfo_file = undefined;
-                kfile.structsize = system.KINFO_FILE_SIZE;
-                switch (errno(system.fcntl(fd, system.F.KINFO, @intFromPtr(&kfile)))) {
-                    .SUCCESS => {},
-                    .BADF => return error.FileNotFound,
-                    else => |err| return unexpectedErrno(err),
-                }
-                const len = mem.indexOfScalar(u8, &kfile.path, 0) orelse MAX_PATH_BYTES;
-                if (len == 0) return error.NameTooLong;
-                const result = out_buffer[0..len];
-                @memcpy(result, kfile.path[0..len]);
-                return result;
-            } else {
-                // This fallback implementation reimplements libutil's `kinfo_getfile()`.
-                // The motivation is to avoid linking -lutil when building zig or general
-                // user executables.
-                var mib = [4]c_int{ CTL.KERN, KERN.PROC, KERN.PROC_FILEDESC, system.getpid() };
-                var len: usize = undefined;
-                sysctl(&mib, null, &len, null, 0) catch |err| switch (err) {
-                    error.PermissionDenied => unreachable,
-                    error.SystemResources => return error.SystemResources,
-                    error.NameTooLong => unreachable,
-                    error.UnknownName => unreachable,
-                    else => return error.Unexpected,
-                };
-                len = len * 4 / 3;
-                const buf = std.heap.c_allocator.alloc(u8, len) catch return error.SystemResources;
-                defer std.heap.c_allocator.free(buf);
-                len = buf.len;
-                sysctl(&mib, &buf[0], &len, null, 0) catch |err| switch (err) {
-                    error.PermissionDenied => unreachable,
-                    error.SystemResources => return error.SystemResources,
-                    error.NameTooLong => unreachable,
-                    error.UnknownName => unreachable,
-                    else => return error.Unexpected,
-                };
-                var i: usize = 0;
-                while (i < len) {
-                    const kf: *align(1) system.kinfo_file = @ptrCast(&buf[i]);
-                    if (kf.fd == fd) {
-                        len = mem.indexOfScalar(u8, &kf.path, 0) orelse MAX_PATH_BYTES;
-                        if (len == 0) return error.NameTooLong;
-                        const result = out_buffer[0..len];
-                        @memcpy(result, kf.path[0..len]);
-                        return result;
-                    }
-                    i += @intCast(kf.structsize);
-                }
-                return error.FileNotFound;
-            }
-        },
-        .dragonfly => {
-            @memset(out_buffer[0..MAX_PATH_BYTES], 0);
-            switch (errno(system.fcntl(fd, F.GETPATH, out_buffer))) {
-                .SUCCESS => {},
-                .BADF => return error.FileNotFound,
-                .RANGE => return error.NameTooLong,
-                else => |err| return unexpectedErrno(err),
-            }
-            const len = mem.indexOfScalar(u8, out_buffer[0..], 0) orelse MAX_PATH_BYTES;
-            return out_buffer[0..len];
-        },
-        .netbsd => {
-            @memset(out_buffer[0..MAX_PATH_BYTES], 0);
-            switch (errno(system.fcntl(fd, F.GETPATH, out_buffer))) {
-                .SUCCESS => {},
-                .ACCES => return error.AccessDenied,
-                .BADF => return error.FileNotFound,
-                .NOENT => return error.FileNotFound,
-                .NOMEM => return error.SystemResources,
-                .RANGE => return error.NameTooLong,
-                else => |err| return unexpectedErrno(err),
-            }
-            const len = mem.indexOfScalar(u8, out_buffer[0..], 0) orelse MAX_PATH_BYTES;
-            return out_buffer[0..len];
-        },
-        else => unreachable, // made unreachable by isGetFdPathSupportedOnTarget above
-    }
-}
-
-/// Spurious wakeups are possible and no precision of timing is guaranteed.
-pub fn nanosleep(seconds: u64, nanoseconds: u64) void {
-    var req = timespec{
-        .tv_sec = math.cast(isize, seconds) orelse math.maxInt(isize),
-        .tv_nsec = math.cast(isize, nanoseconds) orelse math.maxInt(isize),
-    };
-    var rem: timespec = undefined;
-    while (true) {
-        switch (errno(system.nanosleep(&req, &rem))) {
-            .FAULT => unreachable,
-            .INVAL => {
-                // Sometimes Darwin returns EINVAL for no reason.
-                // We treat it as a spurious wakeup.
-                return;
-            },
-            .INTR => {
-                req = rem;
-                continue;
-            },
-            // This prong handles success as well as unexpected errors.
-            else => return,
-        }
-    }
-}
-
-pub fn dl_iterate_phdr(
-    context: anytype,
-    comptime Error: type,
-    comptime callback: fn (info: *dl_phdr_info, size: usize, context: @TypeOf(context)) Error!void,
-) Error!void {
-    const Context = @TypeOf(context);
-
-    switch (builtin.object_format) {
-        .elf, .c => {},
-        else => @compileError("dl_iterate_phdr is not available for this target"),
-    }
-
-    if (builtin.link_libc) {
-        switch (system.dl_iterate_phdr(struct {
-            fn callbackC(info: *dl_phdr_info, size: usize, data: ?*anyopaque) callconv(.C) c_int {
-                const context_ptr: *const Context = @ptrCast(@alignCast(data));
-                callback(info, size, context_ptr.*) catch |err| return @intFromError(err);
-                return 0;
-            }
-        }.callbackC, @ptrCast(@constCast(&context)))) {
-            0 => return,
-            else => |err| return @as(Error, @errorCast(@errorFromInt(@as(std.meta.Int(.unsigned, @bitSizeOf(anyerror)), @intCast(err))))),
-        }
-    }
-
-    const elf_base = std.process.getBaseAddress();
-    const ehdr: *elf.Ehdr = @ptrFromInt(elf_base);
-    // Make sure the base address points to an ELF image.
-    assert(mem.eql(u8, ehdr.e_ident[0..4], elf.MAGIC));
-    const n_phdr = ehdr.e_phnum;
-    const phdrs = (@as([*]elf.Phdr, @ptrFromInt(elf_base + ehdr.e_phoff)))[0..n_phdr];
-
-    var it = dl.linkmap_iterator(phdrs) catch unreachable;
-
-    // The executable has no dynamic link segment, create a single entry for
-    // the whole ELF image.
-    if (it.end()) {
-        // Find the base address for the ELF image, if this is a PIE the value
-        // is non-zero.
-        const base_address = for (phdrs) |*phdr| {
-            if (phdr.p_type == elf.PT_PHDR) {
-                break @intFromPtr(phdrs.ptr) - phdr.p_vaddr;
-                // We could try computing the difference between _DYNAMIC and
-                // the p_vaddr of the PT_DYNAMIC section, but using the phdr is
-                // good enough (Is it?).
-            }
-        } else unreachable;
-
-        var info = dl_phdr_info{
-            .dlpi_addr = base_address,
-            .dlpi_name = "/proc/self/exe",
-            .dlpi_phdr = phdrs.ptr,
-            .dlpi_phnum = ehdr.e_phnum,
-        };
-
-        return callback(&info, @sizeOf(dl_phdr_info), context);
-    }
-
-    // Last return value from the callback function.
-    while (it.next()) |entry| {
-        var dlpi_phdr: [*]elf.Phdr = undefined;
-        var dlpi_phnum: u16 = undefined;
-
-        if (entry.l_addr != 0) {
-            const elf_header: *elf.Ehdr = @ptrFromInt(entry.l_addr);
-            dlpi_phdr = @ptrFromInt(entry.l_addr + elf_header.e_phoff);
-            dlpi_phnum = elf_header.e_phnum;
-        } else {
-            // This is the running ELF image
-            dlpi_phdr = @ptrFromInt(elf_base + ehdr.e_phoff);
-            dlpi_phnum = ehdr.e_phnum;
-        }
-
-        var info = dl_phdr_info{
-            .dlpi_addr = entry.l_addr,
-            .dlpi_name = entry.l_name,
-            .dlpi_phdr = dlpi_phdr,
-            .dlpi_phnum = dlpi_phnum,
-        };
-
-        try callback(&info, @sizeOf(dl_phdr_info), context);
-    }
-}
-
-pub const ClockGetTimeError = error{UnsupportedClock} || UnexpectedError;
-
-/// TODO: change this to return the timespec as a return value
-/// TODO: look into making clk_id an enum
-pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void {
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        var ts: timestamp_t = undefined;
-        switch (system.clock_time_get(@bitCast(clk_id), 1, &ts)) {
-            .SUCCESS => {
-                tp.* = .{
-                    .tv_sec = @intCast(ts / std.time.ns_per_s),
-                    .tv_nsec = @intCast(ts % std.time.ns_per_s),
-                };
-            },
-            .INVAL => return error.UnsupportedClock,
-            else => |err| return unexpectedErrno(err),
-        }
-        return;
-    }
-    if (builtin.os.tag == .windows) {
-        if (clk_id == CLOCK.REALTIME) {
-            var ft: windows.FILETIME = undefined;
-            windows.kernel32.GetSystemTimeAsFileTime(&ft);
-            // FileTime has a granularity of 100 nanoseconds and uses the NTFS/Windows epoch.
-            const ft64 = (@as(u64, ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
-            const ft_per_s = std.time.ns_per_s / 100;
-            tp.* = .{
-                .tv_sec = @as(i64, @intCast(ft64 / ft_per_s)) + std.time.epoch.windows,
-                .tv_nsec = @as(c_long, @intCast(ft64 % ft_per_s)) * 100,
-            };
-            return;
-        } else {
-            // TODO POSIX implementation of CLOCK.MONOTONIC on Windows.
-            return error.UnsupportedClock;
-        }
-    }
-
-    switch (errno(system.clock_gettime(clk_id, tp))) {
-        .SUCCESS => return,
-        .FAULT => unreachable,
-        .INVAL => return error.UnsupportedClock,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub fn clock_getres(clk_id: i32, res: *timespec) ClockGetTimeError!void {
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        var ts: timestamp_t = undefined;
-        switch (system.clock_res_get(@bitCast(clk_id), &ts)) {
-            .SUCCESS => res.* = .{
-                .tv_sec = @intCast(ts / std.time.ns_per_s),
-                .tv_nsec = @intCast(ts % std.time.ns_per_s),
-            },
-            .INVAL => return error.UnsupportedClock,
-            else => |err| return unexpectedErrno(err),
-        }
-        return;
-    }
-
-    switch (errno(system.clock_getres(clk_id, res))) {
-        .SUCCESS => return,
-        .FAULT => unreachable,
-        .INVAL => return error.UnsupportedClock,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub const SchedGetAffinityError = error{PermissionDenied} || UnexpectedError;
-
-pub fn sched_getaffinity(pid: pid_t) SchedGetAffinityError!cpu_set_t {
-    var set: cpu_set_t = undefined;
-    switch (errno(system.sched_getaffinity(pid, @sizeOf(cpu_set_t), &set))) {
-        .SUCCESS => return set,
-        .FAULT => unreachable,
-        .INVAL => unreachable,
-        .SRCH => unreachable,
-        .PERM => return error.PermissionDenied,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Used to convert a slice to a null terminated slice on the stack.
-/// TODO https://github.com/ziglang/zig/issues/287
-pub fn toPosixPath(file_path: []const u8) error{NameTooLong}![MAX_PATH_BYTES - 1:0]u8 {
-    if (std.debug.runtime_safety) assert(std.mem.indexOfScalar(u8, file_path, 0) == null);
-    var path_with_null: [MAX_PATH_BYTES - 1:0]u8 = undefined;
-    // >= rather than > to make room for the null byte
-    if (file_path.len >= MAX_PATH_BYTES) return error.NameTooLong;
-    @memcpy(path_with_null[0..file_path.len], file_path);
-    path_with_null[file_path.len] = 0;
-    return path_with_null;
-}
-
-/// Whether or not error.Unexpected will print its value and a stack trace.
-/// if this happens the fix is to add the error code to the corresponding
-/// switch expression, possibly introduce a new error in the error set, and
-/// send a patch to Zig.
-pub const unexpected_error_tracing = builtin.zig_backend == .stage2_llvm and builtin.mode == .Debug;
-
-pub const UnexpectedError = error{
-    /// The Operating System returned an undocumented error code.
-    /// This error is in theory not possible, but it would be better
-    /// to handle this error than to invoke undefined behavior.
-    Unexpected,
-};
-
-/// Call this when you made a syscall or something that sets errno
-/// and you get an unexpected error.
-pub fn unexpectedErrno(err: E) UnexpectedError {
-    if (unexpected_error_tracing) {
-        std.debug.print("unexpected errno: {d}\n", .{@intFromEnum(err)});
-        std.debug.dumpCurrentStackTrace(null);
-    }
-    return error.Unexpected;
-}
-
-pub const SigaltstackError = error{
-    /// The supplied stack size was less than MINSIGSTKSZ.
-    SizeTooSmall,
-
-    /// Attempted to change the signal stack while it was active.
-    PermissionDenied,
-} || UnexpectedError;
-
-pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) SigaltstackError!void {
-    switch (errno(system.sigaltstack(ss, old_ss))) {
-        .SUCCESS => return,
-        .FAULT => unreachable,
-        .INVAL => unreachable,
-        .NOMEM => return error.SizeTooSmall,
-        .PERM => return error.PermissionDenied,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Examine and change a signal action.
-pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) error{OperationNotSupported}!void {
-    switch (errno(system.sigaction(sig, act, oact))) {
-        .SUCCESS => return,
-        .INVAL, .NOSYS => return error.OperationNotSupported,
-        else => unreachable,
-    }
-}
-
-/// Sets the thread signal mask.
-pub fn sigprocmask(flags: u32, noalias set: ?*const sigset_t, noalias oldset: ?*sigset_t) void {
-    switch (errno(system.sigprocmask(@bitCast(flags), set, oldset))) {
-        .SUCCESS => return,
-        .FAULT => unreachable,
-        .INVAL => unreachable,
-        else => unreachable,
-    }
-}
-
-pub const FutimensError = error{
-    /// times is NULL, or both tv_nsec values are UTIME_NOW, and either:
-    /// *  the effective user ID of the caller does not match the  owner
-    ///    of  the  file,  the  caller does not have write access to the
-    ///    file, and the caller is not privileged (Linux: does not  have
-    ///    either  the  CAP_FOWNER  or the CAP_DAC_OVERRIDE capability);
-    ///    or,
-    /// *  the file is marked immutable (see chattr(1)).
-    AccessDenied,
-
-    /// The caller attempted to change one or both timestamps to a value
-    /// other than the current time, or to change one of the  timestamps
-    /// to the current time while leaving the other timestamp unchanged,
-    /// (i.e., times is not NULL, neither tv_nsec  field  is  UTIME_NOW,
-    /// and neither tv_nsec field is UTIME_OMIT) and either:
-    /// *  the  caller's  effective  user ID does not match the owner of
-    ///    file, and the caller is not privileged (Linux: does not  have
-    ///    the CAP_FOWNER capability); or,
-    /// *  the file is marked append-only or immutable (see chattr(1)).
-    PermissionDenied,
-
-    ReadOnlyFileSystem,
-} || UnexpectedError;
-
-pub fn futimens(fd: fd_t, times: *const [2]timespec) FutimensError!void {
-    if (builtin.os.tag == .wasi and !builtin.link_libc) {
-        // TODO WASI encodes `wasi.fstflags` to signify magic values
-        // similar to UTIME_NOW and UTIME_OMIT. Currently, we ignore
-        // this here, but we should really handle it somehow.
-        const atim = times[0].toTimestamp();
-        const mtim = times[1].toTimestamp();
-        switch (wasi.fd_filestat_set_times(fd, atim, mtim, .{
-            .ATIM = true,
-            .MTIM = true,
-        })) {
-            .SUCCESS => return,
-            .ACCES => return error.AccessDenied,
-            .PERM => return error.PermissionDenied,
-            .BADF => unreachable, // always a race condition
-            .FAULT => unreachable,
-            .INVAL => unreachable,
-            .ROFS => return error.ReadOnlyFileSystem,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-
-    switch (errno(system.futimens(fd, times))) {
-        .SUCCESS => return,
-        .ACCES => return error.AccessDenied,
-        .PERM => return error.PermissionDenied,
-        .BADF => unreachable, // always a race condition
-        .FAULT => unreachable,
-        .INVAL => unreachable,
-        .ROFS => return error.ReadOnlyFileSystem,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub const GetHostNameError = error{PermissionDenied} || UnexpectedError;
-
-pub fn gethostname(name_buffer: *[HOST_NAME_MAX]u8) GetHostNameError![]u8 {
-    if (builtin.link_libc) {
-        switch (errno(system.gethostname(name_buffer, name_buffer.len))) {
-            .SUCCESS => return mem.sliceTo(name_buffer, 0),
-            .FAULT => unreachable,
-            .NAMETOOLONG => unreachable, // HOST_NAME_MAX prevents this
-            .PERM => return error.PermissionDenied,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-    if (builtin.os.tag == .linux) {
-        const uts = uname();
-        const hostname = mem.sliceTo(&uts.nodename, 0);
-        const result = name_buffer[0..hostname.len];
-        @memcpy(result, hostname);
-        return result;
-    }
-
-    @compileError("TODO implement gethostname for this OS");
-}
-
-pub fn uname() utsname {
-    var uts: utsname = undefined;
-    switch (errno(system.uname(&uts))) {
-        .SUCCESS => return uts,
-        .FAULT => unreachable,
-        else => unreachable,
-    }
-}
-
-pub fn res_mkquery(
-    op: u4,
-    dname: []const u8,
-    class: u8,
-    ty: u8,
-    data: []const u8,
-    newrr: ?[*]const u8,
-    buf: []u8,
-) usize {
-    _ = data;
-    _ = newrr;
-    // This implementation is ported from musl libc.
-    // A more idiomatic "ziggy" implementation would be welcome.
-    var name = dname;
-    if (mem.endsWith(u8, name, ".")) name.len -= 1;
-    assert(name.len <= 253);
-    const n = 17 + name.len + @intFromBool(name.len != 0);
-
-    // Construct query template - ID will be filled later
-    var q: [280]u8 = undefined;
-    @memset(q[0..n], 0);
-    q[2] = @as(u8, op) * 8 + 1;
-    q[5] = 1;
-    @memcpy(q[13..][0..name.len], name);
-    var i: usize = 13;
-    var j: usize = undefined;
-    while (q[i] != 0) : (i = j + 1) {
-        j = i;
-        while (q[j] != 0 and q[j] != '.') : (j += 1) {}
-        // TODO determine the circumstances for this and whether or
-        // not this should be an error.
-        if (j - i - 1 > 62) unreachable;
-        q[i - 1] = @intCast(j - i);
-    }
-    q[i + 1] = ty;
-    q[i + 3] = class;
-
-    // Make a reasonably unpredictable id
-    var ts: timespec = undefined;
-    clock_gettime(CLOCK.REALTIME, &ts) catch {};
-    const UInt = std.meta.Int(.unsigned, @bitSizeOf(@TypeOf(ts.tv_nsec)));
-    const unsec: UInt = @bitCast(ts.tv_nsec);
-    const id: u32 = @truncate(unsec + unsec / 65536);
-    q[0] = @truncate(id / 256);
-    q[1] = @truncate(id);
-
-    @memcpy(buf[0..n], q[0..n]);
-    return n;
-}
-
-pub const SendError = error{
-    /// (For UNIX domain sockets, which are identified by pathname) Write permission is  denied
-    /// on  the destination socket file, or search permission is denied for one of the
-    /// directories the path prefix.  (See path_resolution(7).)
-    /// (For UDP sockets) An attempt was made to send to a network/broadcast address as  though
-    /// it was a unicast address.
-    AccessDenied,
-
-    /// The socket is marked nonblocking and the requested operation would block, and
-    /// there is no global event loop configured.
-    /// It's also possible to get this error under the following condition:
-    /// (Internet  domain datagram sockets) The socket referred to by sockfd had not previously
-    /// been bound to an address and, upon attempting to bind it to an ephemeral port,  it  was
-    /// determined that all port numbers in the ephemeral port range are currently in use.  See
-    /// the discussion of /proc/sys/net/ipv4/ip_local_port_range in ip(7).
-    WouldBlock,
-
-    /// Another Fast Open is already in progress.
-    FastOpenAlreadyInProgress,
-
-    /// Connection reset by peer.
-    ConnectionResetByPeer,
-
-    /// The  socket  type requires that message be sent atomically, and the size of the message
-    /// to be sent made this impossible. The message is not transmitted.
-    MessageTooBig,
-
-    /// The output queue for a network interface was full.  This generally indicates  that  the
-    /// interface  has  stopped sending, but may be caused by transient congestion.  (Normally,
-    /// this does not occur in Linux.  Packets are just silently dropped when  a  device  queue
-    /// overflows.)
-    /// This is also caused when there is not enough kernel memory available.
-    SystemResources,
-
-    /// The  local  end  has been shut down on a connection oriented socket.  In this case, the
-    /// process will also receive a SIGPIPE unless MSG.NOSIGNAL is set.
-    BrokenPipe,
-
-    FileDescriptorNotASocket,
-
-    /// Network is unreachable.
-    NetworkUnreachable,
-
-    /// The local network interface used to reach the destination is down.
-    NetworkSubsystemFailed,
-} || UnexpectedError;
-
-pub const SendMsgError = SendError || error{
-    /// The passed address didn't have the correct address family in its sa_family field.
-    AddressFamilyNotSupported,
-
-    /// Returned when socket is AF.UNIX and the given path has a symlink loop.
-    SymLinkLoop,
-
-    /// Returned when socket is AF.UNIX and the given path length exceeds `MAX_PATH_BYTES` bytes.
-    NameTooLong,
-
-    /// Returned when socket is AF.UNIX and the given path does not point to an existing file.
-    FileNotFound,
-    NotDir,
-
-    /// The socket is not connected (connection-oriented sockets only).
-    SocketNotConnected,
-    AddressNotAvailable,
-};
-
-pub fn sendmsg(
-    /// The file descriptor of the sending socket.
-    sockfd: socket_t,
-    /// Message header and iovecs
-    msg: *const msghdr_const,
-    flags: u32,
-) SendMsgError!usize {
-    while (true) {
-        const rc = system.sendmsg(sockfd, msg, flags);
-        if (builtin.os.tag == .windows) {
-            if (rc == windows.ws2_32.SOCKET_ERROR) {
-                switch (windows.ws2_32.WSAGetLastError()) {
-                    .WSAEACCES => return error.AccessDenied,
-                    .WSAEADDRNOTAVAIL => return error.AddressNotAvailable,
-                    .WSAECONNRESET => return error.ConnectionResetByPeer,
-                    .WSAEMSGSIZE => return error.MessageTooBig,
-                    .WSAENOBUFS => return error.SystemResources,
-                    .WSAENOTSOCK => return error.FileDescriptorNotASocket,
-                    .WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported,
-                    .WSAEDESTADDRREQ => unreachable, // A destination address is required.
-                    .WSAEFAULT => unreachable, // The lpBuffers, lpTo, lpOverlapped, lpNumberOfBytesSent, or lpCompletionRoutine parameters are not part of the user address space, or the lpTo parameter is too small.
-                    .WSAEHOSTUNREACH => return error.NetworkUnreachable,
-                    // TODO: WSAEINPROGRESS, WSAEINTR
-                    .WSAEINVAL => unreachable,
-                    .WSAENETDOWN => return error.NetworkSubsystemFailed,
-                    .WSAENETRESET => return error.ConnectionResetByPeer,
-                    .WSAENETUNREACH => return error.NetworkUnreachable,
-                    .WSAENOTCONN => return error.SocketNotConnected,
-                    .WSAESHUTDOWN => unreachable, // The socket has been shut down; it is not possible to WSASendTo on a socket after shutdown has been invoked with how set to SD_SEND or SD_BOTH.
-                    .WSAEWOULDBLOCK => return error.WouldBlock,
-                    .WSANOTINITIALISED => unreachable, // A successful WSAStartup call must occur before using this function.
-                    else => |err| return windows.unexpectedWSAError(err),
-                }
-            } else {
-                return @intCast(rc);
-            }
-        } else {
-            switch (errno(rc)) {
-                .SUCCESS => return @intCast(rc),
-
-                .ACCES => return error.AccessDenied,
-                .AGAIN => return error.WouldBlock,
-                .ALREADY => return error.FastOpenAlreadyInProgress,
-                .BADF => unreachable, // always a race condition
-                .CONNRESET => return error.ConnectionResetByPeer,
-                .DESTADDRREQ => unreachable, // The socket is not connection-mode, and no peer address is set.
-                .FAULT => unreachable, // An invalid user space address was specified for an argument.
-                .INTR => continue,
-                .INVAL => unreachable, // Invalid argument passed.
-                .ISCONN => unreachable, // connection-mode socket was connected already but a recipient was specified
-                .MSGSIZE => return error.MessageTooBig,
-                .NOBUFS => return error.SystemResources,
-                .NOMEM => return error.SystemResources,
-                .NOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
-                .OPNOTSUPP => unreachable, // Some bit in the flags argument is inappropriate for the socket type.
-                .PIPE => return error.BrokenPipe,
-                .AFNOSUPPORT => return error.AddressFamilyNotSupported,
-                .LOOP => return error.SymLinkLoop,
-                .NAMETOOLONG => return error.NameTooLong,
-                .NOENT => return error.FileNotFound,
-                .NOTDIR => return error.NotDir,
-                .HOSTUNREACH => return error.NetworkUnreachable,
-                .NETUNREACH => return error.NetworkUnreachable,
-                .NOTCONN => return error.SocketNotConnected,
-                .NETDOWN => return error.NetworkSubsystemFailed,
-                else => |err| return unexpectedErrno(err),
-            }
-        }
-    }
-}
-
-pub const SendToError = SendMsgError || error{
-    /// The destination address is not reachable by the bound address.
-    UnreachableAddress,
-};
-
-/// Transmit a message to another socket.
-///
-/// The `sendto` call may be used only when the socket is in a connected state (so that the intended
-/// recipient  is  known). The  following call
-///
-///     send(sockfd, buf, len, flags);
-///
-/// is equivalent to
-///
-///     sendto(sockfd, buf, len, flags, NULL, 0);
-///
-/// If  sendto()  is used on a connection-mode (`SOCK.STREAM`, `SOCK.SEQPACKET`) socket, the arguments
-/// `dest_addr` and `addrlen` are asserted to be `null` and `0` respectively, and asserted
-/// that the socket was actually connected.
-/// Otherwise, the address of the target is given by `dest_addr` with `addrlen` specifying  its  size.
-///
-/// If the message is too long to pass atomically through the underlying protocol,
-/// `SendError.MessageTooBig` is returned, and the message is not transmitted.
-///
-/// There is no  indication  of  failure  to  deliver.
-///
-/// When the message does not fit into the send buffer of  the  socket,  `sendto`  normally  blocks,
-/// unless  the socket has been placed in nonblocking I/O mode.  In nonblocking mode it would fail
-/// with `SendError.WouldBlock`.  The `select` call may be used  to  determine when it is
-/// possible to send more data.
-pub fn sendto(
-    /// The file descriptor of the sending socket.
-    sockfd: socket_t,
-    /// Message to send.
-    buf: []const u8,
-    flags: u32,
-    dest_addr: ?*const sockaddr,
-    addrlen: socklen_t,
-) SendToError!usize {
-    if (builtin.os.tag == .windows) {
-        switch (windows.sendto(sockfd, buf.ptr, buf.len, flags, dest_addr, addrlen)) {
-            windows.ws2_32.SOCKET_ERROR => switch (windows.ws2_32.WSAGetLastError()) {
-                .WSAEACCES => return error.AccessDenied,
-                .WSAEADDRNOTAVAIL => return error.AddressNotAvailable,
-                .WSAECONNRESET => return error.ConnectionResetByPeer,
-                .WSAEMSGSIZE => return error.MessageTooBig,
-                .WSAENOBUFS => return error.SystemResources,
-                .WSAENOTSOCK => return error.FileDescriptorNotASocket,
-                .WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported,
-                .WSAEDESTADDRREQ => unreachable, // A destination address is required.
-                .WSAEFAULT => unreachable, // The lpBuffers, lpTo, lpOverlapped, lpNumberOfBytesSent, or lpCompletionRoutine parameters are not part of the user address space, or the lpTo parameter is too small.
-                .WSAEHOSTUNREACH => return error.NetworkUnreachable,
-                // TODO: WSAEINPROGRESS, WSAEINTR
-                .WSAEINVAL => unreachable,
-                .WSAENETDOWN => return error.NetworkSubsystemFailed,
-                .WSAENETRESET => return error.ConnectionResetByPeer,
-                .WSAENETUNREACH => return error.NetworkUnreachable,
-                .WSAENOTCONN => return error.SocketNotConnected,
-                .WSAESHUTDOWN => unreachable, // The socket has been shut down; it is not possible to WSASendTo on a socket after shutdown has been invoked with how set to SD_SEND or SD_BOTH.
-                .WSAEWOULDBLOCK => return error.WouldBlock,
-                .WSANOTINITIALISED => unreachable, // A successful WSAStartup call must occur before using this function.
-                else => |err| return windows.unexpectedWSAError(err),
-            },
-            else => |rc| return @intCast(rc),
-        }
-    }
-    while (true) {
-        const rc = system.sendto(sockfd, buf.ptr, buf.len, flags, dest_addr, addrlen);
-        switch (errno(rc)) {
-            .SUCCESS => return @intCast(rc),
-
-            .ACCES => return error.AccessDenied,
-            .AGAIN => return error.WouldBlock,
-            .ALREADY => return error.FastOpenAlreadyInProgress,
-            .BADF => unreachable, // always a race condition
-            .CONNRESET => return error.ConnectionResetByPeer,
-            .DESTADDRREQ => unreachable, // The socket is not connection-mode, and no peer address is set.
-            .FAULT => unreachable, // An invalid user space address was specified for an argument.
-            .INTR => continue,
-            .INVAL => return error.UnreachableAddress,
-            .ISCONN => unreachable, // connection-mode socket was connected already but a recipient was specified
-            .MSGSIZE => return error.MessageTooBig,
-            .NOBUFS => return error.SystemResources,
-            .NOMEM => return error.SystemResources,
-            .NOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
-            .OPNOTSUPP => unreachable, // Some bit in the flags argument is inappropriate for the socket type.
-            .PIPE => return error.BrokenPipe,
-            .AFNOSUPPORT => return error.AddressFamilyNotSupported,
-            .LOOP => return error.SymLinkLoop,
-            .NAMETOOLONG => return error.NameTooLong,
-            .NOENT => return error.FileNotFound,
-            .NOTDIR => return error.NotDir,
-            .HOSTUNREACH => return error.NetworkUnreachable,
-            .NETUNREACH => return error.NetworkUnreachable,
-            .NOTCONN => return error.SocketNotConnected,
-            .NETDOWN => return error.NetworkSubsystemFailed,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-/// Transmit a message to another socket.
-///
-/// The `send` call may be used only when the socket is in a connected state (so that the intended
-/// recipient  is  known).   The  only  difference  between `send` and `write` is the presence of
-/// flags.  With a zero flags argument, `send` is equivalent to  `write`.   Also,  the  following
-/// call
-///
-///     send(sockfd, buf, len, flags);
-///
-/// is equivalent to
-///
-///     sendto(sockfd, buf, len, flags, NULL, 0);
-///
-/// There is no  indication  of  failure  to  deliver.
-///
-/// When the message does not fit into the send buffer of  the  socket,  `send`  normally  blocks,
-/// unless  the socket has been placed in nonblocking I/O mode.  In nonblocking mode it would fail
-/// with `SendError.WouldBlock`.  The `select` call may be used  to  determine when it is
-/// possible to send more data.
-pub fn send(
-    /// The file descriptor of the sending socket.
-    sockfd: socket_t,
-    buf: []const u8,
-    flags: u32,
-) SendError!usize {
-    return sendto(sockfd, buf, flags, null, 0) catch |err| switch (err) {
-        error.AddressFamilyNotSupported => unreachable,
-        error.SymLinkLoop => unreachable,
-        error.NameTooLong => unreachable,
-        error.FileNotFound => unreachable,
-        error.NotDir => unreachable,
-        error.NetworkUnreachable => unreachable,
-        error.AddressNotAvailable => unreachable,
-        error.SocketNotConnected => unreachable,
-        error.UnreachableAddress => unreachable,
-        else => |e| return e,
-    };
-}
-
-pub const SendFileError = PReadError || WriteError || SendError;
-
-fn count_iovec_bytes(iovs: []const iovec_const) usize {
-    var count: usize = 0;
-    for (iovs) |iov| {
-        count += iov.iov_len;
-    }
-    return count;
-}
-
-/// Transfer data between file descriptors, with optional headers and trailers.
-/// Returns the number of bytes written, which can be zero.
-///
-/// The `sendfile` call copies `in_len` bytes from one file descriptor to another. When possible,
-/// this is done within the operating system kernel, which can provide better performance
-/// characteristics than transferring data from kernel to user space and back, such as with
-/// `read` and `write` calls. When `in_len` is `0`, it means to copy until the end of the input file has been
-/// reached. Note, however, that partial writes are still possible in this case.
-///
-/// `in_fd` must be a file descriptor opened for reading, and `out_fd` must be a file descriptor
-/// opened for writing. They may be any kind of file descriptor; however, if `in_fd` is not a regular
-/// file system file, it may cause this function to fall back to calling `read` and `write`, in which case
-/// atomicity guarantees no longer apply.
-///
-/// Copying begins reading at `in_offset`. The input file descriptor seek position is ignored and not updated.
-/// If the output file descriptor has a seek position, it is updated as bytes are written. When
-/// `in_offset` is past the end of the input file, it successfully reads 0 bytes.
-///
-/// `flags` has different meanings per operating system; refer to the respective man pages.
-///
-/// These systems support atomically sending everything, including headers and trailers:
-/// * macOS
-/// * FreeBSD
-///
-/// These systems support in-kernel data copying, but headers and trailers are not sent atomically:
-/// * Linux
-///
-/// Other systems fall back to calling `read` / `write`.
-///
-/// Linux has a limit on how many bytes may be transferred in one `sendfile` call, which is `0x7ffff000`
-/// on both 64-bit and 32-bit systems. This is due to using a signed C int as the return value, as
-/// well as stuffing the errno codes into the last `4096` values. This is noted on the `sendfile` man page.
-/// The limit on Darwin is `0x7fffffff`, trying to write more than that returns EINVAL.
-/// The corresponding POSIX limit on this is `math.maxInt(isize)`.
-pub fn sendfile(
-    out_fd: fd_t,
-    in_fd: fd_t,
-    in_offset: u64,
-    in_len: u64,
-    headers: []const iovec_const,
-    trailers: []const iovec_const,
-    flags: u32,
-) SendFileError!usize {
-    var header_done = false;
-    var total_written: usize = 0;
-
-    // Prevents EOVERFLOW.
-    const size_t = std.meta.Int(.unsigned, @typeInfo(usize).Int.bits - 1);
-    const max_count = switch (builtin.os.tag) {
-        .linux => 0x7ffff000,
-        .macos, .ios, .watchos, .tvos => math.maxInt(i32),
-        else => math.maxInt(size_t),
-    };
-
-    switch (builtin.os.tag) {
-        .linux => sf: {
-            // sendfile() first appeared in Linux 2.2, glibc 2.1.
-            const call_sf = comptime if (builtin.link_libc)
-                std.c.versionCheck(.{ .major = 2, .minor = 1, .patch = 0 })
-            else
-                builtin.os.version_range.linux.range.max.order(.{ .major = 2, .minor = 2, .patch = 0 }) != .lt;
-            if (!call_sf) break :sf;
-
-            if (headers.len != 0) {
-                const amt = try writev(out_fd, headers);
-                total_written += amt;
-                if (amt < count_iovec_bytes(headers)) return total_written;
-                header_done = true;
-            }
-
-            // Here we match BSD behavior, making a zero count value send as many bytes as possible.
-            const adjusted_count = if (in_len == 0) max_count else @min(in_len, max_count);
-
-            const sendfile_sym = if (lfs64_abi) system.sendfile64 else system.sendfile;
-            while (true) {
-                var offset: off_t = @bitCast(in_offset);
-                const rc = sendfile_sym(out_fd, in_fd, &offset, adjusted_count);
-                switch (errno(rc)) {
-                    .SUCCESS => {
-                        const amt: usize = @bitCast(rc);
-                        total_written += amt;
-                        if (in_len == 0 and amt == 0) {
-                            // We have detected EOF from `in_fd`.
-                            break;
-                        } else if (amt < in_len) {
-                            return total_written;
-                        } else {
-                            break;
-                        }
-                    },
-
-                    .BADF => unreachable, // Always a race condition.
-                    .FAULT => unreachable, // Segmentation fault.
-                    .OVERFLOW => unreachable, // We avoid passing too large of a `count`.
-                    .NOTCONN => return error.BrokenPipe, // `out_fd` is an unconnected socket
-
-                    .INVAL, .NOSYS => {
-                        // EINVAL could be any of the following situations:
-                        // * Descriptor is not valid or locked
-                        // * an mmap(2)-like operation is  not  available  for in_fd
-                        // * count is negative
-                        // * out_fd has the APPEND flag set
-                        // Because of the "mmap(2)-like operation" possibility, we fall back to doing read/write
-                        // manually, the same as ENOSYS.
-                        break :sf;
-                    },
-                    .AGAIN => return error.WouldBlock,
-                    .IO => return error.InputOutput,
-                    .PIPE => return error.BrokenPipe,
-                    .NOMEM => return error.SystemResources,
-                    .NXIO => return error.Unseekable,
-                    .SPIPE => return error.Unseekable,
-                    else => |err| {
-                        unexpectedErrno(err) catch {};
-                        break :sf;
-                    },
-                }
-            }
-
-            if (trailers.len != 0) {
-                total_written += try writev(out_fd, trailers);
-            }
-
-            return total_written;
-        },
-        .freebsd => sf: {
-            var hdtr_data: std.c.sf_hdtr = undefined;
-            var hdtr: ?*std.c.sf_hdtr = null;
-            if (headers.len != 0 or trailers.len != 0) {
-                // Here we carefully avoid `@intCast` by returning partial writes when
-                // too many io vectors are provided.
-                const hdr_cnt = math.cast(u31, headers.len) orelse math.maxInt(u31);
-                if (headers.len > hdr_cnt) return writev(out_fd, headers);
-
-                const trl_cnt = math.cast(u31, trailers.len) orelse math.maxInt(u31);
-
-                hdtr_data = std.c.sf_hdtr{
-                    .headers = headers.ptr,
-                    .hdr_cnt = hdr_cnt,
-                    .trailers = trailers.ptr,
-                    .trl_cnt = trl_cnt,
-                };
-                hdtr = &hdtr_data;
-            }
-
-            while (true) {
-                var sbytes: off_t = undefined;
-                const err = errno(system.sendfile(in_fd, out_fd, @bitCast(in_offset), @min(in_len, max_count), hdtr, &sbytes, flags));
-                const amt: usize = @bitCast(sbytes);
-                switch (err) {
-                    .SUCCESS => return amt,
-
-                    .BADF => unreachable, // Always a race condition.
-                    .FAULT => unreachable, // Segmentation fault.
-                    .NOTCONN => return error.BrokenPipe, // `out_fd` is an unconnected socket
-
-                    .INVAL, .OPNOTSUPP, .NOTSOCK, .NOSYS => {
-                        // EINVAL could be any of the following situations:
-                        // * The fd argument is not a regular file.
-                        // * The s argument is not a SOCK.STREAM type socket.
-                        // * The offset argument is negative.
-                        // Because of some of these possibilities, we fall back to doing read/write
-                        // manually, the same as ENOSYS.
-                        break :sf;
-                    },
-
-                    .INTR => if (amt != 0) return amt else continue,
-
-                    .AGAIN => if (amt != 0) {
-                        return amt;
-                    } else {
-                        return error.WouldBlock;
-                    },
-
-                    .BUSY => if (amt != 0) {
-                        return amt;
-                    } else {
-                        return error.WouldBlock;
-                    },
-
-                    .IO => return error.InputOutput,
-                    .NOBUFS => return error.SystemResources,
-                    .PIPE => return error.BrokenPipe,
-
-                    else => {
-                        unexpectedErrno(err) catch {};
-                        if (amt != 0) {
-                            return amt;
-                        } else {
-                            break :sf;
-                        }
-                    },
-                }
-            }
-        },
-        .macos, .ios, .tvos, .watchos => sf: {
-            var hdtr_data: std.c.sf_hdtr = undefined;
-            var hdtr: ?*std.c.sf_hdtr = null;
-            if (headers.len != 0 or trailers.len != 0) {
-                // Here we carefully avoid `@intCast` by returning partial writes when
-                // too many io vectors are provided.
-                const hdr_cnt = math.cast(u31, headers.len) orelse math.maxInt(u31);
-                if (headers.len > hdr_cnt) return writev(out_fd, headers);
-
-                const trl_cnt = math.cast(u31, trailers.len) orelse math.maxInt(u31);
-
-                hdtr_data = std.c.sf_hdtr{
-                    .headers = headers.ptr,
-                    .hdr_cnt = hdr_cnt,
-                    .trailers = trailers.ptr,
-                    .trl_cnt = trl_cnt,
-                };
-                hdtr = &hdtr_data;
-            }
-
-            while (true) {
-                var sbytes: off_t = @min(in_len, max_count);
-                const err = errno(system.sendfile(in_fd, out_fd, @bitCast(in_offset), &sbytes, hdtr, flags));
-                const amt: usize = @bitCast(sbytes);
-                switch (err) {
-                    .SUCCESS => return amt,
-
-                    .BADF => unreachable, // Always a race condition.
-                    .FAULT => unreachable, // Segmentation fault.
-                    .INVAL => unreachable,
-                    .NOTCONN => return error.BrokenPipe, // `out_fd` is an unconnected socket
-
-                    .OPNOTSUPP, .NOTSOCK, .NOSYS => break :sf,
-
-                    .INTR => if (amt != 0) return amt else continue,
-
-                    .AGAIN => if (amt != 0) {
-                        return amt;
-                    } else {
-                        return error.WouldBlock;
-                    },
-
-                    .IO => return error.InputOutput,
-                    .PIPE => return error.BrokenPipe,
-
-                    else => {
-                        unexpectedErrno(err) catch {};
-                        if (amt != 0) {
-                            return amt;
-                        } else {
-                            break :sf;
-                        }
-                    },
-                }
-            }
-        },
-        else => {}, // fall back to read/write
-    }
-
-    if (headers.len != 0 and !header_done) {
-        const amt = try writev(out_fd, headers);
-        total_written += amt;
-        if (amt < count_iovec_bytes(headers)) return total_written;
-    }
-
-    rw: {
-        var buf: [8 * 4096]u8 = undefined;
-        // Here we match BSD behavior, making a zero count value send as many bytes as possible.
-        const adjusted_count = if (in_len == 0) buf.len else @min(buf.len, in_len);
-        const amt_read = try pread(in_fd, buf[0..adjusted_count], in_offset);
-        if (amt_read == 0) {
-            if (in_len == 0) {
-                // We have detected EOF from `in_fd`.
-                break :rw;
-            } else {
-                return total_written;
-            }
-        }
-        const amt_written = try write(out_fd, buf[0..amt_read]);
-        total_written += amt_written;
-        if (amt_written < in_len or in_len == 0) return total_written;
-    }
-
-    if (trailers.len != 0) {
-        total_written += try writev(out_fd, trailers);
-    }
-
-    return total_written;
-}
-
-pub const CopyFileRangeError = error{
-    FileTooBig,
-    InputOutput,
-    /// `fd_in` is not open for reading; or `fd_out` is not open  for  writing;
-    /// or the  `APPEND`  flag  is  set  for `fd_out`.
-    FilesOpenedWithWrongFlags,
-    IsDir,
-    OutOfMemory,
-    NoSpaceLeft,
-    Unseekable,
-    PermissionDenied,
-    SwapFile,
-    CorruptedData,
-} || PReadError || PWriteError || UnexpectedError;
-
-var has_copy_file_range_syscall = std.atomic.Value(bool).init(true);
-
-/// Transfer data between file descriptors at specified offsets.
-/// Returns the number of bytes written, which can less than requested.
-///
-/// The `copy_file_range` call copies `len` bytes from one file descriptor to another. When possible,
-/// this is done within the operating system kernel, which can provide better performance
-/// characteristics than transferring data from kernel to user space and back, such as with
-/// `pread` and `pwrite` calls.
-///
-/// `fd_in` must be a file descriptor opened for reading, and `fd_out` must be a file descriptor
-/// opened for writing. They may be any kind of file descriptor; however, if `fd_in` is not a regular
-/// file system file, it may cause this function to fall back to calling `pread` and `pwrite`, in which case
-/// atomicity guarantees no longer apply.
-///
-/// If `fd_in` and `fd_out` are the same, source and target ranges must not overlap.
-/// The file descriptor seek positions are ignored and not updated.
-/// When `off_in` is past the end of the input file, it successfully reads 0 bytes.
-///
-/// `flags` has different meanings per operating system; refer to the respective man pages.
-///
-/// These systems support in-kernel data copying:
-/// * Linux 4.5 (cross-filesystem 5.3)
-/// * FreeBSD 13.0
-///
-/// Other systems fall back to calling `pread` / `pwrite`.
-///
-/// Maximum offsets on Linux and FreeBSD are `math.maxInt(i64)`.
-pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len: usize, flags: u32) CopyFileRangeError!usize {
-    if ((comptime builtin.os.isAtLeast(.freebsd, .{ .major = 13, .minor = 0, .patch = 0 }) orelse false) or
-        ((comptime builtin.os.isAtLeast(.linux, .{ .major = 4, .minor = 5, .patch = 0 }) orelse false and
-        std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 })) and
-        has_copy_file_range_syscall.load(.monotonic)))
-    {
-        var off_in_copy: i64 = @bitCast(off_in);
-        var off_out_copy: i64 = @bitCast(off_out);
-
-        while (true) {
-            const rc = system.copy_file_range(fd_in, &off_in_copy, fd_out, &off_out_copy, len, flags);
-            if (builtin.os.tag == .freebsd) {
-                switch (system.getErrno(rc)) {
-                    .SUCCESS => return @intCast(rc),
-                    .BADF => return error.FilesOpenedWithWrongFlags,
-                    .FBIG => return error.FileTooBig,
-                    .IO => return error.InputOutput,
-                    .ISDIR => return error.IsDir,
-                    .NOSPC => return error.NoSpaceLeft,
-                    .INVAL => break, // these may not be regular files, try fallback
-                    .INTEGRITY => return error.CorruptedData,
-                    .INTR => continue,
-                    else => |err| return unexpectedErrno(err),
-                }
-            } else { // assume linux
-                switch (system.getErrno(rc)) {
-                    .SUCCESS => return @intCast(rc),
-                    .BADF => return error.FilesOpenedWithWrongFlags,
-                    .FBIG => return error.FileTooBig,
-                    .IO => return error.InputOutput,
-                    .ISDIR => return error.IsDir,
-                    .NOSPC => return error.NoSpaceLeft,
-                    .INVAL => break, // these may not be regular files, try fallback
-                    .NOMEM => return error.OutOfMemory,
-                    .OVERFLOW => return error.Unseekable,
-                    .PERM => return error.PermissionDenied,
-                    .TXTBSY => return error.SwapFile,
-                    .XDEV => break, // support for cross-filesystem copy added in Linux 5.3, use fallback
-                    .NOSYS => { // syscall added in Linux 4.5, use fallback
-                        has_copy_file_range_syscall.store(false, .monotonic);
-                        break;
-                    },
-                    else => |err| return unexpectedErrno(err),
-                }
-            }
-        }
-    }
-
-    var buf: [8 * 4096]u8 = undefined;
-    const amt_read = try pread(fd_in, buf[0..@min(buf.len, len)], off_in);
-    if (amt_read == 0) return 0;
-    return pwrite(fd_out, buf[0..amt_read], off_out);
-}
-
-pub const PollError = error{
-    /// The network subsystem has failed.
-    NetworkSubsystemFailed,
-
-    /// The kernel had no space to allocate file descriptor tables.
-    SystemResources,
-} || UnexpectedError;
-
-pub fn poll(fds: []pollfd, timeout: i32) PollError!usize {
-    while (true) {
-        const fds_count = math.cast(nfds_t, fds.len) orelse return error.SystemResources;
-        const rc = system.poll(fds.ptr, fds_count, timeout);
-        if (builtin.os.tag == .windows) {
-            if (rc == windows.ws2_32.SOCKET_ERROR) {
-                switch (windows.ws2_32.WSAGetLastError()) {
-                    .WSANOTINITIALISED => unreachable,
-                    .WSAENETDOWN => return error.NetworkSubsystemFailed,
-                    .WSAENOBUFS => return error.SystemResources,
-                    // TODO: handle more errors
-                    else => |err| return windows.unexpectedWSAError(err),
-                }
-            } else {
-                return @intCast(rc);
-            }
-        } else {
-            switch (errno(rc)) {
-                .SUCCESS => return @intCast(rc),
-                .FAULT => unreachable,
-                .INTR => continue,
-                .INVAL => unreachable,
-                .NOMEM => return error.SystemResources,
-                else => |err| return unexpectedErrno(err),
-            }
-        }
-        unreachable;
-    }
-}
-
-pub const PPollError = error{
-    /// The operation was interrupted by a delivery of a signal before it could complete.
-    SignalInterrupt,
-
-    /// The kernel had no space to allocate file descriptor tables.
-    SystemResources,
-} || UnexpectedError;
-
-pub fn ppoll(fds: []pollfd, timeout: ?*const timespec, mask: ?*const sigset_t) PPollError!usize {
-    var ts: timespec = undefined;
-    var ts_ptr: ?*timespec = null;
-    if (timeout) |timeout_ns| {
-        ts_ptr = &ts;
-        ts = timeout_ns.*;
-    }
-    const fds_count = math.cast(nfds_t, fds.len) orelse return error.SystemResources;
-    const rc = system.ppoll(fds.ptr, fds_count, ts_ptr, mask);
-    switch (errno(rc)) {
-        .SUCCESS => return @intCast(rc),
-        .FAULT => unreachable,
-        .INTR => return error.SignalInterrupt,
-        .INVAL => unreachable,
-        .NOMEM => return error.SystemResources,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub const RecvFromError = error{
-    /// The socket is marked nonblocking and the requested operation would block, and
-    /// there is no global event loop configured.
-    WouldBlock,
-
-    /// A remote host refused to allow the network connection, typically because it is not
-    /// running the requested service.
-    ConnectionRefused,
-
-    /// Could not allocate kernel memory.
-    SystemResources,
-
-    ConnectionResetByPeer,
-    ConnectionTimedOut,
-
-    /// The socket has not been bound.
-    SocketNotBound,
-
-    /// The UDP message was too big for the buffer and part of it has been discarded
-    MessageTooBig,
-
-    /// The network subsystem has failed.
-    NetworkSubsystemFailed,
-
-    /// The socket is not connected (connection-oriented sockets only).
-    SocketNotConnected,
-} || UnexpectedError;
-
-pub fn recv(sock: socket_t, buf: []u8, flags: u32) RecvFromError!usize {
-    return recvfrom(sock, buf, flags, null, null);
-}
-
-/// If `sockfd` is opened in non blocking mode, the function will
-/// return error.WouldBlock when EAGAIN is received.
-pub fn recvfrom(
-    sockfd: socket_t,
-    buf: []u8,
-    flags: u32,
-    src_addr: ?*sockaddr,
-    addrlen: ?*socklen_t,
-) RecvFromError!usize {
-    while (true) {
-        const rc = system.recvfrom(sockfd, buf.ptr, buf.len, flags, src_addr, addrlen);
-        if (builtin.os.tag == .windows) {
-            if (rc == windows.ws2_32.SOCKET_ERROR) {
-                switch (windows.ws2_32.WSAGetLastError()) {
-                    .WSANOTINITIALISED => unreachable,
-                    .WSAECONNRESET => return error.ConnectionResetByPeer,
-                    .WSAEINVAL => return error.SocketNotBound,
-                    .WSAEMSGSIZE => return error.MessageTooBig,
-                    .WSAENETDOWN => return error.NetworkSubsystemFailed,
-                    .WSAENOTCONN => return error.SocketNotConnected,
-                    .WSAEWOULDBLOCK => return error.WouldBlock,
-                    .WSAETIMEDOUT => return error.ConnectionTimedOut,
-                    // TODO: handle more errors
-                    else => |err| return windows.unexpectedWSAError(err),
-                }
-            } else {
-                return @intCast(rc);
-            }
-        } else {
-            switch (errno(rc)) {
-                .SUCCESS => return @intCast(rc),
-                .BADF => unreachable, // always a race condition
-                .FAULT => unreachable,
-                .INVAL => unreachable,
-                .NOTCONN => return error.SocketNotConnected,
-                .NOTSOCK => unreachable,
-                .INTR => continue,
-                .AGAIN => return error.WouldBlock,
-                .NOMEM => return error.SystemResources,
-                .CONNREFUSED => return error.ConnectionRefused,
-                .CONNRESET => return error.ConnectionResetByPeer,
-                .TIMEDOUT => return error.ConnectionTimedOut,
-                else => |err| return unexpectedErrno(err),
-            }
-        }
-    }
-}
-
-pub const DnExpandError = error{InvalidDnsPacket};
-
-pub fn dn_expand(
-    msg: []const u8,
-    comp_dn: []const u8,
-    exp_dn: []u8,
-) DnExpandError!usize {
-    // This implementation is ported from musl libc.
-    // A more idiomatic "ziggy" implementation would be welcome.
-    var p = comp_dn.ptr;
-    var len: usize = std.math.maxInt(usize);
-    const end = msg.ptr + msg.len;
-    if (p == end or exp_dn.len == 0) return error.InvalidDnsPacket;
-    var dest = exp_dn.ptr;
-    const dend = dest + @min(exp_dn.len, 254);
-    // detect reference loop using an iteration counter
-    var i: usize = 0;
-    while (i < msg.len) : (i += 2) {
-        // loop invariants: p<end, dest<dend
-        if ((p[0] & 0xc0) != 0) {
-            if (p + 1 == end) return error.InvalidDnsPacket;
-            const j = @as(usize, p[0] & 0x3f) << 8 | p[1];
-            if (len == std.math.maxInt(usize)) len = @intFromPtr(p) + 2 - @intFromPtr(comp_dn.ptr);
-            if (j >= msg.len) return error.InvalidDnsPacket;
-            p = msg.ptr + j;
-        } else if (p[0] != 0) {
-            if (dest != exp_dn.ptr) {
-                dest[0] = '.';
-                dest += 1;
-            }
-            var j = p[0];
-            p += 1;
-            if (j >= @intFromPtr(end) - @intFromPtr(p) or j >= @intFromPtr(dend) - @intFromPtr(dest)) {
-                return error.InvalidDnsPacket;
-            }
-            while (j != 0) {
-                j -= 1;
-                dest[0] = p[0];
-                dest += 1;
-                p += 1;
-            }
-        } else {
-            dest[0] = 0;
-            if (len == std.math.maxInt(usize)) len = @intFromPtr(p) + 1 - @intFromPtr(comp_dn.ptr);
-            return len;
-        }
-    }
-    return error.InvalidDnsPacket;
-}
-
-pub const SetSockOptError = error{
-    /// The socket is already connected, and a specified option cannot be set while the socket is connected.
-    AlreadyConnected,
-
-    /// The option is not supported by the protocol.
-    InvalidProtocolOption,
-
-    /// The send and receive timeout values are too big to fit into the timeout fields in the socket structure.
-    TimeoutTooBig,
-
-    /// Insufficient resources are available in the system to complete the call.
-    SystemResources,
-
-    // Setting the socket option requires more elevated permissions.
-    PermissionDenied,
-
-    NetworkSubsystemFailed,
-    FileDescriptorNotASocket,
-    SocketNotBound,
-    NoDevice,
-} || UnexpectedError;
-
-/// Set a socket's options.
-pub fn setsockopt(fd: socket_t, level: u32, optname: u32, opt: []const u8) SetSockOptError!void {
-    if (builtin.os.tag == .windows) {
-        const rc = windows.ws2_32.setsockopt(fd, @intCast(level), @intCast(optname), opt.ptr, @intCast(opt.len));
-        if (rc == windows.ws2_32.SOCKET_ERROR) {
-            switch (windows.ws2_32.WSAGetLastError()) {
-                .WSANOTINITIALISED => unreachable,
-                .WSAENETDOWN => return error.NetworkSubsystemFailed,
-                .WSAEFAULT => unreachable,
-                .WSAENOTSOCK => return error.FileDescriptorNotASocket,
-                .WSAEINVAL => return error.SocketNotBound,
-                else => |err| return windows.unexpectedWSAError(err),
-            }
-        }
-        return;
-    } 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,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-pub const MemFdCreateError = error{
-    SystemFdQuotaExceeded,
-    ProcessFdQuotaExceeded,
-    OutOfMemory,
-
-    /// memfd_create is available in Linux 3.17 and later. This error is returned
-    /// for older kernel versions.
-    SystemOutdated,
-} || UnexpectedError;
-
-pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t {
-    switch (builtin.os.tag) {
-        .linux => {
-            // memfd_create is available only in glibc versions starting with 2.27.
-            const use_c = std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 });
-            const sys = if (use_c) std.c else linux;
-            const getErrno = if (use_c) std.c.getErrno else linux.getErrno;
-            const rc = sys.memfd_create(name, flags);
-            switch (getErrno(rc)) {
-                .SUCCESS => return @intCast(rc),
-                .FAULT => unreachable, // name has invalid memory
-                .INVAL => unreachable, // name/flags are faulty
-                .NFILE => return error.SystemFdQuotaExceeded,
-                .MFILE => return error.ProcessFdQuotaExceeded,
-                .NOMEM => return error.OutOfMemory,
-                .NOSYS => return error.SystemOutdated,
-                else => |err| return unexpectedErrno(err),
-            }
-        },
-        .freebsd => {
-            if (comptime builtin.os.version_range.semver.max.order(.{ .major = 13, .minor = 0, .patch = 0 }) == .lt)
-                @compileError("memfd_create is unavailable on FreeBSD < 13.0");
-            const rc = system.memfd_create(name, flags);
-            switch (errno(rc)) {
-                .SUCCESS => return rc,
-                .BADF => unreachable, // name argument NULL
-                .INVAL => unreachable, // name too long or invalid/unsupported flags.
-                .MFILE => return error.ProcessFdQuotaExceeded,
-                .NFILE => return error.SystemFdQuotaExceeded,
-                .NOSYS => return error.SystemOutdated,
-                else => |err| return unexpectedErrno(err),
-            }
-        },
-        else => @compileError("target OS does not support memfd_create()"),
-    }
-}
-
-pub const MFD_NAME_PREFIX = "memfd:";
-pub const MFD_MAX_NAME_LEN = NAME_MAX - MFD_NAME_PREFIX.len;
-fn toMemFdPath(name: []const u8) ![MFD_MAX_NAME_LEN:0]u8 {
-    var path_with_null: [MFD_MAX_NAME_LEN:0]u8 = undefined;
-    // >= rather than > to make room for the null byte
-    if (name.len >= MFD_MAX_NAME_LEN) return error.NameTooLong;
-    @memcpy(path_with_null[0..name.len], name);
-    path_with_null[name.len] = 0;
-    return path_with_null;
-}
-
-pub fn memfd_create(name: []const u8, flags: u32) !fd_t {
-    const name_t = try toMemFdPath(name);
-    return memfd_createZ(&name_t, flags);
-}
-
-pub fn getrusage(who: i32) rusage {
-    var result: rusage = undefined;
-    const rc = system.getrusage(who, &result);
-    switch (errno(rc)) {
-        .SUCCESS => return result,
-        .INVAL => unreachable,
-        .FAULT => unreachable,
-        else => unreachable,
-    }
-}
-
-pub const TIOCError = error{NotATerminal};
-
-pub const TermiosGetError = TIOCError || UnexpectedError;
-
-pub fn tcgetattr(handle: fd_t) TermiosGetError!termios {
-    while (true) {
-        var term: termios = undefined;
-        switch (errno(system.tcgetattr(handle, &term))) {
-            .SUCCESS => return term,
-            .INTR => continue,
-            .BADF => unreachable,
-            .NOTTY => return error.NotATerminal,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-pub const TermiosSetError = TermiosGetError || error{ProcessOrphaned};
-
-pub fn tcsetattr(handle: fd_t, optional_action: TCSA, termios_p: termios) TermiosSetError!void {
-    while (true) {
-        switch (errno(system.tcsetattr(handle, optional_action, &termios_p))) {
-            .SUCCESS => return,
-            .BADF => unreachable,
-            .INTR => continue,
-            .INVAL => unreachable,
-            .NOTTY => return error.NotATerminal,
-            .IO => return error.ProcessOrphaned,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-pub const TermioGetPgrpError = TIOCError || UnexpectedError;
-
-/// Returns the process group ID for the TTY associated with the given handle.
-pub fn tcgetpgrp(handle: fd_t) TermioGetPgrpError!pid_t {
-    while (true) {
-        var pgrp: pid_t = undefined;
-        switch (errno(system.tcgetpgrp(handle, &pgrp))) {
-            .SUCCESS => return pgrp,
-            .BADF => unreachable,
-            .INVAL => unreachable,
-            .INTR => continue,
-            .NOTTY => return error.NotATerminal,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-pub const TermioSetPgrpError = TermioGetPgrpError || error{NotAPgrpMember};
-
-/// Sets the controlling process group ID for given TTY.
-/// handle must be valid fd_t to a TTY associated with calling process.
-/// pgrp must be a valid process group, and the calling process must be a member
-/// of that group.
-pub fn tcsetpgrp(handle: fd_t, pgrp: pid_t) TermioSetPgrpError!void {
-    while (true) {
-        switch (errno(system.tcsetpgrp(handle, &pgrp))) {
-            .SUCCESS => return,
-            .BADF => unreachable,
-            .INVAL => unreachable,
-            .INTR => continue,
-            .NOTTY => return error.NotATerminal,
-            .PERM => return TermioSetPgrpError.NotAPgrpMember,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-pub const IoCtl_SIOCGIFINDEX_Error = error{
-    FileSystem,
-    InterfaceNotFound,
-} || UnexpectedError;
-
-pub fn ioctl_SIOCGIFINDEX(fd: fd_t, ifr: *ifreq) IoCtl_SIOCGIFINDEX_Error!void {
-    while (true) {
-        switch (errno(system.ioctl(fd, SIOCGIFINDEX, @intFromPtr(ifr)))) {
-            .SUCCESS => return,
-            .INVAL => unreachable, // Bad parameters.
-            .NOTTY => unreachable,
-            .NXIO => unreachable,
-            .BADF => unreachable, // Always a race condition.
-            .FAULT => unreachable, // Bad pointer parameter.
-            .INTR => continue,
-            .IO => return error.FileSystem,
-            .NODEV => return error.InterfaceNotFound,
-            else => |err| return unexpectedErrno(err),
-        }
-    }
-}
-
-pub fn signalfd(fd: fd_t, mask: *const sigset_t, flags: u32) !fd_t {
-    const rc = system.signalfd(fd, mask, flags);
-    switch (errno(rc)) {
-        .SUCCESS => return @intCast(rc),
-        .BADF, .INVAL => unreachable,
-        .NFILE => return error.SystemFdQuotaExceeded,
-        .NOMEM => return error.SystemResources,
-        .MFILE => return error.ProcessResources,
-        .NODEV => return error.InodeMountFail,
-        .NOSYS => return error.SystemOutdated,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub const SyncError = error{
-    InputOutput,
-    NoSpaceLeft,
-    DiskQuota,
-    AccessDenied,
-} || UnexpectedError;
-
-/// Write all pending file contents and metadata modifications to all filesystems.
-pub fn sync() void {
-    system.sync();
-}
-
-/// Write all pending file contents and metadata modifications to the filesystem which contains the specified file.
-pub fn syncfs(fd: fd_t) SyncError!void {
-    const rc = system.syncfs(fd);
-    switch (errno(rc)) {
-        .SUCCESS => return,
-        .BADF, .INVAL, .ROFS => unreachable,
-        .IO => return error.InputOutput,
-        .NOSPC => return error.NoSpaceLeft,
-        .DQUOT => return error.DiskQuota,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Write all pending file contents and metadata modifications for the specified file descriptor to the underlying filesystem.
-pub fn fsync(fd: fd_t) SyncError!void {
-    if (builtin.os.tag == .windows) {
-        if (windows.kernel32.FlushFileBuffers(fd) != 0)
-            return;
-        switch (windows.kernel32.GetLastError()) {
-            .SUCCESS => return,
-            .INVALID_HANDLE => unreachable,
-            .ACCESS_DENIED => return error.AccessDenied, // a sync was performed but the system couldn't update the access time
-            .UNEXP_NET_ERR => return error.InputOutput,
-            else => return error.InputOutput,
-        }
-    }
-    const rc = system.fsync(fd);
-    switch (errno(rc)) {
-        .SUCCESS => return,
-        .BADF, .INVAL, .ROFS => unreachable,
-        .IO => return error.InputOutput,
-        .NOSPC => return error.NoSpaceLeft,
-        .DQUOT => return error.DiskQuota,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-/// Write all pending file contents for the specified file descriptor to the underlying filesystem, but not necessarily the metadata.
-pub fn fdatasync(fd: fd_t) SyncError!void {
-    if (builtin.os.tag == .windows) {
-        return fsync(fd) catch |err| switch (err) {
-            SyncError.AccessDenied => return, // fdatasync doesn't promise that the access time was synced
-            else => return err,
-        };
-    }
-    const rc = system.fdatasync(fd);
-    switch (errno(rc)) {
-        .SUCCESS => return,
-        .BADF, .INVAL, .ROFS => unreachable,
-        .IO => return error.InputOutput,
-        .NOSPC => return error.NoSpaceLeft,
-        .DQUOT => return error.DiskQuota,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub const PrctlError = error{
-    /// Can only occur with PR_SET_SECCOMP/SECCOMP_MODE_FILTER or
-    /// PR_SET_MM/PR_SET_MM_EXE_FILE
-    AccessDenied,
-    /// Can only occur with PR_SET_MM/PR_SET_MM_EXE_FILE
-    InvalidFileDescriptor,
-    InvalidAddress,
-    /// Can only occur with PR_SET_SPECULATION_CTRL, PR_MPX_ENABLE_MANAGEMENT,
-    /// or PR_MPX_DISABLE_MANAGEMENT
-    UnsupportedFeature,
-    /// Can only occur with PR_SET_FP_MODE
-    OperationNotSupported,
-    PermissionDenied,
-} || UnexpectedError;
-
-pub fn prctl(option: PR, args: anytype) PrctlError!u31 {
-    if (@typeInfo(@TypeOf(args)) != .Struct)
-        @compileError("Expected tuple or struct argument, found " ++ @typeName(@TypeOf(args)));
-    if (args.len > 4)
-        @compileError("prctl takes a maximum of 4 optional arguments");
-
-    var buf: [4]usize = undefined;
-    {
-        comptime var i = 0;
-        inline while (i < args.len) : (i += 1) buf[i] = args[i];
-    }
-
-    const rc = system.prctl(@intFromEnum(option), buf[0], buf[1], buf[2], buf[3]);
-    switch (errno(rc)) {
-        .SUCCESS => return @intCast(rc),
-        .ACCES => return error.AccessDenied,
-        .BADF => return error.InvalidFileDescriptor,
-        .FAULT => return error.InvalidAddress,
-        .INVAL => unreachable,
-        .NODEV, .NXIO => return error.UnsupportedFeature,
-        .OPNOTSUPP => return error.OperationNotSupported,
-        .PERM, .BUSY => return error.PermissionDenied,
-        .RANGE => unreachable,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub const GetrlimitError = UnexpectedError;
-
-pub fn getrlimit(resource: rlimit_resource) GetrlimitError!rlimit {
-    const getrlimit_sym = if (lfs64_abi) system.getrlimit64 else system.getrlimit;
-
-    var limits: rlimit = undefined;
-    switch (errno(getrlimit_sym(resource, &limits))) {
-        .SUCCESS => return limits,
-        .FAULT => unreachable, // bogus pointer
-        .INVAL => unreachable,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub const SetrlimitError = error{ PermissionDenied, LimitTooBig } || UnexpectedError;
-
-pub fn setrlimit(resource: rlimit_resource, limits: rlimit) SetrlimitError!void {
-    const setrlimit_sym = if (lfs64_abi) system.setrlimit64 else system.setrlimit;
-
-    switch (errno(setrlimit_sym(resource, &limits))) {
-        .SUCCESS => return,
-        .FAULT => unreachable, // bogus pointer
-        .INVAL => return error.LimitTooBig, // this could also mean "invalid resource", but that would be unreachable
-        .PERM => return error.PermissionDenied,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub const MincoreError = error{
-    /// A kernel resource was temporarily unavailable.
-    SystemResources,
-    /// vec points to an invalid address.
-    InvalidAddress,
-    /// addr is not page-aligned.
-    InvalidSyscall,
-    /// One of the following:
-    /// * length is greater than user space TASK_SIZE - addr
-    /// * addr + length contains unmapped memory
-    OutOfMemory,
-    /// The mincore syscall is not available on this version and configuration
-    /// of this UNIX-like kernel.
-    MincoreUnavailable,
-} || UnexpectedError;
-
-/// Determine whether pages are resident in memory.
-pub fn mincore(ptr: [*]align(mem.page_size) u8, length: usize, vec: [*]u8) MincoreError!void {
-    return switch (errno(system.mincore(ptr, length, vec))) {
-        .SUCCESS => {},
-        .AGAIN => error.SystemResources,
-        .FAULT => error.InvalidAddress,
-        .INVAL => error.InvalidSyscall,
-        .NOMEM => error.OutOfMemory,
-        .NOSYS => error.MincoreUnavailable,
-        else => |err| unexpectedErrno(err),
-    };
-}
-
-pub const MadviseError = error{
-    /// advice is MADV.REMOVE, but the specified address range is not a shared writable mapping.
-    AccessDenied,
-    /// advice is MADV.HWPOISON, but the caller does not have the CAP_SYS_ADMIN capability.
-    PermissionDenied,
-    /// A kernel resource was temporarily unavailable.
-    SystemResources,
-    /// One of the following:
-    /// * addr is not page-aligned or length is negative
-    /// * advice is not valid
-    /// * advice is MADV.DONTNEED or MADV.REMOVE and the specified address range
-    ///   includes locked, Huge TLB pages, or VM_PFNMAP pages.
-    /// * advice is MADV.MERGEABLE or MADV.UNMERGEABLE, but the kernel was not
-    ///   configured with CONFIG_KSM.
-    /// * advice is MADV.FREE or MADV.WIPEONFORK but the specified address range
-    ///   includes file, Huge TLB, MAP.SHARED, or VM_PFNMAP ranges.
-    InvalidSyscall,
-    /// (for MADV.WILLNEED) Paging in this area would exceed the process's
-    /// maximum resident set size.
-    WouldExceedMaximumResidentSetSize,
-    /// One of the following:
-    /// * (for MADV.WILLNEED) Not enough memory: paging in failed.
-    /// * Addresses in the specified range are not currently mapped, or
-    ///   are outside the address space of the process.
-    OutOfMemory,
-    /// The madvise syscall is not available on this version and configuration
-    /// of the Linux kernel.
-    MadviseUnavailable,
-    /// The operating system returned an undocumented error code.
-    Unexpected,
-};
-
-/// Give advice about use of memory.
-/// This syscall is optional and is sometimes configured to be disabled.
-pub fn madvise(ptr: [*]align(mem.page_size) u8, length: usize, advice: u32) MadviseError!void {
-    switch (errno(system.madvise(ptr, length, advice))) {
-        .SUCCESS => return,
-        .ACCES => return error.AccessDenied,
-        .AGAIN => return error.SystemResources,
-        .BADF => unreachable, // The map exists, but the area maps something that isn't a file.
-        .INVAL => return error.InvalidSyscall,
-        .IO => return error.WouldExceedMaximumResidentSetSize,
-        .NOMEM => return error.OutOfMemory,
-        .NOSYS => return error.MadviseUnavailable,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub const PerfEventOpenError = error{
-    /// Returned if the perf_event_attr size value is too small (smaller
-    /// than PERF_ATTR_SIZE_VER0), too big (larger than the page  size),
-    /// or  larger  than the kernel supports and the extra bytes are not
-    /// zero.  When E2BIG is returned, the perf_event_attr size field is
-    /// overwritten by the kernel to be the size of the structure it was
-    /// expecting.
-    TooBig,
-    /// Returned when the requested event requires CAP_SYS_ADMIN permisโ€
-    /// sions  (or a more permissive perf_event paranoid setting).  Some
-    /// common cases where an unprivileged process  may  encounter  this
-    /// error:  attaching  to a process owned by a different user; moniโ€
-    /// toring all processes on a given CPU (i.e.,  specifying  the  pid
-    /// argument  as  -1); and not setting exclude_kernel when the paraโ€
-    /// noid setting requires it.
-    /// Also:
-    /// Returned on many (but not all) architectures when an unsupported
-    /// exclude_hv,  exclude_idle,  exclude_user, or exclude_kernel setโ€
-    /// ting is specified.
-    /// It can also happen, as with EACCES, when the requested event reโ€
-    /// quires   CAP_SYS_ADMIN   permissions   (or   a  more  permissive
-    /// perf_event paranoid setting).  This includes  setting  a  breakโ€
-    /// point on a kernel address, and (since Linux 3.13) setting a kerโ€
-    /// nel function-trace tracepoint.
-    PermissionDenied,
-    /// Returned if another event already has exclusive  access  to  the
-    /// PMU.
-    DeviceBusy,
-    /// Each  opened  event uses one file descriptor.  If a large number
-    /// of events are opened, the per-process limit  on  the  number  of
-    /// open file descriptors will be reached, and no more events can be
-    /// created.
-    ProcessResources,
-    EventRequiresUnsupportedCpuFeature,
-    /// Returned if  you  try  to  add  more  breakpoint
-    /// events than supported by the hardware.
-    TooManyBreakpoints,
-    /// Returned  if PERF_SAMPLE_STACK_USER is set in sample_type and it
-    /// is not supported by hardware.
-    SampleStackNotSupported,
-    /// Returned if an event requiring a specific  hardware  feature  is
-    /// requested  but  there is no hardware support.  This includes reโ€
-    /// questing low-skid events if not supported, branch tracing if  it
-    /// is not available, sampling if no PMU interrupt is available, and
-    /// branch stacks for software events.
-    EventNotSupported,
-    /// Returned  if  PERF_SAMPLE_CALLCHAIN  is   requested   and   samโ€
-    /// ple_max_stack   is   larger   than   the  maximum  specified  in
-    /// /proc/sys/kernel/perf_event_max_stack.
-    SampleMaxStackOverflow,
-    /// Returned if attempting to attach to a process that does not  exist.
-    ProcessNotFound,
-} || UnexpectedError;
-
-pub fn perf_event_open(
-    attr: *linux.perf_event_attr,
-    pid: pid_t,
-    cpu: i32,
-    group_fd: fd_t,
-    flags: usize,
-) PerfEventOpenError!fd_t {
-    const rc = linux.perf_event_open(attr, pid, cpu, group_fd, flags);
-    switch (errno(rc)) {
-        .SUCCESS => return @intCast(rc),
-        .@"2BIG" => return error.TooBig,
-        .ACCES => return error.PermissionDenied,
-        .BADF => unreachable, // group_fd file descriptor is not valid.
-        .BUSY => return error.DeviceBusy,
-        .FAULT => unreachable, // Segmentation fault.
-        .INVAL => unreachable, // Bad attr settings.
-        .INTR => unreachable, // Mixed perf and ftrace handling for a uprobe.
-        .MFILE => return error.ProcessResources,
-        .NODEV => return error.EventRequiresUnsupportedCpuFeature,
-        .NOENT => unreachable, // Invalid type setting.
-        .NOSPC => return error.TooManyBreakpoints,
-        .NOSYS => return error.SampleStackNotSupported,
-        .OPNOTSUPP => return error.EventNotSupported,
-        .OVERFLOW => return error.SampleMaxStackOverflow,
-        .PERM => return error.PermissionDenied,
-        .SRCH => return error.ProcessNotFound,
-        else => |err| return unexpectedErrno(err),
-    }
-}
-
-pub const TimerFdCreateError = error{
-    AccessDenied,
-    ProcessFdQuotaExceeded,
-    SystemFdQuotaExceeded,
-    NoDevice,
-    SystemResources,
-} || UnexpectedError;
-
-pub const TimerFdGetError = error{InvalidHandle} || UnexpectedError;
-pub const TimerFdSetError = TimerFdGetError || error{Canceled};
-
-pub fn timerfd_create(clokid: i32, flags: linux.TFD) TimerFdCreateError!fd_t {
-    const rc = linux.timerfd_create(clokid, flags);
-    return switch (errno(rc)) {
-        .SUCCESS => @intCast(rc),
-        .INVAL => unreachable,
-        .MFILE => return error.ProcessFdQuotaExceeded,
-        .NFILE => return error.SystemFdQuotaExceeded,
-        .NODEV => return error.NoDevice,
-        .NOMEM => return error.SystemResources,
-        .PERM => return error.AccessDenied,
-        else => |err| return unexpectedErrno(err),
-    };
-}
-
-pub fn timerfd_settime(
-    fd: i32,
-    flags: linux.TFD.TIMER,
-    new_value: *const linux.itimerspec,
-    old_value: ?*linux.itimerspec,
-) TimerFdSetError!void {
-    const rc = linux.timerfd_settime(fd, flags, new_value, old_value);
-    return switch (errno(rc)) {
-        .SUCCESS => {},
-        .BADF => error.InvalidHandle,
-        .FAULT => unreachable,
-        .INVAL => unreachable,
-        .CANCELED => error.Canceled,
-        else => |err| return unexpectedErrno(err),
-    };
-}
-
-pub fn timerfd_gettime(fd: i32) TimerFdGetError!linux.itimerspec {
-    var curr_value: linux.itimerspec = undefined;
-    const rc = linux.timerfd_gettime(fd, &curr_value);
-    return switch (errno(rc)) {
-        .SUCCESS => return curr_value,
-        .BADF => error.InvalidHandle,
-        .FAULT => unreachable,
-        .INVAL => unreachable,
-        else => |err| return unexpectedErrno(err),
-    };
-}
-
-pub const PtraceError = error{
-    DeviceBusy,
-    InputOutput,
-    ProcessNotFound,
-    PermissionDenied,
-} || UnexpectedError;
-
-pub fn ptrace(request: u32, pid: pid_t, addr: usize, signal: usize) PtraceError!void {
-    if (builtin.os.tag == .windows or builtin.os.tag == .wasi)
-        @compileError("Unsupported OS");
-
-    return switch (builtin.os.tag) {
-        .linux => switch (errno(linux.ptrace(request, pid, addr, signal, 0))) {
-            .SUCCESS => {},
-            .SRCH => error.ProcessNotFound,
-            .FAULT => unreachable,
-            .INVAL => unreachable,
-            .IO => return error.InputOutput,
-            .PERM => error.PermissionDenied,
-            .BUSY => error.DeviceBusy,
-            else => |err| return unexpectedErrno(err),
-        },
-
-        .macos, .ios, .tvos, .watchos => switch (errno(darwin.ptrace(
-            @intCast(request),
-            pid,
-            @ptrFromInt(addr),
-            @intCast(signal),
-        ))) {
-            .SUCCESS => {},
-            .SRCH => error.ProcessNotFound,
-            .INVAL => unreachable,
-            .PERM => error.PermissionDenied,
-            .BUSY => error.DeviceBusy,
-            else => |err| return unexpectedErrno(err),
-        },
-
-        else => switch (errno(system.ptrace(request, pid, addr, signal))) {
-            .SUCCESS => {},
-            .SRCH => error.ProcessNotFound,
-            .INVAL => unreachable,
-            .PERM => error.PermissionDenied,
-            .BUSY => error.DeviceBusy,
-            else => |err| return unexpectedErrno(err),
-        },
-    };
-}
-
-const lfs64_abi = builtin.os.tag == .linux and builtin.link_libc and builtin.abi.isGnu();
lib/std/pdb.zig
@@ -2,7 +2,6 @@ const std = @import("std.zig");
 const io = std.io;
 const math = std.math;
 const mem = std.mem;
-const os = std.os;
 const coff = std.coff;
 const fs = std.fs;
 const File = std.fs.File;
lib/std/posix.zig
@@ -0,0 +1,7364 @@
+//! POSIX API layer.
+//!
+//! This is more cross platform than using OS-specific APIs, however, it is
+//! lower-level and less portable than other namespaces such as `std.fs` and
+//! `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
+//! require always linking libc because they use it as the stable syscall ABI.
+//!
+//! Operating systems that are not POSIX-compliant are sometimes supported by
+//! this API layer; sometimes not. Generally, an implementation will be
+//! provided only if such implementation is straightforward on that operating
+//! system. Otherwise, programmers are expected to use OS-specific logic to
+//! deal with the exception.
+
+const builtin = @import("builtin");
+const root = @import("root");
+const std = @import("std.zig");
+const mem = std.mem;
+const fs = std.fs;
+const max_path_bytes = fs.MAX_PATH_BYTES;
+const maxInt = std.math.maxInt;
+const cast = std.math.cast;
+const assert = std.debug.assert;
+const native_os = builtin.os.tag;
+
+test {
+    _ = @import("posix/test.zig");
+}
+
+/// Whether to use libc for the POSIX API layer.
+const use_libc = builtin.link_libc or switch (native_os) {
+    .windows, .wasi => true,
+    else => false,
+};
+
+const linux = std.os.linux;
+const windows = std.os.windows;
+const wasi = std.os.wasi;
+
+/// Applications can override the `system` API layer in their root source file.
+/// Otherwise, when linking libc, this is the C API.
+/// When not linking libc, it is the OS-specific system interface.
+pub const system = if (@hasDecl(root, "os") and @hasDecl(root.os, "system") and root.os != @This())
+    root.os.system
+else if (use_libc)
+    std.c
+else switch (native_os) {
+    .linux => linux,
+    .plan9 => std.os.plan9,
+    else => struct {},
+};
+
+pub const AF = system.AF;
+pub const AF_SUN = system.AF_SUN;
+pub const ARCH = system.ARCH;
+pub const AT = system.AT;
+pub const AT_SUN = system.AT_SUN;
+pub const CLOCK = system.CLOCK;
+pub const CPU_COUNT = system.CPU_COUNT;
+pub const CTL = system.CTL;
+pub const DT = system.DT;
+pub const E = system.E;
+pub const Elf_Symndx = system.Elf_Symndx;
+pub const F = system.F;
+pub const FD_CLOEXEC = system.FD_CLOEXEC;
+pub const Flock = system.Flock;
+pub const HOST_NAME_MAX = system.HOST_NAME_MAX;
+pub const HW = system.HW;
+pub const IFNAMESIZE = system.IFNAMESIZE;
+pub const IOV_MAX = system.IOV_MAX;
+pub const IPPROTO = system.IPPROTO;
+pub const KERN = system.KERN;
+pub const Kevent = system.Kevent;
+pub const LOCK = system.LOCK;
+pub const MADV = system.MADV;
+pub const MAP = system.MAP;
+pub const MSF = system.MSF;
+pub const MAX_ADDR_LEN = system.MAX_ADDR_LEN;
+pub const MFD = system.MFD;
+pub const MMAP2_UNIT = system.MMAP2_UNIT;
+pub const MSG = system.MSG;
+pub const NAME_MAX = system.NAME_MAX;
+pub const O = system.O;
+pub const PATH_MAX = system.PATH_MAX;
+pub const POLL = system.POLL;
+pub const POSIX_FADV = system.POSIX_FADV;
+pub const PR = system.PR;
+pub const PROT = system.PROT;
+pub const REG = system.REG;
+pub const RLIM = system.RLIM;
+pub const RR = system.RR;
+pub const S = system.S;
+pub const SA = system.SA;
+pub const SC = system.SC;
+pub const _SC = system._SC;
+pub const SEEK = system.SEEK;
+pub const SHUT = system.SHUT;
+pub const SIG = system.SIG;
+pub const SIOCGIFINDEX = system.SIOCGIFINDEX;
+pub const SO = system.SO;
+pub const SOCK = system.SOCK;
+pub const SOL = system.SOL;
+pub const STDERR_FILENO = system.STDERR_FILENO;
+pub const STDIN_FILENO = system.STDIN_FILENO;
+pub const STDOUT_FILENO = system.STDOUT_FILENO;
+pub const SYS = system.SYS;
+pub const Sigaction = system.Sigaction;
+pub const Stat = system.Stat;
+pub const T = system.T;
+pub const TCSA = system.TCSA;
+pub const TCP = system.TCP;
+pub const VDSO = system.VDSO;
+pub const W = system.W;
+pub const addrinfo = system.addrinfo;
+pub const blkcnt_t = system.blkcnt_t;
+pub const blksize_t = system.blksize_t;
+pub const clock_t = system.clock_t;
+pub const cpu_set_t = system.cpu_set_t;
+pub const dev_t = system.dev_t;
+pub const dl_phdr_info = system.dl_phdr_info;
+pub const empty_sigset = system.empty_sigset;
+pub const filled_sigset = system.filled_sigset;
+pub const fd_t = system.fd_t;
+pub const gid_t = system.gid_t;
+pub const ifreq = system.ifreq;
+pub const ino_t = system.ino_t;
+pub const mcontext_t = system.mcontext_t;
+pub const mode_t = system.mode_t;
+pub const msghdr = system.msghdr;
+pub const msghdr_const = system.msghdr_const;
+pub const nfds_t = system.nfds_t;
+pub const nlink_t = system.nlink_t;
+pub const off_t = system.off_t;
+pub const pid_t = system.pid_t;
+pub const pollfd = system.pollfd;
+pub const port_t = system.port_t;
+pub const port_event = system.port_event;
+pub const port_notify = system.port_notify;
+pub const file_obj = system.file_obj;
+pub const rlim_t = system.rlim_t;
+pub const rlimit = system.rlimit;
+pub const rlimit_resource = system.rlimit_resource;
+pub const rusage = system.rusage;
+pub const sa_family_t = system.sa_family_t;
+pub const siginfo_t = system.siginfo_t;
+pub const sigset_t = system.sigset_t;
+pub const sockaddr = system.sockaddr;
+pub const socklen_t = system.socklen_t;
+pub const stack_t = system.stack_t;
+pub const time_t = system.time_t;
+pub const timespec = system.timespec;
+pub const timestamp_t = system.timestamp_t;
+pub const timeval = system.timeval;
+pub const timezone = system.timezone;
+pub const ucontext_t = system.ucontext_t;
+pub const uid_t = system.uid_t;
+pub const user_desc = system.user_desc;
+pub const utsname = system.utsname;
+pub const winsize = system.winsize;
+
+pub const termios = system.termios;
+pub const CSIZE = system.CSIZE;
+pub const NCCS = system.NCCS;
+pub const cc_t = system.cc_t;
+pub const V = system.V;
+pub const speed_t = system.speed_t;
+pub const tc_iflag_t = system.tc_iflag_t;
+pub const tc_oflag_t = system.tc_oflag_t;
+pub const tc_cflag_t = system.tc_cflag_t;
+pub const tc_lflag_t = system.tc_lflag_t;
+
+pub const F_OK = system.F_OK;
+pub const R_OK = system.R_OK;
+pub const W_OK = system.W_OK;
+pub const X_OK = system.X_OK;
+
+pub const iovec = extern struct {
+    iov_base: [*]u8,
+    iov_len: usize,
+};
+
+pub const iovec_const = extern struct {
+    iov_base: [*]const u8,
+    iov_len: usize,
+};
+
+pub const ACCMODE = enum(u2) {
+    RDONLY = 0,
+    WRONLY = 1,
+    RDWR = 2,
+};
+
+pub const LOG = struct {
+    /// system is unusable
+    pub const EMERG = 0;
+    /// action must be taken immediately
+    pub const ALERT = 1;
+    /// critical conditions
+    pub const CRIT = 2;
+    /// error conditions
+    pub const ERR = 3;
+    /// warning conditions
+    pub const WARNING = 4;
+    /// normal but significant condition
+    pub const NOTICE = 5;
+    /// informational
+    pub const INFO = 6;
+    /// debug-level messages
+    pub const DEBUG = 7;
+};
+
+pub const socket_t = if (native_os == .windows) windows.ws2_32.SOCKET else fd_t;
+
+/// Obtains errno from the return value of a system function call.
+///
+/// For some systems this will obtain the value directly from the syscall return value;
+/// for others it will use a thread-local errno variable. Therefore, this
+/// function only returns a well-defined value when it is called directly after
+/// the system function call whose errno value is intended to be observed.
+pub fn errno(rc: anytype) E {
+    if (use_libc) {
+        return if (rc == -1) @enumFromInt(std.c._errno().*) else .SUCCESS;
+    }
+    const signed: isize = @bitCast(rc);
+    const int = if (signed > -4096 and signed < 0) -signed else 0;
+    return @enumFromInt(int);
+}
+
+/// Closes the file descriptor.
+///
+/// This function is not capable of returning any indication of failure. An
+/// application which wants to ensure writes have succeeded before closing must
+/// call `fsync` before `close`.
+///
+/// The Zig standard library does not support POSIX thread cancellation.
+pub fn close(fd: fd_t) void {
+    if (native_os == .windows) {
+        return windows.CloseHandle(fd);
+    }
+    if (native_os == .wasi and !builtin.link_libc) {
+        _ = std.os.wasi.fd_close(fd);
+        return;
+    }
+    if (builtin.target.isDarwin()) {
+        // This avoids the EINTR problem.
+        switch (errno(std.c.@"close$NOCANCEL"(fd))) {
+            .BADF => unreachable, // Always a race condition.
+            else => return,
+        }
+    }
+    switch (errno(system.close(fd))) {
+        .BADF => unreachable, // Always a race condition.
+        .INTR => return, // This is still a success. See https://github.com/ziglang/zig/issues/2425
+        else => return,
+    }
+}
+
+pub const FChmodError = error{
+    AccessDenied,
+    InputOutput,
+    SymLinkLoop,
+    FileNotFound,
+    SystemResources,
+    ReadOnlyFileSystem,
+} || UnexpectedError;
+
+/// Changes the mode of the file referred to by the file descriptor.
+///
+/// The process must have the correct privileges in order to do this
+/// successfully, or must have the effective user ID matching the owner
+/// of the file.
+pub fn fchmod(fd: fd_t, mode: mode_t) FChmodError!void {
+    if (!fs.has_executable_bit) @compileError("fchmod unsupported by target OS");
+
+    while (true) {
+        const res = system.fchmod(fd, mode);
+        switch (errno(res)) {
+            .SUCCESS => return,
+            .INTR => continue,
+            .BADF => unreachable,
+            .FAULT => unreachable,
+            .INVAL => unreachable,
+            .ACCES => return error.AccessDenied,
+            .IO => return error.InputOutput,
+            .LOOP => return error.SymLinkLoop,
+            .NOENT => return error.FileNotFound,
+            .NOMEM => return error.SystemResources,
+            .NOTDIR => return error.FileNotFound,
+            .PERM => return error.AccessDenied,
+            .ROFS => return error.ReadOnlyFileSystem,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+pub const FChmodAtError = FChmodError || error{
+    /// A component of `path` exceeded `NAME_MAX`, or the entire path exceeded
+    /// `PATH_MAX`.
+    NameTooLong,
+    /// `path` resolves to a symbolic link, and `AT.SYMLINK_NOFOLLOW` was set
+    /// in `flags`. This error only occurs on Linux, where changing the mode of
+    /// a symbolic link has no meaning and can cause undefined behaviour on
+    /// certain filesystems.
+    ///
+    /// The procfs fallback was used but procfs was not mounted.
+    OperationNotSupported,
+    /// The procfs fallback was used but the process exceeded its open file
+    /// limit.
+    ProcessFdQuotaExceeded,
+    /// The procfs fallback was used but the system exceeded it open file limit.
+    SystemFdQuotaExceeded,
+};
+
+/// Changes the `mode` of `path` relative to the directory referred to by
+/// `dirfd`. The process must have the correct privileges in order to do this
+/// successfully, or must have the effective user ID matching the owner of the
+/// file.
+///
+/// On Linux the `fchmodat2` syscall will be used if available, otherwise a
+/// workaround using procfs will be employed. Changing the mode of a symbolic
+/// link with `AT.SYMLINK_NOFOLLOW` set will also return
+/// `OperationNotSupported`, as:
+///
+///  1. Permissions on the link are ignored when resolving its target.
+///  2. This operation has been known to invoke undefined behaviour across
+///     different filesystems[1].
+///
+/// [1]: https://sourceware.org/legacy-ml/libc-alpha/2020-02/msg00467.html.
+pub inline fn fchmodat(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtError!void {
+    if (!fs.has_executable_bit) @compileError("fchmodat unsupported by target OS");
+
+    // No special handling for linux is needed if we can use the libc fallback
+    // or `flags` is empty. Glibc only added the fallback in 2.32.
+    const skip_fchmodat_fallback = native_os != .linux or
+        std.c.versionCheck(.{ .major = 2, .minor = 32, .patch = 0 }) or
+        flags == 0;
+
+    // This function is marked inline so that when flags is comptime-known,
+    // skip_fchmodat_fallback will be comptime-known true.
+    if (skip_fchmodat_fallback)
+        return fchmodat1(dirfd, path, mode, flags);
+
+    return fchmodat2(dirfd, path, mode, flags);
+}
+
+fn fchmodat1(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtError!void {
+    const path_c = try toPosixPath(path);
+    while (true) {
+        const res = system.fchmodat(dirfd, &path_c, mode, flags);
+        switch (errno(res)) {
+            .SUCCESS => return,
+            .INTR => continue,
+            .BADF => unreachable,
+            .FAULT => unreachable,
+            .INVAL => unreachable,
+            .ACCES => return error.AccessDenied,
+            .IO => return error.InputOutput,
+            .LOOP => return error.SymLinkLoop,
+            .MFILE => return error.ProcessFdQuotaExceeded,
+            .NAMETOOLONG => return error.NameTooLong,
+            .NFILE => return error.SystemFdQuotaExceeded,
+            .NOENT => return error.FileNotFound,
+            .NOTDIR => return error.FileNotFound,
+            .NOMEM => return error.SystemResources,
+            .OPNOTSUPP => return error.OperationNotSupported,
+            .PERM => return error.AccessDenied,
+            .ROFS => return error.ReadOnlyFileSystem,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+fn fchmodat2(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtError!void {
+    const global = struct {
+        var has_fchmodat2: bool = true;
+    };
+    const path_c = try toPosixPath(path);
+    const use_fchmodat2 = (builtin.os.isAtLeast(.linux, .{ .major = 6, .minor = 6, .patch = 0 }) orelse false) and
+        @atomicLoad(bool, &global.has_fchmodat2, .monotonic);
+    while (use_fchmodat2) {
+        // Later on this should be changed to `system.fchmodat2`
+        // when the musl/glibc add a wrapper.
+        const res = linux.fchmodat2(dirfd, &path_c, mode, flags);
+        switch (E.init(res)) {
+            .SUCCESS => return,
+            .INTR => continue,
+            .BADF => unreachable,
+            .FAULT => unreachable,
+            .INVAL => unreachable,
+            .ACCES => return error.AccessDenied,
+            .IO => return error.InputOutput,
+            .LOOP => return error.SymLinkLoop,
+            .NOENT => return error.FileNotFound,
+            .NOMEM => return error.SystemResources,
+            .NOTDIR => return error.FileNotFound,
+            .OPNOTSUPP => return error.OperationNotSupported,
+            .PERM => return error.AccessDenied,
+            .ROFS => return error.ReadOnlyFileSystem,
+
+            .NOSYS => {
+                @atomicStore(bool, &global.has_fchmodat2, false, .monotonic);
+                break;
+            },
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+
+    // Fallback to changing permissions using procfs:
+    //
+    // 1. Open `path` as a `PATH` descriptor.
+    // 2. Stat the fd and check if it isn't a symbolic link.
+    // 3. Generate the procfs reference to the fd via `/proc/self/fd/{fd}`.
+    // 4. Pass the procfs path to `chmod` with the `mode`.
+    var pathfd: fd_t = undefined;
+    while (true) {
+        const rc = system.openat(dirfd, &path_c, .{ .PATH = true, .NOFOLLOW = true, .CLOEXEC = true }, @as(mode_t, 0));
+        switch (errno(rc)) {
+            .SUCCESS => {
+                pathfd = @intCast(rc);
+                break;
+            },
+            .INTR => continue,
+            .FAULT => unreachable,
+            .INVAL => unreachable,
+            .ACCES => return error.AccessDenied,
+            .PERM => return error.AccessDenied,
+            .LOOP => return error.SymLinkLoop,
+            .MFILE => return error.ProcessFdQuotaExceeded,
+            .NAMETOOLONG => return error.NameTooLong,
+            .NFILE => return error.SystemFdQuotaExceeded,
+            .NOENT => return error.FileNotFound,
+            .NOMEM => return error.SystemResources,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+    defer close(pathfd);
+
+    const stat = fstatatZ(pathfd, "", AT.EMPTY_PATH) catch |err| switch (err) {
+        error.NameTooLong => unreachable,
+        error.FileNotFound => unreachable,
+        error.InvalidUtf8 => unreachable,
+        else => |e| return e,
+    };
+    if ((stat.mode & S.IFMT) == S.IFLNK)
+        return error.OperationNotSupported;
+
+    var procfs_buf: ["/proc/self/fd/-2147483648\x00".len]u8 = undefined;
+    const proc_path = std.fmt.bufPrintZ(procfs_buf[0..], "/proc/self/fd/{d}", .{pathfd}) catch unreachable;
+    while (true) {
+        const res = system.chmod(proc_path, mode);
+        switch (errno(res)) {
+            // Getting NOENT here means that procfs isn't mounted.
+            .NOENT => return error.OperationNotSupported,
+
+            .SUCCESS => return,
+            .INTR => continue,
+            .BADF => unreachable,
+            .FAULT => unreachable,
+            .INVAL => unreachable,
+            .ACCES => return error.AccessDenied,
+            .IO => return error.InputOutput,
+            .LOOP => return error.SymLinkLoop,
+            .NOMEM => return error.SystemResources,
+            .NOTDIR => return error.FileNotFound,
+            .PERM => return error.AccessDenied,
+            .ROFS => return error.ReadOnlyFileSystem,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+pub const FChownError = error{
+    AccessDenied,
+    InputOutput,
+    SymLinkLoop,
+    FileNotFound,
+    SystemResources,
+    ReadOnlyFileSystem,
+} || UnexpectedError;
+
+/// Changes the owner and group of the file referred to by the file descriptor.
+/// The process must have the correct privileges in order to do this
+/// successfully. The group may be changed by the owner of the directory to
+/// any group of which the owner is a member. If the owner or group is
+/// specified as `null`, the ID is not changed.
+pub fn fchown(fd: fd_t, owner: ?uid_t, group: ?gid_t) FChownError!void {
+    switch (native_os) {
+        .windows, .wasi => @compileError("Unsupported OS"),
+        else => {},
+    }
+
+    while (true) {
+        const res = system.fchown(fd, owner orelse ~@as(uid_t, 0), group orelse ~@as(gid_t, 0));
+
+        switch (errno(res)) {
+            .SUCCESS => return,
+            .INTR => continue,
+            .BADF => unreachable, // Can be reached if the fd refers to a directory opened without `OpenDirOptions{ .iterate = true }`
+
+            .FAULT => unreachable,
+            .INVAL => unreachable,
+            .ACCES => return error.AccessDenied,
+            .IO => return error.InputOutput,
+            .LOOP => return error.SymLinkLoop,
+            .NOENT => return error.FileNotFound,
+            .NOMEM => return error.SystemResources,
+            .NOTDIR => return error.FileNotFound,
+            .PERM => return error.AccessDenied,
+            .ROFS => return error.ReadOnlyFileSystem,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+pub const RebootError = error{
+    PermissionDenied,
+} || UnexpectedError;
+
+pub const RebootCommand = switch (native_os) {
+    .linux => union(linux.LINUX_REBOOT.CMD) {
+        RESTART: void,
+        HALT: void,
+        CAD_ON: void,
+        CAD_OFF: void,
+        POWER_OFF: void,
+        RESTART2: [*:0]const u8,
+        SW_SUSPEND: void,
+        KEXEC: void,
+    },
+    else => @compileError("Unsupported OS"),
+};
+
+pub fn reboot(cmd: RebootCommand) RebootError!void {
+    switch (native_os) {
+        .linux => {
+            switch (linux.E.init(linux.reboot(
+                .MAGIC1,
+                .MAGIC2,
+                cmd,
+                switch (cmd) {
+                    .RESTART2 => |s| s,
+                    else => null,
+                },
+            ))) {
+                .SUCCESS => {},
+                .PERM => return error.PermissionDenied,
+                else => |err| return std.os.unexpectedErrno(err),
+            }
+            switch (cmd) {
+                .CAD_OFF => {},
+                .CAD_ON => {},
+                .SW_SUSPEND => {},
+
+                .HALT => unreachable,
+                .KEXEC => unreachable,
+                .POWER_OFF => unreachable,
+                .RESTART => unreachable,
+                .RESTART2 => unreachable,
+            }
+        },
+        else => @compileError("Unsupported OS"),
+    }
+}
+
+pub const GetRandomError = OpenError;
+
+/// Obtain a series of random bytes. These bytes can be used to seed user-space
+/// random number generators or for cryptographic purposes.
+/// When linking against libc, this calls the
+/// appropriate OS-specific library call. Otherwise it uses the zig standard
+/// library implementation.
+pub fn getrandom(buffer: []u8) GetRandomError!void {
+    if (native_os == .windows) {
+        return windows.RtlGenRandom(buffer);
+    }
+    if (native_os == .linux or native_os == .freebsd) {
+        var buf = buffer;
+        const use_c = native_os != .linux or
+            std.c.versionCheck(std.SemanticVersion{ .major = 2, .minor = 25, .patch = 0 });
+
+        while (buf.len != 0) {
+            const num_read: usize, const err = if (use_c) res: {
+                const rc = std.c.getrandom(buf.ptr, buf.len, 0);
+                break :res .{ @bitCast(rc), errno(rc) };
+            } else res: {
+                const rc = linux.getrandom(buf.ptr, buf.len, 0);
+                break :res .{ rc, linux.E.init(rc) };
+            };
+
+            switch (err) {
+                .SUCCESS => buf = buf[num_read..],
+                .INVAL => unreachable,
+                .FAULT => unreachable,
+                .INTR => continue,
+                .NOSYS => return getRandomBytesDevURandom(buf),
+                else => return unexpectedErrno(err),
+            }
+        }
+        return;
+    }
+    if (native_os == .emscripten) {
+        const err = errno(std.c.getentropy(buffer.ptr, buffer.len));
+        switch (err) {
+            .SUCCESS => return,
+            else => return unexpectedErrno(err),
+        }
+    }
+    switch (native_os) {
+        .netbsd, .openbsd, .macos, .ios, .tvos, .watchos => {
+            system.arc4random_buf(buffer.ptr, buffer.len);
+            return;
+        },
+        .wasi => switch (wasi.random_get(buffer.ptr, buffer.len)) {
+            .SUCCESS => return,
+            else => |err| return unexpectedErrno(err),
+        },
+        else => return getRandomBytesDevURandom(buffer),
+    }
+}
+
+fn getRandomBytesDevURandom(buf: []u8) !void {
+    const fd = try openZ("/dev/urandom", .{ .ACCMODE = .RDONLY, .CLOEXEC = true }, 0);
+    defer close(fd);
+
+    const st = try fstat(fd);
+    if (!S.ISCHR(st.mode)) {
+        return error.NoDevice;
+    }
+
+    const file: fs.File = .{ .handle = fd };
+    const stream = file.reader();
+    stream.readNoEof(buf) catch return error.Unexpected;
+}
+
+/// Causes abnormal process termination.
+/// If linking against libc, this calls the abort() libc function. Otherwise
+/// it raises SIGABRT followed by SIGKILL and finally lo
+/// Invokes the current signal handler for SIGABRT, if any.
+pub fn abort() noreturn {
+    @setCold(true);
+    // MSVCRT abort() sometimes opens a popup window which is undesirable, so
+    // even when linking libc on Windows we use our own abort implementation.
+    // See https://github.com/ziglang/zig/issues/2071 for more details.
+    if (native_os == .windows) {
+        if (builtin.mode == .Debug) {
+            @breakpoint();
+        }
+        windows.kernel32.ExitProcess(3);
+    }
+    if (!builtin.link_libc and native_os == .linux) {
+        // The Linux man page says that the libc abort() function
+        // "first unblocks the SIGABRT signal", but this is a footgun
+        // for user-defined signal handlers that want to restore some state in
+        // some program sections and crash in others.
+        // So, the user-installed SIGABRT handler is run, if present.
+        raise(SIG.ABRT) catch {};
+
+        // Disable all signal handlers.
+        sigprocmask(SIG.BLOCK, &linux.all_mask, null);
+
+        // Only one thread may proceed to the rest of abort().
+        if (!builtin.single_threaded) {
+            const global = struct {
+                var abort_entered: bool = false;
+            };
+            while (@cmpxchgWeak(bool, &global.abort_entered, false, true, .seq_cst, .seq_cst)) |_| {}
+        }
+
+        // Install default handler so that the tkill below will terminate.
+        const sigact = Sigaction{
+            .handler = .{ .handler = SIG.DFL },
+            .mask = empty_sigset,
+            .flags = 0,
+        };
+        sigaction(SIG.ABRT, &sigact, null) catch |err| switch (err) {
+            error.OperationNotSupported => unreachable,
+        };
+
+        _ = linux.tkill(linux.gettid(), SIG.ABRT);
+
+        const sigabrtmask: linux.sigset_t = [_]u32{0} ** 31 ++ [_]u32{1 << (SIG.ABRT - 1)};
+        sigprocmask(SIG.UNBLOCK, &sigabrtmask, null);
+
+        // Beyond this point should be unreachable.
+        @as(*allowzero volatile u8, @ptrFromInt(0)).* = 0;
+        raise(SIG.KILL) catch {};
+        exit(127); // Pid 1 might not be signalled in some containers.
+    }
+    switch (native_os) {
+        .uefi, .wasi, .emscripten, .cuda, .amdhsa => @trap(),
+        else => system.abort(),
+    }
+}
+
+pub const RaiseError = UnexpectedError;
+
+pub fn raise(sig: u8) RaiseError!void {
+    if (builtin.link_libc) {
+        switch (errno(system.raise(sig))) {
+            .SUCCESS => return,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+
+    if (native_os == .linux) {
+        var set: sigset_t = undefined;
+        // block application signals
+        sigprocmask(SIG.BLOCK, &linux.app_mask, &set);
+
+        const tid = linux.gettid();
+        const rc = linux.tkill(tid, sig);
+
+        // restore signal mask
+        sigprocmask(SIG.SETMASK, &set, null);
+
+        switch (errno(rc)) {
+            .SUCCESS => return,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+
+    @compileError("std.os.raise unimplemented for this target");
+}
+
+pub const KillError = error{ ProcessNotFound, PermissionDenied } || UnexpectedError;
+
+pub fn kill(pid: pid_t, sig: u8) KillError!void {
+    switch (errno(system.kill(pid, sig))) {
+        .SUCCESS => return,
+        .INVAL => unreachable, // invalid signal
+        .PERM => return error.PermissionDenied,
+        .SRCH => return error.ProcessNotFound,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// Exits all threads of the program with the specified status code.
+pub fn exit(status: u8) noreturn {
+    if (builtin.link_libc) {
+        std.c.exit(status);
+    }
+    if (native_os == .windows) {
+        windows.kernel32.ExitProcess(status);
+    }
+    if (native_os == .wasi) {
+        wasi.proc_exit(status);
+    }
+    if (native_os == .linux and !builtin.single_threaded) {
+        linux.exit_group(status);
+    }
+    if (native_os == .uefi) {
+        const uefi = std.os.uefi;
+        // exit() is only available if exitBootServices() has not been called yet.
+        // This call to exit should not fail, so we don't care about its return value.
+        if (uefi.system_table.boot_services) |bs| {
+            _ = bs.exit(uefi.handle, @enumFromInt(status), 0, null);
+        }
+        // If we can't exit, reboot the system instead.
+        uefi.system_table.runtime_services.resetSystem(.ResetCold, @enumFromInt(status), 0, null);
+    }
+    system.exit(status);
+}
+
+pub const ReadError = error{
+    InputOutput,
+    SystemResources,
+    IsDir,
+    OperationAborted,
+    BrokenPipe,
+    ConnectionResetByPeer,
+    ConnectionTimedOut,
+    NotOpenForReading,
+    SocketNotConnected,
+
+    /// This error occurs when no global event loop is configured,
+    /// and reading from the file descriptor would block.
+    WouldBlock,
+
+    /// In WASI, this error occurs when the file descriptor does
+    /// not hold the required rights to read from it.
+    AccessDenied,
+} || UnexpectedError;
+
+/// Returns the number of bytes that were read, which can be less than
+/// buf.len. If 0 bytes were read, that means EOF.
+/// If `fd` is opened in non blocking mode, the function will return error.WouldBlock
+/// when EAGAIN is received.
+///
+/// Linux has a limit on how many bytes may be transferred in one `read` call, which is `0x7ffff000`
+/// on both 64-bit and 32-bit systems. This is due to using a signed C int as the return value, as
+/// well as stuffing the errno codes into the last `4096` values. This is noted on the `read` man page.
+/// The limit on Darwin is `0x7fffffff`, trying to read more than that returns EINVAL.
+/// 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) {
+        return windows.ReadFile(fd, buf, null);
+    }
+    if (native_os == .wasi and !builtin.link_libc) {
+        const iovs = [1]iovec{iovec{
+            .iov_base = buf.ptr,
+            .iov_len = buf.len,
+        }};
+
+        var nread: usize = undefined;
+        switch (wasi.fd_read(fd, &iovs, iovs.len, &nread)) {
+            .SUCCESS => return nread,
+            .INTR => unreachable,
+            .INVAL => unreachable,
+            .FAULT => unreachable,
+            .AGAIN => unreachable,
+            .BADF => return error.NotOpenForReading, // Can be a race condition.
+            .IO => return error.InputOutput,
+            .ISDIR => return error.IsDir,
+            .NOBUFS => return error.SystemResources,
+            .NOMEM => return error.SystemResources,
+            .NOTCONN => return error.SocketNotConnected,
+            .CONNRESET => return error.ConnectionResetByPeer,
+            .TIMEDOUT => return error.ConnectionTimedOut,
+            .NOTCAPABLE => return error.AccessDenied,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+
+    // Prevents EINVAL.
+    const max_count = switch (native_os) {
+        .linux => 0x7ffff000,
+        .macos, .ios, .watchos, .tvos => maxInt(i32),
+        else => maxInt(isize),
+    };
+    while (true) {
+        const rc = system.read(fd, buf.ptr, @min(buf.len, max_count));
+        switch (errno(rc)) {
+            .SUCCESS => return @intCast(rc),
+            .INTR => continue,
+            .INVAL => unreachable,
+            .FAULT => unreachable,
+            .AGAIN => return error.WouldBlock,
+            .BADF => return error.NotOpenForReading, // Can be a race condition.
+            .IO => return error.InputOutput,
+            .ISDIR => return error.IsDir,
+            .NOBUFS => return error.SystemResources,
+            .NOMEM => return error.SystemResources,
+            .NOTCONN => return error.SocketNotConnected,
+            .CONNRESET => return error.ConnectionResetByPeer,
+            .TIMEDOUT => return error.ConnectionTimedOut,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+/// Number of bytes read is returned. Upon reading end-of-file, zero is returned.
+///
+/// For POSIX systems, if `fd` is opened in non blocking mode, the function will
+/// return error.WouldBlock when EAGAIN is received.
+/// On Windows, if the application has a global event loop enabled, I/O Completion Ports are
+/// used to perform the I/O. `error.WouldBlock` is not possible on Windows.
+///
+/// This operation is non-atomic on the following systems:
+/// * Windows
+/// On these systems, the read races with concurrent writes to the same file descriptor.
+///
+/// This function assumes that all vectors, including zero-length vectors, have
+/// a pointer within the address space of the application.
+pub fn readv(fd: fd_t, iov: []const iovec) ReadError!usize {
+    if (native_os == .windows) {
+        // TODO improve this to use ReadFileScatter
+        if (iov.len == 0) return 0;
+        const first = iov[0];
+        return read(fd, first.iov_base[0..first.iov_len]);
+    }
+    if (native_os == .wasi and !builtin.link_libc) {
+        var nread: usize = undefined;
+        switch (wasi.fd_read(fd, iov.ptr, iov.len, &nread)) {
+            .SUCCESS => return nread,
+            .INTR => unreachable,
+            .INVAL => unreachable,
+            .FAULT => unreachable,
+            .AGAIN => unreachable, // currently not support in WASI
+            .BADF => return error.NotOpenForReading, // can be a race condition
+            .IO => return error.InputOutput,
+            .ISDIR => return error.IsDir,
+            .NOBUFS => return error.SystemResources,
+            .NOMEM => return error.SystemResources,
+            .NOTCONN => return error.SocketNotConnected,
+            .CONNRESET => return error.ConnectionResetByPeer,
+            .TIMEDOUT => return error.ConnectionTimedOut,
+            .NOTCAPABLE => return error.AccessDenied,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+
+    while (true) {
+        const rc = system.readv(fd, iov.ptr, @min(iov.len, IOV_MAX));
+        switch (errno(rc)) {
+            .SUCCESS => return @intCast(rc),
+            .INTR => continue,
+            .INVAL => unreachable,
+            .FAULT => unreachable,
+            .AGAIN => return error.WouldBlock,
+            .BADF => return error.NotOpenForReading, // can be a race condition
+            .IO => return error.InputOutput,
+            .ISDIR => return error.IsDir,
+            .NOBUFS => return error.SystemResources,
+            .NOMEM => return error.SystemResources,
+            .NOTCONN => return error.SocketNotConnected,
+            .CONNRESET => return error.ConnectionResetByPeer,
+            .TIMEDOUT => return error.ConnectionTimedOut,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+pub const PReadError = ReadError || error{Unseekable};
+
+/// Number of bytes read is returned. Upon reading end-of-file, zero is returned.
+///
+/// Retries when interrupted by a signal.
+///
+/// For POSIX systems, if `fd` is opened in non blocking mode, the function will
+/// return error.WouldBlock when EAGAIN is received.
+/// On Windows, if the application has a global event loop enabled, I/O Completion Ports are
+/// used to perform the I/O. `error.WouldBlock` is not possible on Windows.
+///
+/// Linux has a limit on how many bytes may be transferred in one `pread` call, which is `0x7ffff000`
+/// on both 64-bit and 32-bit systems. This is due to using a signed C int as the return value, as
+/// well as stuffing the errno codes into the last `4096` values. This is noted on the `read` man page.
+/// The limit on Darwin is `0x7fffffff`, trying to read more than that returns EINVAL.
+/// The corresponding POSIX limit is `maxInt(isize)`.
+pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize {
+    if (buf.len == 0) return 0;
+    if (native_os == .windows) {
+        return windows.ReadFile(fd, buf, offset);
+    }
+    if (native_os == .wasi and !builtin.link_libc) {
+        const iovs = [1]iovec{iovec{
+            .iov_base = buf.ptr,
+            .iov_len = buf.len,
+        }};
+
+        var nread: usize = undefined;
+        switch (wasi.fd_pread(fd, &iovs, iovs.len, offset, &nread)) {
+            .SUCCESS => return nread,
+            .INTR => unreachable,
+            .INVAL => unreachable,
+            .FAULT => unreachable,
+            .AGAIN => unreachable,
+            .BADF => return error.NotOpenForReading, // Can be a race condition.
+            .IO => return error.InputOutput,
+            .ISDIR => return error.IsDir,
+            .NOBUFS => return error.SystemResources,
+            .NOMEM => return error.SystemResources,
+            .NOTCONN => return error.SocketNotConnected,
+            .CONNRESET => return error.ConnectionResetByPeer,
+            .TIMEDOUT => return error.ConnectionTimedOut,
+            .NXIO => return error.Unseekable,
+            .SPIPE => return error.Unseekable,
+            .OVERFLOW => return error.Unseekable,
+            .NOTCAPABLE => return error.AccessDenied,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+
+    // Prevent EINVAL.
+    const max_count = switch (native_os) {
+        .linux => 0x7ffff000,
+        .macos, .ios, .watchos, .tvos => maxInt(i32),
+        else => maxInt(isize),
+    };
+
+    const pread_sym = if (lfs64_abi) system.pread64 else system.pread;
+    while (true) {
+        const rc = pread_sym(fd, buf.ptr, @min(buf.len, max_count), @bitCast(offset));
+        switch (errno(rc)) {
+            .SUCCESS => return @intCast(rc),
+            .INTR => continue,
+            .INVAL => unreachable,
+            .FAULT => unreachable,
+            .AGAIN => return error.WouldBlock,
+            .BADF => return error.NotOpenForReading, // Can be a race condition.
+            .IO => return error.InputOutput,
+            .ISDIR => return error.IsDir,
+            .NOBUFS => return error.SystemResources,
+            .NOMEM => return error.SystemResources,
+            .NOTCONN => return error.SocketNotConnected,
+            .CONNRESET => return error.ConnectionResetByPeer,
+            .TIMEDOUT => return error.ConnectionTimedOut,
+            .NXIO => return error.Unseekable,
+            .SPIPE => return error.Unseekable,
+            .OVERFLOW => return error.Unseekable,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+pub const TruncateError = error{
+    FileTooBig,
+    InputOutput,
+    FileBusy,
+
+    /// In WASI, this error occurs when the file descriptor does
+    /// not hold the required rights to call `ftruncate` on it.
+    AccessDenied,
+} || UnexpectedError;
+
+pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void {
+    if (native_os == .windows) {
+        var io_status_block: windows.IO_STATUS_BLOCK = undefined;
+        var eof_info = windows.FILE_END_OF_FILE_INFORMATION{
+            .EndOfFile = @bitCast(length),
+        };
+
+        const rc = windows.ntdll.NtSetInformationFile(
+            fd,
+            &io_status_block,
+            &eof_info,
+            @sizeOf(windows.FILE_END_OF_FILE_INFORMATION),
+            .FileEndOfFileInformation,
+        );
+
+        switch (rc) {
+            .SUCCESS => return,
+            .INVALID_HANDLE => unreachable, // Handle not open for writing
+            .ACCESS_DENIED => return error.AccessDenied,
+            else => return windows.unexpectedStatus(rc),
+        }
+    }
+    if (native_os == .wasi and !builtin.link_libc) {
+        switch (wasi.fd_filestat_set_size(fd, length)) {
+            .SUCCESS => return,
+            .INTR => unreachable,
+            .FBIG => return error.FileTooBig,
+            .IO => return error.InputOutput,
+            .PERM => return error.AccessDenied,
+            .TXTBSY => return error.FileBusy,
+            .BADF => unreachable, // Handle not open for writing
+            .INVAL => unreachable, // Handle not open for writing
+            .NOTCAPABLE => return error.AccessDenied,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+
+    const ftruncate_sym = if (lfs64_abi) system.ftruncate64 else system.ftruncate;
+    while (true) {
+        switch (errno(ftruncate_sym(fd, @bitCast(length)))) {
+            .SUCCESS => return,
+            .INTR => continue,
+            .FBIG => return error.FileTooBig,
+            .IO => return error.InputOutput,
+            .PERM => return error.AccessDenied,
+            .TXTBSY => return error.FileBusy,
+            .BADF => unreachable, // Handle not open for writing
+            .INVAL => unreachable, // Handle not open for writing
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+/// Number of bytes read is returned. Upon reading end-of-file, zero is returned.
+///
+/// Retries when interrupted by a signal.
+///
+/// For POSIX systems, if `fd` is opened in non blocking mode, the function will
+/// return error.WouldBlock when EAGAIN is received.
+/// On Windows, if the application has a global event loop enabled, I/O Completion Ports are
+/// used to perform the I/O. `error.WouldBlock` is not possible on Windows.
+///
+/// This operation is non-atomic on the following systems:
+/// * Darwin
+/// * Windows
+/// On these systems, the read races with concurrent writes to the same file descriptor.
+pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize {
+    const have_pread_but_not_preadv = switch (native_os) {
+        .windows, .macos, .ios, .watchos, .tvos, .haiku => true,
+        else => false,
+    };
+    if (have_pread_but_not_preadv) {
+        // We could loop here; but proper usage of `preadv` must handle partial reads anyway.
+        // So we simply read into the first vector only.
+        if (iov.len == 0) return 0;
+        const first = iov[0];
+        return pread(fd, first.iov_base[0..first.iov_len], offset);
+    }
+    if (native_os == .wasi and !builtin.link_libc) {
+        var nread: usize = undefined;
+        switch (wasi.fd_pread(fd, iov.ptr, iov.len, offset, &nread)) {
+            .SUCCESS => return nread,
+            .INTR => unreachable,
+            .INVAL => unreachable,
+            .FAULT => unreachable,
+            .AGAIN => unreachable,
+            .BADF => return error.NotOpenForReading, // can be a race condition
+            .IO => return error.InputOutput,
+            .ISDIR => return error.IsDir,
+            .NOBUFS => return error.SystemResources,
+            .NOMEM => return error.SystemResources,
+            .NOTCONN => return error.SocketNotConnected,
+            .CONNRESET => return error.ConnectionResetByPeer,
+            .TIMEDOUT => return error.ConnectionTimedOut,
+            .NXIO => return error.Unseekable,
+            .SPIPE => return error.Unseekable,
+            .OVERFLOW => return error.Unseekable,
+            .NOTCAPABLE => return error.AccessDenied,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+
+    const preadv_sym = if (lfs64_abi) system.preadv64 else system.preadv;
+    while (true) {
+        const rc = preadv_sym(fd, iov.ptr, @min(iov.len, IOV_MAX), @bitCast(offset));
+        switch (errno(rc)) {
+            .SUCCESS => return @bitCast(rc),
+            .INTR => continue,
+            .INVAL => unreachable,
+            .FAULT => unreachable,
+            .AGAIN => return error.WouldBlock,
+            .BADF => return error.NotOpenForReading, // can be a race condition
+            .IO => return error.InputOutput,
+            .ISDIR => return error.IsDir,
+            .NOBUFS => return error.SystemResources,
+            .NOMEM => return error.SystemResources,
+            .NOTCONN => return error.SocketNotConnected,
+            .CONNRESET => return error.ConnectionResetByPeer,
+            .TIMEDOUT => return error.ConnectionTimedOut,
+            .NXIO => return error.Unseekable,
+            .SPIPE => return error.Unseekable,
+            .OVERFLOW => return error.Unseekable,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+pub const WriteError = error{
+    DiskQuota,
+    FileTooBig,
+    InputOutput,
+    NoSpaceLeft,
+    DeviceBusy,
+    InvalidArgument,
+
+    /// In WASI, this error may occur when the file descriptor does
+    /// not hold the required rights to write to it.
+    AccessDenied,
+    BrokenPipe,
+    SystemResources,
+    OperationAborted,
+    NotOpenForWriting,
+
+    /// The process cannot access the file because another process has locked
+    /// a portion of the file. Windows-only.
+    LockViolation,
+
+    /// This error occurs when no global event loop is configured,
+    /// and reading from the file descriptor would block.
+    WouldBlock,
+
+    /// Connection reset by peer.
+    ConnectionResetByPeer,
+} || UnexpectedError;
+
+/// Write to a file descriptor.
+/// Retries when interrupted by a signal.
+/// Returns the number of bytes written. If nonzero bytes were supplied, this will be nonzero.
+///
+/// Note that a successful write() may transfer fewer than count bytes.  Such partial  writes  can
+/// occur  for  various reasons; for example, because there was insufficient space on the disk
+/// device to write all of the requested bytes, or because a blocked write() to a socket,  pipe,  or
+/// similar  was  interrupted by a signal handler after it had transferred some, but before it had
+/// transferred all of the requested bytes.  In the event of a partial write, the caller can  make
+/// another  write() call to transfer the remaining bytes.  The subsequent call will either
+/// transfer further bytes or may result in an error (e.g., if the disk is now full).
+///
+/// For POSIX systems, if `fd` is opened in non blocking mode, the function will
+/// return error.WouldBlock when EAGAIN is received.
+/// On Windows, if the application has a global event loop enabled, I/O Completion Ports are
+/// used to perform the I/O. `error.WouldBlock` is not possible on Windows.
+///
+/// Linux has a limit on how many bytes may be transferred in one `write` call, which is `0x7ffff000`
+/// on both 64-bit and 32-bit systems. This is due to using a signed C int as the return value, as
+/// well as stuffing the errno codes into the last `4096` values. This is noted on the `write` man page.
+/// The limit on Darwin is `0x7fffffff`, trying to read more than that returns EINVAL.
+/// The corresponding POSIX limit is `maxInt(isize)`.
+pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize {
+    if (bytes.len == 0) return 0;
+    if (native_os == .windows) {
+        return windows.WriteFile(fd, bytes, null);
+    }
+
+    if (native_os == .wasi and !builtin.link_libc) {
+        const ciovs = [_]iovec_const{iovec_const{
+            .iov_base = bytes.ptr,
+            .iov_len = bytes.len,
+        }};
+        var nwritten: usize = undefined;
+        switch (wasi.fd_write(fd, &ciovs, ciovs.len, &nwritten)) {
+            .SUCCESS => return nwritten,
+            .INTR => unreachable,
+            .INVAL => unreachable,
+            .FAULT => unreachable,
+            .AGAIN => unreachable,
+            .BADF => return error.NotOpenForWriting, // can be a race condition.
+            .DESTADDRREQ => unreachable, // `connect` was never called.
+            .DQUOT => return error.DiskQuota,
+            .FBIG => return error.FileTooBig,
+            .IO => return error.InputOutput,
+            .NOSPC => return error.NoSpaceLeft,
+            .PERM => return error.AccessDenied,
+            .PIPE => return error.BrokenPipe,
+            .NOTCAPABLE => return error.AccessDenied,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+
+    const max_count = switch (native_os) {
+        .linux => 0x7ffff000,
+        .macos, .ios, .watchos, .tvos => maxInt(i32),
+        else => maxInt(isize),
+    };
+    while (true) {
+        const rc = system.write(fd, bytes.ptr, @min(bytes.len, max_count));
+        switch (errno(rc)) {
+            .SUCCESS => return @intCast(rc),
+            .INTR => continue,
+            .INVAL => return error.InvalidArgument,
+            .FAULT => unreachable,
+            .AGAIN => return error.WouldBlock,
+            .BADF => return error.NotOpenForWriting, // can be a race condition.
+            .DESTADDRREQ => unreachable, // `connect` was never called.
+            .DQUOT => return error.DiskQuota,
+            .FBIG => return error.FileTooBig,
+            .IO => return error.InputOutput,
+            .NOSPC => return error.NoSpaceLeft,
+            .PERM => return error.AccessDenied,
+            .PIPE => return error.BrokenPipe,
+            .CONNRESET => return error.ConnectionResetByPeer,
+            .BUSY => return error.DeviceBusy,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+/// Write multiple buffers to a file descriptor.
+/// Retries when interrupted by a signal.
+/// Returns the number of bytes written. If nonzero bytes were supplied, this will be nonzero.
+///
+/// Note that a successful write() may transfer fewer bytes than supplied.  Such partial  writes  can
+/// occur  for  various reasons; for example, because there was insufficient space on the disk
+/// device to write all of the requested bytes, or because a blocked write() to a socket,  pipe,  or
+/// similar  was  interrupted by a signal handler after it had transferred some, but before it had
+/// transferred all of the requested bytes.  In the event of a partial write, the caller can  make
+/// another  write() call to transfer the remaining bytes.  The subsequent call will either
+/// transfer further bytes or may result in an error (e.g., if the disk is now full).
+///
+/// For POSIX systems, if `fd` is opened in non blocking mode, the function will
+/// return error.WouldBlock when EAGAIN is received.
+/// On Windows, if the application has a global event loop enabled, I/O Completion Ports are
+/// used to perform the I/O. `error.WouldBlock` is not possible on Windows.
+///
+/// If `iov.len` is larger than `IOV_MAX`, a partial write will occur.
+///
+/// This function assumes that all vectors, including zero-length vectors, have
+/// a pointer within the address space of the application.
+pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!usize {
+    if (native_os == .windows) {
+        // TODO improve this to use WriteFileScatter
+        if (iov.len == 0) return 0;
+        const first = iov[0];
+        return write(fd, first.iov_base[0..first.iov_len]);
+    }
+    if (native_os == .wasi and !builtin.link_libc) {
+        var nwritten: usize = undefined;
+        switch (wasi.fd_write(fd, iov.ptr, iov.len, &nwritten)) {
+            .SUCCESS => return nwritten,
+            .INTR => unreachable,
+            .INVAL => unreachable,
+            .FAULT => unreachable,
+            .AGAIN => unreachable,
+            .BADF => return error.NotOpenForWriting, // can be a race condition.
+            .DESTADDRREQ => unreachable, // `connect` was never called.
+            .DQUOT => return error.DiskQuota,
+            .FBIG => return error.FileTooBig,
+            .IO => return error.InputOutput,
+            .NOSPC => return error.NoSpaceLeft,
+            .PERM => return error.AccessDenied,
+            .PIPE => return error.BrokenPipe,
+            .NOTCAPABLE => return error.AccessDenied,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+
+    while (true) {
+        const rc = system.writev(fd, iov.ptr, @min(iov.len, IOV_MAX));
+        switch (errno(rc)) {
+            .SUCCESS => return @intCast(rc),
+            .INTR => continue,
+            .INVAL => return error.InvalidArgument,
+            .FAULT => unreachable,
+            .AGAIN => return error.WouldBlock,
+            .BADF => return error.NotOpenForWriting, // Can be a race condition.
+            .DESTADDRREQ => unreachable, // `connect` was never called.
+            .DQUOT => return error.DiskQuota,
+            .FBIG => return error.FileTooBig,
+            .IO => return error.InputOutput,
+            .NOSPC => return error.NoSpaceLeft,
+            .PERM => return error.AccessDenied,
+            .PIPE => return error.BrokenPipe,
+            .CONNRESET => return error.ConnectionResetByPeer,
+            .BUSY => return error.DeviceBusy,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+pub const PWriteError = WriteError || error{Unseekable};
+
+/// Write to a file descriptor, with a position offset.
+/// Retries when interrupted by a signal.
+/// Returns the number of bytes written. If nonzero bytes were supplied, this will be nonzero.
+///
+/// Note that a successful write() may transfer fewer bytes than supplied.  Such partial  writes  can
+/// occur  for  various reasons; for example, because there was insufficient space on the disk
+/// device to write all of the requested bytes, or because a blocked write() to a socket,  pipe,  or
+/// similar  was  interrupted by a signal handler after it had transferred some, but before it had
+/// transferred all of the requested bytes.  In the event of a partial write, the caller can  make
+/// another  write() call to transfer the remaining bytes.  The subsequent call will either
+/// transfer further bytes or may result in an error (e.g., if the disk is now full).
+///
+/// For POSIX systems, if `fd` is opened in non blocking mode, the function will
+/// return error.WouldBlock when EAGAIN is received.
+/// On Windows, if the application has a global event loop enabled, I/O Completion Ports are
+/// used to perform the I/O. `error.WouldBlock` is not possible on Windows.
+///
+/// Linux has a limit on how many bytes may be transferred in one `pwrite` call, which is `0x7ffff000`
+/// on both 64-bit and 32-bit systems. This is due to using a signed C int as the return value, as
+/// well as stuffing the errno codes into the last `4096` values. This is noted on the `write` man page.
+/// The limit on Darwin is `0x7fffffff`, trying to write more than that returns EINVAL.
+/// The corresponding POSIX limit is `maxInt(isize)`.
+pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize {
+    if (bytes.len == 0) return 0;
+    if (native_os == .windows) {
+        return windows.WriteFile(fd, bytes, offset);
+    }
+    if (native_os == .wasi and !builtin.link_libc) {
+        const ciovs = [1]iovec_const{iovec_const{
+            .iov_base = bytes.ptr,
+            .iov_len = bytes.len,
+        }};
+
+        var nwritten: usize = undefined;
+        switch (wasi.fd_pwrite(fd, &ciovs, ciovs.len, offset, &nwritten)) {
+            .SUCCESS => return nwritten,
+            .INTR => unreachable,
+            .INVAL => unreachable,
+            .FAULT => unreachable,
+            .AGAIN => unreachable,
+            .BADF => return error.NotOpenForWriting, // can be a race condition.
+            .DESTADDRREQ => unreachable, // `connect` was never called.
+            .DQUOT => return error.DiskQuota,
+            .FBIG => return error.FileTooBig,
+            .IO => return error.InputOutput,
+            .NOSPC => return error.NoSpaceLeft,
+            .PERM => return error.AccessDenied,
+            .PIPE => return error.BrokenPipe,
+            .NXIO => return error.Unseekable,
+            .SPIPE => return error.Unseekable,
+            .OVERFLOW => return error.Unseekable,
+            .NOTCAPABLE => return error.AccessDenied,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+
+    // Prevent EINVAL.
+    const max_count = switch (native_os) {
+        .linux => 0x7ffff000,
+        .macos, .ios, .watchos, .tvos => maxInt(i32),
+        else => maxInt(isize),
+    };
+
+    const pwrite_sym = if (lfs64_abi) system.pwrite64 else system.pwrite;
+    while (true) {
+        const rc = pwrite_sym(fd, bytes.ptr, @min(bytes.len, max_count), @bitCast(offset));
+        switch (errno(rc)) {
+            .SUCCESS => return @intCast(rc),
+            .INTR => continue,
+            .INVAL => return error.InvalidArgument,
+            .FAULT => unreachable,
+            .AGAIN => return error.WouldBlock,
+            .BADF => return error.NotOpenForWriting, // Can be a race condition.
+            .DESTADDRREQ => unreachable, // `connect` was never called.
+            .DQUOT => return error.DiskQuota,
+            .FBIG => return error.FileTooBig,
+            .IO => return error.InputOutput,
+            .NOSPC => return error.NoSpaceLeft,
+            .PERM => return error.AccessDenied,
+            .PIPE => return error.BrokenPipe,
+            .NXIO => return error.Unseekable,
+            .SPIPE => return error.Unseekable,
+            .OVERFLOW => return error.Unseekable,
+            .BUSY => return error.DeviceBusy,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+/// Write multiple buffers to a file descriptor, with a position offset.
+/// Retries when interrupted by a signal.
+/// Returns the number of bytes written. If nonzero bytes were supplied, this will be nonzero.
+///
+/// Note that a successful write() may transfer fewer than count bytes.  Such partial  writes  can
+/// occur  for  various reasons; for example, because there was insufficient space on the disk
+/// device to write all of the requested bytes, or because a blocked write() to a socket,  pipe,  or
+/// similar  was  interrupted by a signal handler after it had transferred some, but before it had
+/// transferred all of the requested bytes.  In the event of a partial write, the caller can  make
+/// another  write() call to transfer the remaining bytes.  The subsequent call will either
+/// transfer further bytes or may result in an error (e.g., if the disk is now full).
+///
+/// If `fd` is opened in non blocking mode, the function will
+/// return error.WouldBlock when EAGAIN is received.
+///
+/// The following systems do not have this syscall, and will return partial writes if more than one
+/// vector is provided:
+/// * Darwin
+/// * Windows
+///
+/// If `iov.len` is larger than `IOV_MAX`, a partial write will occur.
+pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usize {
+    const have_pwrite_but_not_pwritev = switch (native_os) {
+        .windows, .macos, .ios, .watchos, .tvos, .haiku => true,
+        else => false,
+    };
+
+    if (have_pwrite_but_not_pwritev) {
+        // We could loop here; but proper usage of `pwritev` must handle partial writes anyway.
+        // So we simply write the first vector only.
+        if (iov.len == 0) return 0;
+        const first = iov[0];
+        return pwrite(fd, first.iov_base[0..first.iov_len], offset);
+    }
+    if (native_os == .wasi and !builtin.link_libc) {
+        var nwritten: usize = undefined;
+        switch (wasi.fd_pwrite(fd, iov.ptr, iov.len, offset, &nwritten)) {
+            .SUCCESS => return nwritten,
+            .INTR => unreachable,
+            .INVAL => unreachable,
+            .FAULT => unreachable,
+            .AGAIN => unreachable,
+            .BADF => return error.NotOpenForWriting, // Can be a race condition.
+            .DESTADDRREQ => unreachable, // `connect` was never called.
+            .DQUOT => return error.DiskQuota,
+            .FBIG => return error.FileTooBig,
+            .IO => return error.InputOutput,
+            .NOSPC => return error.NoSpaceLeft,
+            .PERM => return error.AccessDenied,
+            .PIPE => return error.BrokenPipe,
+            .NXIO => return error.Unseekable,
+            .SPIPE => return error.Unseekable,
+            .OVERFLOW => return error.Unseekable,
+            .NOTCAPABLE => return error.AccessDenied,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+
+    const pwritev_sym = if (lfs64_abi) system.pwritev64 else system.pwritev;
+    while (true) {
+        const rc = pwritev_sym(fd, iov.ptr, @min(iov.len, IOV_MAX), @bitCast(offset));
+        switch (errno(rc)) {
+            .SUCCESS => return @intCast(rc),
+            .INTR => continue,
+            .INVAL => return error.InvalidArgument,
+            .FAULT => unreachable,
+            .AGAIN => return error.WouldBlock,
+            .BADF => return error.NotOpenForWriting, // Can be a race condition.
+            .DESTADDRREQ => unreachable, // `connect` was never called.
+            .DQUOT => return error.DiskQuota,
+            .FBIG => return error.FileTooBig,
+            .IO => return error.InputOutput,
+            .NOSPC => return error.NoSpaceLeft,
+            .PERM => return error.AccessDenied,
+            .PIPE => return error.BrokenPipe,
+            .NXIO => return error.Unseekable,
+            .SPIPE => return error.Unseekable,
+            .OVERFLOW => return error.Unseekable,
+            .BUSY => return error.DeviceBusy,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+pub const OpenError = error{
+    /// In WASI, this error may occur when the file descriptor does
+    /// not hold the required rights to open a new resource relative to it.
+    AccessDenied,
+    SymLinkLoop,
+    ProcessFdQuotaExceeded,
+    SystemFdQuotaExceeded,
+    NoDevice,
+    FileNotFound,
+
+    /// The path exceeded `max_path_bytes` bytes.
+    NameTooLong,
+
+    /// Insufficient kernel memory was available, or
+    /// the named file is a FIFO and per-user hard limit on
+    /// memory allocation for pipes has been reached.
+    SystemResources,
+
+    /// The file is too large to be opened. This error is unreachable
+    /// for 64-bit targets, as well as when opening directories.
+    FileTooBig,
+
+    /// The path refers to directory but the `DIRECTORY` flag was not provided.
+    IsDir,
+
+    /// A new path cannot be created because the device has no room for the new file.
+    /// This error is only reachable when the `CREAT` flag is provided.
+    NoSpaceLeft,
+
+    /// A component used as a directory in the path was not, in fact, a directory, or
+    /// `DIRECTORY` was specified and the path was not a directory.
+    NotDir,
+
+    /// The path already exists and the `CREAT` and `EXCL` flags were provided.
+    PathAlreadyExists,
+    DeviceBusy,
+
+    /// The underlying filesystem does not support file locks
+    FileLocksNotSupported,
+
+    /// Path contains characters that are disallowed by the underlying filesystem.
+    BadPathName,
+
+    /// WASI-only; file paths must be valid UTF-8.
+    InvalidUtf8,
+
+    /// Windows-only; file paths provided by the user must be valid WTF-8.
+    /// https://simonsapin.github.io/wtf-8/
+    InvalidWtf8,
+
+    /// On Windows, `\\server` or `\\server\share` was not found.
+    NetworkNotFound,
+
+    /// One of these three things:
+    /// * pathname  refers to an executable image which is currently being
+    ///   executed and write access was requested.
+    /// * pathname refers to a file that is currently in  use  as  a  swap
+    ///   file, and the O_TRUNC flag was specified.
+    /// * pathname  refers  to  a file that is currently being read by the
+    ///   kernel (e.g., for module/firmware loading), and write access was
+    ///   requested.
+    FileBusy,
+
+    WouldBlock,
+} || UnexpectedError;
+
+/// Open and possibly create a file. Keeps trying if it gets interrupted.
+/// On Windows, `file_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// 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 `openZ`.
+pub fn open(file_path: []const u8, flags: O, perm: 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 and !builtin.link_libc) {
+        return openat(AT.FDCWD, file_path, flags, perm);
+    }
+    const file_path_c = try toPosixPath(file_path);
+    return openZ(&file_path_c, flags, perm);
+}
+
+/// Open and possibly create a file. Keeps trying if it gets interrupted.
+/// On Windows, `file_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// 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 `open`.
+pub fn openZ(file_path: [*:0]const u8, flags: O, perm: 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 and !builtin.link_libc) {
+        return open(mem.sliceTo(file_path, 0), flags, perm);
+    }
+
+    const open_sym = if (lfs64_abi) system.open64 else system.open;
+    while (true) {
+        const rc = open_sym(file_path, flags, perm);
+        switch (errno(rc)) {
+            .SUCCESS => return @intCast(rc),
+            .INTR => continue,
+
+            .FAULT => unreachable,
+            .INVAL => unreachable,
+            .ACCES => return error.AccessDenied,
+            .FBIG => return error.FileTooBig,
+            .OVERFLOW => return error.FileTooBig,
+            .ISDIR => return error.IsDir,
+            .LOOP => return error.SymLinkLoop,
+            .MFILE => return error.ProcessFdQuotaExceeded,
+            .NAMETOOLONG => return error.NameTooLong,
+            .NFILE => return error.SystemFdQuotaExceeded,
+            .NODEV => return error.NoDevice,
+            .NOENT => return error.FileNotFound,
+            .NOMEM => return error.SystemResources,
+            .NOSPC => return error.NoSpaceLeft,
+            .NOTDIR => return error.NotDir,
+            .PERM => return error.AccessDenied,
+            .EXIST => return error.PathAlreadyExists,
+            .BUSY => return error.DeviceBusy,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+/// 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://simonsapin.github.io/wtf-8/).
+/// 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 and !builtin.link_libc) {
+        // `mode` is ignored on WASI, which does not support unix-style file permissions
+        const opts = try openOptionsFromFlagsWasi(flags);
+        const fd = try openatWasi(
+            dir_fd,
+            file_path,
+            opts.lookup_flags,
+            opts.oflags,
+            opts.fs_flags,
+            opts.fs_rights_base,
+            opts.fs_rights_inheriting,
+        );
+        errdefer close(fd);
+
+        if (flags.write) {
+            const info = try fstat_wasi(fd);
+            if (info.filetype == .DIRECTORY)
+                return error.IsDir;
+        }
+
+        return fd;
+    }
+    const file_path_c = try toPosixPath(file_path);
+    return openatZ(dir_fd, &file_path_c, flags, mode);
+}
+
+/// Open and possibly create a file in WASI.
+pub fn openatWasi(
+    dir_fd: fd_t,
+    file_path: []const u8,
+    lookup_flags: wasi.lookupflags_t,
+    oflags: wasi.oflags_t,
+    fdflags: wasi.fdflags_t,
+    base: wasi.rights_t,
+    inheriting: wasi.rights_t,
+) OpenError!fd_t {
+    while (true) {
+        var fd: fd_t = undefined;
+        switch (wasi.path_open(dir_fd, lookup_flags, file_path.ptr, file_path.len, oflags, base, inheriting, fdflags, &fd)) {
+            .SUCCESS => return fd,
+            .INTR => continue,
+
+            .FAULT => unreachable,
+            .INVAL => unreachable,
+            .BADF => unreachable,
+            .ACCES => return error.AccessDenied,
+            .FBIG => return error.FileTooBig,
+            .OVERFLOW => return error.FileTooBig,
+            .ISDIR => return error.IsDir,
+            .LOOP => return error.SymLinkLoop,
+            .MFILE => return error.ProcessFdQuotaExceeded,
+            .NAMETOOLONG => return error.NameTooLong,
+            .NFILE => return error.SystemFdQuotaExceeded,
+            .NODEV => return error.NoDevice,
+            .NOENT => return error.FileNotFound,
+            .NOMEM => return error.SystemResources,
+            .NOSPC => return error.NoSpaceLeft,
+            .NOTDIR => return error.NotDir,
+            .PERM => return error.AccessDenied,
+            .EXIST => return error.PathAlreadyExists,
+            .BUSY => return error.DeviceBusy,
+            .NOTCAPABLE => return error.AccessDenied,
+            .ILSEQ => return error.InvalidUtf8,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+/// A struct to contain all lookup/rights flags accepted by `wasi.path_open`
+const WasiOpenOptions = struct {
+    oflags: wasi.oflags_t,
+    lookup_flags: wasi.lookupflags_t,
+    fs_rights_base: wasi.rights_t,
+    fs_rights_inheriting: wasi.rights_t,
+    fs_flags: wasi.fdflags_t,
+};
+
+/// Compute rights + flags corresponding to the provided POSIX access mode.
+fn openOptionsFromFlagsWasi(oflag: O) OpenError!WasiOpenOptions {
+    const w = std.os.wasi;
+
+    // Next, calculate the read/write rights to request, depending on the
+    // provided POSIX access mode
+    var rights: w.rights_t = .{};
+    if (oflag.read) {
+        rights.FD_READ = true;
+        rights.FD_READDIR = true;
+    }
+    if (oflag.write) {
+        rights.FD_DATASYNC = true;
+        rights.FD_WRITE = true;
+        rights.FD_ALLOCATE = true;
+        rights.FD_FILESTAT_SET_SIZE = true;
+    }
+
+    // https://github.com/ziglang/zig/issues/18882
+    const flag_bits: u32 = @bitCast(oflag);
+    const oflags_int: u16 = @as(u12, @truncate(flag_bits >> 12));
+    const fs_flags_int: u16 = @as(u12, @truncate(flag_bits));
+
+    return .{
+        // https://github.com/ziglang/zig/issues/18882
+        .oflags = @bitCast(oflags_int),
+        .lookup_flags = .{
+            .SYMLINK_FOLLOW = !oflag.NOFOLLOW,
+        },
+        .fs_rights_base = rights,
+        .fs_rights_inheriting = rights,
+        // https://github.com/ziglang/zig/issues/18882
+        .fs_flags = @bitCast(fs_flags_int),
+    };
+}
+
+/// 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://simonsapin.github.io/wtf-8/).
+/// 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 and !builtin.link_libc) {
+        return openat(dir_fd, mem.sliceTo(file_path, 0), flags, mode);
+    }
+
+    const openat_sym = if (lfs64_abi) system.openat64 else system.openat;
+    while (true) {
+        const rc = openat_sym(dir_fd, file_path, flags, mode);
+        switch (errno(rc)) {
+            .SUCCESS => return @intCast(rc),
+            .INTR => continue,
+
+            .FAULT => unreachable,
+            .INVAL => unreachable,
+            .BADF => unreachable,
+            .ACCES => return error.AccessDenied,
+            .FBIG => return error.FileTooBig,
+            .OVERFLOW => return error.FileTooBig,
+            .ISDIR => return error.IsDir,
+            .LOOP => return error.SymLinkLoop,
+            .MFILE => return error.ProcessFdQuotaExceeded,
+            .NAMETOOLONG => return error.NameTooLong,
+            .NFILE => return error.SystemFdQuotaExceeded,
+            .NODEV => return error.NoDevice,
+            .NOENT => return error.FileNotFound,
+            .NOMEM => return error.SystemResources,
+            .NOSPC => return error.NoSpaceLeft,
+            .NOTDIR => return error.NotDir,
+            .PERM => return error.AccessDenied,
+            .EXIST => return error.PathAlreadyExists,
+            .BUSY => return error.DeviceBusy,
+            .OPNOTSUPP => return error.FileLocksNotSupported,
+            .AGAIN => return error.WouldBlock,
+            .TXTBSY => return error.FileBusy,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+pub fn dup(old_fd: fd_t) !fd_t {
+    const rc = system.dup(old_fd);
+    return switch (errno(rc)) {
+        .SUCCESS => return @intCast(rc),
+        .MFILE => error.ProcessFdQuotaExceeded,
+        .BADF => unreachable, // invalid file descriptor
+        else => |err| return unexpectedErrno(err),
+    };
+}
+
+pub fn dup2(old_fd: fd_t, new_fd: fd_t) !void {
+    while (true) {
+        switch (errno(system.dup2(old_fd, new_fd))) {
+            .SUCCESS => return,
+            .BUSY, .INTR => continue,
+            .MFILE => return error.ProcessFdQuotaExceeded,
+            .INVAL => unreachable, // invalid parameters passed to dup2
+            .BADF => unreachable, // invalid file descriptor
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+pub const ExecveError = error{
+    SystemResources,
+    AccessDenied,
+    InvalidExe,
+    FileSystem,
+    IsDir,
+    FileNotFound,
+    NotDir,
+    FileBusy,
+    ProcessFdQuotaExceeded,
+    SystemFdQuotaExceeded,
+    NameTooLong,
+} || UnexpectedError;
+
+/// This function ignores PATH environment variable. See `execvpeZ` for that.
+pub fn execveZ(
+    path: [*:0]const u8,
+    child_argv: [*:null]const ?[*:0]const u8,
+    envp: [*:null]const ?[*:0]const u8,
+) ExecveError {
+    switch (errno(system.execve(path, child_argv, envp))) {
+        .SUCCESS => unreachable,
+        .FAULT => unreachable,
+        .@"2BIG" => return error.SystemResources,
+        .MFILE => return error.ProcessFdQuotaExceeded,
+        .NAMETOOLONG => return error.NameTooLong,
+        .NFILE => return error.SystemFdQuotaExceeded,
+        .NOMEM => return error.SystemResources,
+        .ACCES => return error.AccessDenied,
+        .PERM => return error.AccessDenied,
+        .INVAL => return error.InvalidExe,
+        .NOEXEC => return error.InvalidExe,
+        .IO => return error.FileSystem,
+        .LOOP => return error.FileSystem,
+        .ISDIR => return error.IsDir,
+        .NOENT => return error.FileNotFound,
+        .NOTDIR => return error.NotDir,
+        .TXTBSY => return error.FileBusy,
+        else => |err| switch (native_os) {
+            .macos, .ios, .tvos, .watchos => switch (err) {
+                .BADEXEC => return error.InvalidExe,
+                .BADARCH => return error.InvalidExe,
+                else => return unexpectedErrno(err),
+            },
+            .linux => switch (err) {
+                .LIBBAD => return error.InvalidExe,
+                else => return unexpectedErrno(err),
+            },
+            else => return unexpectedErrno(err),
+        },
+    }
+}
+
+pub const Arg0Expand = enum {
+    expand,
+    no_expand,
+};
+
+/// Like `execvpeZ` except if `arg0_expand` is `.expand`, then `argv` is mutable,
+/// and `argv[0]` is expanded to be the same absolute path that is passed to the execve syscall.
+/// If this function returns with an error, `argv[0]` will be restored to the value it was when it was passed in.
+pub fn execvpeZ_expandArg0(
+    comptime arg0_expand: Arg0Expand,
+    file: [*:0]const u8,
+    child_argv: switch (arg0_expand) {
+        .expand => [*:null]?[*:0]const u8,
+        .no_expand => [*:null]const ?[*:0]const u8,
+    },
+    envp: [*:null]const ?[*:0]const u8,
+) ExecveError {
+    const file_slice = mem.sliceTo(file, 0);
+    if (mem.indexOfScalar(u8, file_slice, '/') != null) return execveZ(file, child_argv, envp);
+
+    const PATH = getenvZ("PATH") orelse "/usr/local/bin:/bin/:/usr/bin";
+    // Use of PATH_MAX here is valid as the path_buf will be passed
+    // directly to the operating system in execveZ.
+    var path_buf: [PATH_MAX]u8 = undefined;
+    var it = mem.tokenizeScalar(u8, PATH, ':');
+    var seen_eacces = false;
+    var err: ExecveError = error.FileNotFound;
+
+    // In case of expanding arg0 we must put it back if we return with an error.
+    const prev_arg0 = child_argv[0];
+    defer switch (arg0_expand) {
+        .expand => child_argv[0] = prev_arg0,
+        .no_expand => {},
+    };
+
+    while (it.next()) |search_path| {
+        const path_len = search_path.len + file_slice.len + 1;
+        if (path_buf.len < path_len + 1) return error.NameTooLong;
+        @memcpy(path_buf[0..search_path.len], search_path);
+        path_buf[search_path.len] = '/';
+        @memcpy(path_buf[search_path.len + 1 ..][0..file_slice.len], file_slice);
+        path_buf[path_len] = 0;
+        const full_path = path_buf[0..path_len :0].ptr;
+        switch (arg0_expand) {
+            .expand => child_argv[0] = full_path,
+            .no_expand => {},
+        }
+        err = execveZ(full_path, child_argv, envp);
+        switch (err) {
+            error.AccessDenied => seen_eacces = true,
+            error.FileNotFound, error.NotDir => {},
+            else => |e| return e,
+        }
+    }
+    if (seen_eacces) return error.AccessDenied;
+    return err;
+}
+
+/// This function also uses the PATH environment variable to get the full path to the executable.
+/// If `file` is an absolute path, this is the same as `execveZ`.
+pub fn execvpeZ(
+    file: [*:0]const u8,
+    argv_ptr: [*:null]const ?[*:0]const u8,
+    envp: [*:null]const ?[*:0]const u8,
+) ExecveError {
+    return execvpeZ_expandArg0(.no_expand, file, argv_ptr, envp);
+}
+
+/// Get an environment variable.
+/// See also `getenvZ`.
+pub fn getenv(key: []const u8) ?[:0]const u8 {
+    if (native_os == .windows) {
+        @compileError("std.os.getenv is unavailable for Windows because environment strings are in WTF-16 format. See std.process.getEnvVarOwned for a cross-platform API or std.process.getenvW for a Windows-specific API.");
+    }
+    if (builtin.link_libc) {
+        var ptr = std.c.environ;
+        while (ptr[0]) |line| : (ptr += 1) {
+            var line_i: usize = 0;
+            while (line[line_i] != 0 and line[line_i] != '=') : (line_i += 1) {}
+            const this_key = line[0..line_i];
+
+            if (!mem.eql(u8, this_key, key)) continue;
+
+            return mem.sliceTo(line + line_i + 1, 0);
+        }
+        return null;
+    }
+    if (native_os == .wasi) {
+        @compileError("std.os.getenv is unavailable for WASI. See std.process.getEnvMap or std.process.getEnvVarOwned for a cross-platform API.");
+    }
+    // The simplified start logic doesn't populate environ.
+    if (std.start.simplified_logic) return null;
+    // TODO see https://github.com/ziglang/zig/issues/4524
+    for (std.os.environ) |ptr| {
+        var line_i: usize = 0;
+        while (ptr[line_i] != 0 and ptr[line_i] != '=') : (line_i += 1) {}
+        const this_key = ptr[0..line_i];
+        if (!mem.eql(u8, key, this_key)) continue;
+
+        return mem.sliceTo(ptr + line_i + 1, 0);
+    }
+    return null;
+}
+
+/// Get an environment variable with a null-terminated name.
+/// See also `getenv`.
+pub fn getenvZ(key: [*:0]const u8) ?[:0]const u8 {
+    if (builtin.link_libc) {
+        const value = system.getenv(key) orelse return null;
+        return mem.sliceTo(value, 0);
+    }
+    if (native_os == .windows) {
+        @compileError("std.os.getenvZ is unavailable for Windows because environment string is in WTF-16 format. See std.process.getEnvVarOwned for cross-platform API or std.process.getenvW for Windows-specific API.");
+    }
+    return getenv(mem.sliceTo(key, 0));
+}
+
+pub const GetCwdError = error{
+    NameTooLong,
+    CurrentWorkingDirectoryUnlinked,
+} || UnexpectedError;
+
+/// The result is a slice of out_buffer, indexed from 0.
+pub fn getcwd(out_buffer: []u8) GetCwdError![]u8 {
+    if (native_os == .windows) {
+        return windows.GetCurrentDirectory(out_buffer);
+    } else if (native_os == .wasi and !builtin.link_libc) {
+        const path = ".";
+        if (out_buffer.len < path.len) return error.NameTooLong;
+        const result = out_buffer[0..path.len];
+        @memcpy(result, path);
+        return result;
+    }
+
+    const err: E = if (builtin.link_libc) err: {
+        const c_err = if (std.c.getcwd(out_buffer.ptr, out_buffer.len)) |_| 0 else std.c._errno().*;
+        break :err @enumFromInt(c_err);
+    } else err: {
+        break :err errno(system.getcwd(out_buffer.ptr, out_buffer.len));
+    };
+    switch (err) {
+        .SUCCESS => return mem.sliceTo(out_buffer, 0),
+        .FAULT => unreachable,
+        .INVAL => unreachable,
+        .NOENT => return error.CurrentWorkingDirectoryUnlinked,
+        .RANGE => return error.NameTooLong,
+        else => return unexpectedErrno(err),
+    }
+}
+
+pub const SymLinkError = error{
+    /// In WASI, this error may occur when the file descriptor does
+    /// not hold the required rights to create a new symbolic link relative to it.
+    AccessDenied,
+    DiskQuota,
+    PathAlreadyExists,
+    FileSystem,
+    SymLinkLoop,
+    FileNotFound,
+    SystemResources,
+    NoSpaceLeft,
+    ReadOnlyFileSystem,
+    NotDir,
+    NameTooLong,
+
+    /// WASI-only; file paths must be valid UTF-8.
+    InvalidUtf8,
+
+    /// Windows-only; file paths provided by the user must be valid WTF-8.
+    /// https://simonsapin.github.io/wtf-8/
+    InvalidWtf8,
+
+    BadPathName,
+} || UnexpectedError;
+
+/// Creates a symbolic link named `sym_link_path` which contains the string `target_path`.
+/// A symbolic link (also known as a soft link) may point to an existing file or to a nonexistent
+/// one; the latter case is known as a dangling link.
+/// On Windows, both paths should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// On WASI, both paths should be encoded as valid UTF-8.
+/// On other platforms, both paths are an opaque sequence of bytes with no particular encoding.
+/// If `sym_link_path` exists, it will not be overwritten.
+/// See also `symlinkZ.
+pub fn symlink(target_path: []const u8, sym_link_path: []const u8) SymLinkError!void {
+    if (native_os == .windows) {
+        @compileError("symlink is not supported on Windows; use std.os.windows.CreateSymbolicLink instead");
+    } else if (native_os == .wasi and !builtin.link_libc) {
+        return symlinkat(target_path, wasi.AT.FDCWD, sym_link_path);
+    }
+    const target_path_c = try toPosixPath(target_path);
+    const sym_link_path_c = try toPosixPath(sym_link_path);
+    return symlinkZ(&target_path_c, &sym_link_path_c);
+}
+
+/// This is the same as `symlink` except the parameters are null-terminated pointers.
+/// See also `symlink`.
+pub fn symlinkZ(target_path: [*:0]const u8, sym_link_path: [*:0]const u8) SymLinkError!void {
+    if (native_os == .windows) {
+        @compileError("symlink is not supported on Windows; use std.os.windows.CreateSymbolicLink instead");
+    } else if (native_os == .wasi and !builtin.link_libc) {
+        return symlinkatZ(target_path, fs.cwd().fd, sym_link_path);
+    }
+    switch (errno(system.symlink(target_path, sym_link_path))) {
+        .SUCCESS => return,
+        .FAULT => unreachable,
+        .INVAL => unreachable,
+        .ACCES => return error.AccessDenied,
+        .PERM => return error.AccessDenied,
+        .DQUOT => return error.DiskQuota,
+        .EXIST => return error.PathAlreadyExists,
+        .IO => return error.FileSystem,
+        .LOOP => return error.SymLinkLoop,
+        .NAMETOOLONG => return error.NameTooLong,
+        .NOENT => return error.FileNotFound,
+        .NOTDIR => return error.NotDir,
+        .NOMEM => return error.SystemResources,
+        .NOSPC => return error.NoSpaceLeft,
+        .ROFS => return error.ReadOnlyFileSystem,
+        .ILSEQ => |err| if (native_os == .wasi)
+            return error.InvalidUtf8
+        else
+            return unexpectedErrno(err),
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// Similar to `symlink`, however, creates a symbolic link named `sym_link_path` which contains the string
+/// `target_path` **relative** to `newdirfd` directory handle.
+/// A symbolic link (also known as a soft link) may point to an existing file or to a nonexistent
+/// one; the latter case is known as a dangling link.
+/// On Windows, both paths should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// On WASI, both paths should be encoded as valid UTF-8.
+/// On other platforms, both paths are an opaque sequence of bytes with no particular encoding.
+/// If `sym_link_path` exists, it will not be overwritten.
+/// See also `symlinkatWasi`, `symlinkatZ` and `symlinkatW`.
+pub fn symlinkat(target_path: []const u8, newdirfd: fd_t, sym_link_path: []const u8) SymLinkError!void {
+    if (native_os == .windows) {
+        @compileError("symlinkat is not supported on Windows; use std.os.windows.CreateSymbolicLink instead");
+    } else if (native_os == .wasi and !builtin.link_libc) {
+        return symlinkatWasi(target_path, newdirfd, sym_link_path);
+    }
+    const target_path_c = try toPosixPath(target_path);
+    const sym_link_path_c = try toPosixPath(sym_link_path);
+    return symlinkatZ(&target_path_c, newdirfd, &sym_link_path_c);
+}
+
+/// WASI-only. The same as `symlinkat` but targeting WASI.
+/// See also `symlinkat`.
+pub fn symlinkatWasi(target_path: []const u8, newdirfd: fd_t, sym_link_path: []const u8) SymLinkError!void {
+    switch (wasi.path_symlink(target_path.ptr, target_path.len, newdirfd, sym_link_path.ptr, sym_link_path.len)) {
+        .SUCCESS => {},
+        .FAULT => unreachable,
+        .INVAL => unreachable,
+        .BADF => unreachable,
+        .ACCES => return error.AccessDenied,
+        .PERM => return error.AccessDenied,
+        .DQUOT => return error.DiskQuota,
+        .EXIST => return error.PathAlreadyExists,
+        .IO => return error.FileSystem,
+        .LOOP => return error.SymLinkLoop,
+        .NAMETOOLONG => return error.NameTooLong,
+        .NOENT => return error.FileNotFound,
+        .NOTDIR => return error.NotDir,
+        .NOMEM => return error.SystemResources,
+        .NOSPC => return error.NoSpaceLeft,
+        .ROFS => return error.ReadOnlyFileSystem,
+        .NOTCAPABLE => return error.AccessDenied,
+        .ILSEQ => return error.InvalidUtf8,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// The same as `symlinkat` except the parameters are null-terminated pointers.
+/// See also `symlinkat`.
+pub fn symlinkatZ(target_path: [*:0]const u8, newdirfd: fd_t, sym_link_path: [*:0]const u8) SymLinkError!void {
+    if (native_os == .windows) {
+        @compileError("symlinkat is not supported on Windows; use std.os.windows.CreateSymbolicLink instead");
+    } else if (native_os == .wasi and !builtin.link_libc) {
+        return symlinkat(mem.sliceTo(target_path, 0), newdirfd, mem.sliceTo(sym_link_path, 0));
+    }
+    switch (errno(system.symlinkat(target_path, newdirfd, sym_link_path))) {
+        .SUCCESS => return,
+        .FAULT => unreachable,
+        .INVAL => unreachable,
+        .ACCES => return error.AccessDenied,
+        .PERM => return error.AccessDenied,
+        .DQUOT => return error.DiskQuota,
+        .EXIST => return error.PathAlreadyExists,
+        .IO => return error.FileSystem,
+        .LOOP => return error.SymLinkLoop,
+        .NAMETOOLONG => return error.NameTooLong,
+        .NOENT => return error.FileNotFound,
+        .NOTDIR => return error.NotDir,
+        .NOMEM => return error.SystemResources,
+        .NOSPC => return error.NoSpaceLeft,
+        .ROFS => return error.ReadOnlyFileSystem,
+        .ILSEQ => |err| if (native_os == .wasi)
+            return error.InvalidUtf8
+        else
+            return unexpectedErrno(err),
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub const LinkError = UnexpectedError || error{
+    AccessDenied,
+    DiskQuota,
+    PathAlreadyExists,
+    FileSystem,
+    SymLinkLoop,
+    LinkQuotaExceeded,
+    NameTooLong,
+    FileNotFound,
+    SystemResources,
+    NoSpaceLeft,
+    ReadOnlyFileSystem,
+    NotSameFileSystem,
+
+    /// WASI-only; file paths must be valid UTF-8.
+    InvalidUtf8,
+};
+
+/// On WASI, both paths should be encoded as valid UTF-8.
+/// On other platforms, both paths are an opaque sequence of bytes with no particular encoding.
+pub fn linkZ(oldpath: [*:0]const u8, newpath: [*:0]const u8, flags: i32) LinkError!void {
+    if (native_os == .wasi and !builtin.link_libc) {
+        return link(mem.sliceTo(oldpath, 0), mem.sliceTo(newpath, 0), flags);
+    }
+    switch (errno(system.link(oldpath, newpath, flags))) {
+        .SUCCESS => return,
+        .ACCES => return error.AccessDenied,
+        .DQUOT => return error.DiskQuota,
+        .EXIST => return error.PathAlreadyExists,
+        .FAULT => unreachable,
+        .IO => return error.FileSystem,
+        .LOOP => return error.SymLinkLoop,
+        .MLINK => return error.LinkQuotaExceeded,
+        .NAMETOOLONG => return error.NameTooLong,
+        .NOENT => return error.FileNotFound,
+        .NOMEM => return error.SystemResources,
+        .NOSPC => return error.NoSpaceLeft,
+        .PERM => return error.AccessDenied,
+        .ROFS => return error.ReadOnlyFileSystem,
+        .XDEV => return error.NotSameFileSystem,
+        .INVAL => unreachable,
+        .ILSEQ => |err| if (native_os == .wasi)
+            return error.InvalidUtf8
+        else
+            return unexpectedErrno(err),
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// On WASI, both paths should be encoded as valid UTF-8.
+/// On other platforms, both paths are an opaque sequence of bytes with no particular encoding.
+pub fn link(oldpath: []const u8, newpath: []const u8, flags: i32) LinkError!void {
+    if (native_os == .wasi and !builtin.link_libc) {
+        return linkat(wasi.AT.FDCWD, oldpath, wasi.AT.FDCWD, newpath, flags) catch |err| switch (err) {
+            error.NotDir => unreachable, // link() does not support directories
+            else => |e| return e,
+        };
+    }
+    const old = try toPosixPath(oldpath);
+    const new = try toPosixPath(newpath);
+    return try linkZ(&old, &new, flags);
+}
+
+pub const LinkatError = LinkError || error{NotDir};
+
+/// On WASI, both paths should be encoded as valid UTF-8.
+/// On other platforms, both paths are an opaque sequence of bytes with no particular encoding.
+pub fn linkatZ(
+    olddir: fd_t,
+    oldpath: [*:0]const u8,
+    newdir: fd_t,
+    newpath: [*:0]const u8,
+    flags: i32,
+) LinkatError!void {
+    if (native_os == .wasi and !builtin.link_libc) {
+        return linkat(olddir, mem.sliceTo(oldpath, 0), newdir, mem.sliceTo(newpath, 0), flags);
+    }
+    switch (errno(system.linkat(olddir, oldpath, newdir, newpath, flags))) {
+        .SUCCESS => return,
+        .ACCES => return error.AccessDenied,
+        .DQUOT => return error.DiskQuota,
+        .EXIST => return error.PathAlreadyExists,
+        .FAULT => unreachable,
+        .IO => return error.FileSystem,
+        .LOOP => return error.SymLinkLoop,
+        .MLINK => return error.LinkQuotaExceeded,
+        .NAMETOOLONG => return error.NameTooLong,
+        .NOENT => return error.FileNotFound,
+        .NOMEM => return error.SystemResources,
+        .NOSPC => return error.NoSpaceLeft,
+        .NOTDIR => return error.NotDir,
+        .PERM => return error.AccessDenied,
+        .ROFS => return error.ReadOnlyFileSystem,
+        .XDEV => return error.NotSameFileSystem,
+        .INVAL => unreachable,
+        .ILSEQ => |err| if (native_os == .wasi)
+            return error.InvalidUtf8
+        else
+            return unexpectedErrno(err),
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// On WASI, both paths should be encoded as valid UTF-8.
+/// On other platforms, both paths are an opaque sequence of bytes with no particular encoding.
+pub fn linkat(
+    olddir: fd_t,
+    oldpath: []const u8,
+    newdir: fd_t,
+    newpath: []const u8,
+    flags: i32,
+) LinkatError!void {
+    if (native_os == .wasi and !builtin.link_libc) {
+        const old: RelativePathWasi = .{ .dir_fd = olddir, .relative_path = oldpath };
+        const new: RelativePathWasi = .{ .dir_fd = newdir, .relative_path = newpath };
+        const old_flags: wasi.lookupflags_t = .{
+            .SYMLINK_FOLLOW = (flags & AT.SYMLINK_FOLLOW) != 0,
+        };
+        switch (wasi.path_link(
+            old.dir_fd,
+            old_flags,
+            old.relative_path.ptr,
+            old.relative_path.len,
+            new.dir_fd,
+            new.relative_path.ptr,
+            new.relative_path.len,
+        )) {
+            .SUCCESS => return,
+            .ACCES => return error.AccessDenied,
+            .DQUOT => return error.DiskQuota,
+            .EXIST => return error.PathAlreadyExists,
+            .FAULT => unreachable,
+            .IO => return error.FileSystem,
+            .LOOP => return error.SymLinkLoop,
+            .MLINK => return error.LinkQuotaExceeded,
+            .NAMETOOLONG => return error.NameTooLong,
+            .NOENT => return error.FileNotFound,
+            .NOMEM => return error.SystemResources,
+            .NOSPC => return error.NoSpaceLeft,
+            .NOTDIR => return error.NotDir,
+            .PERM => return error.AccessDenied,
+            .ROFS => return error.ReadOnlyFileSystem,
+            .XDEV => return error.NotSameFileSystem,
+            .INVAL => unreachable,
+            .ILSEQ => return error.InvalidUtf8,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+    const old = try toPosixPath(oldpath);
+    const new = try toPosixPath(newpath);
+    return try linkatZ(olddir, &old, newdir, &new, flags);
+}
+
+pub const UnlinkError = error{
+    FileNotFound,
+
+    /// In WASI, this error may occur when the file descriptor does
+    /// not hold the required rights to unlink a resource by path relative to it.
+    AccessDenied,
+    FileBusy,
+    FileSystem,
+    IsDir,
+    SymLinkLoop,
+    NameTooLong,
+    NotDir,
+    SystemResources,
+    ReadOnlyFileSystem,
+
+    /// WASI-only; file paths must be valid UTF-8.
+    InvalidUtf8,
+
+    /// Windows-only; file paths provided by the user must be valid WTF-8.
+    /// https://simonsapin.github.io/wtf-8/
+    InvalidWtf8,
+
+    /// On Windows, file paths cannot contain these characters:
+    /// '/', '*', '?', '"', '<', '>', '|'
+    BadPathName,
+
+    /// On Windows, `\\server` or `\\server\share` was not found.
+    NetworkNotFound,
+} || UnexpectedError;
+
+/// Delete a name and possibly the file it refers to.
+/// On Windows, `file_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// 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 `unlinkZ`.
+pub fn unlink(file_path: []const u8) UnlinkError!void {
+    if (native_os == .wasi and !builtin.link_libc) {
+        return unlinkat(wasi.AT.FDCWD, file_path, 0) catch |err| switch (err) {
+            error.DirNotEmpty => unreachable, // only occurs when targeting directories
+            else => |e| return e,
+        };
+    } else if (native_os == .windows) {
+        const file_path_w = try windows.sliceToPrefixedFileW(null, file_path);
+        return unlinkW(file_path_w.span());
+    } else {
+        const file_path_c = try toPosixPath(file_path);
+        return unlinkZ(&file_path_c);
+    }
+}
+
+/// Same as `unlink` except the parameter is null terminated.
+pub fn unlinkZ(file_path: [*:0]const u8) UnlinkError!void {
+    if (native_os == .windows) {
+        const file_path_w = try windows.cStrToPrefixedFileW(null, file_path);
+        return unlinkW(file_path_w.span());
+    } else if (native_os == .wasi and !builtin.link_libc) {
+        return unlink(mem.sliceTo(file_path, 0));
+    }
+    switch (errno(system.unlink(file_path))) {
+        .SUCCESS => return,
+        .ACCES => return error.AccessDenied,
+        .PERM => return error.AccessDenied,
+        .BUSY => return error.FileBusy,
+        .FAULT => unreachable,
+        .INVAL => unreachable,
+        .IO => return error.FileSystem,
+        .ISDIR => return error.IsDir,
+        .LOOP => return error.SymLinkLoop,
+        .NAMETOOLONG => return error.NameTooLong,
+        .NOENT => return error.FileNotFound,
+        .NOTDIR => return error.NotDir,
+        .NOMEM => return error.SystemResources,
+        .ROFS => return error.ReadOnlyFileSystem,
+        .ILSEQ => |err| if (native_os == .wasi)
+            return error.InvalidUtf8
+        else
+            return unexpectedErrno(err),
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// Windows-only. Same as `unlink` except the parameter is null-terminated, WTF16 LE encoded.
+pub fn unlinkW(file_path_w: []const u16) UnlinkError!void {
+    windows.DeleteFile(file_path_w, .{ .dir = fs.cwd().fd }) catch |err| switch (err) {
+        error.DirNotEmpty => unreachable, // we're not passing .remove_dir = true
+        else => |e| return e,
+    };
+}
+
+pub const UnlinkatError = UnlinkError || error{
+    /// When passing `AT.REMOVEDIR`, this error occurs when the named directory is not empty.
+    DirNotEmpty,
+};
+
+/// Delete a file name and possibly the file it refers to, based on an open directory handle.
+/// On Windows, `file_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// 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.
+/// Asserts that the path parameter has no null bytes.
+pub fn unlinkat(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!void {
+    if (native_os == .windows) {
+        const file_path_w = try windows.sliceToPrefixedFileW(dirfd, file_path);
+        return unlinkatW(dirfd, file_path_w.span(), flags);
+    } else if (native_os == .wasi and !builtin.link_libc) {
+        return unlinkatWasi(dirfd, file_path, flags);
+    } else {
+        const file_path_c = try toPosixPath(file_path);
+        return unlinkatZ(dirfd, &file_path_c, flags);
+    }
+}
+
+/// WASI-only. Same as `unlinkat` but targeting WASI.
+/// See also `unlinkat`.
+pub fn unlinkatWasi(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!void {
+    const remove_dir = (flags & AT.REMOVEDIR) != 0;
+    const res = if (remove_dir)
+        wasi.path_remove_directory(dirfd, file_path.ptr, file_path.len)
+    else
+        wasi.path_unlink_file(dirfd, file_path.ptr, file_path.len);
+    switch (res) {
+        .SUCCESS => return,
+        .ACCES => return error.AccessDenied,
+        .PERM => return error.AccessDenied,
+        .BUSY => return error.FileBusy,
+        .FAULT => unreachable,
+        .IO => return error.FileSystem,
+        .ISDIR => return error.IsDir,
+        .LOOP => return error.SymLinkLoop,
+        .NAMETOOLONG => return error.NameTooLong,
+        .NOENT => return error.FileNotFound,
+        .NOTDIR => return error.NotDir,
+        .NOMEM => return error.SystemResources,
+        .ROFS => return error.ReadOnlyFileSystem,
+        .NOTEMPTY => return error.DirNotEmpty,
+        .NOTCAPABLE => return error.AccessDenied,
+        .ILSEQ => return error.InvalidUtf8,
+
+        .INVAL => unreachable, // invalid flags, or pathname has . as last component
+        .BADF => unreachable, // always a race condition
+
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// Same as `unlinkat` but `file_path` is a null-terminated string.
+pub fn unlinkatZ(dirfd: fd_t, file_path_c: [*:0]const u8, flags: u32) UnlinkatError!void {
+    if (native_os == .windows) {
+        const file_path_w = try windows.cStrToPrefixedFileW(dirfd, file_path_c);
+        return unlinkatW(dirfd, file_path_w.span(), flags);
+    } else if (native_os == .wasi and !builtin.link_libc) {
+        return unlinkat(dirfd, mem.sliceTo(file_path_c, 0), flags);
+    }
+    switch (errno(system.unlinkat(dirfd, file_path_c, flags))) {
+        .SUCCESS => return,
+        .ACCES => return error.AccessDenied,
+        .PERM => return error.AccessDenied,
+        .BUSY => return error.FileBusy,
+        .FAULT => unreachable,
+        .IO => return error.FileSystem,
+        .ISDIR => return error.IsDir,
+        .LOOP => return error.SymLinkLoop,
+        .NAMETOOLONG => return error.NameTooLong,
+        .NOENT => return error.FileNotFound,
+        .NOTDIR => return error.NotDir,
+        .NOMEM => return error.SystemResources,
+        .ROFS => return error.ReadOnlyFileSystem,
+        .EXIST => return error.DirNotEmpty,
+        .NOTEMPTY => return error.DirNotEmpty,
+        .ILSEQ => |err| if (native_os == .wasi)
+            return error.InvalidUtf8
+        else
+            return unexpectedErrno(err),
+
+        .INVAL => unreachable, // invalid flags, or pathname has . as last component
+        .BADF => unreachable, // always a race condition
+
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// Same as `unlinkat` but `sub_path_w` is WTF16LE, NT prefixed. Windows only.
+pub fn unlinkatW(dirfd: fd_t, sub_path_w: []const u16, flags: u32) UnlinkatError!void {
+    const remove_dir = (flags & AT.REMOVEDIR) != 0;
+    return windows.DeleteFile(sub_path_w, .{ .dir = dirfd, .remove_dir = remove_dir });
+}
+
+pub const RenameError = error{
+    /// In WASI, this error may occur when the file descriptor does
+    /// not hold the required rights to rename a resource by path relative to it.
+    ///
+    /// On Windows, this error may be returned instead of PathAlreadyExists when
+    /// renaming a directory over an existing directory.
+    AccessDenied,
+    FileBusy,
+    DiskQuota,
+    IsDir,
+    SymLinkLoop,
+    LinkQuotaExceeded,
+    NameTooLong,
+    FileNotFound,
+    NotDir,
+    SystemResources,
+    NoSpaceLeft,
+    PathAlreadyExists,
+    ReadOnlyFileSystem,
+    RenameAcrossMountPoints,
+    /// WASI-only; file paths must be valid UTF-8.
+    InvalidUtf8,
+    /// Windows-only; file paths provided by the user must be valid WTF-8.
+    /// https://simonsapin.github.io/wtf-8/
+    InvalidWtf8,
+    BadPathName,
+    NoDevice,
+    SharingViolation,
+    PipeBusy,
+    /// On Windows, `\\server` or `\\server\share` was not found.
+    NetworkNotFound,
+    /// On Windows, antivirus software is enabled by default. It can be
+    /// disabled, but Windows Update sometimes ignores the user's preference
+    /// and re-enables it. When enabled, antivirus software on Windows
+    /// intercepts file system operations and makes them significantly slower
+    /// in addition to possibly failing with this error code.
+    AntivirusInterference,
+} || UnexpectedError;
+
+/// Change the name or location of a file.
+/// On Windows, both paths should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// On WASI, both paths should be encoded as valid UTF-8.
+/// On other platforms, both paths are an opaque sequence of bytes with no particular encoding.
+pub fn rename(old_path: []const u8, new_path: []const u8) RenameError!void {
+    if (native_os == .wasi and !builtin.link_libc) {
+        return renameat(wasi.AT.FDCWD, old_path, wasi.AT.FDCWD, new_path);
+    } else if (native_os == .windows) {
+        const old_path_w = try windows.sliceToPrefixedFileW(null, old_path);
+        const new_path_w = try windows.sliceToPrefixedFileW(null, new_path);
+        return renameW(old_path_w.span().ptr, new_path_w.span().ptr);
+    } else {
+        const old_path_c = try toPosixPath(old_path);
+        const new_path_c = try toPosixPath(new_path);
+        return renameZ(&old_path_c, &new_path_c);
+    }
+}
+
+/// Same as `rename` except the parameters are null-terminated.
+pub fn renameZ(old_path: [*:0]const u8, new_path: [*:0]const u8) RenameError!void {
+    if (native_os == .windows) {
+        const old_path_w = try windows.cStrToPrefixedFileW(null, old_path);
+        const new_path_w = try windows.cStrToPrefixedFileW(null, new_path);
+        return renameW(old_path_w.span().ptr, new_path_w.span().ptr);
+    } else if (native_os == .wasi and !builtin.link_libc) {
+        return rename(mem.sliceTo(old_path, 0), mem.sliceTo(new_path, 0));
+    }
+    switch (errno(system.rename(old_path, new_path))) {
+        .SUCCESS => return,
+        .ACCES => return error.AccessDenied,
+        .PERM => return error.AccessDenied,
+        .BUSY => return error.FileBusy,
+        .DQUOT => return error.DiskQuota,
+        .FAULT => unreachable,
+        .INVAL => unreachable,
+        .ISDIR => return error.IsDir,
+        .LOOP => return error.SymLinkLoop,
+        .MLINK => return error.LinkQuotaExceeded,
+        .NAMETOOLONG => return error.NameTooLong,
+        .NOENT => return error.FileNotFound,
+        .NOTDIR => return error.NotDir,
+        .NOMEM => return error.SystemResources,
+        .NOSPC => return error.NoSpaceLeft,
+        .EXIST => return error.PathAlreadyExists,
+        .NOTEMPTY => return error.PathAlreadyExists,
+        .ROFS => return error.ReadOnlyFileSystem,
+        .XDEV => return error.RenameAcrossMountPoints,
+        .ILSEQ => |err| if (native_os == .wasi)
+            return error.InvalidUtf8
+        else
+            return unexpectedErrno(err),
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// Same as `rename` except the parameters are null-terminated and WTF16LE encoded.
+/// Assumes target is Windows.
+pub fn renameW(old_path: [*:0]const u16, new_path: [*:0]const u16) RenameError!void {
+    const flags = windows.MOVEFILE_REPLACE_EXISTING | windows.MOVEFILE_WRITE_THROUGH;
+    return windows.MoveFileExW(old_path, new_path, flags);
+}
+
+/// Change the name or location of a file based on an open directory handle.
+/// On Windows, both paths should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// On WASI, both paths should be encoded as valid UTF-8.
+/// On other platforms, both paths are an opaque sequence of bytes with no particular encoding.
+pub fn renameat(
+    old_dir_fd: fd_t,
+    old_path: []const u8,
+    new_dir_fd: fd_t,
+    new_path: []const u8,
+) RenameError!void {
+    if (native_os == .windows) {
+        const old_path_w = try windows.sliceToPrefixedFileW(old_dir_fd, old_path);
+        const new_path_w = try windows.sliceToPrefixedFileW(new_dir_fd, new_path);
+        return renameatW(old_dir_fd, old_path_w.span(), new_dir_fd, new_path_w.span(), windows.TRUE);
+    } else if (native_os == .wasi and !builtin.link_libc) {
+        const old: RelativePathWasi = .{ .dir_fd = old_dir_fd, .relative_path = old_path };
+        const new: RelativePathWasi = .{ .dir_fd = new_dir_fd, .relative_path = new_path };
+        return renameatWasi(old, new);
+    } else {
+        const old_path_c = try toPosixPath(old_path);
+        const new_path_c = try toPosixPath(new_path);
+        return renameatZ(old_dir_fd, &old_path_c, new_dir_fd, &new_path_c);
+    }
+}
+
+/// WASI-only. Same as `renameat` expect targeting WASI.
+/// See also `renameat`.
+fn renameatWasi(old: RelativePathWasi, new: RelativePathWasi) RenameError!void {
+    switch (wasi.path_rename(old.dir_fd, old.relative_path.ptr, old.relative_path.len, new.dir_fd, new.relative_path.ptr, new.relative_path.len)) {
+        .SUCCESS => return,
+        .ACCES => return error.AccessDenied,
+        .PERM => return error.AccessDenied,
+        .BUSY => return error.FileBusy,
+        .DQUOT => return error.DiskQuota,
+        .FAULT => unreachable,
+        .INVAL => unreachable,
+        .ISDIR => return error.IsDir,
+        .LOOP => return error.SymLinkLoop,
+        .MLINK => return error.LinkQuotaExceeded,
+        .NAMETOOLONG => return error.NameTooLong,
+        .NOENT => return error.FileNotFound,
+        .NOTDIR => return error.NotDir,
+        .NOMEM => return error.SystemResources,
+        .NOSPC => return error.NoSpaceLeft,
+        .EXIST => return error.PathAlreadyExists,
+        .NOTEMPTY => return error.PathAlreadyExists,
+        .ROFS => return error.ReadOnlyFileSystem,
+        .XDEV => return error.RenameAcrossMountPoints,
+        .NOTCAPABLE => return error.AccessDenied,
+        .ILSEQ => return error.InvalidUtf8,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// An fd-relative file path
+///
+/// This is currently only used for WASI-specific functionality, but the concept
+/// is the same as the dirfd/pathname pairs in the `*at(...)` POSIX functions.
+const RelativePathWasi = struct {
+    /// Handle to directory
+    dir_fd: fd_t,
+    /// Path to resource within `dir_fd`.
+    relative_path: []const u8,
+};
+
+/// Same as `renameat` except the parameters are null-terminated.
+pub fn renameatZ(
+    old_dir_fd: fd_t,
+    old_path: [*:0]const u8,
+    new_dir_fd: fd_t,
+    new_path: [*:0]const u8,
+) RenameError!void {
+    if (native_os == .windows) {
+        const old_path_w = try windows.cStrToPrefixedFileW(old_dir_fd, old_path);
+        const new_path_w = try windows.cStrToPrefixedFileW(new_dir_fd, new_path);
+        return renameatW(old_dir_fd, old_path_w.span(), new_dir_fd, new_path_w.span(), windows.TRUE);
+    } else if (native_os == .wasi and !builtin.link_libc) {
+        return renameat(old_dir_fd, mem.sliceTo(old_path, 0), new_dir_fd, mem.sliceTo(new_path, 0));
+    }
+
+    switch (errno(system.renameat(old_dir_fd, old_path, new_dir_fd, new_path))) {
+        .SUCCESS => return,
+        .ACCES => return error.AccessDenied,
+        .PERM => return error.AccessDenied,
+        .BUSY => return error.FileBusy,
+        .DQUOT => return error.DiskQuota,
+        .FAULT => unreachable,
+        .INVAL => unreachable,
+        .ISDIR => return error.IsDir,
+        .LOOP => return error.SymLinkLoop,
+        .MLINK => return error.LinkQuotaExceeded,
+        .NAMETOOLONG => return error.NameTooLong,
+        .NOENT => return error.FileNotFound,
+        .NOTDIR => return error.NotDir,
+        .NOMEM => return error.SystemResources,
+        .NOSPC => return error.NoSpaceLeft,
+        .EXIST => return error.PathAlreadyExists,
+        .NOTEMPTY => return error.PathAlreadyExists,
+        .ROFS => return error.ReadOnlyFileSystem,
+        .XDEV => return error.RenameAcrossMountPoints,
+        .ILSEQ => |err| if (native_os == .wasi)
+            return error.InvalidUtf8
+        else
+            return unexpectedErrno(err),
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// Same as `renameat` but Windows-only and the path parameters are
+/// [WTF-16](https://simonsapin.github.io/wtf-8/#potentially-ill-formed-utf-16) encoded.
+pub fn renameatW(
+    old_dir_fd: fd_t,
+    old_path_w: []const u16,
+    new_dir_fd: fd_t,
+    new_path_w: []const u16,
+    ReplaceIfExists: windows.BOOLEAN,
+) RenameError!void {
+    const src_fd = windows.OpenFile(old_path_w, .{
+        .dir = old_dir_fd,
+        .access_mask = windows.SYNCHRONIZE | windows.GENERIC_WRITE | windows.DELETE,
+        .creation = windows.FILE_OPEN,
+        .filter = .any, // This function is supposed to rename both files and directories.
+        .follow_symlinks = false,
+    }) catch |err| switch (err) {
+        error.WouldBlock => unreachable, // Not possible without `.share_access_nonblocking = true`.
+        else => |e| return e,
+    };
+    defer windows.CloseHandle(src_fd);
+
+    var need_fallback = true;
+    var rc: windows.NTSTATUS = undefined;
+    // FILE_RENAME_INFORMATION_EX and FILE_RENAME_POSIX_SEMANTICS require >= win10_rs1,
+    // but FILE_RENAME_IGNORE_READONLY_ATTRIBUTE requires >= win10_rs5. We check >= rs5 here
+    // so that we only use POSIX_SEMANTICS when we know IGNORE_READONLY_ATTRIBUTE will also be
+    // supported in order to avoid either (1) using a redundant call that we can know in advance will return
+    // STATUS_NOT_SUPPORTED or (2) only setting IGNORE_READONLY_ATTRIBUTE when >= rs5
+    // and therefore having different behavior when the Windows version is >= rs1 but < rs5.
+    if (builtin.target.os.isAtLeast(.windows, .win10_rs5) orelse false) {
+        const struct_buf_len = @sizeOf(windows.FILE_RENAME_INFORMATION_EX) + (max_path_bytes - 1);
+        var rename_info_buf: [struct_buf_len]u8 align(@alignOf(windows.FILE_RENAME_INFORMATION_EX)) = undefined;
+        const struct_len = @sizeOf(windows.FILE_RENAME_INFORMATION_EX) - 1 + new_path_w.len * 2;
+        if (struct_len > struct_buf_len) return error.NameTooLong;
+
+        const rename_info: *windows.FILE_RENAME_INFORMATION_EX = @ptrCast(&rename_info_buf);
+        var io_status_block: windows.IO_STATUS_BLOCK = undefined;
+
+        var flags: windows.ULONG = windows.FILE_RENAME_POSIX_SEMANTICS | windows.FILE_RENAME_IGNORE_READONLY_ATTRIBUTE;
+        if (ReplaceIfExists == windows.TRUE) flags |= windows.FILE_RENAME_REPLACE_IF_EXISTS;
+        rename_info.* = .{
+            .Flags = flags,
+            .RootDirectory = if (fs.path.isAbsoluteWindowsWTF16(new_path_w)) null else new_dir_fd,
+            .FileNameLength = @intCast(new_path_w.len * 2), // already checked error.NameTooLong
+            .FileName = undefined,
+        };
+        @memcpy((&rename_info.FileName).ptr, new_path_w);
+        rc = windows.ntdll.NtSetInformationFile(
+            src_fd,
+            &io_status_block,
+            rename_info,
+            @intCast(struct_len), // already checked for error.NameTooLong
+            .FileRenameInformationEx,
+        );
+        switch (rc) {
+            .SUCCESS => return,
+            // INVALID_PARAMETER here means that the filesystem does not support FileRenameInformationEx
+            .INVALID_PARAMETER => {},
+            .DIRECTORY_NOT_EMPTY => return error.PathAlreadyExists,
+            .FILE_IS_A_DIRECTORY => return error.IsDir,
+            .NOT_A_DIRECTORY => return error.NotDir,
+            // For all other statuses, fall down to the switch below to handle them.
+            else => need_fallback = false,
+        }
+    }
+
+    if (need_fallback) {
+        const struct_buf_len = @sizeOf(windows.FILE_RENAME_INFORMATION) + (max_path_bytes - 1);
+        var rename_info_buf: [struct_buf_len]u8 align(@alignOf(windows.FILE_RENAME_INFORMATION)) = undefined;
+        const struct_len = @sizeOf(windows.FILE_RENAME_INFORMATION) - 1 + new_path_w.len * 2;
+        if (struct_len > struct_buf_len) return error.NameTooLong;
+
+        const rename_info: *windows.FILE_RENAME_INFORMATION = @ptrCast(&rename_info_buf);
+        var io_status_block: windows.IO_STATUS_BLOCK = undefined;
+
+        rename_info.* = .{
+            .Flags = ReplaceIfExists,
+            .RootDirectory = if (fs.path.isAbsoluteWindowsWTF16(new_path_w)) null else new_dir_fd,
+            .FileNameLength = @intCast(new_path_w.len * 2), // already checked error.NameTooLong
+            .FileName = undefined,
+        };
+        @memcpy((&rename_info.FileName).ptr, new_path_w);
+
+        rc =
+            windows.ntdll.NtSetInformationFile(
+            src_fd,
+            &io_status_block,
+            rename_info,
+            @intCast(struct_len), // already checked for error.NameTooLong
+            .FileRenameInformation,
+        );
+    }
+
+    switch (rc) {
+        .SUCCESS => {},
+        .INVALID_HANDLE => unreachable,
+        .INVALID_PARAMETER => unreachable,
+        .OBJECT_PATH_SYNTAX_BAD => unreachable,
+        .ACCESS_DENIED => return error.AccessDenied,
+        .OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
+        .OBJECT_PATH_NOT_FOUND => return error.FileNotFound,
+        .NOT_SAME_DEVICE => return error.RenameAcrossMountPoints,
+        .OBJECT_NAME_COLLISION => return error.PathAlreadyExists,
+        else => return windows.unexpectedStatus(rc),
+    }
+}
+
+/// On Windows, `sub_dir_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// On WASI, `sub_dir_path` should be encoded as valid UTF-8.
+/// On other platforms, `sub_dir_path` is an opaque sequence of bytes with no particular encoding.
+pub fn mkdirat(dir_fd: fd_t, sub_dir_path: []const u8, mode: u32) MakeDirError!void {
+    if (native_os == .windows) {
+        const sub_dir_path_w = try windows.sliceToPrefixedFileW(dir_fd, sub_dir_path);
+        return mkdiratW(dir_fd, sub_dir_path_w.span(), mode);
+    } else if (native_os == .wasi and !builtin.link_libc) {
+        return mkdiratWasi(dir_fd, sub_dir_path, mode);
+    } else {
+        const sub_dir_path_c = try toPosixPath(sub_dir_path);
+        return mkdiratZ(dir_fd, &sub_dir_path_c, mode);
+    }
+}
+
+pub fn mkdiratWasi(dir_fd: fd_t, sub_dir_path: []const u8, mode: u32) MakeDirError!void {
+    _ = mode;
+    switch (wasi.path_create_directory(dir_fd, sub_dir_path.ptr, sub_dir_path.len)) {
+        .SUCCESS => return,
+        .ACCES => return error.AccessDenied,
+        .BADF => unreachable,
+        .PERM => return error.AccessDenied,
+        .DQUOT => return error.DiskQuota,
+        .EXIST => return error.PathAlreadyExists,
+        .FAULT => unreachable,
+        .LOOP => return error.SymLinkLoop,
+        .MLINK => return error.LinkQuotaExceeded,
+        .NAMETOOLONG => return error.NameTooLong,
+        .NOENT => return error.FileNotFound,
+        .NOMEM => return error.SystemResources,
+        .NOSPC => return error.NoSpaceLeft,
+        .NOTDIR => return error.NotDir,
+        .ROFS => return error.ReadOnlyFileSystem,
+        .NOTCAPABLE => return error.AccessDenied,
+        .ILSEQ => return error.InvalidUtf8,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// Same as `mkdirat` except the parameters are null-terminated.
+pub fn mkdiratZ(dir_fd: fd_t, sub_dir_path: [*:0]const u8, mode: u32) MakeDirError!void {
+    if (native_os == .windows) {
+        const sub_dir_path_w = try windows.cStrToPrefixedFileW(dir_fd, sub_dir_path);
+        return mkdiratW(dir_fd, sub_dir_path_w.span(), mode);
+    } else if (native_os == .wasi and !builtin.link_libc) {
+        return mkdirat(dir_fd, mem.sliceTo(sub_dir_path, 0), mode);
+    }
+    switch (errno(system.mkdirat(dir_fd, sub_dir_path, mode))) {
+        .SUCCESS => return,
+        .ACCES => return error.AccessDenied,
+        .BADF => unreachable,
+        .PERM => return error.AccessDenied,
+        .DQUOT => return error.DiskQuota,
+        .EXIST => return error.PathAlreadyExists,
+        .FAULT => unreachable,
+        .LOOP => return error.SymLinkLoop,
+        .MLINK => return error.LinkQuotaExceeded,
+        .NAMETOOLONG => return error.NameTooLong,
+        .NOENT => return error.FileNotFound,
+        .NOMEM => return error.SystemResources,
+        .NOSPC => return error.NoSpaceLeft,
+        .NOTDIR => return error.NotDir,
+        .ROFS => return error.ReadOnlyFileSystem,
+        // dragonfly: when dir_fd is unlinked from filesystem
+        .NOTCONN => return error.FileNotFound,
+        .ILSEQ => |err| if (native_os == .wasi)
+            return error.InvalidUtf8
+        else
+            return unexpectedErrno(err),
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// Windows-only. Same as `mkdirat` except the parameter WTF16 LE encoded.
+pub fn mkdiratW(dir_fd: fd_t, sub_path_w: []const u16, mode: u32) MakeDirError!void {
+    _ = mode;
+    const sub_dir_handle = windows.OpenFile(sub_path_w, .{
+        .dir = dir_fd,
+        .access_mask = windows.GENERIC_READ | windows.SYNCHRONIZE,
+        .creation = windows.FILE_CREATE,
+        .filter = .dir_only,
+    }) catch |err| switch (err) {
+        error.IsDir => return error.Unexpected,
+        error.PipeBusy => return error.Unexpected,
+        error.WouldBlock => return error.Unexpected,
+        error.AntivirusInterference => return error.Unexpected,
+        else => |e| return e,
+    };
+    windows.CloseHandle(sub_dir_handle);
+}
+
+pub const MakeDirError = error{
+    /// In WASI, this error may occur when the file descriptor does
+    /// not hold the required rights to create a new directory relative to it.
+    AccessDenied,
+    DiskQuota,
+    PathAlreadyExists,
+    SymLinkLoop,
+    LinkQuotaExceeded,
+    NameTooLong,
+    FileNotFound,
+    SystemResources,
+    NoSpaceLeft,
+    NotDir,
+    ReadOnlyFileSystem,
+    /// WASI-only; file paths must be valid UTF-8.
+    InvalidUtf8,
+    /// Windows-only; file paths provided by the user must be valid WTF-8.
+    /// https://simonsapin.github.io/wtf-8/
+    InvalidWtf8,
+    BadPathName,
+    NoDevice,
+    /// On Windows, `\\server` or `\\server\share` was not found.
+    NetworkNotFound,
+} || UnexpectedError;
+
+/// Create a directory.
+/// `mode` is ignored on Windows and WASI.
+/// On Windows, `dir_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// On WASI, `dir_path` should be encoded as valid UTF-8.
+/// On other platforms, `dir_path` is an opaque sequence of bytes with no particular encoding.
+pub fn mkdir(dir_path: []const u8, mode: u32) MakeDirError!void {
+    if (native_os == .wasi and !builtin.link_libc) {
+        return mkdirat(wasi.AT.FDCWD, dir_path, mode);
+    } else if (native_os == .windows) {
+        const dir_path_w = try windows.sliceToPrefixedFileW(null, dir_path);
+        return mkdirW(dir_path_w.span(), mode);
+    } else {
+        const dir_path_c = try toPosixPath(dir_path);
+        return mkdirZ(&dir_path_c, mode);
+    }
+}
+
+/// Same as `mkdir` but the parameter is null-terminated.
+/// On Windows, `dir_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// On WASI, `dir_path` should be encoded as valid UTF-8.
+/// On other platforms, `dir_path` is an opaque sequence of bytes with no particular encoding.
+pub fn mkdirZ(dir_path: [*:0]const u8, mode: u32) MakeDirError!void {
+    if (native_os == .windows) {
+        const dir_path_w = try windows.cStrToPrefixedFileW(null, dir_path);
+        return mkdirW(dir_path_w.span(), mode);
+    } else if (native_os == .wasi and !builtin.link_libc) {
+        return mkdir(mem.sliceTo(dir_path, 0), mode);
+    }
+    switch (errno(system.mkdir(dir_path, mode))) {
+        .SUCCESS => return,
+        .ACCES => return error.AccessDenied,
+        .PERM => return error.AccessDenied,
+        .DQUOT => return error.DiskQuota,
+        .EXIST => return error.PathAlreadyExists,
+        .FAULT => unreachable,
+        .LOOP => return error.SymLinkLoop,
+        .MLINK => return error.LinkQuotaExceeded,
+        .NAMETOOLONG => return error.NameTooLong,
+        .NOENT => return error.FileNotFound,
+        .NOMEM => return error.SystemResources,
+        .NOSPC => return error.NoSpaceLeft,
+        .NOTDIR => return error.NotDir,
+        .ROFS => return error.ReadOnlyFileSystem,
+        .ILSEQ => |err| if (native_os == .wasi)
+            return error.InvalidUtf8
+        else
+            return unexpectedErrno(err),
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// Windows-only. Same as `mkdir` but the parameters is WTF16LE encoded.
+pub fn mkdirW(dir_path_w: []const u16, mode: u32) MakeDirError!void {
+    _ = mode;
+    const sub_dir_handle = windows.OpenFile(dir_path_w, .{
+        .dir = fs.cwd().fd,
+        .access_mask = windows.GENERIC_READ | windows.SYNCHRONIZE,
+        .creation = windows.FILE_CREATE,
+        .filter = .dir_only,
+    }) catch |err| switch (err) {
+        error.IsDir => return error.Unexpected,
+        error.PipeBusy => return error.Unexpected,
+        error.WouldBlock => return error.Unexpected,
+        error.AntivirusInterference => return error.Unexpected,
+        else => |e| return e,
+    };
+    windows.CloseHandle(sub_dir_handle);
+}
+
+pub const DeleteDirError = error{
+    AccessDenied,
+    FileBusy,
+    SymLinkLoop,
+    NameTooLong,
+    FileNotFound,
+    SystemResources,
+    NotDir,
+    DirNotEmpty,
+    ReadOnlyFileSystem,
+    /// WASI-only; file paths must be valid UTF-8.
+    InvalidUtf8,
+    /// Windows-only; file paths provided by the user must be valid WTF-8.
+    /// https://simonsapin.github.io/wtf-8/
+    InvalidWtf8,
+    BadPathName,
+    /// On Windows, `\\server` or `\\server\share` was not found.
+    NetworkNotFound,
+} || UnexpectedError;
+
+/// Deletes an empty directory.
+/// On Windows, `dir_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// On WASI, `dir_path` should be encoded as valid UTF-8.
+/// On other platforms, `dir_path` is an opaque sequence of bytes with no particular encoding.
+pub fn rmdir(dir_path: []const u8) DeleteDirError!void {
+    if (native_os == .wasi and !builtin.link_libc) {
+        return unlinkat(wasi.AT.FDCWD, dir_path, AT.REMOVEDIR) catch |err| switch (err) {
+            error.FileSystem => unreachable, // only occurs when targeting files
+            error.IsDir => unreachable, // only occurs when targeting files
+            else => |e| return e,
+        };
+    } else if (native_os == .windows) {
+        const dir_path_w = try windows.sliceToPrefixedFileW(null, dir_path);
+        return rmdirW(dir_path_w.span());
+    } else {
+        const dir_path_c = try toPosixPath(dir_path);
+        return rmdirZ(&dir_path_c);
+    }
+}
+
+/// Same as `rmdir` except the parameter is null-terminated.
+/// On Windows, `dir_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// On WASI, `dir_path` should be encoded as valid UTF-8.
+/// On other platforms, `dir_path` is an opaque sequence of bytes with no particular encoding.
+pub fn rmdirZ(dir_path: [*:0]const u8) DeleteDirError!void {
+    if (native_os == .windows) {
+        const dir_path_w = try windows.cStrToPrefixedFileW(null, dir_path);
+        return rmdirW(dir_path_w.span());
+    } else if (native_os == .wasi and !builtin.link_libc) {
+        return rmdir(mem.sliceTo(dir_path, 0));
+    }
+    switch (errno(system.rmdir(dir_path))) {
+        .SUCCESS => return,
+        .ACCES => return error.AccessDenied,
+        .PERM => return error.AccessDenied,
+        .BUSY => return error.FileBusy,
+        .FAULT => unreachable,
+        .INVAL => return error.BadPathName,
+        .LOOP => return error.SymLinkLoop,
+        .NAMETOOLONG => return error.NameTooLong,
+        .NOENT => return error.FileNotFound,
+        .NOMEM => return error.SystemResources,
+        .NOTDIR => return error.NotDir,
+        .EXIST => return error.DirNotEmpty,
+        .NOTEMPTY => return error.DirNotEmpty,
+        .ROFS => return error.ReadOnlyFileSystem,
+        .ILSEQ => |err| if (native_os == .wasi)
+            return error.InvalidUtf8
+        else
+            return unexpectedErrno(err),
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// Windows-only. Same as `rmdir` except the parameter is WTF-16 LE encoded.
+pub fn rmdirW(dir_path_w: []const u16) DeleteDirError!void {
+    return windows.DeleteFile(dir_path_w, .{ .dir = fs.cwd().fd, .remove_dir = true }) catch |err| switch (err) {
+        error.IsDir => unreachable,
+        else => |e| return e,
+    };
+}
+
+pub const ChangeCurDirError = error{
+    AccessDenied,
+    FileSystem,
+    SymLinkLoop,
+    NameTooLong,
+    FileNotFound,
+    SystemResources,
+    NotDir,
+    BadPathName,
+    /// WASI-only; file paths must be valid UTF-8.
+    InvalidUtf8,
+    /// Windows-only; file paths provided by the user must be valid WTF-8.
+    /// https://simonsapin.github.io/wtf-8/
+    InvalidWtf8,
+} || UnexpectedError;
+
+/// Changes the current working directory of the calling process.
+/// On Windows, `dir_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// On WASI, `dir_path` should be encoded as valid UTF-8.
+/// On other platforms, `dir_path` is an opaque sequence of bytes with no particular encoding.
+pub fn chdir(dir_path: []const u8) ChangeCurDirError!void {
+    if (native_os == .wasi and !builtin.link_libc) {
+        @compileError("WASI does not support os.chdir");
+    } else if (native_os == .windows) {
+        var wtf16_dir_path: [windows.PATH_MAX_WIDE]u16 = undefined;
+        const len = try std.unicode.wtf8ToWtf16Le(wtf16_dir_path[0..], dir_path);
+        if (len > wtf16_dir_path.len) return error.NameTooLong;
+        return chdirW(wtf16_dir_path[0..len]);
+    } else {
+        const dir_path_c = try toPosixPath(dir_path);
+        return chdirZ(&dir_path_c);
+    }
+}
+
+/// Same as `chdir` except the parameter is null-terminated.
+/// On Windows, `dir_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// On WASI, `dir_path` should be encoded as valid UTF-8.
+/// On other platforms, `dir_path` is an opaque sequence of bytes with no particular encoding.
+pub fn chdirZ(dir_path: [*:0]const u8) ChangeCurDirError!void {
+    if (native_os == .windows) {
+        var wtf16_dir_path: [windows.PATH_MAX_WIDE]u16 = undefined;
+        const len = try std.unicode.wtf8ToWtf16Le(wtf16_dir_path[0..], mem.span(dir_path));
+        if (len > wtf16_dir_path.len) return error.NameTooLong;
+        return chdirW(wtf16_dir_path[0..len]);
+    } else if (native_os == .wasi and !builtin.link_libc) {
+        return chdir(mem.span(dir_path));
+    }
+    switch (errno(system.chdir(dir_path))) {
+        .SUCCESS => return,
+        .ACCES => return error.AccessDenied,
+        .FAULT => unreachable,
+        .IO => return error.FileSystem,
+        .LOOP => return error.SymLinkLoop,
+        .NAMETOOLONG => return error.NameTooLong,
+        .NOENT => return error.FileNotFound,
+        .NOMEM => return error.SystemResources,
+        .NOTDIR => return error.NotDir,
+        .ILSEQ => |err| if (native_os == .wasi)
+            return error.InvalidUtf8
+        else
+            return unexpectedErrno(err),
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// Windows-only. Same as `chdir` except the parameter is WTF16 LE encoded.
+pub fn chdirW(dir_path: []const u16) ChangeCurDirError!void {
+    windows.SetCurrentDirectory(dir_path) catch |err| switch (err) {
+        error.NoDevice => return error.FileSystem,
+        else => |e| return e,
+    };
+}
+
+pub const FchdirError = error{
+    AccessDenied,
+    NotDir,
+    FileSystem,
+} || UnexpectedError;
+
+pub fn fchdir(dirfd: fd_t) FchdirError!void {
+    if (dirfd == AT.FDCWD) return;
+    while (true) {
+        switch (errno(system.fchdir(dirfd))) {
+            .SUCCESS => return,
+            .ACCES => return error.AccessDenied,
+            .BADF => unreachable,
+            .NOTDIR => return error.NotDir,
+            .INTR => continue,
+            .IO => return error.FileSystem,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+pub const ReadLinkError = error{
+    /// In WASI, this error may occur when the file descriptor does
+    /// not hold the required rights to read value of a symbolic link relative to it.
+    AccessDenied,
+    FileSystem,
+    SymLinkLoop,
+    NameTooLong,
+    FileNotFound,
+    SystemResources,
+    NotLink,
+    NotDir,
+    /// WASI-only; file paths must be valid UTF-8.
+    InvalidUtf8,
+    /// Windows-only; file paths provided by the user must be valid WTF-8.
+    /// https://simonsapin.github.io/wtf-8/
+    InvalidWtf8,
+    BadPathName,
+    /// Windows-only. This error may occur if the opened reparse point is
+    /// of unsupported type.
+    UnsupportedReparsePointType,
+    /// On Windows, `\\server` or `\\server\share` was not found.
+    NetworkNotFound,
+} || UnexpectedError;
+
+/// Read value of a symbolic link.
+/// On Windows, `file_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// 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.
+/// The return value is a slice of `out_buffer` from index 0.
+/// On Windows, the result is encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// On WASI, the result is encoded as UTF-8.
+/// On other platforms, the result is an opaque sequence of bytes with no particular encoding.
+pub fn readlink(file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 {
+    if (native_os == .wasi and !builtin.link_libc) {
+        return readlinkat(wasi.AT.FDCWD, file_path, out_buffer);
+    } else if (native_os == .windows) {
+        const file_path_w = try windows.sliceToPrefixedFileW(null, file_path);
+        return readlinkW(file_path_w.span(), out_buffer);
+    } else {
+        const file_path_c = try toPosixPath(file_path);
+        return readlinkZ(&file_path_c, out_buffer);
+    }
+}
+
+/// Windows-only. Same as `readlink` except `file_path` is WTF16 LE encoded.
+/// The result is encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// See also `readlinkZ`.
+pub fn readlinkW(file_path: []const u16, out_buffer: []u8) ReadLinkError![]u8 {
+    return windows.ReadLink(fs.cwd().fd, file_path, out_buffer);
+}
+
+/// Same as `readlink` except `file_path` is null-terminated.
+pub fn readlinkZ(file_path: [*:0]const u8, out_buffer: []u8) ReadLinkError![]u8 {
+    if (native_os == .windows) {
+        const file_path_w = try windows.cStrToPrefixedFileW(null, file_path);
+        return readlinkW(file_path_w.span(), out_buffer);
+    } else if (native_os == .wasi and !builtin.link_libc) {
+        return readlink(mem.sliceTo(file_path, 0), out_buffer);
+    }
+    const rc = system.readlink(file_path, out_buffer.ptr, out_buffer.len);
+    switch (errno(rc)) {
+        .SUCCESS => return out_buffer[0..@bitCast(rc)],
+        .ACCES => return error.AccessDenied,
+        .FAULT => unreachable,
+        .INVAL => return error.NotLink,
+        .IO => return error.FileSystem,
+        .LOOP => return error.SymLinkLoop,
+        .NAMETOOLONG => return error.NameTooLong,
+        .NOENT => return error.FileNotFound,
+        .NOMEM => return error.SystemResources,
+        .NOTDIR => return error.NotDir,
+        .ILSEQ => |err| if (native_os == .wasi)
+            return error.InvalidUtf8
+        else
+            return unexpectedErrno(err),
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// Similar to `readlink` except reads value of a symbolink link **relative** to `dirfd` directory handle.
+/// On Windows, `file_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// 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.
+/// The return value is a slice of `out_buffer` from index 0.
+/// On Windows, the result is encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// On WASI, the result is encoded as UTF-8.
+/// On other platforms, the result is an opaque sequence of bytes with no particular encoding.
+/// See also `readlinkatWasi`, `realinkatZ` and `realinkatW`.
+pub fn readlinkat(dirfd: fd_t, file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 {
+    if (native_os == .wasi and !builtin.link_libc) {
+        return readlinkatWasi(dirfd, file_path, out_buffer);
+    }
+    if (native_os == .windows) {
+        const file_path_w = try windows.sliceToPrefixedFileW(dirfd, file_path);
+        return readlinkatW(dirfd, file_path_w.span(), out_buffer);
+    }
+    const file_path_c = try toPosixPath(file_path);
+    return readlinkatZ(dirfd, &file_path_c, out_buffer);
+}
+
+/// WASI-only. Same as `readlinkat` but targets WASI.
+/// See also `readlinkat`.
+pub fn readlinkatWasi(dirfd: fd_t, file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 {
+    var bufused: usize = undefined;
+    switch (wasi.path_readlink(dirfd, file_path.ptr, file_path.len, out_buffer.ptr, out_buffer.len, &bufused)) {
+        .SUCCESS => return out_buffer[0..bufused],
+        .ACCES => return error.AccessDenied,
+        .FAULT => unreachable,
+        .INVAL => return error.NotLink,
+        .IO => return error.FileSystem,
+        .LOOP => return error.SymLinkLoop,
+        .NAMETOOLONG => return error.NameTooLong,
+        .NOENT => return error.FileNotFound,
+        .NOMEM => return error.SystemResources,
+        .NOTDIR => return error.NotDir,
+        .NOTCAPABLE => return error.AccessDenied,
+        .ILSEQ => return error.InvalidUtf8,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// Windows-only. Same as `readlinkat` except `file_path` is null-terminated, WTF16 LE encoded.
+/// The result is encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// See also `readlinkat`.
+pub fn readlinkatW(dirfd: fd_t, file_path: []const u16, out_buffer: []u8) ReadLinkError![]u8 {
+    return windows.ReadLink(dirfd, file_path, out_buffer);
+}
+
+/// Same as `readlinkat` except `file_path` is null-terminated.
+/// See also `readlinkat`.
+pub fn readlinkatZ(dirfd: fd_t, file_path: [*:0]const u8, out_buffer: []u8) ReadLinkError![]u8 {
+    if (native_os == .windows) {
+        const file_path_w = try windows.cStrToPrefixedFileW(dirfd, file_path);
+        return readlinkatW(dirfd, file_path_w.span(), out_buffer);
+    } else if (native_os == .wasi and !builtin.link_libc) {
+        return readlinkat(dirfd, mem.sliceTo(file_path, 0), out_buffer);
+    }
+    const rc = system.readlinkat(dirfd, file_path, out_buffer.ptr, out_buffer.len);
+    switch (errno(rc)) {
+        .SUCCESS => return out_buffer[0..@bitCast(rc)],
+        .ACCES => return error.AccessDenied,
+        .FAULT => unreachable,
+        .INVAL => return error.NotLink,
+        .IO => return error.FileSystem,
+        .LOOP => return error.SymLinkLoop,
+        .NAMETOOLONG => return error.NameTooLong,
+        .NOENT => return error.FileNotFound,
+        .NOMEM => return error.SystemResources,
+        .NOTDIR => return error.NotDir,
+        .ILSEQ => |err| if (native_os == .wasi)
+            return error.InvalidUtf8
+        else
+            return unexpectedErrno(err),
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub const SetEidError = error{
+    InvalidUserId,
+    PermissionDenied,
+} || UnexpectedError;
+
+pub const SetIdError = error{ResourceLimitReached} || SetEidError;
+
+pub fn setuid(uid: uid_t) SetIdError!void {
+    switch (errno(system.setuid(uid))) {
+        .SUCCESS => return,
+        .AGAIN => return error.ResourceLimitReached,
+        .INVAL => return error.InvalidUserId,
+        .PERM => return error.PermissionDenied,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub fn seteuid(uid: uid_t) SetEidError!void {
+    switch (errno(system.seteuid(uid))) {
+        .SUCCESS => return,
+        .INVAL => return error.InvalidUserId,
+        .PERM => return error.PermissionDenied,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub fn setreuid(ruid: uid_t, euid: uid_t) SetIdError!void {
+    switch (errno(system.setreuid(ruid, euid))) {
+        .SUCCESS => return,
+        .AGAIN => return error.ResourceLimitReached,
+        .INVAL => return error.InvalidUserId,
+        .PERM => return error.PermissionDenied,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub fn setgid(gid: gid_t) SetIdError!void {
+    switch (errno(system.setgid(gid))) {
+        .SUCCESS => return,
+        .AGAIN => return error.ResourceLimitReached,
+        .INVAL => return error.InvalidUserId,
+        .PERM => return error.PermissionDenied,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub fn setegid(uid: uid_t) SetEidError!void {
+    switch (errno(system.setegid(uid))) {
+        .SUCCESS => return,
+        .INVAL => return error.InvalidUserId,
+        .PERM => return error.PermissionDenied,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub fn setregid(rgid: gid_t, egid: gid_t) SetIdError!void {
+    switch (errno(system.setregid(rgid, egid))) {
+        .SUCCESS => return,
+        .AGAIN => return error.ResourceLimitReached,
+        .INVAL => return error.InvalidUserId,
+        .PERM => return error.PermissionDenied,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// Test whether a file descriptor refers to a terminal.
+pub fn isatty(handle: fd_t) bool {
+    if (native_os == .windows) {
+        if (fs.File.isCygwinPty(.{ .handle = handle }))
+            return true;
+
+        var out: windows.DWORD = undefined;
+        return windows.kernel32.GetConsoleMode(handle, &out) != 0;
+    }
+    if (builtin.link_libc) {
+        return system.isatty(handle) != 0;
+    }
+    if (native_os == .wasi) {
+        var statbuf: wasi.fdstat_t = undefined;
+        const err = wasi.fd_fdstat_get(handle, &statbuf);
+        if (err != .SUCCESS)
+            return false;
+
+        // A tty is a character device that we can't seek or tell on.
+        if (statbuf.fs_filetype != .CHARACTER_DEVICE)
+            return false;
+        if (statbuf.fs_rights_base.FD_SEEK or statbuf.fs_rights_base.FD_TELL)
+            return false;
+
+        return true;
+    }
+    if (native_os == .linux) {
+        while (true) {
+            var wsz: linux.winsize = undefined;
+            const fd: usize = @bitCast(@as(isize, handle));
+            const rc = linux.syscall3(.ioctl, fd, linux.T.IOCGWINSZ, @intFromPtr(&wsz));
+            switch (linux.E.init(rc)) {
+                .SUCCESS => return true,
+                .INTR => continue,
+                else => return false,
+            }
+        }
+    }
+    return system.isatty(handle) != 0;
+}
+
+pub const SocketError = error{
+    /// Permission to create a socket of the specified type and/or
+    /// proโ€tocol is denied.
+    PermissionDenied,
+
+    /// The implementation does not support the specified address family.
+    AddressFamilyNotSupported,
+
+    /// Unknown protocol, or protocol family not available.
+    ProtocolFamilyNotAvailable,
+
+    /// The per-process limit on the number of open file descriptors has been reached.
+    ProcessFdQuotaExceeded,
+
+    /// The system-wide limit on the total number of open files has been reached.
+    SystemFdQuotaExceeded,
+
+    /// Insufficient memory is available. The socket cannot be created until sufficient
+    /// resources are freed.
+    SystemResources,
+
+    /// The protocol type or the specified protocol is not supported within this domain.
+    ProtocolNotSupported,
+
+    /// The socket type is not supported by the protocol.
+    SocketTypeNotSupported,
+} || UnexpectedError;
+
+pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t {
+    if (native_os == .windows) {
+        // NOTE: windows translates the SOCK.NONBLOCK/SOCK.CLOEXEC flags into
+        // windows-analagous operations
+        const filtered_sock_type = socket_type & ~@as(u32, SOCK.NONBLOCK | SOCK.CLOEXEC);
+        const flags: u32 = if ((socket_type & SOCK.CLOEXEC) != 0)
+            windows.ws2_32.WSA_FLAG_NO_HANDLE_INHERIT
+        else
+            0;
+        const rc = try windows.WSASocketW(
+            @bitCast(domain),
+            @bitCast(filtered_sock_type),
+            @bitCast(protocol),
+            null,
+            0,
+            flags,
+        );
+        errdefer windows.closesocket(rc) catch unreachable;
+        if ((socket_type & SOCK.NONBLOCK) != 0) {
+            var mode: c_ulong = 1; // nonblocking
+            if (windows.ws2_32.SOCKET_ERROR == windows.ws2_32.ioctlsocket(rc, windows.ws2_32.FIONBIO, &mode)) {
+                switch (windows.ws2_32.WSAGetLastError()) {
+                    // have not identified any error codes that should be handled yet
+                    else => unreachable,
+                }
+            }
+        }
+        return rc;
+    }
+
+    const have_sock_flags = !builtin.target.isDarwin();
+    const filtered_sock_type = if (!have_sock_flags)
+        socket_type & ~@as(u32, SOCK.NONBLOCK | SOCK.CLOEXEC)
+    else
+        socket_type;
+    const rc = system.socket(domain, filtered_sock_type, protocol);
+    switch (errno(rc)) {
+        .SUCCESS => {
+            const fd: fd_t = @intCast(rc);
+            errdefer close(fd);
+            if (!have_sock_flags) {
+                try setSockFlags(fd, socket_type);
+            }
+            return fd;
+        },
+        .ACCES => return error.PermissionDenied,
+        .AFNOSUPPORT => return error.AddressFamilyNotSupported,
+        .INVAL => return error.ProtocolFamilyNotAvailable,
+        .MFILE => return error.ProcessFdQuotaExceeded,
+        .NFILE => return error.SystemFdQuotaExceeded,
+        .NOBUFS => return error.SystemResources,
+        .NOMEM => return error.SystemResources,
+        .PROTONOSUPPORT => return error.ProtocolNotSupported,
+        .PROTOTYPE => return error.SocketTypeNotSupported,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub const ShutdownError = error{
+    ConnectionAborted,
+
+    /// Connection was reset by peer, application should close socket as it is no longer usable.
+    ConnectionResetByPeer,
+    BlockingOperationInProgress,
+
+    /// The network subsystem has failed.
+    NetworkSubsystemFailed,
+
+    /// The socket is not connected (connection-oriented sockets only).
+    SocketNotConnected,
+    SystemResources,
+} || UnexpectedError;
+
+pub const ShutdownHow = enum { recv, send, both };
+
+/// Shutdown socket send/receive operations
+pub fn shutdown(sock: socket_t, how: ShutdownHow) ShutdownError!void {
+    if (native_os == .windows) {
+        const result = windows.ws2_32.shutdown(sock, switch (how) {
+            .recv => windows.ws2_32.SD_RECEIVE,
+            .send => windows.ws2_32.SD_SEND,
+            .both => windows.ws2_32.SD_BOTH,
+        });
+        if (0 != result) switch (windows.ws2_32.WSAGetLastError()) {
+            .WSAECONNABORTED => return error.ConnectionAborted,
+            .WSAECONNRESET => return error.ConnectionResetByPeer,
+            .WSAEINPROGRESS => return error.BlockingOperationInProgress,
+            .WSAEINVAL => unreachable,
+            .WSAENETDOWN => return error.NetworkSubsystemFailed,
+            .WSAENOTCONN => return error.SocketNotConnected,
+            .WSAENOTSOCK => unreachable,
+            .WSANOTINITIALISED => unreachable,
+            else => |err| return windows.unexpectedWSAError(err),
+        };
+    } else {
+        const rc = system.shutdown(sock, switch (how) {
+            .recv => SHUT.RD,
+            .send => SHUT.WR,
+            .both => SHUT.RDWR,
+        });
+        switch (errno(rc)) {
+            .SUCCESS => return,
+            .BADF => unreachable,
+            .INVAL => unreachable,
+            .NOTCONN => return error.SocketNotConnected,
+            .NOTSOCK => unreachable,
+            .NOBUFS => return error.SystemResources,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+pub const BindError = error{
+    /// The address is protected, and the user is not the superuser.
+    /// For UNIX domain sockets: Search permission is denied on  a  component
+    /// of  the  path  prefix.
+    AccessDenied,
+
+    /// The given address is already in use, or in the case of Internet domain sockets,
+    /// The  port number was specified as zero in the socket
+    /// address structure, but, upon attempting to bind to  an  ephemeral  port,  it  was
+    /// determined  that  all  port  numbers in the ephemeral port range are currently in
+    /// use.  See the discussion of /proc/sys/net/ipv4/ip_local_port_range ip(7).
+    AddressInUse,
+
+    /// A nonexistent interface was requested or the requested address was not local.
+    AddressNotAvailable,
+
+    /// The address is not valid for the address family of socket.
+    AddressFamilyNotSupported,
+
+    /// Too many symbolic links were encountered in resolving addr.
+    SymLinkLoop,
+
+    /// addr is too long.
+    NameTooLong,
+
+    /// A component in the directory prefix of the socket pathname does not exist.
+    FileNotFound,
+
+    /// Insufficient kernel memory was available.
+    SystemResources,
+
+    /// A component of the path prefix is not a directory.
+    NotDir,
+
+    /// The socket inode would reside on a read-only filesystem.
+    ReadOnlyFileSystem,
+
+    /// The network subsystem has failed.
+    NetworkSubsystemFailed,
+
+    FileDescriptorNotASocket,
+
+    AlreadyBound,
+} || UnexpectedError;
+
+/// addr is `*const T` where T is one of the sockaddr
+pub fn bind(sock: socket_t, addr: *const sockaddr, len: socklen_t) BindError!void {
+    if (native_os == .windows) {
+        const rc = windows.bind(sock, addr, len);
+        if (rc == windows.ws2_32.SOCKET_ERROR) {
+            switch (windows.ws2_32.WSAGetLastError()) {
+                .WSANOTINITIALISED => unreachable, // not initialized WSA
+                .WSAEACCES => return error.AccessDenied,
+                .WSAEADDRINUSE => return error.AddressInUse,
+                .WSAEADDRNOTAVAIL => return error.AddressNotAvailable,
+                .WSAENOTSOCK => return error.FileDescriptorNotASocket,
+                .WSAEFAULT => unreachable, // invalid pointers
+                .WSAEINVAL => return error.AlreadyBound,
+                .WSAENOBUFS => return error.SystemResources,
+                .WSAENETDOWN => return error.NetworkSubsystemFailed,
+                else => |err| return windows.unexpectedWSAError(err),
+            }
+            unreachable;
+        }
+        return;
+    } else {
+        const rc = system.bind(sock, addr, len);
+        switch (errno(rc)) {
+            .SUCCESS => return,
+            .ACCES, .PERM => return error.AccessDenied,
+            .ADDRINUSE => return error.AddressInUse,
+            .BADF => unreachable, // always a race condition if this error is returned
+            .INVAL => unreachable, // invalid parameters
+            .NOTSOCK => unreachable, // invalid `sockfd`
+            .AFNOSUPPORT => return error.AddressFamilyNotSupported,
+            .ADDRNOTAVAIL => return error.AddressNotAvailable,
+            .FAULT => unreachable, // invalid `addr` pointer
+            .LOOP => return error.SymLinkLoop,
+            .NAMETOOLONG => return error.NameTooLong,
+            .NOENT => return error.FileNotFound,
+            .NOMEM => return error.SystemResources,
+            .NOTDIR => return error.NotDir,
+            .ROFS => return error.ReadOnlyFileSystem,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+    unreachable;
+}
+
+pub const ListenError = error{
+    /// Another socket is already listening on the same port.
+    /// For Internet domain sockets, the  socket referred to by sockfd had not previously
+    /// been bound to an address and, upon attempting to bind it to an ephemeral port, it
+    /// was determined that all port numbers in the ephemeral port range are currently in
+    /// use.  See the discussion of /proc/sys/net/ipv4/ip_local_port_range in ip(7).
+    AddressInUse,
+
+    /// The file descriptor sockfd does not refer to a socket.
+    FileDescriptorNotASocket,
+
+    /// The socket is not of a type that supports the listen() operation.
+    OperationNotSupported,
+
+    /// The network subsystem has failed.
+    NetworkSubsystemFailed,
+
+    /// Ran out of system resources
+    /// On Windows it can either run out of socket descriptors or buffer space
+    SystemResources,
+
+    /// Already connected
+    AlreadyConnected,
+
+    /// Socket has not been bound yet
+    SocketNotBound,
+} || UnexpectedError;
+
+pub fn listen(sock: socket_t, backlog: u31) ListenError!void {
+    if (native_os == .windows) {
+        const rc = windows.listen(sock, backlog);
+        if (rc == windows.ws2_32.SOCKET_ERROR) {
+            switch (windows.ws2_32.WSAGetLastError()) {
+                .WSANOTINITIALISED => unreachable, // not initialized WSA
+                .WSAENETDOWN => return error.NetworkSubsystemFailed,
+                .WSAEADDRINUSE => return error.AddressInUse,
+                .WSAEISCONN => return error.AlreadyConnected,
+                .WSAEINVAL => return error.SocketNotBound,
+                .WSAEMFILE, .WSAENOBUFS => return error.SystemResources,
+                .WSAENOTSOCK => return error.FileDescriptorNotASocket,
+                .WSAEOPNOTSUPP => return error.OperationNotSupported,
+                .WSAEINPROGRESS => unreachable,
+                else => |err| return windows.unexpectedWSAError(err),
+            }
+        }
+        return;
+    } else {
+        const rc = system.listen(sock, backlog);
+        switch (errno(rc)) {
+            .SUCCESS => return,
+            .ADDRINUSE => return error.AddressInUse,
+            .BADF => unreachable,
+            .NOTSOCK => return error.FileDescriptorNotASocket,
+            .OPNOTSUPP => return error.OperationNotSupported,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+pub const AcceptError = error{
+    ConnectionAborted,
+
+    /// The file descriptor sockfd does not refer to a socket.
+    FileDescriptorNotASocket,
+
+    /// The per-process limit on the number of open file descriptors has been reached.
+    ProcessFdQuotaExceeded,
+
+    /// The system-wide limit on the total number of open files has been reached.
+    SystemFdQuotaExceeded,
+
+    /// Not enough free memory.  This often means that the memory allocation  is  limited
+    /// by the socket buffer limits, not by the system memory.
+    SystemResources,
+
+    /// Socket is not listening for new connections.
+    SocketNotListening,
+
+    ProtocolFailure,
+
+    /// Firewall rules forbid connection.
+    BlockedByFirewall,
+
+    /// This error occurs when no global event loop is configured,
+    /// and accepting from the socket would block.
+    WouldBlock,
+
+    /// An incoming connection was indicated, but was subsequently terminated by the
+    /// remote peer prior to accepting the call.
+    ConnectionResetByPeer,
+
+    /// The network subsystem has failed.
+    NetworkSubsystemFailed,
+
+    /// The referenced socket is not a type that supports connection-oriented service.
+    OperationNotSupported,
+} || UnexpectedError;
+
+/// Accept a connection on a socket.
+/// If `sockfd` is opened in non blocking mode, the function will
+/// return error.WouldBlock when EAGAIN is received.
+pub fn accept(
+    /// This argument is a socket that has been created with `socket`, bound to a local address
+    /// with `bind`, and is listening for connections after a `listen`.
+    sock: socket_t,
+    /// This argument is a pointer to a sockaddr structure.  This structure is filled in with  the
+    /// address  of  the  peer  socket, as known to the communications layer.  The exact format of the
+    /// address returned addr is determined by the socket's address  family  (see  `socket`  and  the
+    /// respective  protocol  man  pages).
+    addr: ?*sockaddr,
+    /// This argument is a value-result argument: the caller must initialize it to contain  the
+    /// size (in bytes) of the structure pointed to by addr; on return it will contain the actual size
+    /// of the peer address.
+    ///
+    /// The returned address is truncated if the buffer provided is too small; in this  case,  `addr_size`
+    /// will return a value greater than was supplied to the call.
+    addr_size: ?*socklen_t,
+    /// The following values can be bitwise ORed in flags to obtain different behavior:
+    /// * `SOCK.NONBLOCK` - Set the `NONBLOCK` file status flag on the open file description (see `open`)
+    ///   referred  to by the new file descriptor.  Using this flag saves extra calls to `fcntl` to achieve
+    ///   the same result.
+    /// * `SOCK.CLOEXEC`  - Set the close-on-exec (`FD_CLOEXEC`) flag on the new file descriptor.   See  the
+    ///   description  of the `CLOEXEC` flag in `open` for reasons why this may be useful.
+    flags: u32,
+) AcceptError!socket_t {
+    const have_accept4 = !(builtin.target.isDarwin() or native_os == .windows);
+    assert(0 == (flags & ~@as(u32, SOCK.NONBLOCK | SOCK.CLOEXEC))); // Unsupported flag(s)
+
+    const accepted_sock: socket_t = while (true) {
+        const rc = if (have_accept4)
+            system.accept4(sock, addr, addr_size, flags)
+        else if (native_os == .windows)
+            windows.accept(sock, addr, addr_size)
+        else
+            system.accept(sock, addr, addr_size);
+
+        if (native_os == .windows) {
+            if (rc == windows.ws2_32.INVALID_SOCKET) {
+                switch (windows.ws2_32.WSAGetLastError()) {
+                    .WSANOTINITIALISED => unreachable, // not initialized WSA
+                    .WSAECONNRESET => return error.ConnectionResetByPeer,
+                    .WSAEFAULT => unreachable,
+                    .WSAEINVAL => return error.SocketNotListening,
+                    .WSAEMFILE => return error.ProcessFdQuotaExceeded,
+                    .WSAENETDOWN => return error.NetworkSubsystemFailed,
+                    .WSAENOBUFS => return error.FileDescriptorNotASocket,
+                    .WSAEOPNOTSUPP => return error.OperationNotSupported,
+                    .WSAEWOULDBLOCK => return error.WouldBlock,
+                    else => |err| return windows.unexpectedWSAError(err),
+                }
+            } else {
+                break rc;
+            }
+        } else {
+            switch (errno(rc)) {
+                .SUCCESS => break @intCast(rc),
+                .INTR => continue,
+                .AGAIN => return error.WouldBlock,
+                .BADF => unreachable, // always a race condition
+                .CONNABORTED => return error.ConnectionAborted,
+                .FAULT => unreachable,
+                .INVAL => return error.SocketNotListening,
+                .NOTSOCK => unreachable,
+                .MFILE => return error.ProcessFdQuotaExceeded,
+                .NFILE => return error.SystemFdQuotaExceeded,
+                .NOBUFS => return error.SystemResources,
+                .NOMEM => return error.SystemResources,
+                .OPNOTSUPP => unreachable,
+                .PROTO => return error.ProtocolFailure,
+                .PERM => return error.BlockedByFirewall,
+                else => |err| return unexpectedErrno(err),
+            }
+        }
+    };
+
+    errdefer switch (native_os) {
+        .windows => windows.closesocket(accepted_sock) catch unreachable,
+        else => close(accepted_sock),
+    };
+    if (!have_accept4) {
+        try setSockFlags(accepted_sock, flags);
+    }
+    return accepted_sock;
+}
+
+fn setSockFlags(sock: socket_t, flags: u32) !void {
+    if ((flags & SOCK.CLOEXEC) != 0) {
+        if (native_os == .windows) {
+            // TODO: Find out if this is supported for sockets
+        } else {
+            var fd_flags = fcntl(sock, F.GETFD, 0) catch |err| switch (err) {
+                error.FileBusy => unreachable,
+                error.Locked => unreachable,
+                error.PermissionDenied => unreachable,
+                error.DeadLock => unreachable,
+                error.LockedRegionLimitExceeded => unreachable,
+                else => |e| return e,
+            };
+            fd_flags |= FD_CLOEXEC;
+            _ = fcntl(sock, F.SETFD, fd_flags) catch |err| switch (err) {
+                error.FileBusy => unreachable,
+                error.Locked => unreachable,
+                error.PermissionDenied => unreachable,
+                error.DeadLock => unreachable,
+                error.LockedRegionLimitExceeded => unreachable,
+                else => |e| return e,
+            };
+        }
+    }
+    if ((flags & SOCK.NONBLOCK) != 0) {
+        if (native_os == .windows) {
+            var mode: c_ulong = 1;
+            if (windows.ws2_32.ioctlsocket(sock, windows.ws2_32.FIONBIO, &mode) == windows.ws2_32.SOCKET_ERROR) {
+                switch (windows.ws2_32.WSAGetLastError()) {
+                    .WSANOTINITIALISED => unreachable,
+                    .WSAENETDOWN => return error.NetworkSubsystemFailed,
+                    .WSAENOTSOCK => return error.FileDescriptorNotASocket,
+                    // TODO: handle more errors
+                    else => |err| return windows.unexpectedWSAError(err),
+                }
+            }
+        } else {
+            var fl_flags = fcntl(sock, F.GETFL, 0) catch |err| switch (err) {
+                error.FileBusy => unreachable,
+                error.Locked => unreachable,
+                error.PermissionDenied => unreachable,
+                error.DeadLock => unreachable,
+                error.LockedRegionLimitExceeded => unreachable,
+                else => |e| return e,
+            };
+            fl_flags |= 1 << @bitOffsetOf(O, "NONBLOCK");
+            _ = fcntl(sock, F.SETFL, fl_flags) catch |err| switch (err) {
+                error.FileBusy => unreachable,
+                error.Locked => unreachable,
+                error.PermissionDenied => unreachable,
+                error.DeadLock => unreachable,
+                error.LockedRegionLimitExceeded => unreachable,
+                else => |e| return e,
+            };
+        }
+    }
+}
+
+pub const EpollCreateError = error{
+    /// The  per-user   limit   on   the   number   of   epoll   instances   imposed   by
+    /// /proc/sys/fs/epoll/max_user_instances  was encountered.  See epoll(7) for further
+    /// details.
+    /// Or, The per-process limit on the number of open file descriptors has been reached.
+    ProcessFdQuotaExceeded,
+
+    /// The system-wide limit on the total number of open files has been reached.
+    SystemFdQuotaExceeded,
+
+    /// There was insufficient memory to create the kernel object.
+    SystemResources,
+} || UnexpectedError;
+
+pub fn epoll_create1(flags: u32) EpollCreateError!i32 {
+    const rc = system.epoll_create1(flags);
+    switch (errno(rc)) {
+        .SUCCESS => return @intCast(rc),
+        else => |err| return unexpectedErrno(err),
+
+        .INVAL => unreachable,
+        .MFILE => return error.ProcessFdQuotaExceeded,
+        .NFILE => return error.SystemFdQuotaExceeded,
+        .NOMEM => return error.SystemResources,
+    }
+}
+
+pub const EpollCtlError = error{
+    /// op was EPOLL_CTL_ADD, and the supplied file descriptor fd is  already  registered
+    /// with this epoll instance.
+    FileDescriptorAlreadyPresentInSet,
+
+    /// fd refers to an epoll instance and this EPOLL_CTL_ADD operation would result in a
+    /// circular loop of epoll instances monitoring one another.
+    OperationCausesCircularLoop,
+
+    /// op was EPOLL_CTL_MOD or EPOLL_CTL_DEL, and fd is not registered with  this  epoll
+    /// instance.
+    FileDescriptorNotRegistered,
+
+    /// There was insufficient memory to handle the requested op control operation.
+    SystemResources,
+
+    /// The  limit  imposed  by /proc/sys/fs/epoll/max_user_watches was encountered while
+    /// trying to register (EPOLL_CTL_ADD) a new file descriptor on  an  epoll  instance.
+    /// See epoll(7) for further details.
+    UserResourceLimitReached,
+
+    /// The target file fd does not support epoll.  This error can occur if fd refers to,
+    /// for example, a regular file or a directory.
+    FileDescriptorIncompatibleWithEpoll,
+} || UnexpectedError;
+
+pub fn epoll_ctl(epfd: i32, op: u32, fd: i32, event: ?*linux.epoll_event) EpollCtlError!void {
+    const rc = system.epoll_ctl(epfd, op, fd, event);
+    switch (errno(rc)) {
+        .SUCCESS => return,
+        else => |err| return unexpectedErrno(err),
+
+        .BADF => unreachable, // always a race condition if this happens
+        .EXIST => return error.FileDescriptorAlreadyPresentInSet,
+        .INVAL => unreachable,
+        .LOOP => return error.OperationCausesCircularLoop,
+        .NOENT => return error.FileDescriptorNotRegistered,
+        .NOMEM => return error.SystemResources,
+        .NOSPC => return error.UserResourceLimitReached,
+        .PERM => return error.FileDescriptorIncompatibleWithEpoll,
+    }
+}
+
+/// Waits for an I/O event on an epoll file descriptor.
+/// Returns the number of file descriptors ready for the requested I/O,
+/// or zero if no file descriptor became ready during the requested timeout milliseconds.
+pub fn epoll_wait(epfd: i32, events: []linux.epoll_event, timeout: i32) usize {
+    while (true) {
+        // TODO get rid of the @intCast
+        const rc = system.epoll_wait(epfd, events.ptr, @intCast(events.len), timeout);
+        switch (errno(rc)) {
+            .SUCCESS => return @intCast(rc),
+            .INTR => continue,
+            .BADF => unreachable,
+            .FAULT => unreachable,
+            .INVAL => unreachable,
+            else => unreachable,
+        }
+    }
+}
+
+pub const EventFdError = error{
+    SystemResources,
+    ProcessFdQuotaExceeded,
+    SystemFdQuotaExceeded,
+} || UnexpectedError;
+
+pub fn eventfd(initval: u32, flags: u32) EventFdError!i32 {
+    const rc = system.eventfd(initval, flags);
+    switch (errno(rc)) {
+        .SUCCESS => return @intCast(rc),
+        else => |err| return unexpectedErrno(err),
+
+        .INVAL => unreachable, // invalid parameters
+        .MFILE => return error.ProcessFdQuotaExceeded,
+        .NFILE => return error.SystemFdQuotaExceeded,
+        .NODEV => return error.SystemResources,
+        .NOMEM => return error.SystemResources,
+    }
+}
+
+pub const GetSockNameError = error{
+    /// Insufficient resources were available in the system to perform the operation.
+    SystemResources,
+
+    /// The network subsystem has failed.
+    NetworkSubsystemFailed,
+
+    /// Socket hasn't been bound yet
+    SocketNotBound,
+
+    FileDescriptorNotASocket,
+} || UnexpectedError;
+
+pub fn getsockname(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSockNameError!void {
+    if (native_os == .windows) {
+        const rc = windows.getsockname(sock, addr, addrlen);
+        if (rc == windows.ws2_32.SOCKET_ERROR) {
+            switch (windows.ws2_32.WSAGetLastError()) {
+                .WSANOTINITIALISED => unreachable,
+                .WSAENETDOWN => return error.NetworkSubsystemFailed,
+                .WSAEFAULT => unreachable, // addr or addrlen have invalid pointers or addrlen points to an incorrect value
+                .WSAENOTSOCK => return error.FileDescriptorNotASocket,
+                .WSAEINVAL => return error.SocketNotBound,
+                else => |err| return windows.unexpectedWSAError(err),
+            }
+        }
+        return;
+    } else {
+        const rc = system.getsockname(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,
+        }
+    }
+}
+
+pub fn getpeername(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSockNameError!void {
+    if (native_os == .windows) {
+        const rc = windows.getpeername(sock, addr, addrlen);
+        if (rc == windows.ws2_32.SOCKET_ERROR) {
+            switch (windows.ws2_32.WSAGetLastError()) {
+                .WSANOTINITIALISED => unreachable,
+                .WSAENETDOWN => return error.NetworkSubsystemFailed,
+                .WSAEFAULT => unreachable, // addr or addrlen have invalid pointers or addrlen points to an incorrect value
+                .WSAENOTSOCK => return error.FileDescriptorNotASocket,
+                .WSAEINVAL => return error.SocketNotBound,
+                else => |err| return windows.unexpectedWSAError(err),
+            }
+        }
+        return;
+    } else {
+        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,
+        }
+    }
+}
+
+pub const ConnectError = error{
+    /// For UNIX domain sockets, which are identified by pathname: Write permission is denied on  the  socket
+    /// file,  or  search  permission  is  denied  for  one of the directories in the path prefix.
+    /// or
+    /// The user tried to connect to a broadcast address without having the socket broadcast flag enabled  or
+    /// the connection request failed because of a local firewall rule.
+    PermissionDenied,
+
+    /// Local address is already in use.
+    AddressInUse,
+
+    /// (Internet  domain  sockets)  The  socket  referred  to  by sockfd had not previously been bound to an
+    /// address and, upon attempting to bind it to an ephemeral port, it was determined that all port numbers
+    /// in    the    ephemeral    port    range    are   currently   in   use.    See   the   discussion   of
+    /// /proc/sys/net/ipv4/ip_local_port_range in ip(7).
+    AddressNotAvailable,
+
+    /// The passed address didn't have the correct address family in its sa_family field.
+    AddressFamilyNotSupported,
+
+    /// Insufficient entries in the routing cache.
+    SystemResources,
+
+    /// A connect() on a stream socket found no one listening on the remote address.
+    ConnectionRefused,
+
+    /// Network is unreachable.
+    NetworkUnreachable,
+
+    /// Timeout  while  attempting  connection.   The server may be too busy to accept new connections.  Note
+    /// that for IP sockets the timeout may be very long when syncookies are enabled on the server.
+    ConnectionTimedOut,
+
+    /// This error occurs when no global event loop is configured,
+    /// and connecting to the socket would block.
+    WouldBlock,
+
+    /// The given path for the unix socket does not exist.
+    FileNotFound,
+
+    /// Connection was reset by peer before connect could complete.
+    ConnectionResetByPeer,
+
+    /// Socket is non-blocking and already has a pending connection in progress.
+    ConnectionPending,
+} || UnexpectedError;
+
+/// Initiate a connection on a socket.
+/// If `sockfd` is opened in non blocking mode, the function will
+/// return error.WouldBlock when EAGAIN or EINPROGRESS is received.
+pub fn connect(sock: socket_t, sock_addr: *const sockaddr, len: socklen_t) ConnectError!void {
+    if (native_os == .windows) {
+        const rc = windows.ws2_32.connect(sock, sock_addr, @intCast(len));
+        if (rc == 0) return;
+        switch (windows.ws2_32.WSAGetLastError()) {
+            .WSAEADDRINUSE => return error.AddressInUse,
+            .WSAEADDRNOTAVAIL => return error.AddressNotAvailable,
+            .WSAECONNREFUSED => return error.ConnectionRefused,
+            .WSAECONNRESET => return error.ConnectionResetByPeer,
+            .WSAETIMEDOUT => return error.ConnectionTimedOut,
+            .WSAEHOSTUNREACH, // TODO: should we return NetworkUnreachable in this case as well?
+            .WSAENETUNREACH,
+            => return error.NetworkUnreachable,
+            .WSAEFAULT => unreachable,
+            .WSAEINVAL => unreachable,
+            .WSAEISCONN => unreachable,
+            .WSAENOTSOCK => unreachable,
+            .WSAEWOULDBLOCK => return error.WouldBlock,
+            .WSAEACCES => unreachable,
+            .WSAENOBUFS => return error.SystemResources,
+            .WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported,
+            else => |err| return windows.unexpectedWSAError(err),
+        }
+        return;
+    }
+
+    while (true) {
+        switch (errno(system.connect(sock, sock_addr, len))) {
+            .SUCCESS => return,
+            .ACCES => return error.PermissionDenied,
+            .PERM => return error.PermissionDenied,
+            .ADDRINUSE => return error.AddressInUse,
+            .ADDRNOTAVAIL => return error.AddressNotAvailable,
+            .AFNOSUPPORT => return error.AddressFamilyNotSupported,
+            .AGAIN, .INPROGRESS => return error.WouldBlock,
+            .ALREADY => return error.ConnectionPending,
+            .BADF => unreachable, // sockfd is not a valid open file descriptor.
+            .CONNREFUSED => return error.ConnectionRefused,
+            .CONNRESET => return error.ConnectionResetByPeer,
+            .FAULT => unreachable, // The socket structure address is outside the user's address space.
+            .INTR => continue,
+            .ISCONN => unreachable, // The socket is already connected.
+            .HOSTUNREACH => return error.NetworkUnreachable,
+            .NETUNREACH => return error.NetworkUnreachable,
+            .NOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
+            .PROTOTYPE => unreachable, // The socket type does not support the requested communications protocol.
+            .TIMEDOUT => return error.ConnectionTimedOut,
+            .NOENT => return error.FileNotFound, // Returned when socket is AF.UNIX and the given path does not exist.
+            .CONNABORTED => unreachable, // Tried to reuse socket that previously received error.ConnectionRefused.
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+pub fn getsockoptError(sockfd: fd_t) ConnectError!void {
+    var err_code: i32 = undefined;
+    var size: u32 = @sizeOf(u32);
+    const rc = system.getsockopt(sockfd, SOL.SOCKET, SO.ERROR, @ptrCast(&err_code), &size);
+    assert(size == 4);
+    switch (errno(rc)) {
+        .SUCCESS => switch (@as(E, @enumFromInt(err_code))) {
+            .SUCCESS => return,
+            .ACCES => return error.PermissionDenied,
+            .PERM => return error.PermissionDenied,
+            .ADDRINUSE => return error.AddressInUse,
+            .ADDRNOTAVAIL => return error.AddressNotAvailable,
+            .AFNOSUPPORT => return error.AddressFamilyNotSupported,
+            .AGAIN => return error.SystemResources,
+            .ALREADY => return error.ConnectionPending,
+            .BADF => unreachable, // sockfd is not a valid open file descriptor.
+            .CONNREFUSED => return error.ConnectionRefused,
+            .FAULT => unreachable, // The socket structure address is outside the user's address space.
+            .ISCONN => unreachable, // The socket is already connected.
+            .HOSTUNREACH => return error.NetworkUnreachable,
+            .NETUNREACH => return error.NetworkUnreachable,
+            .NOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
+            .PROTOTYPE => unreachable, // The socket type does not support the requested communications protocol.
+            .TIMEDOUT => return error.ConnectionTimedOut,
+            .CONNRESET => return error.ConnectionResetByPeer,
+            else => |err| return unexpectedErrno(err),
+        },
+        .BADF => unreachable, // The argument sockfd is not a valid file descriptor.
+        .FAULT => unreachable, // The address pointed to by optval or optlen is not in a valid part of the process address space.
+        .INVAL => unreachable,
+        .NOPROTOOPT => unreachable, // The option is unknown at the level indicated.
+        .NOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub const WaitPidResult = struct {
+    pid: pid_t,
+    status: u32,
+};
+
+/// Use this version of the `waitpid` wrapper if you spawned your child process using explicit
+/// `fork` and `execve` method.
+pub fn waitpid(pid: pid_t, flags: u32) WaitPidResult {
+    var status: if (builtin.link_libc) c_int else u32 = undefined;
+    while (true) {
+        const rc = system.waitpid(pid, &status, @intCast(flags));
+        switch (errno(rc)) {
+            .SUCCESS => return .{
+                .pid = @intCast(rc),
+                .status = @bitCast(status),
+            },
+            .INTR => continue,
+            .CHILD => unreachable, // The process specified does not exist. It would be a race condition to handle this error.
+            .INVAL => unreachable, // Invalid flags.
+            else => unreachable,
+        }
+    }
+}
+
+pub fn wait4(pid: pid_t, flags: u32, ru: ?*rusage) WaitPidResult {
+    var status: if (builtin.link_libc) c_int else u32 = undefined;
+    while (true) {
+        const rc = system.wait4(pid, &status, @intCast(flags), ru);
+        switch (errno(rc)) {
+            .SUCCESS => return .{
+                .pid = @intCast(rc),
+                .status = @bitCast(status),
+            },
+            .INTR => continue,
+            .CHILD => unreachable, // The process specified does not exist. It would be a race condition to handle this error.
+            .INVAL => unreachable, // Invalid flags.
+            else => unreachable,
+        }
+    }
+}
+
+pub const FStatError = error{
+    SystemResources,
+
+    /// In WASI, this error may occur when the file descriptor does
+    /// not hold the required rights to get its filestat information.
+    AccessDenied,
+} || UnexpectedError;
+
+/// Return information about a file descriptor.
+pub fn fstat(fd: fd_t) FStatError!Stat {
+    if (native_os == .wasi and !builtin.link_libc) {
+        return Stat.fromFilestat(try fstat_wasi(fd));
+    }
+    if (native_os == .windows) {
+        @compileError("fstat is not yet implemented on Windows");
+    }
+
+    const fstat_sym = if (lfs64_abi) system.fstat64 else system.fstat;
+    var stat = mem.zeroes(Stat);
+    switch (errno(fstat_sym(fd, &stat))) {
+        .SUCCESS => return stat,
+        .INVAL => unreachable,
+        .BADF => unreachable, // Always a race condition.
+        .NOMEM => return error.SystemResources,
+        .ACCES => return error.AccessDenied,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+fn fstat_wasi(fd: fd_t) FStatError!wasi.filestat_t {
+    var stat: wasi.filestat_t = undefined;
+    switch (wasi.fd_filestat_get(fd, &stat)) {
+        .SUCCESS => return stat,
+        .INVAL => unreachable,
+        .BADF => unreachable, // Always a race condition.
+        .NOMEM => return error.SystemResources,
+        .ACCES => return error.AccessDenied,
+        .NOTCAPABLE => return error.AccessDenied,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub const FStatAtError = FStatError || error{
+    NameTooLong,
+    FileNotFound,
+    SymLinkLoop,
+    /// WASI-only; file paths must be valid UTF-8.
+    InvalidUtf8,
+};
+
+/// Similar to `fstat`, but returns stat of a resource pointed to by `pathname`
+/// which is relative to `dirfd` handle.
+/// On WASI, `pathname` should be encoded as valid UTF-8.
+/// On other platforms, `pathname` is an opaque sequence of bytes with no particular encoding.
+/// See also `fstatatZ` and `fstatat_wasi`.
+pub fn fstatat(dirfd: fd_t, pathname: []const u8, flags: u32) FStatAtError!Stat {
+    if (native_os == .wasi and !builtin.link_libc) {
+        const filestat = try fstatat_wasi(dirfd, pathname, .{
+            .SYMLINK_FOLLOW = (flags & AT.SYMLINK_NOFOLLOW) == 0,
+        });
+        return Stat.fromFilestat(filestat);
+    } else if (native_os == .windows) {
+        @compileError("fstatat is not yet implemented on Windows");
+    } else {
+        const pathname_c = try toPosixPath(pathname);
+        return fstatatZ(dirfd, &pathname_c, flags);
+    }
+}
+
+/// Same as `fstatat` but `pathname` is null-terminated.
+/// See also `fstatat`.
+pub fn fstatatZ(dirfd: fd_t, pathname: [*:0]const u8, flags: u32) FStatAtError!Stat {
+    if (native_os == .wasi and !builtin.link_libc) {
+        const filestat = try fstatat_wasi(dirfd, mem.sliceTo(pathname, 0), .{
+            .SYMLINK_FOLLOW = (flags & AT.SYMLINK_NOFOLLOW) == 0,
+        });
+        return Stat.fromFilestat(filestat);
+    }
+
+    const fstatat_sym = if (lfs64_abi) system.fstatat64 else system.fstatat;
+    var stat = mem.zeroes(Stat);
+    switch (errno(fstatat_sym(dirfd, pathname, &stat, flags))) {
+        .SUCCESS => return stat,
+        .INVAL => unreachable,
+        .BADF => unreachable, // Always a race condition.
+        .NOMEM => return error.SystemResources,
+        .ACCES => return error.AccessDenied,
+        .PERM => return error.AccessDenied,
+        .FAULT => unreachable,
+        .NAMETOOLONG => return error.NameTooLong,
+        .LOOP => return error.SymLinkLoop,
+        .NOENT => return error.FileNotFound,
+        .NOTDIR => return error.FileNotFound,
+        .ILSEQ => |err| if (native_os == .wasi)
+            return error.InvalidUtf8
+        else
+            return unexpectedErrno(err),
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// WASI-only. Same as `fstatat` but targeting WASI.
+/// `pathname` should be encoded as valid UTF-8.
+/// See also `fstatat`.
+fn fstatat_wasi(dirfd: fd_t, pathname: []const u8, flags: wasi.lookupflags_t) FStatAtError!wasi.filestat_t {
+    var stat: wasi.filestat_t = undefined;
+    switch (wasi.path_filestat_get(dirfd, flags, pathname.ptr, pathname.len, &stat)) {
+        .SUCCESS => return stat,
+        .INVAL => unreachable,
+        .BADF => unreachable, // Always a race condition.
+        .NOMEM => return error.SystemResources,
+        .ACCES => return error.AccessDenied,
+        .FAULT => unreachable,
+        .NAMETOOLONG => return error.NameTooLong,
+        .NOENT => return error.FileNotFound,
+        .NOTDIR => return error.FileNotFound,
+        .NOTCAPABLE => return error.AccessDenied,
+        .ILSEQ => return error.InvalidUtf8,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub const KQueueError = error{
+    /// The per-process limit on the number of open file descriptors has been reached.
+    ProcessFdQuotaExceeded,
+
+    /// The system-wide limit on the total number of open files has been reached.
+    SystemFdQuotaExceeded,
+} || UnexpectedError;
+
+pub fn kqueue() KQueueError!i32 {
+    const rc = system.kqueue();
+    switch (errno(rc)) {
+        .SUCCESS => return @intCast(rc),
+        .MFILE => return error.ProcessFdQuotaExceeded,
+        .NFILE => return error.SystemFdQuotaExceeded,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub const KEventError = error{
+    /// The process does not have permission to register a filter.
+    AccessDenied,
+
+    /// The event could not be found to be modified or deleted.
+    EventNotFound,
+
+    /// No memory was available to register the event.
+    SystemResources,
+
+    /// The specified process to attach to does not exist.
+    ProcessNotFound,
+
+    /// changelist or eventlist had too many items on it.
+    /// TODO remove this possibility
+    Overflow,
+};
+
+pub fn kevent(
+    kq: i32,
+    changelist: []const Kevent,
+    eventlist: []Kevent,
+    timeout: ?*const timespec,
+) KEventError!usize {
+    while (true) {
+        const rc = system.kevent(
+            kq,
+            changelist.ptr,
+            cast(c_int, changelist.len) orelse return error.Overflow,
+            eventlist.ptr,
+            cast(c_int, eventlist.len) orelse return error.Overflow,
+            timeout,
+        );
+        switch (errno(rc)) {
+            .SUCCESS => return @intCast(rc),
+            .ACCES => return error.AccessDenied,
+            .FAULT => unreachable,
+            .BADF => unreachable, // Always a race condition.
+            .INTR => continue,
+            .INVAL => unreachable,
+            .NOENT => return error.EventNotFound,
+            .NOMEM => return error.SystemResources,
+            .SRCH => return error.ProcessNotFound,
+            else => unreachable,
+        }
+    }
+}
+
+pub const INotifyInitError = error{
+    ProcessFdQuotaExceeded,
+    SystemFdQuotaExceeded,
+    SystemResources,
+} || UnexpectedError;
+
+/// initialize an inotify instance
+pub fn inotify_init1(flags: u32) INotifyInitError!i32 {
+    const rc = system.inotify_init1(flags);
+    switch (errno(rc)) {
+        .SUCCESS => return @intCast(rc),
+        .INVAL => unreachable,
+        .MFILE => return error.ProcessFdQuotaExceeded,
+        .NFILE => return error.SystemFdQuotaExceeded,
+        .NOMEM => return error.SystemResources,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub const INotifyAddWatchError = error{
+    AccessDenied,
+    NameTooLong,
+    FileNotFound,
+    SystemResources,
+    UserResourceLimitReached,
+    NotDir,
+    WatchAlreadyExists,
+} || UnexpectedError;
+
+/// add a watch to an initialized inotify instance
+pub fn inotify_add_watch(inotify_fd: i32, pathname: []const u8, mask: u32) INotifyAddWatchError!i32 {
+    const pathname_c = try toPosixPath(pathname);
+    return inotify_add_watchZ(inotify_fd, &pathname_c, mask);
+}
+
+/// Same as `inotify_add_watch` except pathname is null-terminated.
+pub fn inotify_add_watchZ(inotify_fd: i32, pathname: [*:0]const u8, mask: u32) INotifyAddWatchError!i32 {
+    const rc = system.inotify_add_watch(inotify_fd, pathname, mask);
+    switch (errno(rc)) {
+        .SUCCESS => return @intCast(rc),
+        .ACCES => return error.AccessDenied,
+        .BADF => unreachable,
+        .FAULT => unreachable,
+        .INVAL => unreachable,
+        .NAMETOOLONG => return error.NameTooLong,
+        .NOENT => return error.FileNotFound,
+        .NOMEM => return error.SystemResources,
+        .NOSPC => return error.UserResourceLimitReached,
+        .NOTDIR => return error.NotDir,
+        .EXIST => return error.WatchAlreadyExists,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// remove an existing watch from an inotify instance
+pub fn inotify_rm_watch(inotify_fd: i32, wd: i32) void {
+    switch (errno(system.inotify_rm_watch(inotify_fd, wd))) {
+        .SUCCESS => return,
+        .BADF => unreachable,
+        .INVAL => unreachable,
+        else => unreachable,
+    }
+}
+
+pub const FanotifyInitError = error{
+    ProcessFdQuotaExceeded,
+    SystemFdQuotaExceeded,
+    SystemResources,
+    OperationNotSupported,
+    PermissionDenied,
+} || UnexpectedError;
+
+pub fn fanotify_init(flags: u32, event_f_flags: u32) FanotifyInitError!i32 {
+    const rc = system.fanotify_init(flags, event_f_flags);
+    switch (errno(rc)) {
+        .SUCCESS => return @intCast(rc),
+        .INVAL => unreachable,
+        .MFILE => return error.ProcessFdQuotaExceeded,
+        .NFILE => return error.SystemFdQuotaExceeded,
+        .NOMEM => return error.SystemResources,
+        .NOSYS => return error.OperationNotSupported,
+        .PERM => return error.PermissionDenied,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub const FanotifyMarkError = error{
+    MarkAlreadyExists,
+    IsDir,
+    NotAssociatedWithFileSystem,
+    FileNotFound,
+    SystemResources,
+    UserMarkQuotaExceeded,
+    NotImplemented,
+    NotDir,
+    OperationNotSupported,
+    PermissionDenied,
+    NotSameFileSystem,
+    NameTooLong,
+} || UnexpectedError;
+
+pub fn fanotify_mark(fanotify_fd: i32, flags: u32, mask: u64, dirfd: i32, pathname: ?[]const u8) FanotifyMarkError!void {
+    if (pathname) |path| {
+        const path_c = try toPosixPath(path);
+        return fanotify_markZ(fanotify_fd, flags, mask, dirfd, &path_c);
+    }
+
+    return fanotify_markZ(fanotify_fd, flags, mask, dirfd, null);
+}
+
+pub fn fanotify_markZ(fanotify_fd: i32, flags: u32, mask: u64, dirfd: i32, pathname: ?[*:0]const u8) FanotifyMarkError!void {
+    const rc = system.fanotify_mark(fanotify_fd, flags, mask, dirfd, pathname);
+    switch (errno(rc)) {
+        .SUCCESS => return,
+        .BADF => unreachable,
+        .EXIST => return error.MarkAlreadyExists,
+        .INVAL => unreachable,
+        .ISDIR => return error.IsDir,
+        .NODEV => return error.NotAssociatedWithFileSystem,
+        .NOENT => return error.FileNotFound,
+        .NOMEM => return error.SystemResources,
+        .NOSPC => return error.UserMarkQuotaExceeded,
+        .NOSYS => return error.NotImplemented,
+        .NOTDIR => return error.NotDir,
+        .OPNOTSUPP => return error.OperationNotSupported,
+        .PERM => return error.PermissionDenied,
+        .XDEV => return error.NotSameFileSystem,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub const MProtectError = error{
+    /// The memory cannot be given the specified access.  This can happen, for example, if you
+    /// mmap(2)  a  file  to  which  you have read-only access, then ask mprotect() to mark it
+    /// PROT_WRITE.
+    AccessDenied,
+
+    /// Changing  the  protection  of a memory region would result in the total number of mapโ€
+    /// pings with distinct attributes (e.g., read versus read/write protection) exceeding the
+    /// allowed maximum.  (For example, making the protection of a range PROT_READ in the midโ€
+    /// dle of a region currently protected as PROT_READ|PROT_WRITE would result in three mapโ€
+    /// pings: two read/write mappings at each end and a read-only mapping in the middle.)
+    OutOfMemory,
+} || UnexpectedError;
+
+/// `memory.len` must be page-aligned.
+pub fn mprotect(memory: []align(mem.page_size) u8, protection: u32) MProtectError!void {
+    assert(mem.isAligned(memory.len, mem.page_size));
+    if (native_os == .windows) {
+        const win_prot: windows.DWORD = switch (@as(u3, @truncate(protection))) {
+            0b000 => windows.PAGE_NOACCESS,
+            0b001 => windows.PAGE_READONLY,
+            0b010 => unreachable, // +w -r not allowed
+            0b011 => windows.PAGE_READWRITE,
+            0b100 => windows.PAGE_EXECUTE,
+            0b101 => windows.PAGE_EXECUTE_READ,
+            0b110 => unreachable, // +w -r not allowed
+            0b111 => windows.PAGE_EXECUTE_READWRITE,
+        };
+        var old: windows.DWORD = undefined;
+        windows.VirtualProtect(memory.ptr, memory.len, win_prot, &old) catch |err| switch (err) {
+            error.InvalidAddress => return error.AccessDenied,
+            error.Unexpected => return error.Unexpected,
+        };
+    } else {
+        switch (errno(system.mprotect(memory.ptr, memory.len, protection))) {
+            .SUCCESS => return,
+            .INVAL => unreachable,
+            .ACCES => return error.AccessDenied,
+            .NOMEM => return error.OutOfMemory,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+pub const ForkError = error{SystemResources} || UnexpectedError;
+
+pub fn fork() ForkError!pid_t {
+    const rc = system.fork();
+    switch (errno(rc)) {
+        .SUCCESS => return @intCast(rc),
+        .AGAIN => return error.SystemResources,
+        .NOMEM => return error.SystemResources,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub const MMapError = error{
+    /// The underlying filesystem of the specified file does not support memory mapping.
+    MemoryMappingNotSupported,
+
+    /// A file descriptor refers to a non-regular file. Or a file mapping was requested,
+    /// but the file descriptor is not open for reading. Or `MAP.SHARED` was requested
+    /// and `PROT_WRITE` is set, but the file descriptor is not open in `RDWR` mode.
+    /// Or `PROT_WRITE` is set, but the file is append-only.
+    AccessDenied,
+
+    /// The `prot` argument asks for `PROT_EXEC` but the mapped area belongs to a file on
+    /// a filesystem that was mounted no-exec.
+    PermissionDenied,
+    LockedMemoryLimitExceeded,
+    ProcessFdQuotaExceeded,
+    SystemFdQuotaExceeded,
+    OutOfMemory,
+} || UnexpectedError;
+
+/// Map files or devices into memory.
+/// `length` does not need to be aligned.
+/// Use of a mapped region can result in these signals:
+/// * SIGSEGV - Attempted write into a region mapped as read-only.
+/// * SIGBUS - Attempted  access to a portion of the buffer that does not correspond to the file
+pub fn mmap(
+    ptr: ?[*]align(mem.page_size) u8,
+    length: usize,
+    prot: u32,
+    flags: system.MAP,
+    fd: fd_t,
+    offset: u64,
+) MMapError![]align(mem.page_size) u8 {
+    const mmap_sym = if (lfs64_abi) system.mmap64 else system.mmap;
+    const rc = mmap_sym(ptr, length, prot, @bitCast(flags), fd, @bitCast(offset));
+    const err: E = if (builtin.link_libc) blk: {
+        if (rc != std.c.MAP_FAILED) return @as([*]align(mem.page_size) u8, @ptrCast(@alignCast(rc)))[0..length];
+        break :blk @enumFromInt(system._errno().*);
+    } else blk: {
+        const err = errno(rc);
+        if (err == .SUCCESS) return @as([*]align(mem.page_size) u8, @ptrFromInt(rc))[0..length];
+        break :blk err;
+    };
+    switch (err) {
+        .SUCCESS => unreachable,
+        .TXTBSY => return error.AccessDenied,
+        .ACCES => return error.AccessDenied,
+        .PERM => return error.PermissionDenied,
+        .AGAIN => return error.LockedMemoryLimitExceeded,
+        .BADF => unreachable, // Always a race condition.
+        .OVERFLOW => unreachable, // The number of pages used for length + offset would overflow.
+        .NODEV => return error.MemoryMappingNotSupported,
+        .INVAL => unreachable, // Invalid parameters to mmap()
+        .MFILE => return error.ProcessFdQuotaExceeded,
+        .NFILE => return error.SystemFdQuotaExceeded,
+        .NOMEM => return error.OutOfMemory,
+        else => return unexpectedErrno(err),
+    }
+}
+
+/// Deletes the mappings for the specified address range, causing
+/// further references to addresses within the range to generate invalid memory references.
+/// Note that while POSIX allows unmapping a region in the middle of an existing mapping,
+/// Zig's munmap function does not, for two reasons:
+/// * It violates the Zig principle that resource deallocation must succeed.
+/// * The Windows function, VirtualFree, has this restriction.
+pub fn munmap(memory: []align(mem.page_size) const u8) void {
+    switch (errno(system.munmap(memory.ptr, memory.len))) {
+        .SUCCESS => return,
+        .INVAL => unreachable, // Invalid parameters.
+        .NOMEM => unreachable, // Attempted to unmap a region in the middle of an existing mapping.
+        else => unreachable,
+    }
+}
+
+pub const MSyncError = error{
+    UnmappedMemory,
+} || UnexpectedError;
+
+pub fn msync(memory: []align(mem.page_size) u8, flags: i32) MSyncError!void {
+    switch (errno(system.msync(memory.ptr, memory.len, flags))) {
+        .SUCCESS => return,
+        .NOMEM => return error.UnmappedMemory, // Unsuccessful, provided pointer does not point mapped memory
+        .INVAL => unreachable, // Invalid parameters.
+        else => unreachable,
+    }
+}
+
+pub const AccessError = error{
+    PermissionDenied,
+    FileNotFound,
+    NameTooLong,
+    InputOutput,
+    SystemResources,
+    BadPathName,
+    FileBusy,
+    SymLinkLoop,
+    ReadOnlyFileSystem,
+    /// WASI-only; file paths must be valid UTF-8.
+    InvalidUtf8,
+    /// Windows-only; file paths provided by the user must be valid WTF-8.
+    /// https://simonsapin.github.io/wtf-8/
+    InvalidWtf8,
+} || UnexpectedError;
+
+/// check user's permissions for a file
+///
+/// * On Windows, asserts `path` is valid [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// * On WASI, invalid UTF-8 passed to `path` causes `error.InvalidUtf8`.
+/// * On other platforms, `path` is an opaque sequence of bytes with no particular encoding.
+///
+/// On Windows, `mode` is ignored. This is a POSIX API that is only partially supported by
+/// Windows. See `fs` for the cross-platform file system API.
+pub fn access(path: []const u8, mode: u32) AccessError!void {
+    if (native_os == .windows) {
+        const path_w = windows.sliceToPrefixedFileW(null, path) catch |err| switch (err) {
+            error.AccessDenied => return error.PermissionDenied,
+            else => |e| return e,
+        };
+        _ = try windows.GetFileAttributesW(path_w.span().ptr);
+        return;
+    } else if (native_os == .wasi and !builtin.link_libc) {
+        return faccessat(wasi.AT.FDCWD, path, mode, 0);
+    }
+    const path_c = try toPosixPath(path);
+    return accessZ(&path_c, mode);
+}
+
+/// Same as `access` except `path` is null-terminated.
+pub fn accessZ(path: [*:0]const u8, mode: u32) AccessError!void {
+    if (native_os == .windows) {
+        const path_w = windows.cStrToPrefixedFileW(null, path) catch |err| switch (err) {
+            error.AccessDenied => return error.PermissionDenied,
+            else => |e| return e,
+        };
+        _ = try windows.GetFileAttributesW(path_w.span().ptr);
+        return;
+    } else if (native_os == .wasi and !builtin.link_libc) {
+        return access(mem.sliceTo(path, 0), mode);
+    }
+    switch (errno(system.access(path, mode))) {
+        .SUCCESS => return,
+        .ACCES => return error.PermissionDenied,
+        .ROFS => return error.ReadOnlyFileSystem,
+        .LOOP => return error.SymLinkLoop,
+        .TXTBSY => return error.FileBusy,
+        .NOTDIR => return error.FileNotFound,
+        .NOENT => return error.FileNotFound,
+        .NAMETOOLONG => return error.NameTooLong,
+        .INVAL => unreachable,
+        .FAULT => unreachable,
+        .IO => return error.InputOutput,
+        .NOMEM => return error.SystemResources,
+        .ILSEQ => |err| if (native_os == .wasi)
+            return error.InvalidUtf8
+        else
+            return unexpectedErrno(err),
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// Check user's permissions for a file, based on an open directory handle.
+///
+/// * On Windows, asserts `path` is valid [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// * On WASI, invalid UTF-8 passed to `path` causes `error.InvalidUtf8`.
+/// * On other platforms, `path` is an opaque sequence of bytes with no particular encoding.
+///
+/// On Windows, `mode` is ignored. This is a POSIX API that is only partially supported by
+/// Windows. See `fs` for the cross-platform file system API.
+pub fn faccessat(dirfd: fd_t, path: []const u8, mode: u32, flags: u32) AccessError!void {
+    if (native_os == .windows) {
+        const path_w = try windows.sliceToPrefixedFileW(dirfd, path);
+        return faccessatW(dirfd, path_w.span().ptr);
+    } else if (native_os == .wasi and !builtin.link_libc) {
+        const resolved: RelativePathWasi = .{ .dir_fd = dirfd, .relative_path = path };
+
+        const st = blk: {
+            break :blk fstatat_wasi(dirfd, path, .{
+                .SYMLINK_FOLLOW = (flags & AT.SYMLINK_NOFOLLOW) == 0,
+            });
+        } catch |err| switch (err) {
+            error.AccessDenied => return error.PermissionDenied,
+            else => |e| return e,
+        };
+
+        if (mode != F_OK) {
+            var directory: wasi.fdstat_t = undefined;
+            if (wasi.fd_fdstat_get(resolved.dir_fd, &directory) != .SUCCESS) {
+                return error.PermissionDenied;
+            }
+
+            var rights: wasi.rights_t = .{};
+            if (mode & R_OK != 0) {
+                if (st.filetype == .DIRECTORY) {
+                    rights.FD_READDIR = true;
+                } else {
+                    rights.FD_READ = true;
+                }
+            }
+            if (mode & W_OK != 0) {
+                rights.FD_WRITE = true;
+            }
+            // No validation for X_OK
+
+            // https://github.com/ziglang/zig/issues/18882
+            const rights_int: u64 = @bitCast(rights);
+            const inheriting_int: u64 = @bitCast(directory.fs_rights_inheriting);
+            if ((rights_int & inheriting_int) != rights_int) {
+                return error.PermissionDenied;
+            }
+        }
+        return;
+    }
+    const path_c = try toPosixPath(path);
+    return faccessatZ(dirfd, &path_c, mode, flags);
+}
+
+/// Same as `faccessat` except the path parameter is null-terminated.
+pub fn faccessatZ(dirfd: fd_t, path: [*:0]const u8, mode: u32, flags: u32) AccessError!void {
+    if (native_os == .windows) {
+        const path_w = try windows.cStrToPrefixedFileW(dirfd, path);
+        return faccessatW(dirfd, path_w.span().ptr);
+    } else if (native_os == .wasi and !builtin.link_libc) {
+        return faccessat(dirfd, mem.sliceTo(path, 0), mode, flags);
+    }
+    switch (errno(system.faccessat(dirfd, path, mode, flags))) {
+        .SUCCESS => return,
+        .ACCES => return error.PermissionDenied,
+        .ROFS => return error.ReadOnlyFileSystem,
+        .LOOP => return error.SymLinkLoop,
+        .TXTBSY => return error.FileBusy,
+        .NOTDIR => return error.FileNotFound,
+        .NOENT => return error.FileNotFound,
+        .NAMETOOLONG => return error.NameTooLong,
+        .INVAL => unreachable,
+        .FAULT => unreachable,
+        .IO => return error.InputOutput,
+        .NOMEM => return error.SystemResources,
+        .ILSEQ => |err| if (native_os == .wasi)
+            return error.InvalidUtf8
+        else
+            return unexpectedErrno(err),
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// Same as `faccessat` except asserts the target is Windows and the path parameter
+/// is NtDll-prefixed, null-terminated, WTF-16 encoded.
+pub fn faccessatW(dirfd: fd_t, sub_path_w: [*:0]const u16) AccessError!void {
+    if (sub_path_w[0] == '.' and sub_path_w[1] == 0) {
+        return;
+    }
+    if (sub_path_w[0] == '.' and sub_path_w[1] == '.' and sub_path_w[2] == 0) {
+        return;
+    }
+
+    const path_len_bytes = cast(u16, mem.sliceTo(sub_path_w, 0).len * 2) orelse return error.NameTooLong;
+    var nt_name = windows.UNICODE_STRING{
+        .Length = path_len_bytes,
+        .MaximumLength = path_len_bytes,
+        .Buffer = @constCast(sub_path_w),
+    };
+    var attr = windows.OBJECT_ATTRIBUTES{
+        .Length = @sizeOf(windows.OBJECT_ATTRIBUTES),
+        .RootDirectory = if (fs.path.isAbsoluteWindowsW(sub_path_w)) null else dirfd,
+        .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here.
+        .ObjectName = &nt_name,
+        .SecurityDescriptor = null,
+        .SecurityQualityOfService = null,
+    };
+    var basic_info: windows.FILE_BASIC_INFORMATION = undefined;
+    switch (windows.ntdll.NtQueryAttributesFile(&attr, &basic_info)) {
+        .SUCCESS => return,
+        .OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
+        .OBJECT_PATH_NOT_FOUND => return error.FileNotFound,
+        .OBJECT_NAME_INVALID => unreachable,
+        .INVALID_PARAMETER => unreachable,
+        .ACCESS_DENIED => return error.PermissionDenied,
+        .OBJECT_PATH_SYNTAX_BAD => unreachable,
+        else => |rc| return windows.unexpectedStatus(rc),
+    }
+}
+
+pub const PipeError = error{
+    SystemFdQuotaExceeded,
+    ProcessFdQuotaExceeded,
+} || UnexpectedError;
+
+/// Creates a unidirectional data channel that can be used for interprocess communication.
+pub fn pipe() PipeError![2]fd_t {
+    var fds: [2]fd_t = undefined;
+    switch (errno(system.pipe(&fds))) {
+        .SUCCESS => return fds,
+        .INVAL => unreachable, // Invalid parameters to pipe()
+        .FAULT => unreachable, // Invalid fds pointer
+        .NFILE => return error.SystemFdQuotaExceeded,
+        .MFILE => return error.ProcessFdQuotaExceeded,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub fn pipe2(flags: O) PipeError![2]fd_t {
+    // https://github.com/ziglang/zig/issues/19352
+    if (@hasDecl(system, "pipe2")) {
+        var fds: [2]fd_t = undefined;
+        switch (errno(system.pipe2(&fds, flags))) {
+            .SUCCESS => return fds,
+            .INVAL => unreachable, // Invalid flags
+            .FAULT => unreachable, // Invalid fds pointer
+            .NFILE => return error.SystemFdQuotaExceeded,
+            .MFILE => return error.ProcessFdQuotaExceeded,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+
+    const fds: [2]fd_t = try pipe();
+    errdefer {
+        close(fds[0]);
+        close(fds[1]);
+    }
+
+    // https://github.com/ziglang/zig/issues/18882
+    if (@as(u32, @bitCast(flags)) == 0)
+        return fds;
+
+    // CLOEXEC is special, it's a file descriptor flag and must be set using
+    // F.SETFD.
+    if (flags.CLOEXEC) {
+        for (fds) |fd| {
+            switch (errno(system.fcntl(fd, F.SETFD, @as(u32, FD_CLOEXEC)))) {
+                .SUCCESS => {},
+                .INVAL => unreachable, // Invalid flags
+                .BADF => unreachable, // Always a race condition
+                else => |err| return unexpectedErrno(err),
+            }
+        }
+    }
+
+    const new_flags: u32 = f: {
+        var new_flags = flags;
+        new_flags.CLOEXEC = false;
+        break :f @bitCast(new_flags);
+    };
+    // Set every other flag affecting the file status using F.SETFL.
+    if (new_flags != 0) {
+        for (fds) |fd| {
+            switch (errno(system.fcntl(fd, F.SETFL, new_flags))) {
+                .SUCCESS => {},
+                .INVAL => unreachable, // Invalid flags
+                .BADF => unreachable, // Always a race condition
+                else => |err| return unexpectedErrno(err),
+            }
+        }
+    }
+
+    return fds;
+}
+
+pub const SysCtlError = error{
+    PermissionDenied,
+    SystemResources,
+    NameTooLong,
+    UnknownName,
+} || UnexpectedError;
+
+pub fn sysctl(
+    name: []const c_int,
+    oldp: ?*anyopaque,
+    oldlenp: ?*usize,
+    newp: ?*anyopaque,
+    newlen: usize,
+) SysCtlError!void {
+    if (native_os == .wasi) {
+        @panic("unsupported"); // TODO should be compile error, not panic
+    }
+    if (native_os == .haiku) {
+        @panic("unsupported"); // TODO should be compile error, not panic
+    }
+
+    const name_len = cast(c_uint, name.len) orelse return error.NameTooLong;
+    switch (errno(system.sysctl(name.ptr, name_len, oldp, oldlenp, newp, newlen))) {
+        .SUCCESS => return,
+        .FAULT => unreachable,
+        .PERM => return error.PermissionDenied,
+        .NOMEM => return error.SystemResources,
+        .NOENT => return error.UnknownName,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub fn sysctlbynameZ(
+    name: [*:0]const u8,
+    oldp: ?*anyopaque,
+    oldlenp: ?*usize,
+    newp: ?*anyopaque,
+    newlen: usize,
+) SysCtlError!void {
+    if (native_os == .wasi) {
+        @panic("unsupported"); // TODO should be compile error, not panic
+    }
+    if (native_os == .haiku) {
+        @panic("unsupported"); // TODO should be compile error, not panic
+    }
+
+    switch (errno(system.sysctlbyname(name, oldp, oldlenp, newp, newlen))) {
+        .SUCCESS => return,
+        .FAULT => unreachable,
+        .PERM => return error.PermissionDenied,
+        .NOMEM => return error.SystemResources,
+        .NOENT => return error.UnknownName,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub fn gettimeofday(tv: ?*timeval, tz: ?*timezone) void {
+    switch (errno(system.gettimeofday(tv, tz))) {
+        .SUCCESS => return,
+        .INVAL => unreachable,
+        else => unreachable,
+    }
+}
+
+pub const SeekError = error{
+    Unseekable,
+
+    /// In WASI, this error may occur when the file descriptor does
+    /// not hold the required rights to seek on it.
+    AccessDenied,
+} || UnexpectedError;
+
+/// Repositions read/write file offset relative to the beginning.
+pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {
+    if (native_os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
+        var result: u64 = undefined;
+        switch (errno(system.llseek(fd, offset, &result, SEEK.SET))) {
+            .SUCCESS => return,
+            .BADF => unreachable, // always a race condition
+            .INVAL => return error.Unseekable,
+            .OVERFLOW => return error.Unseekable,
+            .SPIPE => return error.Unseekable,
+            .NXIO => return error.Unseekable,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+    if (native_os == .windows) {
+        return windows.SetFilePointerEx_BEGIN(fd, offset);
+    }
+    if (native_os == .wasi and !builtin.link_libc) {
+        var new_offset: wasi.filesize_t = undefined;
+        switch (wasi.fd_seek(fd, @bitCast(offset), .SET, &new_offset)) {
+            .SUCCESS => return,
+            .BADF => unreachable, // always a race condition
+            .INVAL => return error.Unseekable,
+            .OVERFLOW => return error.Unseekable,
+            .SPIPE => return error.Unseekable,
+            .NXIO => return error.Unseekable,
+            .NOTCAPABLE => return error.AccessDenied,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+
+    const lseek_sym = if (lfs64_abi) system.lseek64 else system.lseek;
+    switch (errno(lseek_sym(fd, @bitCast(offset), SEEK.SET))) {
+        .SUCCESS => return,
+        .BADF => unreachable, // always a race condition
+        .INVAL => return error.Unseekable,
+        .OVERFLOW => return error.Unseekable,
+        .SPIPE => return error.Unseekable,
+        .NXIO => return error.Unseekable,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// Repositions read/write file offset relative to the current offset.
+pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {
+    if (native_os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
+        var result: u64 = undefined;
+        switch (errno(system.llseek(fd, @bitCast(offset), &result, SEEK.CUR))) {
+            .SUCCESS => return,
+            .BADF => unreachable, // always a race condition
+            .INVAL => return error.Unseekable,
+            .OVERFLOW => return error.Unseekable,
+            .SPIPE => return error.Unseekable,
+            .NXIO => return error.Unseekable,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+    if (native_os == .windows) {
+        return windows.SetFilePointerEx_CURRENT(fd, offset);
+    }
+    if (native_os == .wasi and !builtin.link_libc) {
+        var new_offset: wasi.filesize_t = undefined;
+        switch (wasi.fd_seek(fd, offset, .CUR, &new_offset)) {
+            .SUCCESS => return,
+            .BADF => unreachable, // always a race condition
+            .INVAL => return error.Unseekable,
+            .OVERFLOW => return error.Unseekable,
+            .SPIPE => return error.Unseekable,
+            .NXIO => return error.Unseekable,
+            .NOTCAPABLE => return error.AccessDenied,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+    const lseek_sym = if (lfs64_abi) system.lseek64 else system.lseek;
+    switch (errno(lseek_sym(fd, @bitCast(offset), SEEK.CUR))) {
+        .SUCCESS => return,
+        .BADF => unreachable, // always a race condition
+        .INVAL => return error.Unseekable,
+        .OVERFLOW => return error.Unseekable,
+        .SPIPE => return error.Unseekable,
+        .NXIO => return error.Unseekable,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// Repositions read/write file offset relative to the end.
+pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {
+    if (native_os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
+        var result: u64 = undefined;
+        switch (errno(system.llseek(fd, @bitCast(offset), &result, SEEK.END))) {
+            .SUCCESS => return,
+            .BADF => unreachable, // always a race condition
+            .INVAL => return error.Unseekable,
+            .OVERFLOW => return error.Unseekable,
+            .SPIPE => return error.Unseekable,
+            .NXIO => return error.Unseekable,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+    if (native_os == .windows) {
+        return windows.SetFilePointerEx_END(fd, offset);
+    }
+    if (native_os == .wasi and !builtin.link_libc) {
+        var new_offset: wasi.filesize_t = undefined;
+        switch (wasi.fd_seek(fd, offset, .END, &new_offset)) {
+            .SUCCESS => return,
+            .BADF => unreachable, // always a race condition
+            .INVAL => return error.Unseekable,
+            .OVERFLOW => return error.Unseekable,
+            .SPIPE => return error.Unseekable,
+            .NXIO => return error.Unseekable,
+            .NOTCAPABLE => return error.AccessDenied,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+    const lseek_sym = if (lfs64_abi) system.lseek64 else system.lseek;
+    switch (errno(lseek_sym(fd, @bitCast(offset), SEEK.END))) {
+        .SUCCESS => return,
+        .BADF => unreachable, // always a race condition
+        .INVAL => return error.Unseekable,
+        .OVERFLOW => return error.Unseekable,
+        .SPIPE => return error.Unseekable,
+        .NXIO => return error.Unseekable,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// Returns the read/write file offset relative to the beginning.
+pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 {
+    if (native_os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
+        var result: u64 = undefined;
+        switch (errno(system.llseek(fd, 0, &result, SEEK.CUR))) {
+            .SUCCESS => return result,
+            .BADF => unreachable, // always a race condition
+            .INVAL => return error.Unseekable,
+            .OVERFLOW => return error.Unseekable,
+            .SPIPE => return error.Unseekable,
+            .NXIO => return error.Unseekable,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+    if (native_os == .windows) {
+        return windows.SetFilePointerEx_CURRENT_get(fd);
+    }
+    if (native_os == .wasi and !builtin.link_libc) {
+        var new_offset: wasi.filesize_t = undefined;
+        switch (wasi.fd_seek(fd, 0, .CUR, &new_offset)) {
+            .SUCCESS => return new_offset,
+            .BADF => unreachable, // always a race condition
+            .INVAL => return error.Unseekable,
+            .OVERFLOW => return error.Unseekable,
+            .SPIPE => return error.Unseekable,
+            .NXIO => return error.Unseekable,
+            .NOTCAPABLE => return error.AccessDenied,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+    const lseek_sym = if (lfs64_abi) system.lseek64 else system.lseek;
+    const rc = lseek_sym(fd, 0, SEEK.CUR);
+    switch (errno(rc)) {
+        .SUCCESS => return @bitCast(rc),
+        .BADF => unreachable, // always a race condition
+        .INVAL => return error.Unseekable,
+        .OVERFLOW => return error.Unseekable,
+        .SPIPE => return error.Unseekable,
+        .NXIO => return error.Unseekable,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub const FcntlError = error{
+    PermissionDenied,
+    FileBusy,
+    ProcessFdQuotaExceeded,
+    Locked,
+    DeadLock,
+    LockedRegionLimitExceeded,
+} || UnexpectedError;
+
+pub fn fcntl(fd: fd_t, cmd: i32, arg: usize) FcntlError!usize {
+    while (true) {
+        const rc = system.fcntl(fd, cmd, arg);
+        switch (errno(rc)) {
+            .SUCCESS => return @intCast(rc),
+            .INTR => continue,
+            .AGAIN, .ACCES => return error.Locked,
+            .BADF => unreachable,
+            .BUSY => return error.FileBusy,
+            .INVAL => unreachable, // invalid parameters
+            .PERM => return error.PermissionDenied,
+            .MFILE => return error.ProcessFdQuotaExceeded,
+            .NOTDIR => unreachable, // invalid parameter
+            .DEADLK => return error.DeadLock,
+            .NOLCK => return error.LockedRegionLimitExceeded,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+pub const FlockError = error{
+    WouldBlock,
+
+    /// The kernel ran out of memory for allocating file locks
+    SystemResources,
+
+    /// The underlying filesystem does not support file locks
+    FileLocksNotSupported,
+} || UnexpectedError;
+
+/// Depending on the operating system `flock` may or may not interact with
+/// `fcntl` locks made by other processes.
+pub fn flock(fd: fd_t, operation: i32) FlockError!void {
+    while (true) {
+        const rc = system.flock(fd, operation);
+        switch (errno(rc)) {
+            .SUCCESS => return,
+            .BADF => unreachable,
+            .INTR => continue,
+            .INVAL => unreachable, // invalid parameters
+            .NOLCK => return error.SystemResources,
+            .AGAIN => return error.WouldBlock, // TODO: integrate with async instead of just returning an error
+            .OPNOTSUPP => return error.FileLocksNotSupported,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+pub const RealPathError = error{
+    FileNotFound,
+    AccessDenied,
+    NameTooLong,
+    NotSupported,
+    NotDir,
+    SymLinkLoop,
+    InputOutput,
+    FileTooBig,
+    IsDir,
+    ProcessFdQuotaExceeded,
+    SystemFdQuotaExceeded,
+    NoDevice,
+    SystemResources,
+    NoSpaceLeft,
+    FileSystem,
+    BadPathName,
+    DeviceBusy,
+
+    SharingViolation,
+    PipeBusy,
+
+    /// Windows-only; file paths provided by the user must be valid WTF-8.
+    /// https://simonsapin.github.io/wtf-8/
+    InvalidWtf8,
+
+    /// On Windows, `\\server` or `\\server\share` was not found.
+    NetworkNotFound,
+
+    PathAlreadyExists,
+
+    /// On Windows, antivirus software is enabled by default. It can be
+    /// disabled, but Windows Update sometimes ignores the user's preference
+    /// and re-enables it. When enabled, antivirus software on Windows
+    /// intercepts file system operations and makes them significantly slower
+    /// in addition to possibly failing with this error code.
+    AntivirusInterference,
+
+    /// On Windows, the volume does not contain a recognized file system. File
+    /// system drivers might not be loaded, or the volume may be corrupt.
+    UnrecognizedVolume,
+} || UnexpectedError;
+
+/// Return the canonicalized absolute pathname.
+///
+/// Expands all symbolic links and resolves references to `.`, `..`, and
+/// extra `/` characters in `pathname`.
+///
+/// On Windows, `pathname` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+///
+/// On other platforms, `pathname` is an opaque sequence of bytes with no particular encoding.
+///
+/// The return value is a slice of `out_buffer`, but not necessarily from the beginning.
+///
+/// See also `realpathZ` and `realpathW`.
+///
+/// * On Windows, the result is encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+/// * On other platforms, the result is an opaque sequence of bytes with no particular encoding.
+///
+/// Calling this function is usually a bug.
+pub fn realpath(pathname: []const u8, out_buffer: *[max_path_bytes]u8) RealPathError![]u8 {
+    if (native_os == .windows) {
+        const pathname_w = try windows.sliceToPrefixedFileW(null, pathname);
+        return realpathW(pathname_w.span(), out_buffer);
+    } else if (native_os == .wasi and !builtin.link_libc) {
+        @compileError("WASI does not support os.realpath");
+    }
+    const pathname_c = try toPosixPath(pathname);
+    return realpathZ(&pathname_c, out_buffer);
+}
+
+/// Same as `realpath` except `pathname` is null-terminated.
+///
+/// Calling this function is usually a bug.
+pub fn realpathZ(pathname: [*:0]const u8, out_buffer: *[max_path_bytes]u8) RealPathError![]u8 {
+    if (native_os == .windows) {
+        const pathname_w = try windows.cStrToPrefixedFileW(null, pathname);
+        return realpathW(pathname_w.span(), out_buffer);
+    } else if (native_os == .wasi and !builtin.link_libc) {
+        return realpath(mem.sliceTo(pathname, 0), out_buffer);
+    }
+    if (!builtin.link_libc) {
+        const flags: O = switch (native_os) {
+            .linux => .{
+                .NONBLOCK = true,
+                .CLOEXEC = true,
+                .PATH = true,
+            },
+            else => .{
+                .NONBLOCK = true,
+                .CLOEXEC = true,
+            },
+        };
+        const fd = openZ(pathname, flags, 0) catch |err| switch (err) {
+            error.FileLocksNotSupported => unreachable,
+            error.WouldBlock => unreachable,
+            error.FileBusy => unreachable, // not asking for write permissions
+            error.InvalidUtf8 => unreachable, // WASI-only
+            else => |e| return e,
+        };
+        defer close(fd);
+
+        return std.os.getFdPath(fd, out_buffer);
+    }
+    const result_path = std.c.realpath(pathname, out_buffer) orelse switch (@as(E, @enumFromInt(std.c._errno().*))) {
+        .SUCCESS => unreachable,
+        .INVAL => unreachable,
+        .BADF => unreachable,
+        .FAULT => unreachable,
+        .ACCES => return error.AccessDenied,
+        .NOENT => return error.FileNotFound,
+        .OPNOTSUPP => return error.NotSupported,
+        .NOTDIR => return error.NotDir,
+        .NAMETOOLONG => return error.NameTooLong,
+        .LOOP => return error.SymLinkLoop,
+        .IO => return error.InputOutput,
+        else => |err| return unexpectedErrno(err),
+    };
+    return mem.sliceTo(result_path, 0);
+}
+
+/// Same as `realpath` except `pathname` is WTF16LE-encoded.
+///
+/// The result is encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
+///
+/// Calling this function is usually a bug.
+pub fn realpathW(pathname: []const u16, out_buffer: *[max_path_bytes]u8) RealPathError![]u8 {
+    const w = windows;
+
+    const dir = fs.cwd().fd;
+    const access_mask = w.GENERIC_READ | w.SYNCHRONIZE;
+    const share_access = w.FILE_SHARE_READ;
+    const creation = w.FILE_OPEN;
+    const h_file = blk: {
+        const res = w.OpenFile(pathname, .{
+            .dir = dir,
+            .access_mask = access_mask,
+            .share_access = share_access,
+            .creation = creation,
+            .filter = .any,
+        }) catch |err| switch (err) {
+            error.WouldBlock => unreachable,
+            else => |e| return e,
+        };
+        break :blk res;
+    };
+    defer w.CloseHandle(h_file);
+
+    return std.os.getFdPath(h_file, out_buffer);
+}
+
+/// Spurious wakeups are possible and no precision of timing is guaranteed.
+pub fn nanosleep(seconds: u64, nanoseconds: u64) void {
+    var req = timespec{
+        .tv_sec = cast(isize, seconds) orelse maxInt(isize),
+        .tv_nsec = cast(isize, nanoseconds) orelse maxInt(isize),
+    };
+    var rem: timespec = undefined;
+    while (true) {
+        switch (errno(system.nanosleep(&req, &rem))) {
+            .FAULT => unreachable,
+            .INVAL => {
+                // Sometimes Darwin returns EINVAL for no reason.
+                // We treat it as a spurious wakeup.
+                return;
+            },
+            .INTR => {
+                req = rem;
+                continue;
+            },
+            // This prong handles success as well as unexpected errors.
+            else => return,
+        }
+    }
+}
+
+pub fn dl_iterate_phdr(
+    context: anytype,
+    comptime Error: type,
+    comptime callback: fn (info: *dl_phdr_info, size: usize, context: @TypeOf(context)) Error!void,
+) Error!void {
+    const Context = @TypeOf(context);
+    const elf = std.elf;
+    const dl = @import("dynamic_library.zig");
+
+    switch (builtin.object_format) {
+        .elf, .c => {},
+        else => @compileError("dl_iterate_phdr is not available for this target"),
+    }
+
+    if (builtin.link_libc) {
+        switch (system.dl_iterate_phdr(struct {
+            fn callbackC(info: *dl_phdr_info, size: usize, data: ?*anyopaque) callconv(.C) c_int {
+                const context_ptr: *const Context = @ptrCast(@alignCast(data));
+                callback(info, size, context_ptr.*) catch |err| return @intFromError(err);
+                return 0;
+            }
+        }.callbackC, @ptrCast(@constCast(&context)))) {
+            0 => return,
+            else => |err| return @as(Error, @errorCast(@errorFromInt(@as(std.meta.Int(.unsigned, @bitSizeOf(anyerror)), @intCast(err))))),
+        }
+    }
+
+    const elf_base = std.process.getBaseAddress();
+    const ehdr: *elf.Ehdr = @ptrFromInt(elf_base);
+    // Make sure the base address points to an ELF image.
+    assert(mem.eql(u8, ehdr.e_ident[0..4], elf.MAGIC));
+    const n_phdr = ehdr.e_phnum;
+    const phdrs = (@as([*]elf.Phdr, @ptrFromInt(elf_base + ehdr.e_phoff)))[0..n_phdr];
+
+    var it = dl.linkmap_iterator(phdrs) catch unreachable;
+
+    // The executable has no dynamic link segment, create a single entry for
+    // the whole ELF image.
+    if (it.end()) {
+        // Find the base address for the ELF image, if this is a PIE the value
+        // is non-zero.
+        const base_address = for (phdrs) |*phdr| {
+            if (phdr.p_type == elf.PT_PHDR) {
+                break @intFromPtr(phdrs.ptr) - phdr.p_vaddr;
+                // We could try computing the difference between _DYNAMIC and
+                // the p_vaddr of the PT_DYNAMIC section, but using the phdr is
+                // good enough (Is it?).
+            }
+        } else unreachable;
+
+        var info = dl_phdr_info{
+            .dlpi_addr = base_address,
+            .dlpi_name = "/proc/self/exe",
+            .dlpi_phdr = phdrs.ptr,
+            .dlpi_phnum = ehdr.e_phnum,
+        };
+
+        return callback(&info, @sizeOf(dl_phdr_info), context);
+    }
+
+    // Last return value from the callback function.
+    while (it.next()) |entry| {
+        var dlpi_phdr: [*]elf.Phdr = undefined;
+        var dlpi_phnum: u16 = undefined;
+
+        if (entry.l_addr != 0) {
+            const elf_header: *elf.Ehdr = @ptrFromInt(entry.l_addr);
+            dlpi_phdr = @ptrFromInt(entry.l_addr + elf_header.e_phoff);
+            dlpi_phnum = elf_header.e_phnum;
+        } else {
+            // This is the running ELF image
+            dlpi_phdr = @ptrFromInt(elf_base + ehdr.e_phoff);
+            dlpi_phnum = ehdr.e_phnum;
+        }
+
+        var info = dl_phdr_info{
+            .dlpi_addr = entry.l_addr,
+            .dlpi_name = entry.l_name,
+            .dlpi_phdr = dlpi_phdr,
+            .dlpi_phnum = dlpi_phnum,
+        };
+
+        try callback(&info, @sizeOf(dl_phdr_info), context);
+    }
+}
+
+pub const ClockGetTimeError = error{UnsupportedClock} || UnexpectedError;
+
+/// TODO: change this to return the timespec as a return value
+/// TODO: look into making clk_id an enum
+pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void {
+    if (native_os == .wasi and !builtin.link_libc) {
+        var ts: timestamp_t = undefined;
+        switch (system.clock_time_get(@bitCast(clk_id), 1, &ts)) {
+            .SUCCESS => {
+                tp.* = .{
+                    .tv_sec = @intCast(ts / std.time.ns_per_s),
+                    .tv_nsec = @intCast(ts % std.time.ns_per_s),
+                };
+            },
+            .INVAL => return error.UnsupportedClock,
+            else => |err| return unexpectedErrno(err),
+        }
+        return;
+    }
+    if (native_os == .windows) {
+        if (clk_id == CLOCK.REALTIME) {
+            var ft: windows.FILETIME = undefined;
+            windows.kernel32.GetSystemTimeAsFileTime(&ft);
+            // FileTime has a granularity of 100 nanoseconds and uses the NTFS/Windows epoch.
+            const ft64 = (@as(u64, ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
+            const ft_per_s = std.time.ns_per_s / 100;
+            tp.* = .{
+                .tv_sec = @as(i64, @intCast(ft64 / ft_per_s)) + std.time.epoch.windows,
+                .tv_nsec = @as(c_long, @intCast(ft64 % ft_per_s)) * 100,
+            };
+            return;
+        } else {
+            // TODO POSIX implementation of CLOCK.MONOTONIC on Windows.
+            return error.UnsupportedClock;
+        }
+    }
+
+    switch (errno(system.clock_gettime(clk_id, tp))) {
+        .SUCCESS => return,
+        .FAULT => unreachable,
+        .INVAL => return error.UnsupportedClock,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub fn clock_getres(clk_id: i32, res: *timespec) ClockGetTimeError!void {
+    if (native_os == .wasi and !builtin.link_libc) {
+        var ts: timestamp_t = undefined;
+        switch (system.clock_res_get(@bitCast(clk_id), &ts)) {
+            .SUCCESS => res.* = .{
+                .tv_sec = @intCast(ts / std.time.ns_per_s),
+                .tv_nsec = @intCast(ts % std.time.ns_per_s),
+            },
+            .INVAL => return error.UnsupportedClock,
+            else => |err| return unexpectedErrno(err),
+        }
+        return;
+    }
+
+    switch (errno(system.clock_getres(clk_id, res))) {
+        .SUCCESS => return,
+        .FAULT => unreachable,
+        .INVAL => return error.UnsupportedClock,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub const SchedGetAffinityError = error{PermissionDenied} || UnexpectedError;
+
+pub fn sched_getaffinity(pid: pid_t) SchedGetAffinityError!cpu_set_t {
+    var set: cpu_set_t = undefined;
+    switch (errno(system.sched_getaffinity(pid, @sizeOf(cpu_set_t), &set))) {
+        .SUCCESS => return set,
+        .FAULT => unreachable,
+        .INVAL => unreachable,
+        .SRCH => unreachable,
+        .PERM => return error.PermissionDenied,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub const SigaltstackError = error{
+    /// The supplied stack size was less than MINSIGSTKSZ.
+    SizeTooSmall,
+
+    /// Attempted to change the signal stack while it was active.
+    PermissionDenied,
+} || UnexpectedError;
+
+pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) SigaltstackError!void {
+    switch (errno(system.sigaltstack(ss, old_ss))) {
+        .SUCCESS => return,
+        .FAULT => unreachable,
+        .INVAL => unreachable,
+        .NOMEM => return error.SizeTooSmall,
+        .PERM => return error.PermissionDenied,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// Examine and change a signal action.
+pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) error{OperationNotSupported}!void {
+    switch (errno(system.sigaction(sig, act, oact))) {
+        .SUCCESS => return,
+        .INVAL, .NOSYS => return error.OperationNotSupported,
+        else => unreachable,
+    }
+}
+
+/// Sets the thread signal mask.
+pub fn sigprocmask(flags: u32, noalias set: ?*const sigset_t, noalias oldset: ?*sigset_t) void {
+    switch (errno(system.sigprocmask(@bitCast(flags), set, oldset))) {
+        .SUCCESS => return,
+        .FAULT => unreachable,
+        .INVAL => unreachable,
+        else => unreachable,
+    }
+}
+
+pub const FutimensError = error{
+    /// times is NULL, or both tv_nsec values are UTIME_NOW, and either:
+    /// *  the effective user ID of the caller does not match the  owner
+    ///    of  the  file,  the  caller does not have write access to the
+    ///    file, and the caller is not privileged (Linux: does not  have
+    ///    either  the  CAP_FOWNER  or the CAP_DAC_OVERRIDE capability);
+    ///    or,
+    /// *  the file is marked immutable (see chattr(1)).
+    AccessDenied,
+
+    /// The caller attempted to change one or both timestamps to a value
+    /// other than the current time, or to change one of the  timestamps
+    /// to the current time while leaving the other timestamp unchanged,
+    /// (i.e., times is not NULL, neither tv_nsec  field  is  UTIME_NOW,
+    /// and neither tv_nsec field is UTIME_OMIT) and either:
+    /// *  the  caller's  effective  user ID does not match the owner of
+    ///    file, and the caller is not privileged (Linux: does not  have
+    ///    the CAP_FOWNER capability); or,
+    /// *  the file is marked append-only or immutable (see chattr(1)).
+    PermissionDenied,
+
+    ReadOnlyFileSystem,
+} || UnexpectedError;
+
+pub fn futimens(fd: fd_t, times: *const [2]timespec) FutimensError!void {
+    if (native_os == .wasi and !builtin.link_libc) {
+        // TODO WASI encodes `wasi.fstflags` to signify magic values
+        // similar to UTIME_NOW and UTIME_OMIT. Currently, we ignore
+        // this here, but we should really handle it somehow.
+        const atim = times[0].toTimestamp();
+        const mtim = times[1].toTimestamp();
+        switch (wasi.fd_filestat_set_times(fd, atim, mtim, .{
+            .ATIM = true,
+            .MTIM = true,
+        })) {
+            .SUCCESS => return,
+            .ACCES => return error.AccessDenied,
+            .PERM => return error.PermissionDenied,
+            .BADF => unreachable, // always a race condition
+            .FAULT => unreachable,
+            .INVAL => unreachable,
+            .ROFS => return error.ReadOnlyFileSystem,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+
+    switch (errno(system.futimens(fd, times))) {
+        .SUCCESS => return,
+        .ACCES => return error.AccessDenied,
+        .PERM => return error.PermissionDenied,
+        .BADF => unreachable, // always a race condition
+        .FAULT => unreachable,
+        .INVAL => unreachable,
+        .ROFS => return error.ReadOnlyFileSystem,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub const GetHostNameError = error{PermissionDenied} || UnexpectedError;
+
+pub fn gethostname(name_buffer: *[HOST_NAME_MAX]u8) GetHostNameError![]u8 {
+    if (builtin.link_libc) {
+        switch (errno(system.gethostname(name_buffer, name_buffer.len))) {
+            .SUCCESS => return mem.sliceTo(name_buffer, 0),
+            .FAULT => unreachable,
+            .NAMETOOLONG => unreachable, // HOST_NAME_MAX prevents this
+            .PERM => return error.PermissionDenied,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+    if (native_os == .linux) {
+        const uts = uname();
+        const hostname = mem.sliceTo(&uts.nodename, 0);
+        const result = name_buffer[0..hostname.len];
+        @memcpy(result, hostname);
+        return result;
+    }
+
+    @compileError("TODO implement gethostname for this OS");
+}
+
+pub fn uname() utsname {
+    var uts: utsname = undefined;
+    switch (errno(system.uname(&uts))) {
+        .SUCCESS => return uts,
+        .FAULT => unreachable,
+        else => unreachable,
+    }
+}
+
+pub fn res_mkquery(
+    op: u4,
+    dname: []const u8,
+    class: u8,
+    ty: u8,
+    data: []const u8,
+    newrr: ?[*]const u8,
+    buf: []u8,
+) usize {
+    _ = data;
+    _ = newrr;
+    // This implementation is ported from musl libc.
+    // A more idiomatic "ziggy" implementation would be welcome.
+    var name = dname;
+    if (mem.endsWith(u8, name, ".")) name.len -= 1;
+    assert(name.len <= 253);
+    const n = 17 + name.len + @intFromBool(name.len != 0);
+
+    // Construct query template - ID will be filled later
+    var q: [280]u8 = undefined;
+    @memset(q[0..n], 0);
+    q[2] = @as(u8, op) * 8 + 1;
+    q[5] = 1;
+    @memcpy(q[13..][0..name.len], name);
+    var i: usize = 13;
+    var j: usize = undefined;
+    while (q[i] != 0) : (i = j + 1) {
+        j = i;
+        while (q[j] != 0 and q[j] != '.') : (j += 1) {}
+        // TODO determine the circumstances for this and whether or
+        // not this should be an error.
+        if (j - i - 1 > 62) unreachable;
+        q[i - 1] = @intCast(j - i);
+    }
+    q[i + 1] = ty;
+    q[i + 3] = class;
+
+    // Make a reasonably unpredictable id
+    var ts: timespec = undefined;
+    clock_gettime(CLOCK.REALTIME, &ts) catch {};
+    const UInt = std.meta.Int(.unsigned, @bitSizeOf(@TypeOf(ts.tv_nsec)));
+    const unsec: UInt = @bitCast(ts.tv_nsec);
+    const id: u32 = @truncate(unsec + unsec / 65536);
+    q[0] = @truncate(id / 256);
+    q[1] = @truncate(id);
+
+    @memcpy(buf[0..n], q[0..n]);
+    return n;
+}
+
+pub const SendError = error{
+    /// (For UNIX domain sockets, which are identified by pathname) Write permission is  denied
+    /// on  the destination socket file, or search permission is denied for one of the
+    /// directories the path prefix.  (See path_resolution(7).)
+    /// (For UDP sockets) An attempt was made to send to a network/broadcast address as  though
+    /// it was a unicast address.
+    AccessDenied,
+
+    /// The socket is marked nonblocking and the requested operation would block, and
+    /// there is no global event loop configured.
+    /// It's also possible to get this error under the following condition:
+    /// (Internet  domain datagram sockets) The socket referred to by sockfd had not previously
+    /// been bound to an address and, upon attempting to bind it to an ephemeral port,  it  was
+    /// determined that all port numbers in the ephemeral port range are currently in use.  See
+    /// the discussion of /proc/sys/net/ipv4/ip_local_port_range in ip(7).
+    WouldBlock,
+
+    /// Another Fast Open is already in progress.
+    FastOpenAlreadyInProgress,
+
+    /// Connection reset by peer.
+    ConnectionResetByPeer,
+
+    /// The  socket  type requires that message be sent atomically, and the size of the message
+    /// to be sent made this impossible. The message is not transmitted.
+    MessageTooBig,
+
+    /// The output queue for a network interface was full.  This generally indicates  that  the
+    /// interface  has  stopped sending, but may be caused by transient congestion.  (Normally,
+    /// this does not occur in Linux.  Packets are just silently dropped when  a  device  queue
+    /// overflows.)
+    /// This is also caused when there is not enough kernel memory available.
+    SystemResources,
+
+    /// The  local  end  has been shut down on a connection oriented socket.  In this case, the
+    /// process will also receive a SIGPIPE unless MSG.NOSIGNAL is set.
+    BrokenPipe,
+
+    FileDescriptorNotASocket,
+
+    /// Network is unreachable.
+    NetworkUnreachable,
+
+    /// The local network interface used to reach the destination is down.
+    NetworkSubsystemFailed,
+} || UnexpectedError;
+
+pub const SendMsgError = SendError || error{
+    /// The passed address didn't have the correct address family in its sa_family field.
+    AddressFamilyNotSupported,
+
+    /// Returned when socket is AF.UNIX and the given path has a symlink loop.
+    SymLinkLoop,
+
+    /// Returned when socket is AF.UNIX and the given path length exceeds `max_path_bytes` bytes.
+    NameTooLong,
+
+    /// Returned when socket is AF.UNIX and the given path does not point to an existing file.
+    FileNotFound,
+    NotDir,
+
+    /// The socket is not connected (connection-oriented sockets only).
+    SocketNotConnected,
+    AddressNotAvailable,
+};
+
+pub fn sendmsg(
+    /// The file descriptor of the sending socket.
+    sockfd: socket_t,
+    /// Message header and iovecs
+    msg: *const msghdr_const,
+    flags: u32,
+) SendMsgError!usize {
+    while (true) {
+        const rc = system.sendmsg(sockfd, msg, flags);
+        if (native_os == .windows) {
+            if (rc == windows.ws2_32.SOCKET_ERROR) {
+                switch (windows.ws2_32.WSAGetLastError()) {
+                    .WSAEACCES => return error.AccessDenied,
+                    .WSAEADDRNOTAVAIL => return error.AddressNotAvailable,
+                    .WSAECONNRESET => return error.ConnectionResetByPeer,
+                    .WSAEMSGSIZE => return error.MessageTooBig,
+                    .WSAENOBUFS => return error.SystemResources,
+                    .WSAENOTSOCK => return error.FileDescriptorNotASocket,
+                    .WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported,
+                    .WSAEDESTADDRREQ => unreachable, // A destination address is required.
+                    .WSAEFAULT => unreachable, // The lpBuffers, lpTo, lpOverlapped, lpNumberOfBytesSent, or lpCompletionRoutine parameters are not part of the user address space, or the lpTo parameter is too small.
+                    .WSAEHOSTUNREACH => return error.NetworkUnreachable,
+                    // TODO: WSAEINPROGRESS, WSAEINTR
+                    .WSAEINVAL => unreachable,
+                    .WSAENETDOWN => return error.NetworkSubsystemFailed,
+                    .WSAENETRESET => return error.ConnectionResetByPeer,
+                    .WSAENETUNREACH => return error.NetworkUnreachable,
+                    .WSAENOTCONN => return error.SocketNotConnected,
+                    .WSAESHUTDOWN => unreachable, // The socket has been shut down; it is not possible to WSASendTo on a socket after shutdown has been invoked with how set to SD_SEND or SD_BOTH.
+                    .WSAEWOULDBLOCK => return error.WouldBlock,
+                    .WSANOTINITIALISED => unreachable, // A successful WSAStartup call must occur before using this function.
+                    else => |err| return windows.unexpectedWSAError(err),
+                }
+            } else {
+                return @intCast(rc);
+            }
+        } else {
+            switch (errno(rc)) {
+                .SUCCESS => return @intCast(rc),
+
+                .ACCES => return error.AccessDenied,
+                .AGAIN => return error.WouldBlock,
+                .ALREADY => return error.FastOpenAlreadyInProgress,
+                .BADF => unreachable, // always a race condition
+                .CONNRESET => return error.ConnectionResetByPeer,
+                .DESTADDRREQ => unreachable, // The socket is not connection-mode, and no peer address is set.
+                .FAULT => unreachable, // An invalid user space address was specified for an argument.
+                .INTR => continue,
+                .INVAL => unreachable, // Invalid argument passed.
+                .ISCONN => unreachable, // connection-mode socket was connected already but a recipient was specified
+                .MSGSIZE => return error.MessageTooBig,
+                .NOBUFS => return error.SystemResources,
+                .NOMEM => return error.SystemResources,
+                .NOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
+                .OPNOTSUPP => unreachable, // Some bit in the flags argument is inappropriate for the socket type.
+                .PIPE => return error.BrokenPipe,
+                .AFNOSUPPORT => return error.AddressFamilyNotSupported,
+                .LOOP => return error.SymLinkLoop,
+                .NAMETOOLONG => return error.NameTooLong,
+                .NOENT => return error.FileNotFound,
+                .NOTDIR => return error.NotDir,
+                .HOSTUNREACH => return error.NetworkUnreachable,
+                .NETUNREACH => return error.NetworkUnreachable,
+                .NOTCONN => return error.SocketNotConnected,
+                .NETDOWN => return error.NetworkSubsystemFailed,
+                else => |err| return unexpectedErrno(err),
+            }
+        }
+    }
+}
+
+pub const SendToError = SendMsgError || error{
+    /// The destination address is not reachable by the bound address.
+    UnreachableAddress,
+};
+
+/// Transmit a message to another socket.
+///
+/// The `sendto` call may be used only when the socket is in a connected state (so that the intended
+/// recipient  is  known). The  following call
+///
+///     send(sockfd, buf, len, flags);
+///
+/// is equivalent to
+///
+///     sendto(sockfd, buf, len, flags, NULL, 0);
+///
+/// If  sendto()  is used on a connection-mode (`SOCK.STREAM`, `SOCK.SEQPACKET`) socket, the arguments
+/// `dest_addr` and `addrlen` are asserted to be `null` and `0` respectively, and asserted
+/// that the socket was actually connected.
+/// Otherwise, the address of the target is given by `dest_addr` with `addrlen` specifying  its  size.
+///
+/// If the message is too long to pass atomically through the underlying protocol,
+/// `SendError.MessageTooBig` is returned, and the message is not transmitted.
+///
+/// There is no  indication  of  failure  to  deliver.
+///
+/// When the message does not fit into the send buffer of  the  socket,  `sendto`  normally  blocks,
+/// unless  the socket has been placed in nonblocking I/O mode.  In nonblocking mode it would fail
+/// with `SendError.WouldBlock`.  The `select` call may be used  to  determine when it is
+/// possible to send more data.
+pub fn sendto(
+    /// The file descriptor of the sending socket.
+    sockfd: socket_t,
+    /// Message to send.
+    buf: []const u8,
+    flags: u32,
+    dest_addr: ?*const sockaddr,
+    addrlen: socklen_t,
+) SendToError!usize {
+    if (native_os == .windows) {
+        switch (windows.sendto(sockfd, buf.ptr, buf.len, flags, dest_addr, addrlen)) {
+            windows.ws2_32.SOCKET_ERROR => switch (windows.ws2_32.WSAGetLastError()) {
+                .WSAEACCES => return error.AccessDenied,
+                .WSAEADDRNOTAVAIL => return error.AddressNotAvailable,
+                .WSAECONNRESET => return error.ConnectionResetByPeer,
+                .WSAEMSGSIZE => return error.MessageTooBig,
+                .WSAENOBUFS => return error.SystemResources,
+                .WSAENOTSOCK => return error.FileDescriptorNotASocket,
+                .WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported,
+                .WSAEDESTADDRREQ => unreachable, // A destination address is required.
+                .WSAEFAULT => unreachable, // The lpBuffers, lpTo, lpOverlapped, lpNumberOfBytesSent, or lpCompletionRoutine parameters are not part of the user address space, or the lpTo parameter is too small.
+                .WSAEHOSTUNREACH => return error.NetworkUnreachable,
+                // TODO: WSAEINPROGRESS, WSAEINTR
+                .WSAEINVAL => unreachable,
+                .WSAENETDOWN => return error.NetworkSubsystemFailed,
+                .WSAENETRESET => return error.ConnectionResetByPeer,
+                .WSAENETUNREACH => return error.NetworkUnreachable,
+                .WSAENOTCONN => return error.SocketNotConnected,
+                .WSAESHUTDOWN => unreachable, // The socket has been shut down; it is not possible to WSASendTo on a socket after shutdown has been invoked with how set to SD_SEND or SD_BOTH.
+                .WSAEWOULDBLOCK => return error.WouldBlock,
+                .WSANOTINITIALISED => unreachable, // A successful WSAStartup call must occur before using this function.
+                else => |err| return windows.unexpectedWSAError(err),
+            },
+            else => |rc| return @intCast(rc),
+        }
+    }
+    while (true) {
+        const rc = system.sendto(sockfd, buf.ptr, buf.len, flags, dest_addr, addrlen);
+        switch (errno(rc)) {
+            .SUCCESS => return @intCast(rc),
+
+            .ACCES => return error.AccessDenied,
+            .AGAIN => return error.WouldBlock,
+            .ALREADY => return error.FastOpenAlreadyInProgress,
+            .BADF => unreachable, // always a race condition
+            .CONNRESET => return error.ConnectionResetByPeer,
+            .DESTADDRREQ => unreachable, // The socket is not connection-mode, and no peer address is set.
+            .FAULT => unreachable, // An invalid user space address was specified for an argument.
+            .INTR => continue,
+            .INVAL => return error.UnreachableAddress,
+            .ISCONN => unreachable, // connection-mode socket was connected already but a recipient was specified
+            .MSGSIZE => return error.MessageTooBig,
+            .NOBUFS => return error.SystemResources,
+            .NOMEM => return error.SystemResources,
+            .NOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
+            .OPNOTSUPP => unreachable, // Some bit in the flags argument is inappropriate for the socket type.
+            .PIPE => return error.BrokenPipe,
+            .AFNOSUPPORT => return error.AddressFamilyNotSupported,
+            .LOOP => return error.SymLinkLoop,
+            .NAMETOOLONG => return error.NameTooLong,
+            .NOENT => return error.FileNotFound,
+            .NOTDIR => return error.NotDir,
+            .HOSTUNREACH => return error.NetworkUnreachable,
+            .NETUNREACH => return error.NetworkUnreachable,
+            .NOTCONN => return error.SocketNotConnected,
+            .NETDOWN => return error.NetworkSubsystemFailed,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+/// Transmit a message to another socket.
+///
+/// The `send` call may be used only when the socket is in a connected state (so that the intended
+/// recipient  is  known).   The  only  difference  between `send` and `write` is the presence of
+/// flags.  With a zero flags argument, `send` is equivalent to  `write`.   Also,  the  following
+/// call
+///
+///     send(sockfd, buf, len, flags);
+///
+/// is equivalent to
+///
+///     sendto(sockfd, buf, len, flags, NULL, 0);
+///
+/// There is no  indication  of  failure  to  deliver.
+///
+/// When the message does not fit into the send buffer of  the  socket,  `send`  normally  blocks,
+/// unless  the socket has been placed in nonblocking I/O mode.  In nonblocking mode it would fail
+/// with `SendError.WouldBlock`.  The `select` call may be used  to  determine when it is
+/// possible to send more data.
+pub fn send(
+    /// The file descriptor of the sending socket.
+    sockfd: socket_t,
+    buf: []const u8,
+    flags: u32,
+) SendError!usize {
+    return sendto(sockfd, buf, flags, null, 0) catch |err| switch (err) {
+        error.AddressFamilyNotSupported => unreachable,
+        error.SymLinkLoop => unreachable,
+        error.NameTooLong => unreachable,
+        error.FileNotFound => unreachable,
+        error.NotDir => unreachable,
+        error.NetworkUnreachable => unreachable,
+        error.AddressNotAvailable => unreachable,
+        error.SocketNotConnected => unreachable,
+        error.UnreachableAddress => unreachable,
+        else => |e| return e,
+    };
+}
+
+pub const SendFileError = PReadError || WriteError || SendError;
+
+/// Transfer data between file descriptors, with optional headers and trailers.
+///
+/// Returns the number of bytes written, which can be zero.
+///
+/// The `sendfile` call copies `in_len` bytes from one file descriptor to another. When possible,
+/// this is done within the operating system kernel, which can provide better performance
+/// characteristics than transferring data from kernel to user space and back, such as with
+/// `read` and `write` calls. When `in_len` is `0`, it means to copy until the end of the input file has been
+/// reached. Note, however, that partial writes are still possible in this case.
+///
+/// `in_fd` must be a file descriptor opened for reading, and `out_fd` must be a file descriptor
+/// opened for writing. They may be any kind of file descriptor; however, if `in_fd` is not a regular
+/// file system file, it may cause this function to fall back to calling `read` and `write`, in which case
+/// atomicity guarantees no longer apply.
+///
+/// Copying begins reading at `in_offset`. The input file descriptor seek position is ignored and not updated.
+/// If the output file descriptor has a seek position, it is updated as bytes are written. When
+/// `in_offset` is past the end of the input file, it successfully reads 0 bytes.
+///
+/// `flags` has different meanings per operating system; refer to the respective man pages.
+///
+/// These systems support atomically sending everything, including headers and trailers:
+/// * macOS
+/// * FreeBSD
+///
+/// These systems support in-kernel data copying, but headers and trailers are not sent atomically:
+/// * Linux
+///
+/// Other systems fall back to calling `read` / `write`.
+///
+/// Linux has a limit on how many bytes may be transferred in one `sendfile` call, which is `0x7ffff000`
+/// on both 64-bit and 32-bit systems. This is due to using a signed C int as the return value, as
+/// well as stuffing the errno codes into the last `4096` values. This is noted on the `sendfile` man page.
+/// The limit on Darwin is `0x7fffffff`, trying to write more than that returns EINVAL.
+/// The corresponding POSIX limit on this is `maxInt(isize)`.
+pub fn sendfile(
+    out_fd: fd_t,
+    in_fd: fd_t,
+    in_offset: u64,
+    in_len: u64,
+    headers: []const iovec_const,
+    trailers: []const iovec_const,
+    flags: u32,
+) SendFileError!usize {
+    var header_done = false;
+    var total_written: usize = 0;
+
+    // Prevents EOVERFLOW.
+    const size_t = std.meta.Int(.unsigned, @typeInfo(usize).Int.bits - 1);
+    const max_count = switch (native_os) {
+        .linux => 0x7ffff000,
+        .macos, .ios, .watchos, .tvos => maxInt(i32),
+        else => maxInt(size_t),
+    };
+
+    switch (native_os) {
+        .linux => sf: {
+            // sendfile() first appeared in Linux 2.2, glibc 2.1.
+            const call_sf = comptime if (builtin.link_libc)
+                std.c.versionCheck(.{ .major = 2, .minor = 1, .patch = 0 })
+            else
+                builtin.os.version_range.linux.range.max.order(.{ .major = 2, .minor = 2, .patch = 0 }) != .lt;
+            if (!call_sf) break :sf;
+
+            if (headers.len != 0) {
+                const amt = try writev(out_fd, headers);
+                total_written += amt;
+                if (amt < count_iovec_bytes(headers)) return total_written;
+                header_done = true;
+            }
+
+            // Here we match BSD behavior, making a zero count value send as many bytes as possible.
+            const adjusted_count = if (in_len == 0) max_count else @min(in_len, max_count);
+
+            const sendfile_sym = if (lfs64_abi) system.sendfile64 else system.sendfile;
+            while (true) {
+                var offset: off_t = @bitCast(in_offset);
+                const rc = sendfile_sym(out_fd, in_fd, &offset, adjusted_count);
+                switch (errno(rc)) {
+                    .SUCCESS => {
+                        const amt: usize = @bitCast(rc);
+                        total_written += amt;
+                        if (in_len == 0 and amt == 0) {
+                            // We have detected EOF from `in_fd`.
+                            break;
+                        } else if (amt < in_len) {
+                            return total_written;
+                        } else {
+                            break;
+                        }
+                    },
+
+                    .BADF => unreachable, // Always a race condition.
+                    .FAULT => unreachable, // Segmentation fault.
+                    .OVERFLOW => unreachable, // We avoid passing too large of a `count`.
+                    .NOTCONN => return error.BrokenPipe, // `out_fd` is an unconnected socket
+
+                    .INVAL, .NOSYS => {
+                        // EINVAL could be any of the following situations:
+                        // * Descriptor is not valid or locked
+                        // * an mmap(2)-like operation is  not  available  for in_fd
+                        // * count is negative
+                        // * out_fd has the APPEND flag set
+                        // Because of the "mmap(2)-like operation" possibility, we fall back to doing read/write
+                        // manually, the same as ENOSYS.
+                        break :sf;
+                    },
+                    .AGAIN => return error.WouldBlock,
+                    .IO => return error.InputOutput,
+                    .PIPE => return error.BrokenPipe,
+                    .NOMEM => return error.SystemResources,
+                    .NXIO => return error.Unseekable,
+                    .SPIPE => return error.Unseekable,
+                    else => |err| {
+                        unexpectedErrno(err) catch {};
+                        break :sf;
+                    },
+                }
+            }
+
+            if (trailers.len != 0) {
+                total_written += try writev(out_fd, trailers);
+            }
+
+            return total_written;
+        },
+        .freebsd => sf: {
+            var hdtr_data: std.c.sf_hdtr = undefined;
+            var hdtr: ?*std.c.sf_hdtr = null;
+            if (headers.len != 0 or trailers.len != 0) {
+                // Here we carefully avoid `@intCast` by returning partial writes when
+                // too many io vectors are provided.
+                const hdr_cnt = cast(u31, headers.len) orelse maxInt(u31);
+                if (headers.len > hdr_cnt) return writev(out_fd, headers);
+
+                const trl_cnt = cast(u31, trailers.len) orelse maxInt(u31);
+
+                hdtr_data = std.c.sf_hdtr{
+                    .headers = headers.ptr,
+                    .hdr_cnt = hdr_cnt,
+                    .trailers = trailers.ptr,
+                    .trl_cnt = trl_cnt,
+                };
+                hdtr = &hdtr_data;
+            }
+
+            while (true) {
+                var sbytes: off_t = undefined;
+                const err = errno(system.sendfile(in_fd, out_fd, @bitCast(in_offset), @min(in_len, max_count), hdtr, &sbytes, flags));
+                const amt: usize = @bitCast(sbytes);
+                switch (err) {
+                    .SUCCESS => return amt,
+
+                    .BADF => unreachable, // Always a race condition.
+                    .FAULT => unreachable, // Segmentation fault.
+                    .NOTCONN => return error.BrokenPipe, // `out_fd` is an unconnected socket
+
+                    .INVAL, .OPNOTSUPP, .NOTSOCK, .NOSYS => {
+                        // EINVAL could be any of the following situations:
+                        // * The fd argument is not a regular file.
+                        // * The s argument is not a SOCK.STREAM type socket.
+                        // * The offset argument is negative.
+                        // Because of some of these possibilities, we fall back to doing read/write
+                        // manually, the same as ENOSYS.
+                        break :sf;
+                    },
+
+                    .INTR => if (amt != 0) return amt else continue,
+
+                    .AGAIN => if (amt != 0) {
+                        return amt;
+                    } else {
+                        return error.WouldBlock;
+                    },
+
+                    .BUSY => if (amt != 0) {
+                        return amt;
+                    } else {
+                        return error.WouldBlock;
+                    },
+
+                    .IO => return error.InputOutput,
+                    .NOBUFS => return error.SystemResources,
+                    .PIPE => return error.BrokenPipe,
+
+                    else => {
+                        unexpectedErrno(err) catch {};
+                        if (amt != 0) {
+                            return amt;
+                        } else {
+                            break :sf;
+                        }
+                    },
+                }
+            }
+        },
+        .macos, .ios, .tvos, .watchos => sf: {
+            var hdtr_data: std.c.sf_hdtr = undefined;
+            var hdtr: ?*std.c.sf_hdtr = null;
+            if (headers.len != 0 or trailers.len != 0) {
+                // Here we carefully avoid `@intCast` by returning partial writes when
+                // too many io vectors are provided.
+                const hdr_cnt = cast(u31, headers.len) orelse maxInt(u31);
+                if (headers.len > hdr_cnt) return writev(out_fd, headers);
+
+                const trl_cnt = cast(u31, trailers.len) orelse maxInt(u31);
+
+                hdtr_data = std.c.sf_hdtr{
+                    .headers = headers.ptr,
+                    .hdr_cnt = hdr_cnt,
+                    .trailers = trailers.ptr,
+                    .trl_cnt = trl_cnt,
+                };
+                hdtr = &hdtr_data;
+            }
+
+            while (true) {
+                var sbytes: off_t = @min(in_len, max_count);
+                const err = errno(system.sendfile(in_fd, out_fd, @bitCast(in_offset), &sbytes, hdtr, flags));
+                const amt: usize = @bitCast(sbytes);
+                switch (err) {
+                    .SUCCESS => return amt,
+
+                    .BADF => unreachable, // Always a race condition.
+                    .FAULT => unreachable, // Segmentation fault.
+                    .INVAL => unreachable,
+                    .NOTCONN => return error.BrokenPipe, // `out_fd` is an unconnected socket
+
+                    .OPNOTSUPP, .NOTSOCK, .NOSYS => break :sf,
+
+                    .INTR => if (amt != 0) return amt else continue,
+
+                    .AGAIN => if (amt != 0) {
+                        return amt;
+                    } else {
+                        return error.WouldBlock;
+                    },
+
+                    .IO => return error.InputOutput,
+                    .PIPE => return error.BrokenPipe,
+
+                    else => {
+                        unexpectedErrno(err) catch {};
+                        if (amt != 0) {
+                            return amt;
+                        } else {
+                            break :sf;
+                        }
+                    },
+                }
+            }
+        },
+        else => {}, // fall back to read/write
+    }
+
+    if (headers.len != 0 and !header_done) {
+        const amt = try writev(out_fd, headers);
+        total_written += amt;
+        if (amt < count_iovec_bytes(headers)) return total_written;
+    }
+
+    rw: {
+        var buf: [8 * 4096]u8 = undefined;
+        // Here we match BSD behavior, making a zero count value send as many bytes as possible.
+        const adjusted_count = if (in_len == 0) buf.len else @min(buf.len, in_len);
+        const amt_read = try pread(in_fd, buf[0..adjusted_count], in_offset);
+        if (amt_read == 0) {
+            if (in_len == 0) {
+                // We have detected EOF from `in_fd`.
+                break :rw;
+            } else {
+                return total_written;
+            }
+        }
+        const amt_written = try write(out_fd, buf[0..amt_read]);
+        total_written += amt_written;
+        if (amt_written < in_len or in_len == 0) return total_written;
+    }
+
+    if (trailers.len != 0) {
+        total_written += try writev(out_fd, trailers);
+    }
+
+    return total_written;
+}
+
+fn count_iovec_bytes(iovs: []const iovec_const) usize {
+    var count: usize = 0;
+    for (iovs) |iov| {
+        count += iov.iov_len;
+    }
+    return count;
+}
+
+pub const CopyFileRangeError = error{
+    FileTooBig,
+    InputOutput,
+    /// `fd_in` is not open for reading; or `fd_out` is not open  for  writing;
+    /// or the  `APPEND`  flag  is  set  for `fd_out`.
+    FilesOpenedWithWrongFlags,
+    IsDir,
+    OutOfMemory,
+    NoSpaceLeft,
+    Unseekable,
+    PermissionDenied,
+    SwapFile,
+    CorruptedData,
+} || PReadError || PWriteError || UnexpectedError;
+
+/// Transfer data between file descriptors at specified offsets.
+///
+/// Returns the number of bytes written, which can less than requested.
+///
+/// The `copy_file_range` call copies `len` bytes from one file descriptor to another. When possible,
+/// this is done within the operating system kernel, which can provide better performance
+/// characteristics than transferring data from kernel to user space and back, such as with
+/// `pread` and `pwrite` calls.
+///
+/// `fd_in` must be a file descriptor opened for reading, and `fd_out` must be a file descriptor
+/// opened for writing. They may be any kind of file descriptor; however, if `fd_in` is not a regular
+/// file system file, it may cause this function to fall back to calling `pread` and `pwrite`, in which case
+/// atomicity guarantees no longer apply.
+///
+/// If `fd_in` and `fd_out` are the same, source and target ranges must not overlap.
+/// The file descriptor seek positions are ignored and not updated.
+/// When `off_in` is past the end of the input file, it successfully reads 0 bytes.
+///
+/// `flags` has different meanings per operating system; refer to the respective man pages.
+///
+/// These systems support in-kernel data copying:
+/// * Linux 4.5 (cross-filesystem 5.3)
+/// * FreeBSD 13.0
+///
+/// Other systems fall back to calling `pread` / `pwrite`.
+///
+/// Maximum offsets on Linux and FreeBSD are `maxInt(i64)`.
+pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len: usize, flags: u32) CopyFileRangeError!usize {
+    const global = struct {
+        var has_copy_file_range = true;
+    };
+
+    if ((comptime builtin.os.isAtLeast(.freebsd, .{ .major = 13, .minor = 0, .patch = 0 }) orelse false) or
+        ((comptime builtin.os.isAtLeast(.linux, .{ .major = 4, .minor = 5, .patch = 0 }) orelse false and
+        std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 })) and
+        @atomicLoad(bool, &global.has_copy_file_range, .monotonic)))
+    {
+        var off_in_copy: i64 = @bitCast(off_in);
+        var off_out_copy: i64 = @bitCast(off_out);
+
+        while (true) {
+            const rc = system.copy_file_range(fd_in, &off_in_copy, fd_out, &off_out_copy, len, flags);
+            if (native_os == .freebsd) {
+                switch (errno(rc)) {
+                    .SUCCESS => return @intCast(rc),
+                    .BADF => return error.FilesOpenedWithWrongFlags,
+                    .FBIG => return error.FileTooBig,
+                    .IO => return error.InputOutput,
+                    .ISDIR => return error.IsDir,
+                    .NOSPC => return error.NoSpaceLeft,
+                    .INVAL => break, // these may not be regular files, try fallback
+                    .INTEGRITY => return error.CorruptedData,
+                    .INTR => continue,
+                    else => |err| return unexpectedErrno(err),
+                }
+            } else { // assume linux
+                switch (errno(rc)) {
+                    .SUCCESS => return @intCast(rc),
+                    .BADF => return error.FilesOpenedWithWrongFlags,
+                    .FBIG => return error.FileTooBig,
+                    .IO => return error.InputOutput,
+                    .ISDIR => return error.IsDir,
+                    .NOSPC => return error.NoSpaceLeft,
+                    .INVAL => break, // these may not be regular files, try fallback
+                    .NOMEM => return error.OutOfMemory,
+                    .OVERFLOW => return error.Unseekable,
+                    .PERM => return error.PermissionDenied,
+                    .TXTBSY => return error.SwapFile,
+                    .XDEV => break, // support for cross-filesystem copy added in Linux 5.3, use fallback
+                    .NOSYS => {
+                        @atomicStore(bool, &global.has_copy_file_range, false, .monotonic);
+                        break;
+                    },
+                    else => |err| return unexpectedErrno(err),
+                }
+            }
+        }
+    }
+
+    var buf: [8 * 4096]u8 = undefined;
+    const amt_read = try pread(fd_in, buf[0..@min(buf.len, len)], off_in);
+    if (amt_read == 0) return 0;
+    return pwrite(fd_out, buf[0..amt_read], off_out);
+}
+
+pub const PollError = error{
+    /// The network subsystem has failed.
+    NetworkSubsystemFailed,
+
+    /// The kernel had no space to allocate file descriptor tables.
+    SystemResources,
+} || UnexpectedError;
+
+pub fn poll(fds: []pollfd, timeout: i32) PollError!usize {
+    while (true) {
+        const fds_count = cast(nfds_t, fds.len) orelse return error.SystemResources;
+        const rc = system.poll(fds.ptr, fds_count, timeout);
+        if (native_os == .windows) {
+            if (rc == windows.ws2_32.SOCKET_ERROR) {
+                switch (windows.ws2_32.WSAGetLastError()) {
+                    .WSANOTINITIALISED => unreachable,
+                    .WSAENETDOWN => return error.NetworkSubsystemFailed,
+                    .WSAENOBUFS => return error.SystemResources,
+                    // TODO: handle more errors
+                    else => |err| return windows.unexpectedWSAError(err),
+                }
+            } else {
+                return @intCast(rc);
+            }
+        } else {
+            switch (errno(rc)) {
+                .SUCCESS => return @intCast(rc),
+                .FAULT => unreachable,
+                .INTR => continue,
+                .INVAL => unreachable,
+                .NOMEM => return error.SystemResources,
+                else => |err| return unexpectedErrno(err),
+            }
+        }
+        unreachable;
+    }
+}
+
+pub const PPollError = error{
+    /// The operation was interrupted by a delivery of a signal before it could complete.
+    SignalInterrupt,
+
+    /// The kernel had no space to allocate file descriptor tables.
+    SystemResources,
+} || UnexpectedError;
+
+pub fn ppoll(fds: []pollfd, timeout: ?*const timespec, mask: ?*const sigset_t) PPollError!usize {
+    var ts: timespec = undefined;
+    var ts_ptr: ?*timespec = null;
+    if (timeout) |timeout_ns| {
+        ts_ptr = &ts;
+        ts = timeout_ns.*;
+    }
+    const fds_count = cast(nfds_t, fds.len) orelse return error.SystemResources;
+    const rc = system.ppoll(fds.ptr, fds_count, ts_ptr, mask);
+    switch (errno(rc)) {
+        .SUCCESS => return @intCast(rc),
+        .FAULT => unreachable,
+        .INTR => return error.SignalInterrupt,
+        .INVAL => unreachable,
+        .NOMEM => return error.SystemResources,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub const RecvFromError = error{
+    /// The socket is marked nonblocking and the requested operation would block, and
+    /// there is no global event loop configured.
+    WouldBlock,
+
+    /// A remote host refused to allow the network connection, typically because it is not
+    /// running the requested service.
+    ConnectionRefused,
+
+    /// Could not allocate kernel memory.
+    SystemResources,
+
+    ConnectionResetByPeer,
+    ConnectionTimedOut,
+
+    /// The socket has not been bound.
+    SocketNotBound,
+
+    /// The UDP message was too big for the buffer and part of it has been discarded
+    MessageTooBig,
+
+    /// The network subsystem has failed.
+    NetworkSubsystemFailed,
+
+    /// The socket is not connected (connection-oriented sockets only).
+    SocketNotConnected,
+} || UnexpectedError;
+
+pub fn recv(sock: socket_t, buf: []u8, flags: u32) RecvFromError!usize {
+    return recvfrom(sock, buf, flags, null, null);
+}
+
+/// If `sockfd` is opened in non blocking mode, the function will
+/// return error.WouldBlock when EAGAIN is received.
+pub fn recvfrom(
+    sockfd: socket_t,
+    buf: []u8,
+    flags: u32,
+    src_addr: ?*sockaddr,
+    addrlen: ?*socklen_t,
+) RecvFromError!usize {
+    while (true) {
+        const rc = system.recvfrom(sockfd, buf.ptr, buf.len, flags, src_addr, addrlen);
+        if (native_os == .windows) {
+            if (rc == windows.ws2_32.SOCKET_ERROR) {
+                switch (windows.ws2_32.WSAGetLastError()) {
+                    .WSANOTINITIALISED => unreachable,
+                    .WSAECONNRESET => return error.ConnectionResetByPeer,
+                    .WSAEINVAL => return error.SocketNotBound,
+                    .WSAEMSGSIZE => return error.MessageTooBig,
+                    .WSAENETDOWN => return error.NetworkSubsystemFailed,
+                    .WSAENOTCONN => return error.SocketNotConnected,
+                    .WSAEWOULDBLOCK => return error.WouldBlock,
+                    .WSAETIMEDOUT => return error.ConnectionTimedOut,
+                    // TODO: handle more errors
+                    else => |err| return windows.unexpectedWSAError(err),
+                }
+            } else {
+                return @intCast(rc);
+            }
+        } else {
+            switch (errno(rc)) {
+                .SUCCESS => return @intCast(rc),
+                .BADF => unreachable, // always a race condition
+                .FAULT => unreachable,
+                .INVAL => unreachable,
+                .NOTCONN => return error.SocketNotConnected,
+                .NOTSOCK => unreachable,
+                .INTR => continue,
+                .AGAIN => return error.WouldBlock,
+                .NOMEM => return error.SystemResources,
+                .CONNREFUSED => return error.ConnectionRefused,
+                .CONNRESET => return error.ConnectionResetByPeer,
+                .TIMEDOUT => return error.ConnectionTimedOut,
+                else => |err| return unexpectedErrno(err),
+            }
+        }
+    }
+}
+
+pub const DnExpandError = error{InvalidDnsPacket};
+
+pub fn dn_expand(
+    msg: []const u8,
+    comp_dn: []const u8,
+    exp_dn: []u8,
+) DnExpandError!usize {
+    // This implementation is ported from musl libc.
+    // A more idiomatic "ziggy" implementation would be welcome.
+    var p = comp_dn.ptr;
+    var len: usize = maxInt(usize);
+    const end = msg.ptr + msg.len;
+    if (p == end or exp_dn.len == 0) return error.InvalidDnsPacket;
+    var dest = exp_dn.ptr;
+    const dend = dest + @min(exp_dn.len, 254);
+    // detect reference loop using an iteration counter
+    var i: usize = 0;
+    while (i < msg.len) : (i += 2) {
+        // loop invariants: p<end, dest<dend
+        if ((p[0] & 0xc0) != 0) {
+            if (p + 1 == end) return error.InvalidDnsPacket;
+            const j = @as(usize, p[0] & 0x3f) << 8 | p[1];
+            if (len == maxInt(usize)) len = @intFromPtr(p) + 2 - @intFromPtr(comp_dn.ptr);
+            if (j >= msg.len) return error.InvalidDnsPacket;
+            p = msg.ptr + j;
+        } else if (p[0] != 0) {
+            if (dest != exp_dn.ptr) {
+                dest[0] = '.';
+                dest += 1;
+            }
+            var j = p[0];
+            p += 1;
+            if (j >= @intFromPtr(end) - @intFromPtr(p) or j >= @intFromPtr(dend) - @intFromPtr(dest)) {
+                return error.InvalidDnsPacket;
+            }
+            while (j != 0) {
+                j -= 1;
+                dest[0] = p[0];
+                dest += 1;
+                p += 1;
+            }
+        } else {
+            dest[0] = 0;
+            if (len == maxInt(usize)) len = @intFromPtr(p) + 1 - @intFromPtr(comp_dn.ptr);
+            return len;
+        }
+    }
+    return error.InvalidDnsPacket;
+}
+
+pub const SetSockOptError = error{
+    /// The socket is already connected, and a specified option cannot be set while the socket is connected.
+    AlreadyConnected,
+
+    /// The option is not supported by the protocol.
+    InvalidProtocolOption,
+
+    /// The send and receive timeout values are too big to fit into the timeout fields in the socket structure.
+    TimeoutTooBig,
+
+    /// Insufficient resources are available in the system to complete the call.
+    SystemResources,
+
+    // Setting the socket option requires more elevated permissions.
+    PermissionDenied,
+
+    NetworkSubsystemFailed,
+    FileDescriptorNotASocket,
+    SocketNotBound,
+    NoDevice,
+} || UnexpectedError;
+
+/// Set a socket's options.
+pub fn setsockopt(fd: socket_t, level: u32, optname: u32, opt: []const u8) SetSockOptError!void {
+    if (native_os == .windows) {
+        const rc = windows.ws2_32.setsockopt(fd, @intCast(level), @intCast(optname), opt.ptr, @intCast(opt.len));
+        if (rc == windows.ws2_32.SOCKET_ERROR) {
+            switch (windows.ws2_32.WSAGetLastError()) {
+                .WSANOTINITIALISED => unreachable,
+                .WSAENETDOWN => return error.NetworkSubsystemFailed,
+                .WSAEFAULT => unreachable,
+                .WSAENOTSOCK => return error.FileDescriptorNotASocket,
+                .WSAEINVAL => return error.SocketNotBound,
+                else => |err| return windows.unexpectedWSAError(err),
+            }
+        }
+        return;
+    } 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,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+pub const MemFdCreateError = error{
+    SystemFdQuotaExceeded,
+    ProcessFdQuotaExceeded,
+    OutOfMemory,
+    /// Either the name provided exceeded `NAME_MAX`, or invalid flags were passed.
+    NameTooLong,
+
+    /// memfd_create is available in Linux 3.17 and later. This error is returned
+    /// for older kernel versions.
+    SystemOutdated,
+} || UnexpectedError;
+
+pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t {
+    switch (native_os) {
+        .linux => {
+            // memfd_create is available only in glibc versions starting with 2.27.
+            const use_c = std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 });
+            const sys = if (use_c) std.c else linux;
+            const rc = sys.memfd_create(name, flags);
+            switch (errno(rc)) {
+                .SUCCESS => return @intCast(rc),
+                .FAULT => unreachable, // name has invalid memory
+                .INVAL => return error.NameTooLong, // or, program has a bug and flags are faulty
+                .NFILE => return error.SystemFdQuotaExceeded,
+                .MFILE => return error.ProcessFdQuotaExceeded,
+                .NOMEM => return error.OutOfMemory,
+                .NOSYS => return error.SystemOutdated,
+                else => |err| return unexpectedErrno(err),
+            }
+        },
+        .freebsd => {
+            if (comptime builtin.os.version_range.semver.max.order(.{ .major = 13, .minor = 0, .patch = 0 }) == .lt)
+                @compileError("memfd_create is unavailable on FreeBSD < 13.0");
+            const rc = system.memfd_create(name, flags);
+            switch (errno(rc)) {
+                .SUCCESS => return rc,
+                .BADF => unreachable, // name argument NULL
+                .INVAL => unreachable, // name too long or invalid/unsupported flags.
+                .MFILE => return error.ProcessFdQuotaExceeded,
+                .NFILE => return error.SystemFdQuotaExceeded,
+                .NOSYS => return error.SystemOutdated,
+                else => |err| return unexpectedErrno(err),
+            }
+        },
+        else => @compileError("target OS does not support memfd_create()"),
+    }
+}
+
+pub fn memfd_create(name: []const u8, flags: u32) MemFdCreateError!fd_t {
+    var buffer: [NAME_MAX - "memfd:".len - 1:0]u8 = undefined;
+    if (name.len > buffer.len) return error.NameTooLong;
+    @memcpy(buffer[0..name.len], name);
+    buffer[name.len] = 0;
+    return memfd_createZ(&buffer, flags);
+}
+
+pub fn getrusage(who: i32) rusage {
+    var result: rusage = undefined;
+    const rc = system.getrusage(who, &result);
+    switch (errno(rc)) {
+        .SUCCESS => return result,
+        .INVAL => unreachable,
+        .FAULT => unreachable,
+        else => unreachable,
+    }
+}
+
+pub const TIOCError = error{NotATerminal};
+
+pub const TermiosGetError = TIOCError || UnexpectedError;
+
+pub fn tcgetattr(handle: fd_t) TermiosGetError!termios {
+    while (true) {
+        var term: termios = undefined;
+        switch (errno(system.tcgetattr(handle, &term))) {
+            .SUCCESS => return term,
+            .INTR => continue,
+            .BADF => unreachable,
+            .NOTTY => return error.NotATerminal,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+pub const TermiosSetError = TermiosGetError || error{ProcessOrphaned};
+
+pub fn tcsetattr(handle: fd_t, optional_action: TCSA, termios_p: termios) TermiosSetError!void {
+    while (true) {
+        switch (errno(system.tcsetattr(handle, optional_action, &termios_p))) {
+            .SUCCESS => return,
+            .BADF => unreachable,
+            .INTR => continue,
+            .INVAL => unreachable,
+            .NOTTY => return error.NotATerminal,
+            .IO => return error.ProcessOrphaned,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+pub const TermioGetPgrpError = TIOCError || UnexpectedError;
+
+/// Returns the process group ID for the TTY associated with the given handle.
+pub fn tcgetpgrp(handle: fd_t) TermioGetPgrpError!pid_t {
+    while (true) {
+        var pgrp: pid_t = undefined;
+        switch (errno(system.tcgetpgrp(handle, &pgrp))) {
+            .SUCCESS => return pgrp,
+            .BADF => unreachable,
+            .INVAL => unreachable,
+            .INTR => continue,
+            .NOTTY => return error.NotATerminal,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+pub const TermioSetPgrpError = TermioGetPgrpError || error{NotAPgrpMember};
+
+/// Sets the controlling process group ID for given TTY.
+/// handle must be valid fd_t to a TTY associated with calling process.
+/// pgrp must be a valid process group, and the calling process must be a member
+/// of that group.
+pub fn tcsetpgrp(handle: fd_t, pgrp: pid_t) TermioSetPgrpError!void {
+    while (true) {
+        switch (errno(system.tcsetpgrp(handle, &pgrp))) {
+            .SUCCESS => return,
+            .BADF => unreachable,
+            .INVAL => unreachable,
+            .INTR => continue,
+            .NOTTY => return error.NotATerminal,
+            .PERM => return TermioSetPgrpError.NotAPgrpMember,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+pub fn signalfd(fd: fd_t, mask: *const sigset_t, flags: u32) !fd_t {
+    const rc = system.signalfd(fd, mask, flags);
+    switch (errno(rc)) {
+        .SUCCESS => return @intCast(rc),
+        .BADF, .INVAL => unreachable,
+        .NFILE => return error.SystemFdQuotaExceeded,
+        .NOMEM => return error.SystemResources,
+        .MFILE => return error.ProcessResources,
+        .NODEV => return error.InodeMountFail,
+        .NOSYS => return error.SystemOutdated,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub const SyncError = error{
+    InputOutput,
+    NoSpaceLeft,
+    DiskQuota,
+    AccessDenied,
+} || UnexpectedError;
+
+/// Write all pending file contents and metadata modifications to all filesystems.
+pub fn sync() void {
+    system.sync();
+}
+
+/// Write all pending file contents and metadata modifications to the filesystem which contains the specified file.
+pub fn syncfs(fd: fd_t) SyncError!void {
+    const rc = system.syncfs(fd);
+    switch (errno(rc)) {
+        .SUCCESS => return,
+        .BADF, .INVAL, .ROFS => unreachable,
+        .IO => return error.InputOutput,
+        .NOSPC => return error.NoSpaceLeft,
+        .DQUOT => return error.DiskQuota,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// Write all pending file contents and metadata modifications for the specified file descriptor to the underlying filesystem.
+pub fn fsync(fd: fd_t) SyncError!void {
+    if (native_os == .windows) {
+        if (windows.kernel32.FlushFileBuffers(fd) != 0)
+            return;
+        switch (windows.kernel32.GetLastError()) {
+            .SUCCESS => return,
+            .INVALID_HANDLE => unreachable,
+            .ACCESS_DENIED => return error.AccessDenied, // a sync was performed but the system couldn't update the access time
+            .UNEXP_NET_ERR => return error.InputOutput,
+            else => return error.InputOutput,
+        }
+    }
+    const rc = system.fsync(fd);
+    switch (errno(rc)) {
+        .SUCCESS => return,
+        .BADF, .INVAL, .ROFS => unreachable,
+        .IO => return error.InputOutput,
+        .NOSPC => return error.NoSpaceLeft,
+        .DQUOT => return error.DiskQuota,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+/// Write all pending file contents for the specified file descriptor to the underlying filesystem, but not necessarily the metadata.
+pub fn fdatasync(fd: fd_t) SyncError!void {
+    if (native_os == .windows) {
+        return fsync(fd) catch |err| switch (err) {
+            SyncError.AccessDenied => return, // fdatasync doesn't promise that the access time was synced
+            else => return err,
+        };
+    }
+    const rc = system.fdatasync(fd);
+    switch (errno(rc)) {
+        .SUCCESS => return,
+        .BADF, .INVAL, .ROFS => unreachable,
+        .IO => return error.InputOutput,
+        .NOSPC => return error.NoSpaceLeft,
+        .DQUOT => return error.DiskQuota,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub const PrctlError = error{
+    /// Can only occur with PR_SET_SECCOMP/SECCOMP_MODE_FILTER or
+    /// PR_SET_MM/PR_SET_MM_EXE_FILE
+    AccessDenied,
+    /// Can only occur with PR_SET_MM/PR_SET_MM_EXE_FILE
+    InvalidFileDescriptor,
+    InvalidAddress,
+    /// Can only occur with PR_SET_SPECULATION_CTRL, PR_MPX_ENABLE_MANAGEMENT,
+    /// or PR_MPX_DISABLE_MANAGEMENT
+    UnsupportedFeature,
+    /// Can only occur with PR_SET_FP_MODE
+    OperationNotSupported,
+    PermissionDenied,
+} || UnexpectedError;
+
+pub fn prctl(option: PR, args: anytype) PrctlError!u31 {
+    if (@typeInfo(@TypeOf(args)) != .Struct)
+        @compileError("Expected tuple or struct argument, found " ++ @typeName(@TypeOf(args)));
+    if (args.len > 4)
+        @compileError("prctl takes a maximum of 4 optional arguments");
+
+    var buf: [4]usize = undefined;
+    {
+        comptime var i = 0;
+        inline while (i < args.len) : (i += 1) buf[i] = args[i];
+    }
+
+    const rc = system.prctl(@intFromEnum(option), buf[0], buf[1], buf[2], buf[3]);
+    switch (errno(rc)) {
+        .SUCCESS => return @intCast(rc),
+        .ACCES => return error.AccessDenied,
+        .BADF => return error.InvalidFileDescriptor,
+        .FAULT => return error.InvalidAddress,
+        .INVAL => unreachable,
+        .NODEV, .NXIO => return error.UnsupportedFeature,
+        .OPNOTSUPP => return error.OperationNotSupported,
+        .PERM, .BUSY => return error.PermissionDenied,
+        .RANGE => unreachable,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub const GetrlimitError = UnexpectedError;
+
+pub fn getrlimit(resource: rlimit_resource) GetrlimitError!rlimit {
+    const getrlimit_sym = if (lfs64_abi) system.getrlimit64 else system.getrlimit;
+
+    var limits: rlimit = undefined;
+    switch (errno(getrlimit_sym(resource, &limits))) {
+        .SUCCESS => return limits,
+        .FAULT => unreachable, // bogus pointer
+        .INVAL => unreachable,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub const SetrlimitError = error{ PermissionDenied, LimitTooBig } || UnexpectedError;
+
+pub fn setrlimit(resource: rlimit_resource, limits: rlimit) SetrlimitError!void {
+    const setrlimit_sym = if (lfs64_abi) system.setrlimit64 else system.setrlimit;
+
+    switch (errno(setrlimit_sym(resource, &limits))) {
+        .SUCCESS => return,
+        .FAULT => unreachable, // bogus pointer
+        .INVAL => return error.LimitTooBig, // this could also mean "invalid resource", but that would be unreachable
+        .PERM => return error.PermissionDenied,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub const MincoreError = error{
+    /// A kernel resource was temporarily unavailable.
+    SystemResources,
+    /// vec points to an invalid address.
+    InvalidAddress,
+    /// addr is not page-aligned.
+    InvalidSyscall,
+    /// One of the following:
+    /// * length is greater than user space TASK_SIZE - addr
+    /// * addr + length contains unmapped memory
+    OutOfMemory,
+    /// The mincore syscall is not available on this version and configuration
+    /// of this UNIX-like kernel.
+    MincoreUnavailable,
+} || UnexpectedError;
+
+/// Determine whether pages are resident in memory.
+pub fn mincore(ptr: [*]align(mem.page_size) u8, length: usize, vec: [*]u8) MincoreError!void {
+    return switch (errno(system.mincore(ptr, length, vec))) {
+        .SUCCESS => {},
+        .AGAIN => error.SystemResources,
+        .FAULT => error.InvalidAddress,
+        .INVAL => error.InvalidSyscall,
+        .NOMEM => error.OutOfMemory,
+        .NOSYS => error.MincoreUnavailable,
+        else => |err| unexpectedErrno(err),
+    };
+}
+
+pub const MadviseError = error{
+    /// advice is MADV.REMOVE, but the specified address range is not a shared writable mapping.
+    AccessDenied,
+    /// advice is MADV.HWPOISON, but the caller does not have the CAP_SYS_ADMIN capability.
+    PermissionDenied,
+    /// A kernel resource was temporarily unavailable.
+    SystemResources,
+    /// One of the following:
+    /// * addr is not page-aligned or length is negative
+    /// * advice is not valid
+    /// * advice is MADV.DONTNEED or MADV.REMOVE and the specified address range
+    ///   includes locked, Huge TLB pages, or VM_PFNMAP pages.
+    /// * advice is MADV.MERGEABLE or MADV.UNMERGEABLE, but the kernel was not
+    ///   configured with CONFIG_KSM.
+    /// * advice is MADV.FREE or MADV.WIPEONFORK but the specified address range
+    ///   includes file, Huge TLB, MAP.SHARED, or VM_PFNMAP ranges.
+    InvalidSyscall,
+    /// (for MADV.WILLNEED) Paging in this area would exceed the process's
+    /// maximum resident set size.
+    WouldExceedMaximumResidentSetSize,
+    /// One of the following:
+    /// * (for MADV.WILLNEED) Not enough memory: paging in failed.
+    /// * Addresses in the specified range are not currently mapped, or
+    ///   are outside the address space of the process.
+    OutOfMemory,
+    /// The madvise syscall is not available on this version and configuration
+    /// of the Linux kernel.
+    MadviseUnavailable,
+    /// The operating system returned an undocumented error code.
+    Unexpected,
+};
+
+/// Give advice about use of memory.
+/// This syscall is optional and is sometimes configured to be disabled.
+pub fn madvise(ptr: [*]align(mem.page_size) u8, length: usize, advice: u32) MadviseError!void {
+    switch (errno(system.madvise(ptr, length, advice))) {
+        .SUCCESS => return,
+        .ACCES => return error.AccessDenied,
+        .AGAIN => return error.SystemResources,
+        .BADF => unreachable, // The map exists, but the area maps something that isn't a file.
+        .INVAL => return error.InvalidSyscall,
+        .IO => return error.WouldExceedMaximumResidentSetSize,
+        .NOMEM => return error.OutOfMemory,
+        .NOSYS => return error.MadviseUnavailable,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub const PerfEventOpenError = error{
+    /// Returned if the perf_event_attr size value is too small (smaller
+    /// than PERF_ATTR_SIZE_VER0), too big (larger than the page  size),
+    /// or  larger  than the kernel supports and the extra bytes are not
+    /// zero.  When E2BIG is returned, the perf_event_attr size field is
+    /// overwritten by the kernel to be the size of the structure it was
+    /// expecting.
+    TooBig,
+    /// Returned when the requested event requires CAP_SYS_ADMIN permisโ€
+    /// sions  (or a more permissive perf_event paranoid setting).  Some
+    /// common cases where an unprivileged process  may  encounter  this
+    /// error:  attaching  to a process owned by a different user; moniโ€
+    /// toring all processes on a given CPU (i.e.,  specifying  the  pid
+    /// argument  as  -1); and not setting exclude_kernel when the paraโ€
+    /// noid setting requires it.
+    /// Also:
+    /// Returned on many (but not all) architectures when an unsupported
+    /// exclude_hv,  exclude_idle,  exclude_user, or exclude_kernel setโ€
+    /// ting is specified.
+    /// It can also happen, as with EACCES, when the requested event reโ€
+    /// quires   CAP_SYS_ADMIN   permissions   (or   a  more  permissive
+    /// perf_event paranoid setting).  This includes  setting  a  breakโ€
+    /// point on a kernel address, and (since Linux 3.13) setting a kerโ€
+    /// nel function-trace tracepoint.
+    PermissionDenied,
+    /// Returned if another event already has exclusive  access  to  the
+    /// PMU.
+    DeviceBusy,
+    /// Each  opened  event uses one file descriptor.  If a large number
+    /// of events are opened, the per-process limit  on  the  number  of
+    /// open file descriptors will be reached, and no more events can be
+    /// created.
+    ProcessResources,
+    EventRequiresUnsupportedCpuFeature,
+    /// Returned if  you  try  to  add  more  breakpoint
+    /// events than supported by the hardware.
+    TooManyBreakpoints,
+    /// Returned  if PERF_SAMPLE_STACK_USER is set in sample_type and it
+    /// is not supported by hardware.
+    SampleStackNotSupported,
+    /// Returned if an event requiring a specific  hardware  feature  is
+    /// requested  but  there is no hardware support.  This includes reโ€
+    /// questing low-skid events if not supported, branch tracing if  it
+    /// is not available, sampling if no PMU interrupt is available, and
+    /// branch stacks for software events.
+    EventNotSupported,
+    /// Returned  if  PERF_SAMPLE_CALLCHAIN  is   requested   and   samโ€
+    /// ple_max_stack   is   larger   than   the  maximum  specified  in
+    /// /proc/sys/kernel/perf_event_max_stack.
+    SampleMaxStackOverflow,
+    /// Returned if attempting to attach to a process that does not  exist.
+    ProcessNotFound,
+} || UnexpectedError;
+
+pub fn perf_event_open(
+    attr: *linux.perf_event_attr,
+    pid: pid_t,
+    cpu: i32,
+    group_fd: fd_t,
+    flags: usize,
+) PerfEventOpenError!fd_t {
+    const rc = linux.perf_event_open(attr, pid, cpu, group_fd, flags);
+    switch (errno(rc)) {
+        .SUCCESS => return @intCast(rc),
+        .@"2BIG" => return error.TooBig,
+        .ACCES => return error.PermissionDenied,
+        .BADF => unreachable, // group_fd file descriptor is not valid.
+        .BUSY => return error.DeviceBusy,
+        .FAULT => unreachable, // Segmentation fault.
+        .INVAL => unreachable, // Bad attr settings.
+        .INTR => unreachable, // Mixed perf and ftrace handling for a uprobe.
+        .MFILE => return error.ProcessResources,
+        .NODEV => return error.EventRequiresUnsupportedCpuFeature,
+        .NOENT => unreachable, // Invalid type setting.
+        .NOSPC => return error.TooManyBreakpoints,
+        .NOSYS => return error.SampleStackNotSupported,
+        .OPNOTSUPP => return error.EventNotSupported,
+        .OVERFLOW => return error.SampleMaxStackOverflow,
+        .PERM => return error.PermissionDenied,
+        .SRCH => return error.ProcessNotFound,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub const TimerFdCreateError = error{
+    AccessDenied,
+    ProcessFdQuotaExceeded,
+    SystemFdQuotaExceeded,
+    NoDevice,
+    SystemResources,
+} || UnexpectedError;
+
+pub const TimerFdGetError = error{InvalidHandle} || UnexpectedError;
+pub const TimerFdSetError = TimerFdGetError || error{Canceled};
+
+pub fn timerfd_create(clokid: i32, flags: linux.TFD) TimerFdCreateError!fd_t {
+    const rc = linux.timerfd_create(clokid, flags);
+    return switch (errno(rc)) {
+        .SUCCESS => @intCast(rc),
+        .INVAL => unreachable,
+        .MFILE => return error.ProcessFdQuotaExceeded,
+        .NFILE => return error.SystemFdQuotaExceeded,
+        .NODEV => return error.NoDevice,
+        .NOMEM => return error.SystemResources,
+        .PERM => return error.AccessDenied,
+        else => |err| return unexpectedErrno(err),
+    };
+}
+
+pub fn timerfd_settime(
+    fd: i32,
+    flags: linux.TFD.TIMER,
+    new_value: *const linux.itimerspec,
+    old_value: ?*linux.itimerspec,
+) TimerFdSetError!void {
+    const rc = linux.timerfd_settime(fd, flags, new_value, old_value);
+    return switch (errno(rc)) {
+        .SUCCESS => {},
+        .BADF => error.InvalidHandle,
+        .FAULT => unreachable,
+        .INVAL => unreachable,
+        .CANCELED => error.Canceled,
+        else => |err| return unexpectedErrno(err),
+    };
+}
+
+pub fn timerfd_gettime(fd: i32) TimerFdGetError!linux.itimerspec {
+    var curr_value: linux.itimerspec = undefined;
+    const rc = linux.timerfd_gettime(fd, &curr_value);
+    return switch (errno(rc)) {
+        .SUCCESS => return curr_value,
+        .BADF => error.InvalidHandle,
+        .FAULT => unreachable,
+        .INVAL => unreachable,
+        else => |err| return unexpectedErrno(err),
+    };
+}
+
+pub const PtraceError = error{
+    DeviceBusy,
+    InputOutput,
+    ProcessNotFound,
+    PermissionDenied,
+} || UnexpectedError;
+
+pub fn ptrace(request: u32, pid: pid_t, addr: usize, signal: usize) PtraceError!void {
+    if (native_os == .windows or native_os == .wasi)
+        @compileError("Unsupported OS");
+
+    return switch (native_os) {
+        .linux => switch (errno(linux.ptrace(request, pid, addr, signal, 0))) {
+            .SUCCESS => {},
+            .SRCH => error.ProcessNotFound,
+            .FAULT => unreachable,
+            .INVAL => unreachable,
+            .IO => return error.InputOutput,
+            .PERM => error.PermissionDenied,
+            .BUSY => error.DeviceBusy,
+            else => |err| return unexpectedErrno(err),
+        },
+
+        .macos, .ios, .tvos, .watchos => switch (errno(std.c.ptrace(
+            @intCast(request),
+            pid,
+            @ptrFromInt(addr),
+            @intCast(signal),
+        ))) {
+            .SUCCESS => {},
+            .SRCH => error.ProcessNotFound,
+            .INVAL => unreachable,
+            .PERM => error.PermissionDenied,
+            .BUSY => error.DeviceBusy,
+            else => |err| return unexpectedErrno(err),
+        },
+
+        else => switch (errno(system.ptrace(request, pid, addr, signal))) {
+            .SUCCESS => {},
+            .SRCH => error.ProcessNotFound,
+            .INVAL => unreachable,
+            .PERM => error.PermissionDenied,
+            .BUSY => error.DeviceBusy,
+            else => |err| return unexpectedErrno(err),
+        },
+    };
+}
+
+pub const IoCtl_SIOCGIFINDEX_Error = error{
+    FileSystem,
+    InterfaceNotFound,
+} || UnexpectedError;
+
+pub fn ioctl_SIOCGIFINDEX(fd: fd_t, ifr: *ifreq) IoCtl_SIOCGIFINDEX_Error!void {
+    while (true) {
+        switch (errno(system.ioctl(fd, SIOCGIFINDEX, @intFromPtr(ifr)))) {
+            .SUCCESS => return,
+            .INVAL => unreachable, // Bad parameters.
+            .NOTTY => unreachable,
+            .NXIO => unreachable,
+            .BADF => unreachable, // Always a race condition.
+            .FAULT => unreachable, // Bad pointer parameter.
+            .INTR => continue,
+            .IO => return error.FileSystem,
+            .NODEV => return error.InterfaceNotFound,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+}
+
+const lfs64_abi = native_os == .linux and builtin.link_libc and builtin.abi.isGnu();
+
+/// Whether or not `error.Unexpected` will print its value and a stack trace.
+///
+/// If this happens the fix is to add the error code to the corresponding
+/// switch expression, possibly introduce a new error in the error set, and
+/// send a patch to Zig.
+pub const unexpected_error_tracing = builtin.zig_backend == .stage2_llvm and builtin.mode == .Debug;
+
+pub const UnexpectedError = error{
+    /// The Operating System returned an undocumented error code.
+    ///
+    /// This error is in theory not possible, but it would be better
+    /// to handle this error than to invoke undefined behavior.
+    ///
+    /// When this error code is observed, it usually means the Zig Standard
+    /// Library needs a small patch to add the error code to the error set for
+    /// the respective function.
+    Unexpected,
+};
+
+/// Call this when you made a syscall or something that sets errno
+/// and you get an unexpected error.
+pub fn unexpectedErrno(err: E) UnexpectedError {
+    if (unexpected_error_tracing) {
+        std.debug.print("unexpected errno: {d}\n", .{@intFromEnum(err)});
+        std.debug.dumpCurrentStackTrace(null);
+    }
+    return error.Unexpected;
+}
+
+/// Used to convert a slice to a null terminated slice on the stack.
+pub fn toPosixPath(file_path: []const u8) error{NameTooLong}![PATH_MAX - 1:0]u8 {
+    if (std.debug.runtime_safety) assert(mem.indexOfScalar(u8, file_path, 0) == null);
+    var path_with_null: [PATH_MAX - 1:0]u8 = undefined;
+    // >= rather than > to make room for the null byte
+    if (file_path.len >= PATH_MAX) return error.NameTooLong;
+    @memcpy(path_with_null[0..file_path.len], file_path);
+    path_with_null[file_path.len] = 0;
+    return path_with_null;
+}
lib/std/process.zig
@@ -1,6 +1,5 @@
 const std = @import("std.zig");
 const builtin = @import("builtin");
-const os = std.os;
 const fs = std.fs;
 const mem = std.mem;
 const math = std.math;
@@ -8,20 +7,27 @@ const Allocator = mem.Allocator;
 const assert = std.debug.assert;
 const testing = std.testing;
 const child_process = @import("child_process.zig");
+const native_os = builtin.os.tag;
+const posix = std.posix;
+const windows = std.os.windows;
 
 pub const Child = child_process.ChildProcess;
-pub const abort = os.abort;
-pub const exit = os.exit;
-pub const changeCurDir = os.chdir;
-pub const changeCurDirC = os.chdirC;
+pub const abort = posix.abort;
+pub const exit = posix.exit;
+pub const changeCurDir = posix.chdir;
+pub const changeCurDirC = posix.chdirC;
+
+pub const GetCwdError = posix.GetCwdError;
 
 /// The result is a slice of `out_buffer`, from index `0`.
 /// On Windows, the result is encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
 /// On other platforms, the result is an opaque sequence of bytes with no particular encoding.
 pub fn getCwd(out_buffer: []u8) ![]u8 {
-    return os.getcwd(out_buffer);
+    return posix.getcwd(out_buffer);
 }
 
+pub const GetCwdAllocError = Allocator.Error || posix.GetCwdError;
+
 /// Caller must free the returned memory.
 /// On Windows, the result is encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
 /// On other platforms, the result is an opaque sequence of bytes with no particular encoding.
@@ -34,7 +40,7 @@ pub fn getCwdAlloc(allocator: Allocator) ![]u8 {
 
     var current_buf: []u8 = &stack_buf;
     while (true) {
-        if (os.getcwd(current_buf)) |slice| {
+        if (posix.getcwd(current_buf)) |slice| {
             return allocator.dupe(u8, slice);
         } else |err| switch (err) {
             error.NameTooLong => {
@@ -51,7 +57,7 @@ pub fn getCwdAlloc(allocator: Allocator) ![]u8 {
 }
 
 test getCwdAlloc {
-    if (builtin.os.tag == .wasi) return error.SkipZigTest;
+    if (native_os == .wasi) return error.SkipZigTest;
 
     const cwd = try getCwdAlloc(testing.allocator);
     testing.allocator.free(cwd);
@@ -72,13 +78,13 @@ pub const EnvMap = struct {
     pub const EnvNameHashContext = struct {
         fn upcase(c: u21) u21 {
             if (c <= std.math.maxInt(u16))
-                return std.os.windows.ntdll.RtlUpcaseUnicodeChar(@as(u16, @intCast(c)));
+                return windows.ntdll.RtlUpcaseUnicodeChar(@as(u16, @intCast(c)));
             return c;
         }
 
         pub fn hash(self: @This(), s: []const u8) u64 {
             _ = self;
-            if (builtin.os.tag == .windows) {
+            if (native_os == .windows) {
                 var h = std.hash.Wyhash.init(0);
                 var it = std.unicode.Wtf8View.initUnchecked(s).iterator();
                 while (it.nextCodepoint()) |cp| {
@@ -96,7 +102,7 @@ pub const EnvMap = struct {
 
         pub fn eql(self: @This(), a: []const u8, b: []const u8) bool {
             _ = self;
-            if (builtin.os.tag == .windows) {
+            if (native_os == .windows) {
                 var it_a = std.unicode.Wtf8View.initUnchecked(a).iterator();
                 var it_b = std.unicode.Wtf8View.initUnchecked(b).iterator();
                 while (true) {
@@ -228,7 +234,7 @@ test "EnvMap" {
     try testing.expectEqual(@as(EnvMap.Size, 2), env.count());
 
     // case insensitivity on Windows only
-    if (builtin.os.tag == .windows) {
+    if (native_os == .windows) {
         try testing.expectEqualStrings("1", env.get("something_New_aNd_LONGER").?);
     } else {
         try testing.expect(null == env.get("something_New_aNd_LONGER"));
@@ -248,7 +254,7 @@ test "EnvMap" {
 
     try testing.expectEqual(@as(EnvMap.Size, 1), env.count());
 
-    if (builtin.os.tag == .windows) {
+    if (native_os == .windows) {
         // test Unicode case-insensitivity on Windows
         try env.put("ะšะ˜ะ ะธะปะปะ˜ะฆะ", "something else");
         try testing.expectEqualStrings("something else", env.get("ะบะธั€ะธะปะปะธั†ะฐ").?);
@@ -279,8 +285,8 @@ pub fn getEnvMap(allocator: Allocator) GetEnvMapError!EnvMap {
     var result = EnvMap.init(allocator);
     errdefer result.deinit();
 
-    if (builtin.os.tag == .windows) {
-        const ptr = os.windows.peb().ProcessParameters.Environment;
+    if (native_os == .windows) {
+        const ptr = windows.peb().ProcessParameters.Environment;
 
         var i: usize = 0;
         while (ptr[i] != 0) {
@@ -310,13 +316,13 @@ pub fn getEnvMap(allocator: Allocator) GetEnvMapError!EnvMap {
             try result.putMove(key, value);
         }
         return result;
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
+    } else if (native_os == .wasi and !builtin.link_libc) {
         var environ_count: usize = undefined;
         var environ_buf_size: usize = undefined;
 
-        const environ_sizes_get_ret = os.wasi.environ_sizes_get(&environ_count, &environ_buf_size);
+        const environ_sizes_get_ret = std.os.wasi.environ_sizes_get(&environ_count, &environ_buf_size);
         if (environ_sizes_get_ret != .SUCCESS) {
-            return os.unexpectedErrno(environ_sizes_get_ret);
+            return posix.unexpectedErrno(environ_sizes_get_ret);
         }
 
         if (environ_count == 0) {
@@ -328,9 +334,9 @@ pub fn getEnvMap(allocator: Allocator) GetEnvMapError!EnvMap {
         const environ_buf = try allocator.alloc(u8, environ_buf_size);
         defer allocator.free(environ_buf);
 
-        const environ_get_ret = os.wasi.environ_get(environ.ptr, environ_buf.ptr);
+        const environ_get_ret = std.os.wasi.environ_get(environ.ptr, environ_buf.ptr);
         if (environ_get_ret != .SUCCESS) {
-            return os.unexpectedErrno(environ_get_ret);
+            return posix.unexpectedErrno(environ_get_ret);
         }
 
         for (environ) |env| {
@@ -356,7 +362,7 @@ pub fn getEnvMap(allocator: Allocator) GetEnvMapError!EnvMap {
         }
         return result;
     } else {
-        for (os.environ) |line| {
+        for (std.os.environ) |line| {
             var line_i: usize = 0;
             while (line[line_i] != 0 and line[line_i] != '=') : (line_i += 1) {}
             const key = line[0..line_i];
@@ -391,37 +397,37 @@ pub const GetEnvVarOwnedError = error{
 /// On Windows, the value is encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
 /// On other platforms, the value is an opaque sequence of bytes with no particular encoding.
 pub fn getEnvVarOwned(allocator: Allocator, key: []const u8) GetEnvVarOwnedError![]u8 {
-    if (builtin.os.tag == .windows) {
+    if (native_os == .windows) {
         const result_w = blk: {
             var stack_alloc = std.heap.stackFallback(256 * @sizeOf(u16), allocator);
             const stack_allocator = stack_alloc.get();
             const key_w = try std.unicode.wtf8ToWtf16LeAllocZ(stack_allocator, key);
             defer stack_allocator.free(key_w);
 
-            break :blk std.os.getenvW(key_w) orelse return error.EnvironmentVariableNotFound;
+            break :blk getenvW(key_w) orelse return error.EnvironmentVariableNotFound;
         };
         // wtf16LeToWtf8Alloc can only fail with OutOfMemory
         return std.unicode.wtf16LeToWtf8Alloc(allocator, result_w);
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
+    } else if (native_os == .wasi and !builtin.link_libc) {
         var envmap = getEnvMap(allocator) catch return error.OutOfMemory;
         defer envmap.deinit();
         const val = envmap.get(key) orelse return error.EnvironmentVariableNotFound;
         return allocator.dupe(u8, val);
     } else {
-        const result = os.getenv(key) orelse return error.EnvironmentVariableNotFound;
+        const result = posix.getenv(key) orelse return error.EnvironmentVariableNotFound;
         return allocator.dupe(u8, result);
     }
 }
 
 /// On Windows, `key` must be valid UTF-8.
 pub fn hasEnvVarConstant(comptime key: []const u8) bool {
-    if (builtin.os.tag == .windows) {
+    if (native_os == .windows) {
         const key_w = comptime std.unicode.utf8ToUtf16LeStringLiteral(key);
-        return std.os.getenvW(key_w) != null;
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
+        return getenvW(key_w) != null;
+    } else if (native_os == .wasi and !builtin.link_libc) {
         @compileError("hasEnvVarConstant is not supported for WASI without libc");
     } else {
-        return os.getenv(key) != null;
+        return posix.getenv(key) != null;
     }
 }
 
@@ -436,19 +442,63 @@ pub const HasEnvVarError = error{
 /// On Windows, if `key` is not valid [WTF-8](https://simonsapin.github.io/wtf-8/),
 /// then `error.InvalidWtf8` is returned.
 pub fn hasEnvVar(allocator: Allocator, key: []const u8) HasEnvVarError!bool {
-    if (builtin.os.tag == .windows) {
+    if (native_os == .windows) {
         var stack_alloc = std.heap.stackFallback(256 * @sizeOf(u16), allocator);
         const stack_allocator = stack_alloc.get();
         const key_w = try std.unicode.wtf8ToWtf16LeAllocZ(stack_allocator, key);
         defer stack_allocator.free(key_w);
-        return std.os.getenvW(key_w) != null;
-    } else if (builtin.os.tag == .wasi and !builtin.link_libc) {
+        return getenvW(key_w) != null;
+    } else if (native_os == .wasi and !builtin.link_libc) {
         var envmap = getEnvMap(allocator) catch return error.OutOfMemory;
         defer envmap.deinit();
         return envmap.getPtr(key) != null;
     } else {
-        return os.getenv(key) != null;
+        return posix.getenv(key) != null;
+    }
+}
+
+/// Windows-only. Get an environment variable with a null-terminated, WTF-16 encoded name.
+///
+/// This function performs a Unicode-aware case-insensitive lookup using RtlEqualUnicodeString.
+///
+/// See also:
+/// * `std.posix.getenv`
+/// * `getEnvMap`
+/// * `getEnvVarOwned`
+/// * `hasEnvVarConstant`
+/// * `hasEnvVar`
+pub fn getenvW(key: [*:0]const u16) ?[:0]const u16 {
+    if (native_os != .windows) {
+        @compileError("Windows-only");
+    }
+    const key_slice = mem.sliceTo(key, 0);
+    const ptr = windows.peb().ProcessParameters.Environment;
+    var i: usize = 0;
+    while (ptr[i] != 0) {
+        const key_start = i;
+
+        // There are some special environment variables that start with =,
+        // so we need a special case to not treat = as a key/value separator
+        // if it's the first character.
+        // https://devblogs.microsoft.com/oldnewthing/20100506-00/?p=14133
+        if (ptr[key_start] == '=') i += 1;
+
+        while (ptr[i] != 0 and ptr[i] != '=') : (i += 1) {}
+        const this_key = ptr[key_start..i];
+
+        if (ptr[i] == '=') i += 1;
+
+        const value_start = i;
+        while (ptr[i] != 0) : (i += 1) {}
+        const this_value = ptr[value_start..i :0];
+
+        if (windows.eqlIgnoreCaseWTF16(key_slice, this_key)) {
+            return this_value;
+        }
+
+        i += 1; // skip over null byte
     }
+    return null;
 }
 
 test getEnvVarOwned {
@@ -459,7 +509,7 @@ test getEnvVarOwned {
 }
 
 test hasEnvVarConstant {
-    if (builtin.os.tag == .wasi and !builtin.link_libc) return error.SkipZigTest;
+    if (native_os == .wasi and !builtin.link_libc) return error.SkipZigTest;
 
     try testing.expect(!hasEnvVarConstant("BADENV"));
 }
@@ -478,14 +528,14 @@ pub const ArgIteratorPosix = struct {
     pub fn init() ArgIteratorPosix {
         return ArgIteratorPosix{
             .index = 0,
-            .count = os.argv.len,
+            .count = std.os.argv.len,
         };
     }
 
     pub fn next(self: *ArgIteratorPosix) ?[:0]const u8 {
         if (self.index == self.count) return null;
 
-        const s = os.argv[self.index];
+        const s = std.os.argv[self.index];
         self.index += 1;
         return mem.sliceTo(s, 0);
     }
@@ -503,7 +553,7 @@ pub const ArgIteratorWasi = struct {
     index: usize,
     args: [][:0]u8,
 
-    pub const InitError = error{OutOfMemory} || os.UnexpectedError;
+    pub const InitError = error{OutOfMemory} || posix.UnexpectedError;
 
     /// You must call deinit to free the internal buffer of the
     /// iterator after you are done.
@@ -517,13 +567,12 @@ pub const ArgIteratorWasi = struct {
     }
 
     fn internalInit(allocator: Allocator) InitError![][:0]u8 {
-        const w = os.wasi;
         var count: usize = undefined;
         var buf_size: usize = undefined;
 
-        switch (w.args_sizes_get(&count, &buf_size)) {
+        switch (std.os.wasi.args_sizes_get(&count, &buf_size)) {
             .SUCCESS => {},
-            else => |err| return os.unexpectedErrno(err),
+            else => |err| return posix.unexpectedErrno(err),
         }
 
         if (count == 0) {
@@ -535,9 +584,9 @@ pub const ArgIteratorWasi = struct {
 
         const argv_buf = try allocator.alloc(u8, buf_size);
 
-        switch (w.args_get(argv.ptr, argv_buf.ptr)) {
+        switch (std.os.wasi.args_get(argv.ptr, argv_buf.ptr)) {
             .SUCCESS => {},
-            else => |err| return os.unexpectedErrno(err),
+            else => |err| return posix.unexpectedErrno(err),
         }
 
         var result_args = try allocator.alloc([:0]u8, count);
@@ -1007,7 +1056,7 @@ pub fn ArgIteratorGeneral(comptime options: ArgIteratorGeneralOptions) type {
 
 /// Cross-platform command line argument iterator.
 pub const ArgIterator = struct {
-    const InnerType = switch (builtin.os.tag) {
+    const InnerType = switch (native_os) {
         .windows => ArgIteratorWindows,
         .wasi => if (builtin.link_libc) ArgIteratorPosix else ArgIteratorWasi,
         else => ArgIteratorPosix,
@@ -1018,10 +1067,10 @@ pub const ArgIterator = struct {
     /// Initialize the args iterator. Consider using initWithAllocator() instead
     /// for cross-platform compatibility.
     pub fn init() ArgIterator {
-        if (builtin.os.tag == .wasi) {
+        if (native_os == .wasi) {
             @compileError("In WASI, use initWithAllocator instead.");
         }
-        if (builtin.os.tag == .windows) {
+        if (native_os == .windows) {
             @compileError("In Windows, use initWithAllocator instead.");
         }
 
@@ -1032,11 +1081,11 @@ pub const ArgIterator = struct {
 
     /// You must deinitialize iterator's internal buffers by calling `deinit` when done.
     pub fn initWithAllocator(allocator: Allocator) InitError!ArgIterator {
-        if (builtin.os.tag == .wasi and !builtin.link_libc) {
+        if (native_os == .wasi and !builtin.link_libc) {
             return ArgIterator{ .inner = try InnerType.init(allocator) };
         }
-        if (builtin.os.tag == .windows) {
-            const cmd_line_w = os.windows.kernel32.GetCommandLineW();
+        if (native_os == .windows) {
+            const cmd_line_w = windows.kernel32.GetCommandLineW();
             return ArgIterator{ .inner = try InnerType.init(allocator, cmd_line_w) };
         }
 
@@ -1061,11 +1110,11 @@ pub const ArgIterator = struct {
     /// was created with `initWithAllocator` function.
     pub fn deinit(self: *ArgIterator) void {
         // Unless we're targeting WASI or Windows, this is a no-op.
-        if (builtin.os.tag == .wasi and !builtin.link_libc) {
+        if (native_os == .wasi and !builtin.link_libc) {
             self.inner.deinit();
         }
 
-        if (builtin.os.tag == .windows) {
+        if (native_os == .windows) {
             self.inner.deinit();
         }
     }
@@ -1334,13 +1383,13 @@ fn testResponseFileCmdLine(input_cmd_line: []const u8, expected_args: []const []
 }
 
 pub const UserInfo = struct {
-    uid: os.uid_t,
-    gid: os.gid_t,
+    uid: posix.uid_t,
+    gid: posix.gid_t,
 };
 
 /// POSIX function which gets a uid from username.
 pub fn getUserInfo(name: []const u8) !UserInfo {
-    return switch (builtin.os.tag) {
+    return switch (native_os) {
         .linux,
         .macos,
         .watchos,
@@ -1376,8 +1425,8 @@ pub fn posixGetUserInfo(name: []const u8) !UserInfo {
     var buf: [std.mem.page_size]u8 = undefined;
     var name_index: usize = 0;
     var state = State.Start;
-    var uid: os.uid_t = 0;
-    var gid: os.gid_t = 0;
+    var uid: posix.uid_t = 0;
+    var gid: posix.gid_t = 0;
 
     while (true) {
         const amt_read = try reader.read(buf[0..]);
@@ -1462,36 +1511,36 @@ pub fn posixGetUserInfo(name: []const u8) !UserInfo {
 }
 
 pub fn getBaseAddress() usize {
-    switch (builtin.os.tag) {
+    switch (native_os) {
         .linux => {
-            const base = os.system.getauxval(std.elf.AT_BASE);
+            const base = std.os.linux.getauxval(std.elf.AT_BASE);
             if (base != 0) {
                 return base;
             }
-            const phdr = os.system.getauxval(std.elf.AT_PHDR);
+            const phdr = std.os.linux.getauxval(std.elf.AT_PHDR);
             return phdr - @sizeOf(std.elf.Ehdr);
         },
         .macos, .freebsd, .netbsd => {
             return @intFromPtr(&std.c._mh_execute_header);
         },
-        .windows => return @intFromPtr(os.windows.kernel32.GetModuleHandleW(null)),
+        .windows => return @intFromPtr(windows.kernel32.GetModuleHandleW(null)),
         else => @compileError("Unsupported OS"),
     }
 }
 
 /// Tells whether calling the `execv` or `execve` functions will be a compile error.
-pub const can_execv = switch (builtin.os.tag) {
+pub const can_execv = switch (native_os) {
     .windows, .haiku, .wasi => false,
     else => true,
 };
 
 /// Tells whether spawning child processes is supported (e.g. via ChildProcess)
-pub const can_spawn = switch (builtin.os.tag) {
+pub const can_spawn = switch (native_os) {
     .wasi, .watchos, .tvos => false,
     else => true,
 };
 
-pub const ExecvError = std.os.ExecveError || error{OutOfMemory};
+pub const ExecvError = std.posix.ExecveError || error{OutOfMemory};
 
 /// Replaces the current process image with the executed process.
 /// This function must allocate memory to add a null terminating bytes on path and each arg.
@@ -1500,7 +1549,7 @@ pub const ExecvError = std.os.ExecveError || error{OutOfMemory};
 /// `argv[0]` is the executable path.
 /// This function also uses the PATH environment variable to get the full path to the executable.
 /// Due to the heap-allocation, it is illegal to call this function in a fork() child.
-/// For that use case, use the `std.os` functions directly.
+/// For that use case, use the `std.posix` functions directly.
 pub fn execv(allocator: Allocator, argv: []const []const u8) ExecvError {
     return execve(allocator, argv, null);
 }
@@ -1512,7 +1561,7 @@ pub fn execv(allocator: Allocator, argv: []const []const u8) ExecvError {
 /// `argv[0]` is the executable path.
 /// This function also uses the PATH environment variable to get the full path to the executable.
 /// Due to the heap-allocation, it is illegal to call this function in a fork() child.
-/// For that use case, use the `std.os` functions directly.
+/// For that use case, use the `std.posix` functions directly.
 pub fn execve(
     allocator: Allocator,
     argv: []const []const u8,
@@ -1536,14 +1585,14 @@ pub fn execve(
         } else if (builtin.output_mode == .Exe) {
             // Then we have Zig start code and this works.
             // TODO type-safety for null-termination of `os.environ`.
-            break :m @as([*:null]const ?[*:0]const u8, @ptrCast(os.environ.ptr));
+            break :m @as([*:null]const ?[*:0]const u8, @ptrCast(std.os.environ.ptr));
         } else {
             // TODO come up with a solution for this.
             @compileError("missing std lib enhancement: std.process.execv implementation has no way to collect the environment variables to forward to the child process");
         }
     };
 
-    return os.execvpeZ_expandArg0(.no_expand, argv_buf.ptr[0].?, argv_buf.ptr, envp);
+    return posix.execvpeZ_expandArg0(.no_expand, argv_buf.ptr[0].?, argv_buf.ptr, envp);
 }
 
 pub const TotalSystemMemoryError = error{
@@ -1555,14 +1604,14 @@ pub const TotalSystemMemoryError = error{
 /// and Linux's /proc/meminfo reporting more memory when
 /// using QEMU user mode emulation.
 pub fn totalSystemMemory() TotalSystemMemoryError!u64 {
-    switch (builtin.os.tag) {
+    switch (native_os) {
         .linux => {
             return totalSystemMemoryLinux() catch return error.UnknownTotalSystemMemory;
         },
         .freebsd => {
             var physmem: c_ulong = undefined;
             var len: usize = @sizeOf(c_ulong);
-            os.sysctlbynameZ("hw.physmem", &physmem, &len, null, 0) catch |err| switch (err) {
+            posix.sysctlbynameZ("hw.physmem", &physmem, &len, null, 0) catch |err| switch (err) {
                 error.NameTooLong, error.UnknownName => unreachable,
                 else => return error.UnknownTotalSystemMemory,
             };
@@ -1570,12 +1619,12 @@ pub fn totalSystemMemory() TotalSystemMemoryError!u64 {
         },
         .openbsd => {
             const mib: [2]c_int = [_]c_int{
-                std.os.CTL.HW,
-                std.os.HW.PHYSMEM64,
+                posix.CTL.HW,
+                posix.HW.PHYSMEM64,
             };
             var physmem: i64 = undefined;
             var len: usize = @sizeOf(@TypeOf(physmem));
-            std.os.sysctl(&mib, &physmem, &len, null, 0) catch |err| switch (err) {
+            posix.sysctl(&mib, &physmem, &len, null, 0) catch |err| switch (err) {
                 error.NameTooLong => unreachable, // constant, known good value
                 error.PermissionDenied => unreachable, // only when setting values,
                 error.SystemResources => unreachable, // memory already on the stack
@@ -1586,11 +1635,11 @@ pub fn totalSystemMemory() TotalSystemMemoryError!u64 {
             return @as(u64, @bitCast(physmem));
         },
         .windows => {
-            var sbi: std.os.windows.SYSTEM_BASIC_INFORMATION = undefined;
-            const rc = std.os.windows.ntdll.NtQuerySystemInformation(
+            var sbi: windows.SYSTEM_BASIC_INFORMATION = undefined;
+            const rc = windows.ntdll.NtQuerySystemInformation(
                 .SystemBasicInformation,
                 &sbi,
-                @sizeOf(std.os.windows.SYSTEM_BASIC_INFORMATION),
+                @sizeOf(windows.SYSTEM_BASIC_INFORMATION),
                 null,
             );
             if (rc != .SUCCESS) {
lib/std/start.zig
@@ -407,7 +407,7 @@ fn posixCallMainAndExit() callconv(.C) noreturn {
                     // FIXME: Make __aeabi_read_tp call the kernel helper kuser_get_tls
                     // For the time being use a simple abort instead of a @panic call to
                     // keep the binary bloat under control.
-                    std.os.abort();
+                    std.posix.abort();
                 }
             }
 
@@ -422,7 +422,7 @@ fn posixCallMainAndExit() callconv(.C) noreturn {
         expandStackSize(phdrs);
     }
 
-    std.os.exit(callMainWithArgs(argc, argv, envp));
+    std.posix.exit(callMainWithArgs(argc, argv, envp));
 }
 
 fn expandStackSize(phdrs: []elf.Phdr) void {
@@ -432,13 +432,13 @@ fn expandStackSize(phdrs: []elf.Phdr) void {
                 assert(phdr.p_memsz % std.mem.page_size == 0);
 
                 // Silently fail if we are unable to get limits.
-                const limits = std.os.getrlimit(.STACK) catch break;
+                const limits = std.posix.getrlimit(.STACK) catch break;
 
                 // Clamp to limits.max .
                 const wanted_stack_size = @min(phdr.p_memsz, limits.max);
 
                 if (wanted_stack_size > limits.cur) {
-                    std.os.setrlimit(.STACK, .{
+                    std.posix.setrlimit(.STACK, .{
                         .cur = wanted_stack_size,
                         .max = limits.max,
                     }) catch {
@@ -464,7 +464,7 @@ inline fn callMainWithArgs(argc: usize, argv: [*][*:0]u8, envp: [][*:0]u8) u8 {
     std.os.environ = envp;
 
     std.debug.maybeEnableSegfaultHandler();
-    std.os.maybeIgnoreSigpipe();
+    maybeIgnoreSigpipe();
 
     return callMain();
 }
@@ -563,3 +563,38 @@ pub fn call_wWinMain() std.os.windows.INT {
     // second parameter hPrevInstance, MSDN: "This parameter is always NULL"
     return root.wWinMain(hInstance, null, lpCmdLine, nCmdShow);
 }
+
+fn maybeIgnoreSigpipe() void {
+    const have_sigpipe_support = switch (builtin.os.tag) {
+        .linux,
+        .plan9,
+        .solaris,
+        .netbsd,
+        .openbsd,
+        .haiku,
+        .macos,
+        .ios,
+        .watchos,
+        .tvos,
+        .dragonfly,
+        .freebsd,
+        => true,
+
+        else => false,
+    };
+
+    if (have_sigpipe_support and !std.options.keep_sigpipe) {
+        const posix = std.posix;
+        const act: posix.Sigaction = .{
+            // Set handler to a noop function instead of `SIG.IGN` to prevent
+            // leaking signal disposition to a child process.
+            .handler = .{ .handler = noopSigHandler },
+            .mask = posix.empty_sigset,
+            .flags = 0,
+        };
+        posix.sigaction(posix.SIG.PIPE, &act, null) catch |err|
+            std.debug.panic("failed to set noop SIGPIPE handler: {s}", .{@errorName(err)});
+    }
+}
+
+fn noopSigHandler(_: c_int) callconv(.C) void {}
lib/std/std.zig
@@ -85,12 +85,11 @@ pub const math = @import("math.zig");
 pub const mem = @import("mem.zig");
 pub const meta = @import("meta.zig");
 pub const net = @import("net.zig");
-pub const posix = @import("os.zig");
-/// Non-portable Operating System-specific API.
 pub const os = @import("os.zig");
 pub const once = @import("once.zig").once;
 pub const packed_int_array = @import("packed_int_array.zig");
 pub const pdb = @import("pdb.zig");
+pub const posix = @import("posix.zig");
 pub const process = @import("process.zig");
 /// Deprecated: use `Random` instead.
 pub const rand = Random;
@@ -170,3 +169,7 @@ comptime {
 test {
     testing.refAllDecls(@This());
 }
+
+comptime {
+    debug.assert(@import("std") == @This()); // std lib tests require --zig-lib-dir
+}
lib/std/Thread.zig
@@ -5,9 +5,11 @@
 const std = @import("std.zig");
 const builtin = @import("builtin");
 const math = std.math;
-const os = std.os;
 const assert = std.debug.assert;
 const target = builtin.target;
+const native_os = builtin.os.tag;
+const posix = std.posix;
+const windows = std.os.windows;
 
 pub const Futex = @import("Thread/Futex.zig");
 pub const ResetEvent = @import("Thread/ResetEvent.zig");
@@ -18,23 +20,23 @@ pub const RwLock = @import("Thread/RwLock.zig");
 pub const Pool = @import("Thread/Pool.zig");
 pub const WaitGroup = @import("Thread/WaitGroup.zig");
 
-pub const use_pthreads = target.os.tag != .windows and target.os.tag != .wasi and builtin.link_libc;
+pub const use_pthreads = native_os != .windows and native_os != .wasi and builtin.link_libc;
 
 const Thread = @This();
-const Impl = if (target.os.tag == .windows)
+const Impl = if (native_os == .windows)
     WindowsThreadImpl
 else if (use_pthreads)
     PosixThreadImpl
-else if (target.os.tag == .linux)
+else if (native_os == .linux)
     LinuxThreadImpl
-else if (target.os.tag == .wasi)
+else if (native_os == .wasi)
     WasiThreadImpl
 else
     UnsupportedImpl;
 
 impl: Impl,
 
-pub const max_name_len = switch (target.os.tag) {
+pub const max_name_len = switch (native_os) {
     .linux => 15,
     .windows => 31,
     .macos, .ios, .watchos, .tvos => 63,
@@ -50,7 +52,7 @@ pub const SetNameError = error{
     NameTooLong,
     Unsupported,
     Unexpected,
-} || os.PrctlError || os.WriteError || std.fs.File.OpenError || std.fmt.BufPrintError;
+} || posix.PrctlError || posix.WriteError || std.fs.File.OpenError || std.fmt.BufPrintError;
 
 pub fn setName(self: Thread, name: []const u8) SetNameError!void {
     if (name.len > max_name_len) return error.NameTooLong;
@@ -62,21 +64,21 @@ pub fn setName(self: Thread, name: []const u8) SetNameError!void {
         break :blk name_buf[0..name.len :0];
     };
 
-    switch (target.os.tag) {
+    switch (native_os) {
         .linux => if (use_pthreads) {
             if (self.getHandle() == std.c.pthread_self()) {
                 // Set the name of the calling thread (no thread id required).
-                const err = try os.prctl(.SET_NAME, .{@intFromPtr(name_with_terminator.ptr)});
-                switch (@as(os.E, @enumFromInt(err))) {
+                const err = try posix.prctl(.SET_NAME, .{@intFromPtr(name_with_terminator.ptr)});
+                switch (@as(posix.E, @enumFromInt(err))) {
                     .SUCCESS => return,
-                    else => |e| return os.unexpectedErrno(e),
+                    else => |e| return posix.unexpectedErrno(e),
                 }
             } else {
                 const err = std.c.pthread_setname_np(self.getHandle(), name_with_terminator.ptr);
                 switch (err) {
                     .SUCCESS => return,
                     .RANGE => unreachable,
-                    else => |e| return os.unexpectedErrno(e),
+                    else => |e| return posix.unexpectedErrno(e),
                 }
             }
         } else {
@@ -95,21 +97,21 @@ pub fn setName(self: Thread, name: []const u8) SetNameError!void {
             const byte_len = math.cast(c_ushort, len * 2) orelse return error.NameTooLong;
 
             // Note: NT allocates its own copy, no use-after-free here.
-            const unicode_string = os.windows.UNICODE_STRING{
+            const unicode_string = windows.UNICODE_STRING{
                 .Length = byte_len,
                 .MaximumLength = byte_len,
                 .Buffer = &buf,
             };
 
-            switch (os.windows.ntdll.NtSetInformationThread(
+            switch (windows.ntdll.NtSetInformationThread(
                 self.getHandle(),
                 .ThreadNameInformation,
                 &unicode_string,
-                @sizeOf(os.windows.UNICODE_STRING),
+                @sizeOf(windows.UNICODE_STRING),
             )) {
                 .SUCCESS => return,
                 .NOT_IMPLEMENTED => return error.Unsupported,
-                else => |err| return os.windows.unexpectedStatus(err),
+                else => |err| return windows.unexpectedStatus(err),
             }
         },
         .macos, .ios, .watchos, .tvos => if (use_pthreads) {
@@ -119,7 +121,7 @@ pub fn setName(self: Thread, name: []const u8) SetNameError!void {
             const err = std.c.pthread_setname_np(name_with_terminator.ptr);
             switch (err) {
                 .SUCCESS => return,
-                else => |e| return os.unexpectedErrno(e),
+                else => |e| return posix.unexpectedErrno(e),
             }
         },
         .netbsd, .solaris, .illumos => if (use_pthreads) {
@@ -129,7 +131,7 @@ pub fn setName(self: Thread, name: []const u8) SetNameError!void {
                 .INVAL => unreachable,
                 .SRCH => unreachable,
                 .NOMEM => unreachable,
-                else => |e| return os.unexpectedErrno(e),
+                else => |e| return posix.unexpectedErrno(e),
             }
         },
         .freebsd, .openbsd => if (use_pthreads) {
@@ -148,7 +150,7 @@ pub fn setName(self: Thread, name: []const u8) SetNameError!void {
                 .FAULT => unreachable,
                 .NAMETOOLONG => unreachable, // already checked
                 .SRCH => unreachable,
-                else => |e| return os.unexpectedErrno(e),
+                else => |e| return posix.unexpectedErrno(e),
             }
         },
         else => {},
@@ -159,7 +161,7 @@ pub fn setName(self: Thread, name: []const u8) SetNameError!void {
 pub const GetNameError = error{
     Unsupported,
     Unexpected,
-} || os.PrctlError || os.ReadError || std.fs.File.OpenError || std.fmt.BufPrintError;
+} || posix.PrctlError || posix.ReadError || std.fs.File.OpenError || std.fmt.BufPrintError;
 
 /// On Windows, the result is encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
 /// On other platforms, the result is an opaque sequence of bytes with no particular encoding.
@@ -167,21 +169,21 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co
     buffer_ptr[max_name_len] = 0;
     var buffer: [:0]u8 = buffer_ptr;
 
-    switch (target.os.tag) {
+    switch (native_os) {
         .linux => if (use_pthreads) {
             if (self.getHandle() == std.c.pthread_self()) {
                 // Get the name of the calling thread (no thread id required).
-                const err = try os.prctl(.GET_NAME, .{@intFromPtr(buffer.ptr)});
-                switch (@as(os.E, @enumFromInt(err))) {
+                const err = try posix.prctl(.GET_NAME, .{@intFromPtr(buffer.ptr)});
+                switch (@as(posix.E, @enumFromInt(err))) {
                     .SUCCESS => return std.mem.sliceTo(buffer, 0),
-                    else => |e| return os.unexpectedErrno(e),
+                    else => |e| return posix.unexpectedErrno(e),
                 }
             } else {
                 const err = std.c.pthread_getname_np(self.getHandle(), buffer.ptr, max_name_len + 1);
                 switch (err) {
                     .SUCCESS => return std.mem.sliceTo(buffer, 0),
                     .RANGE => unreachable,
-                    else => |e| return os.unexpectedErrno(e),
+                    else => |e| return posix.unexpectedErrno(e),
                 }
             }
         } else {
@@ -196,10 +198,10 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co
             return if (data_len >= 1) buffer[0 .. data_len - 1] else null;
         },
         .windows => {
-            const buf_capacity = @sizeOf(os.windows.UNICODE_STRING) + (@sizeOf(u16) * max_name_len);
-            var buf: [buf_capacity]u8 align(@alignOf(os.windows.UNICODE_STRING)) = undefined;
+            const buf_capacity = @sizeOf(windows.UNICODE_STRING) + (@sizeOf(u16) * max_name_len);
+            var buf: [buf_capacity]u8 align(@alignOf(windows.UNICODE_STRING)) = undefined;
 
-            switch (os.windows.ntdll.NtQueryInformationThread(
+            switch (windows.ntdll.NtQueryInformationThread(
                 self.getHandle(),
                 .ThreadNameInformation,
                 &buf,
@@ -207,12 +209,12 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co
                 null,
             )) {
                 .SUCCESS => {
-                    const string = @as(*const os.windows.UNICODE_STRING, @ptrCast(&buf));
+                    const string = @as(*const windows.UNICODE_STRING, @ptrCast(&buf));
                     const len = std.unicode.wtf16LeToWtf8(buffer, string.Buffer.?[0 .. string.Length / 2]);
                     return if (len > 0) buffer[0..len] else null;
                 },
                 .NOT_IMPLEMENTED => return error.Unsupported,
-                else => |err| return os.windows.unexpectedStatus(err),
+                else => |err| return windows.unexpectedStatus(err),
             }
         },
         .macos, .ios, .watchos, .tvos => if (use_pthreads) {
@@ -220,7 +222,7 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co
             switch (err) {
                 .SUCCESS => return std.mem.sliceTo(buffer, 0),
                 .SRCH => unreachable,
-                else => |e| return os.unexpectedErrno(e),
+                else => |e| return posix.unexpectedErrno(e),
             }
         },
         .netbsd, .solaris, .illumos => if (use_pthreads) {
@@ -229,7 +231,7 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co
                 .SUCCESS => return std.mem.sliceTo(buffer, 0),
                 .INVAL => unreachable,
                 .SRCH => unreachable,
-                else => |e| return os.unexpectedErrno(e),
+                else => |e| return posix.unexpectedErrno(e),
             }
         },
         .freebsd, .openbsd => if (use_pthreads) {
@@ -246,7 +248,7 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co
                 .INVAL => unreachable,
                 .FAULT => unreachable,
                 .SRCH => unreachable,
-                else => |e| return os.unexpectedErrno(e),
+                else => |e| return posix.unexpectedErrno(e),
             }
         },
         else => {},
@@ -255,7 +257,7 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co
 }
 
 /// Represents an ID per thread guaranteed to be unique only within a process.
-pub const Id = switch (target.os.tag) {
+pub const Id = switch (native_os) {
     .linux,
     .dragonfly,
     .netbsd,
@@ -265,7 +267,7 @@ pub const Id = switch (target.os.tag) {
     .wasi,
     => u32,
     .macos, .ios, .watchos, .tvos => u64,
-    .windows => os.windows.DWORD,
+    .windows => windows.DWORD,
     else => usize,
 };
 
@@ -368,13 +370,13 @@ pub const YieldError = error{
 
 /// Yields the current thread potentially allowing other threads to run.
 pub fn yield() YieldError!void {
-    if (builtin.os.tag == .windows) {
+    if (native_os == .windows) {
         // The return value has to do with how many other threads there are; it is not
         // an error condition on Windows.
-        _ = os.windows.kernel32.SwitchToThread();
+        _ = windows.kernel32.SwitchToThread();
         return;
     }
-    switch (os.errno(os.system.sched_yield())) {
+    switch (posix.errno(posix.system.sched_yield())) {
         .SUCCESS => return,
         .NOSYS => return error.SystemCannotYield,
         else => return error.SystemCannotYield,
@@ -390,7 +392,7 @@ const Completion = std.atomic.Value(enum(u8) {
 
 /// Used by the Thread implementations to call the spawned function with the arguments.
 fn callFn(comptime f: anytype, args: anytype) switch (Impl) {
-    WindowsThreadImpl => std.os.windows.DWORD,
+    WindowsThreadImpl => windows.DWORD,
     LinuxThreadImpl => u8,
     PosixThreadImpl => ?*anyopaque,
     else => unreachable,
@@ -470,13 +472,11 @@ const UnsupportedImpl = struct {
 
     fn unsupported(unused: anytype) noreturn {
         _ = unused;
-        @compileError("Unsupported operating system " ++ @tagName(target.os.tag));
+        @compileError("Unsupported operating system " ++ @tagName(native_os));
     }
 };
 
 const WindowsThreadImpl = struct {
-    const windows = os.windows;
-
     pub const ThreadHandle = windows.HANDLE;
 
     fn getCurrentId() windows.DWORD {
@@ -584,7 +584,7 @@ const PosixThreadImpl = struct {
     pub const ThreadHandle = c.pthread_t;
 
     fn getCurrentId() Id {
-        switch (target.os.tag) {
+        switch (native_os) {
             .linux => {
                 return LinuxThreadImpl.getCurrentId();
             },
@@ -616,15 +616,15 @@ const PosixThreadImpl = struct {
     }
 
     fn getCpuCount() !usize {
-        switch (target.os.tag) {
+        switch (native_os) {
             .linux => {
                 return LinuxThreadImpl.getCpuCount();
             },
             .openbsd => {
                 var count: c_int = undefined;
                 var count_size: usize = @sizeOf(c_int);
-                const mib = [_]c_int{ os.CTL.HW, os.system.HW.NCPUONLINE };
-                os.sysctl(&mib, &count, &count_size, null, 0) catch |err| switch (err) {
+                const mib = [_]c_int{ std.c.CTL.HW, std.c.HW.NCPUONLINE };
+                std.c.sysctl(&mib, &count, &count_size, null, 0) catch |err| switch (err) {
                     error.NameTooLong, error.UnknownName => unreachable,
                     else => |e| return e,
                 };
@@ -634,25 +634,25 @@ const PosixThreadImpl = struct {
                 // The "proper" way to get the cpu count would be to query
                 // /dev/kstat via ioctls, and traverse a linked list for each
                 // cpu.
-                const rc = c.sysconf(os._SC.NPROCESSORS_ONLN);
-                return switch (os.errno(rc)) {
+                const rc = c.sysconf(std.c._SC.NPROCESSORS_ONLN);
+                return switch (posix.errno(rc)) {
                     .SUCCESS => @as(usize, @intCast(rc)),
-                    else => |err| os.unexpectedErrno(err),
+                    else => |err| posix.unexpectedErrno(err),
                 };
             },
             .haiku => {
-                var system_info: os.system.system_info = undefined;
-                const rc = os.system.get_system_info(&system_info); // always returns B_OK
-                return switch (os.errno(rc)) {
+                var system_info: std.c.system_info = undefined;
+                const rc = std.c.get_system_info(&system_info); // always returns B_OK
+                return switch (posix.errno(rc)) {
                     .SUCCESS => @as(usize, @intCast(system_info.cpu_count)),
-                    else => |err| os.unexpectedErrno(err),
+                    else => |err| posix.unexpectedErrno(err),
                 };
             },
             else => {
                 var count: c_int = undefined;
                 var count_len: usize = @sizeOf(c_int);
                 const name = if (comptime target.isDarwin()) "hw.logicalcpu" else "hw.ncpu";
-                os.sysctlbynameZ(name, &count, &count_len, null, 0) catch |err| switch (err) {
+                posix.sysctlbynameZ(name, &count, &count_len, null, 0) catch |err| switch (err) {
                     error.NameTooLong, error.UnknownName => unreachable,
                     else => |e| return e,
                 };
@@ -699,7 +699,7 @@ const PosixThreadImpl = struct {
             .AGAIN => return error.SystemResources,
             .PERM => unreachable,
             .INVAL => unreachable,
-            else => |err| return os.unexpectedErrno(err),
+            else => |err| return posix.unexpectedErrno(err),
         }
     }
 
@@ -1013,7 +1013,7 @@ const WasiThreadImpl = struct {
 };
 
 const LinuxThreadImpl = struct {
-    const linux = os.linux;
+    const linux = std.os.linux;
 
     pub const ThreadHandle = i32;
 
@@ -1028,9 +1028,9 @@ const LinuxThreadImpl = struct {
     }
 
     fn getCpuCount() !usize {
-        const cpu_set = try os.sched_getaffinity(0);
+        const cpu_set = try posix.sched_getaffinity(0);
         // TODO: should not need this usize cast
-        return @as(usize, os.CPU_COUNT(cpu_set));
+        return @as(usize, posix.CPU_COUNT(cpu_set));
     }
 
     thread: *ThreadCompletion,
@@ -1228,10 +1228,10 @@ const LinuxThreadImpl = struct {
         // map all memory needed without read/write permissions
         // to avoid committing the whole region right away
         // anonymous mapping ensures file descriptor limits are not exceeded
-        const mapped = os.mmap(
+        const mapped = posix.mmap(
             null,
             map_bytes,
-            os.PROT.NONE,
+            posix.PROT.NONE,
             .{ .TYPE = .PRIVATE, .ANONYMOUS = true },
             -1,
             0,
@@ -1244,24 +1244,24 @@ const LinuxThreadImpl = struct {
             else => |e| return e,
         };
         assert(mapped.len >= map_bytes);
-        errdefer os.munmap(mapped);
+        errdefer posix.munmap(mapped);
 
         // map everything but the guard page as read/write
-        os.mprotect(
+        posix.mprotect(
             @alignCast(mapped[guard_offset..]),
-            os.PROT.READ | os.PROT.WRITE,
+            posix.PROT.READ | posix.PROT.WRITE,
         ) catch |err| switch (err) {
             error.AccessDenied => unreachable,
             else => |e| return e,
         };
 
         // Prepare the TLS segment and prepare a user_desc struct when needed on x86
-        var tls_ptr = os.linux.tls.prepareTLS(mapped[tls_offset..]);
-        var user_desc: if (target.cpu.arch == .x86) os.linux.user_desc else void = undefined;
+        var tls_ptr = linux.tls.prepareTLS(mapped[tls_offset..]);
+        var user_desc: if (target.cpu.arch == .x86) linux.user_desc else void = undefined;
         if (target.cpu.arch == .x86) {
             defer tls_ptr = @intFromPtr(&user_desc);
             user_desc = .{
-                .entry_number = os.linux.tls.tls_image.gdt_entry_number,
+                .entry_number = linux.tls.tls_image.gdt_entry_number,
                 .base_addr = tls_ptr,
                 .limit = 0xfffff,
                 .flags = .{
@@ -1286,7 +1286,7 @@ const LinuxThreadImpl = struct {
             linux.CLONE.PARENT_SETTID | linux.CLONE.CHILD_CLEARTID |
             linux.CLONE.SIGHAND | linux.CLONE.SYSVSEM | linux.CLONE.SETTLS;
 
-        switch (linux.getErrno(linux.clone(
+        switch (linux.E.init(linux.clone(
             Instance.entryFn,
             @intFromPtr(&mapped[stack_offset]),
             flags,
@@ -1302,7 +1302,7 @@ const LinuxThreadImpl = struct {
             .NOSPC => unreachable,
             .PERM => unreachable,
             .USERS => unreachable,
-            else => |err| return os.unexpectedErrno(err),
+            else => |err| return posix.unexpectedErrno(err),
         }
     }
 
@@ -1319,7 +1319,7 @@ const LinuxThreadImpl = struct {
     }
 
     fn join(self: Impl) void {
-        defer os.munmap(self.thread.mapped);
+        defer posix.munmap(self.thread.mapped);
 
         var spin: u8 = 10;
         while (true) {
@@ -1334,7 +1334,7 @@ const LinuxThreadImpl = struct {
                 continue;
             }
 
-            switch (linux.getErrno(linux.futex_wait(
+            switch (linux.E.init(linux.futex_wait(
                 &self.thread.child_tid.raw,
                 linux.FUTEX.WAIT,
                 tid,
@@ -1383,7 +1383,7 @@ test "setName, getName" {
             // Wait for the main thread to have set the thread field in the context.
             ctx.start_wait_event.wait();
 
-            switch (target.os.tag) {
+            switch (native_os) {
                 .windows => testThreadName(&ctx.thread) catch |err| switch (err) {
                     error.Unsupported => return error.SkipZigTest,
                     else => return err,
@@ -1406,7 +1406,7 @@ test "setName, getName" {
     context.start_wait_event.set();
     context.test_done_event.wait();
 
-    switch (target.os.tag) {
+    switch (native_os) {
         .macos, .ios, .watchos, .tvos => {
             const res = thread.setName("foobar");
             try std.testing.expectError(error.Unsupported, res);
lib/std/time.zig
@@ -2,8 +2,9 @@ const std = @import("std.zig");
 const builtin = @import("builtin");
 const assert = std.debug.assert;
 const testing = std.testing;
-const os = std.os;
 const math = std.math;
+const windows = std.os.windows;
+const posix = std.posix;
 
 pub const epoch = @import("time/epoch.zig");
 
@@ -11,8 +12,8 @@ pub const epoch = @import("time/epoch.zig");
 pub fn sleep(nanoseconds: u64) void {
     if (builtin.os.tag == .windows) {
         const big_ms_from_ns = nanoseconds / ns_per_ms;
-        const ms = math.cast(os.windows.DWORD, big_ms_from_ns) orelse math.maxInt(os.windows.DWORD);
-        os.windows.kernel32.Sleep(ms);
+        const ms = math.cast(windows.DWORD, big_ms_from_ns) orelse math.maxInt(windows.DWORD);
+        windows.kernel32.Sleep(ms);
         return;
     }
 
@@ -40,7 +41,7 @@ pub fn sleep(nanoseconds: u64) void {
     }
 
     if (builtin.os.tag == .uefi) {
-        const boot_services = os.uefi.system_table.boot_services.?;
+        const boot_services = std.os.uefi.system_table.boot_services.?;
         const us_from_ns = nanoseconds / ns_per_us;
         const us = math.cast(usize, us_from_ns) orelse math.maxInt(usize);
         _ = boot_services.stall(us);
@@ -49,7 +50,7 @@ pub fn sleep(nanoseconds: u64) void {
 
     const s = nanoseconds / ns_per_s;
     const ns = nanoseconds % ns_per_s;
-    std.os.nanosleep(s, ns);
+    posix.nanosleep(s, ns);
 }
 
 test "sleep" {
@@ -60,7 +61,7 @@ test "sleep" {
 /// Precision of timing depends on the hardware and operating system.
 /// The return value is signed because it is possible to have a date that is
 /// before the epoch.
-/// See `std.os.clock_gettime` for a POSIX timestamp.
+/// See `posix.clock_gettime` for a POSIX timestamp.
 pub fn timestamp() i64 {
     return @divFloor(milliTimestamp(), ms_per_s);
 }
@@ -69,7 +70,7 @@ pub fn timestamp() i64 {
 /// Precision of timing depends on the hardware and operating system.
 /// The return value is signed because it is possible to have a date that is
 /// before the epoch.
-/// See `std.os.clock_gettime` for a POSIX timestamp.
+/// See `posix.clock_gettime` for a POSIX timestamp.
 pub fn milliTimestamp() i64 {
     return @as(i64, @intCast(@divFloor(nanoTimestamp(), ns_per_ms)));
 }
@@ -78,7 +79,7 @@ pub fn milliTimestamp() i64 {
 /// Precision of timing depends on the hardware and operating system.
 /// The return value is signed because it is possible to have a date that is
 /// before the epoch.
-/// See `std.os.clock_gettime` for a POSIX timestamp.
+/// See `posix.clock_gettime` for a POSIX timestamp.
 pub fn microTimestamp() i64 {
     return @as(i64, @intCast(@divFloor(nanoTimestamp(), ns_per_us)));
 }
@@ -88,21 +89,21 @@ pub fn microTimestamp() i64 {
 /// On Windows this has a maximum granularity of 100 nanoseconds.
 /// The return value is signed because it is possible to have a date that is
 /// before the epoch.
-/// See `std.os.clock_gettime` for a POSIX timestamp.
+/// See `posix.clock_gettime` for a POSIX timestamp.
 pub fn nanoTimestamp() i128 {
     switch (builtin.os.tag) {
         .windows => {
             // FileTime has a granularity of 100 nanoseconds and uses the NTFS/Windows epoch,
             // which is 1601-01-01.
             const epoch_adj = epoch.windows * (ns_per_s / 100);
-            var ft: os.windows.FILETIME = undefined;
-            os.windows.kernel32.GetSystemTimeAsFileTime(&ft);
+            var ft: windows.FILETIME = undefined;
+            windows.kernel32.GetSystemTimeAsFileTime(&ft);
             const ft64 = (@as(u64, ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
             return @as(i128, @as(i64, @bitCast(ft64)) + epoch_adj) * 100;
         },
         .wasi => {
-            var ns: os.wasi.timestamp_t = undefined;
-            const err = os.wasi.clock_time_get(.REALTIME, 1, &ns);
+            var ns: std.os.wasi.timestamp_t = undefined;
+            const err = std.os.wasi.clock_time_get(.REALTIME, 1, &ns);
             assert(err == .SUCCESS);
             return ns;
         },
@@ -113,8 +114,8 @@ pub fn nanoTimestamp() i128 {
             return value.toEpoch();
         },
         else => {
-            var ts: os.timespec = undefined;
-            os.clock_gettime(os.CLOCK.REALTIME, &ts) catch |err| switch (err) {
+            var ts: posix.timespec = undefined;
+            posix.clock_gettime(posix.CLOCK.REALTIME, &ts) catch |err| switch (err) {
                 error.UnsupportedClock, error.Unexpected => return 0, // "Precision of timing depends on hardware and OS".
             };
             return (@as(i128, ts.tv_sec) * ns_per_s) + ts.tv_nsec;
@@ -172,7 +173,7 @@ pub const s_per_week = s_per_day * 7;
 /// It also tries to be monotonic, but this is not a guarantee due to OS/hardware bugs.
 /// If you need monotonic readings for elapsed time, consider `Timer` instead.
 pub const Instant = struct {
-    timestamp: if (is_posix) os.timespec else u64,
+    timestamp: if (is_posix) posix.timespec else u64,
 
     // true if we should use clock_gettime()
     const is_posix = switch (builtin.os.tag) {
@@ -188,11 +189,11 @@ pub const Instant = struct {
         const clock_id = switch (builtin.os.tag) {
             .windows => {
                 // QPC on windows doesn't fail on >= XP/2000 and includes time suspended.
-                return Instant{ .timestamp = os.windows.QueryPerformanceCounter() };
+                return Instant{ .timestamp = windows.QueryPerformanceCounter() };
             },
             .wasi => {
-                var ns: os.wasi.timestamp_t = undefined;
-                const rc = os.wasi.clock_time_get(.MONOTONIC, 1, &ns);
+                var ns: std.os.wasi.timestamp_t = undefined;
+                const rc = std.os.wasi.clock_time_get(.MONOTONIC, 1, &ns);
                 if (rc != .SUCCESS) return error.Unsupported;
                 return .{ .timestamp = ns };
             },
@@ -204,21 +205,21 @@ pub const Instant = struct {
             },
             // On darwin, use UPTIME_RAW instead of MONOTONIC as it ticks while
             // suspended.
-            .macos, .ios, .tvos, .watchos => os.CLOCK.UPTIME_RAW,
+            .macos, .ios, .tvos, .watchos => posix.CLOCK.UPTIME_RAW,
             // On freebsd derivatives, use MONOTONIC_FAST as currently there's
             // no precision tradeoff.
-            .freebsd, .dragonfly => os.CLOCK.MONOTONIC_FAST,
+            .freebsd, .dragonfly => posix.CLOCK.MONOTONIC_FAST,
             // On linux, use BOOTTIME instead of MONOTONIC as it ticks while
             // suspended.
-            .linux => os.CLOCK.BOOTTIME,
+            .linux => posix.CLOCK.BOOTTIME,
             // On other posix systems, MONOTONIC is generally the fastest and
             // ticks while suspended.
-            else => os.CLOCK.MONOTONIC,
+            else => posix.CLOCK.MONOTONIC,
         };
 
-        var ts: os.timespec = undefined;
-        os.clock_gettime(clock_id, &ts) catch return error.Unsupported;
-        return Instant{ .timestamp = ts };
+        var ts: posix.timespec = undefined;
+        posix.clock_gettime(clock_id, &ts) catch return error.Unsupported;
+        return .{ .timestamp = ts };
     }
 
     /// Quickly compares two instances between each other.
@@ -245,7 +246,7 @@ pub const Instant = struct {
             // https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/ns-ntddk-kuser_shared_data
             // https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/ntexapi_x/kuser_shared_data/index.htm
             const qpc = self.timestamp - earlier.timestamp;
-            const qpf = os.windows.QueryPerformanceFrequency();
+            const qpf = windows.QueryPerformanceFrequency();
 
             // 10Mhz (1 qpc tick every 100ns) is a common enough QPF value that we can optimize on it.
             // https://github.com/microsoft/STL/blob/785143a0c73f030238ef618890fd4d6ae2b3a3a0/stl/inc/chrono#L694-L701
lib/std/zig.zig
@@ -1002,7 +1002,7 @@ pub const EnvVar = enum {
     }
 
     pub fn getPosix(comptime ev: EnvVar) ?[:0]const u8 {
-        return std.os.getenvZ(@tagName(ev));
+        return std.posix.getenvZ(@tagName(ev));
     }
 };
 
src/link/Elf/synthetic_sections.zig
@@ -317,16 +317,16 @@ pub const ZigGotSection = struct {
                 if (elf_file.base.child_pid) |pid| {
                     switch (builtin.os.tag) {
                         .linux => {
-                            var local_vec: [1]std.os.iovec_const = .{.{
+                            var local_vec: [1]std.posix.iovec_const = .{.{
                                 .iov_base = &buf,
                                 .iov_len = buf.len,
                             }};
-                            var remote_vec: [1]std.os.iovec_const = .{.{
+                            var remote_vec: [1]std.posix.iovec_const = .{.{
                                 .iov_base = @as([*]u8, @ptrFromInt(@as(usize, @intCast(vaddr)))),
                                 .iov_len = buf.len,
                             }};
                             const rc = std.os.linux.process_vm_writev(pid, &local_vec, &remote_vec, 0);
-                            switch (std.os.errno(rc)) {
+                            switch (std.os.linux.E.init(rc)) {
                                 .SUCCESS => assert(rc == buf.len),
                                 else => |errno| log.warn("process_vm_writev failure: {s}", .{@tagName(errno)}),
                             }
src/link/Elf/ZigObject.zig
@@ -965,16 +965,16 @@ fn updateDeclCode(
     if (elf_file.base.child_pid) |pid| {
         switch (builtin.os.tag) {
             .linux => {
-                var code_vec: [1]std.os.iovec_const = .{.{
+                var code_vec: [1]std.posix.iovec_const = .{.{
                     .iov_base = code.ptr,
                     .iov_len = code.len,
                 }};
-                var remote_vec: [1]std.os.iovec_const = .{.{
+                var remote_vec: [1]std.posix.iovec_const = .{.{
                     .iov_base = @as([*]u8, @ptrFromInt(@as(usize, @intCast(sym.address(.{}, elf_file))))),
                     .iov_len = code.len,
                 }};
                 const rc = std.os.linux.process_vm_writev(pid, &code_vec, &remote_vec, 0);
-                switch (std.os.errno(rc)) {
+                switch (std.os.linux.E.init(rc)) {
                     .SUCCESS => assert(rc == code.len),
                     else => |errno| log.warn("process_vm_writev failure: {s}", .{@tagName(errno)}),
                 }
src/link/Wasm/Archive.zig
@@ -193,7 +193,7 @@ pub fn parseObject(archive: Archive, wasm_file: *const Wasm, file_offset: u32) !
     const object_name = try archive.parseName(header);
     const name = name: {
         var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
-        const path = try std.os.realpath(archive.name, &buffer);
+        const path = try std.posix.realpath(archive.name, &buffer);
         break :name try std.fmt.allocPrint(gpa, "{s}({s})", .{ path, object_name });
     };
     defer gpa.free(name);
src/link/C.zig
@@ -518,7 +518,7 @@ const Flush = struct {
     asm_buf: std.ArrayListUnmanaged(u8) = .{},
 
     /// We collect a list of buffers to write, and write them all at once with pwritev ๐Ÿ˜Ž
-    all_buffers: std.ArrayListUnmanaged(std.os.iovec_const) = .{},
+    all_buffers: std.ArrayListUnmanaged(std.posix.iovec_const) = .{},
     /// Keeps track of the total bytes of `all_buffers`.
     file_size: u64 = 0,
 
@@ -752,7 +752,7 @@ pub fn flushEmitH(module: *Module) !void {
 
     // We collect a list of buffers to write, and write them all at once with pwritev ๐Ÿ˜Ž
     const num_buffers = emit_h.decl_table.count() + 1;
-    var all_buffers = try std.ArrayList(std.os.iovec_const).initCapacity(module.gpa, num_buffers);
+    var all_buffers = try std.ArrayList(std.posix.iovec_const).initCapacity(module.gpa, num_buffers);
     defer all_buffers.deinit();
 
     var file_size: u64 = zig_h.len;
src/link/Dwarf.zig
@@ -2118,7 +2118,7 @@ fn pwriteDbgLineNops(
 
     const page_of_nops = [1]u8{DW.LNS.negate_stmt} ** 4096;
     const three_byte_nop = [3]u8{ DW.LNS.advance_pc, 0b1000_0000, 0 };
-    var vecs: [512]std.os.iovec_const = undefined;
+    var vecs: [512]std.posix.iovec_const = undefined;
     var vec_index: usize = 0;
     {
         var padding_left = prev_padding_size;
@@ -2235,7 +2235,7 @@ fn pwriteDbgInfoNops(
     defer tracy.end();
 
     const page_of_nops = [1]u8{@intFromEnum(AbbrevCode.padding)} ** 4096;
-    var vecs: [32]std.os.iovec_const = undefined;
+    var vecs: [32]std.posix.iovec_const = undefined;
     var vec_index: usize = 0;
     {
         var padding_left = prev_padding_size;
@@ -2807,10 +2807,10 @@ fn genIncludeDirsAndFileNames(self: *Dwarf, arena: Allocator) !struct {
         const full_path = try dif.mod.root.joinString(arena, dif.sub_file_path);
         const dir_path = std.fs.path.dirname(full_path) orelse ".";
         const sub_file_path = std.fs.path.basename(full_path);
-        // TODO re-investigate if realpath is needed here
+        // https://github.com/ziglang/zig/issues/19353
         var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
         const resolved = if (!std.fs.path.isAbsolute(dir_path))
-            std.os.realpath(dir_path, &buffer) catch dir_path
+            std.posix.realpath(dir_path, &buffer) catch dir_path
         else
             dir_path;
 
src/link/Elf.zig
@@ -422,7 +422,7 @@ pub fn createEmpty(
             const index: File.Index = @intCast(try self.files.addOne(gpa));
             self.files.set(index, .{ .zig_object = .{
                 .index = index,
-                .path = try std.fmt.allocPrint(arena, "{s}.o", .{std.fs.path.stem(
+                .path = try std.fmt.allocPrint(arena, "{s}.o", .{fs.path.stem(
                     zcu.main_mod.root_src_path,
                 )}),
             } });
@@ -1673,7 +1673,7 @@ pub const ParseError = error{
     NotSupported,
     InvalidCharacter,
     UnknownFileType,
-} || LdScript.Error || std.os.AccessError || std.os.SeekError || std.fs.File.OpenError || std.fs.File.ReadError;
+} || LdScript.Error || fs.Dir.AccessError || fs.File.SeekError || fs.File.OpenError || fs.File.ReadError;
 
 pub fn parsePositional(self: *Elf, path: []const u8, must_link: bool) ParseError!void {
     const tracy = trace(@src());
@@ -1703,7 +1703,7 @@ fn parseObject(self: *Elf, path: []const u8) ParseError!void {
     defer tracy.end();
 
     const gpa = self.base.comp.gpa;
-    const handle = try std.fs.cwd().openFile(path, .{});
+    const handle = try fs.cwd().openFile(path, .{});
     const fh = try self.addFileHandle(handle);
 
     const index = @as(File.Index, @intCast(try self.files.addOne(gpa)));
@@ -1723,7 +1723,7 @@ fn parseArchive(self: *Elf, path: []const u8, must_link: bool) ParseError!void {
     defer tracy.end();
 
     const gpa = self.base.comp.gpa;
-    const handle = try std.fs.cwd().openFile(path, .{});
+    const handle = try fs.cwd().openFile(path, .{});
     const fh = try self.addFileHandle(handle);
 
     var archive = Archive{};
@@ -1749,7 +1749,7 @@ fn parseSharedObject(self: *Elf, lib: SystemLib) ParseError!void {
     defer tracy.end();
 
     const gpa = self.base.comp.gpa;
-    const handle = try std.fs.cwd().openFile(lib.path, .{});
+    const handle = try fs.cwd().openFile(lib.path, .{});
     defer handle.close();
 
     const index = @as(File.Index, @intCast(try self.files.addOne(gpa)));
@@ -1770,7 +1770,7 @@ fn parseLdScript(self: *Elf, lib: SystemLib) ParseError!void {
     defer tracy.end();
 
     const gpa = self.base.comp.gpa;
-    const in_file = try std.fs.cwd().openFile(lib.path, .{});
+    const in_file = try fs.cwd().openFile(lib.path, .{});
     defer in_file.close();
     const data = try in_file.readToEndAlloc(gpa, std.math.maxInt(u32));
     defer gpa.free(data);
@@ -5468,7 +5468,7 @@ pub fn file(self: *Elf, index: File.Index) ?File {
     };
 }
 
-pub fn addFileHandle(self: *Elf, handle: std.fs.File) !File.HandleIndex {
+pub fn addFileHandle(self: *Elf, handle: fs.File) !File.HandleIndex {
     const gpa = self.base.comp.gpa;
     const index: File.HandleIndex = @intCast(self.file_handles.items.len);
     const fh = try self.file_handles.addOne(gpa);
@@ -6045,7 +6045,7 @@ fn fmtDumpState(
 }
 
 /// Caller owns the memory.
-pub fn preadAllAlloc(allocator: Allocator, handle: std.fs.File, offset: u64, size: u64) ![]u8 {
+pub fn preadAllAlloc(allocator: Allocator, handle: fs.File, offset: u64, size: u64) ![]u8 {
     const buffer = try allocator.alloc(u8, math.cast(usize, size) orelse return error.Overflow);
     errdefer allocator.free(buffer);
     const amt = try handle.preadAll(buffer, offset);
src/link/MachO.zig
@@ -258,7 +258,7 @@ pub fn createEmpty(
             const index: File.Index = @intCast(try self.files.addOne(gpa));
             self.files.set(index, .{ .zig_object = .{
                 .index = index,
-                .path = try std.fmt.allocPrint(arena, "{s}.o", .{std.fs.path.stem(
+                .path = try std.fmt.allocPrint(arena, "{s}.o", .{fs.path.stem(
                     zcu.main_mod.root_src_path,
                 )}),
             } });
@@ -843,7 +843,7 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void {
         }
 
         for (self.frameworks) |framework| {
-            const name = std.fs.path.stem(framework.path);
+            const name = fs.path.stem(framework.path);
             const arg = if (framework.needed)
                 try std.fmt.allocPrint(arena, "-needed_framework {s}", .{name})
             else if (framework.weak)
@@ -917,7 +917,7 @@ pub const ParseError = error{
     NotSupported,
     Unhandled,
     UnknownFileType,
-} || std.os.SeekError || std.fs.File.OpenError || std.fs.File.ReadError || tapi.TapiError;
+} || fs.File.SeekError || fs.File.OpenError || fs.File.ReadError || tapi.TapiError;
 
 pub fn parsePositional(self: *MachO, path: []const u8, must_link: bool) ParseError!void {
     const tracy = trace(@src());
@@ -956,7 +956,7 @@ fn parseObject(self: *MachO, path: []const u8) ParseError!void {
     defer tracy.end();
 
     const gpa = self.base.comp.gpa;
-    const file = try std.fs.cwd().openFile(path, .{});
+    const file = try fs.cwd().openFile(path, .{});
     const handle = try self.addFileHandle(file);
     const mtime: u64 = mtime: {
         const stat = file.stat() catch break :mtime 0;
@@ -992,7 +992,7 @@ fn parseArchive(self: *MachO, lib: SystemLib, must_link: bool, fat_arch: ?fat.Ar
 
     const gpa = self.base.comp.gpa;
 
-    const file = try std.fs.cwd().openFile(lib.path, .{});
+    const file = try fs.cwd().openFile(lib.path, .{});
     const handle = try self.addFileHandle(file);
 
     var archive = Archive{};
@@ -1029,7 +1029,7 @@ fn parseDylib(self: *MachO, lib: SystemLib, explicit: bool, fat_arch: ?fat.Arch)
 
     const gpa = self.base.comp.gpa;
 
-    const file = try std.fs.cwd().openFile(lib.path, .{});
+    const file = try fs.cwd().openFile(lib.path, .{});
     defer file.close();
 
     const index = @as(File.Index, @intCast(try self.files.addOne(gpa)));
@@ -1054,7 +1054,7 @@ fn parseTbd(self: *MachO, lib: SystemLib, explicit: bool) ParseError!File.Index
     defer tracy.end();
 
     const gpa = self.base.comp.gpa;
-    const file = try std.fs.cwd().openFile(lib.path, .{});
+    const file = try fs.cwd().openFile(lib.path, .{});
     defer file.close();
 
     var lib_stub = LibStub.loadFromFile(gpa, file) catch return error.MalformedTbd; // TODO actually handle different errors
@@ -1080,10 +1080,10 @@ fn parseTbd(self: *MachO, lib: SystemLib, explicit: bool) ParseError!File.Index
 /// image unless overriden by -no_implicit_dylibs.
 fn isHoisted(self: *MachO, install_name: []const u8) bool {
     if (self.no_implicit_dylibs) return true;
-    if (std.fs.path.dirname(install_name)) |dirname| {
+    if (fs.path.dirname(install_name)) |dirname| {
         if (mem.startsWith(u8, dirname, "/usr/lib")) return true;
         if (eatPrefix(dirname, "/System/Library/Frameworks/")) |path| {
-            const basename = std.fs.path.basename(install_name);
+            const basename = fs.path.basename(install_name);
             if (mem.indexOfScalar(u8, path, '.')) |index| {
                 if (mem.eql(u8, basename, path[0..index])) return true;
             }
@@ -1105,7 +1105,7 @@ fn accessLibPath(
         test_path.clearRetainingCapacity();
         try test_path.writer().print("{s}" ++ sep ++ "lib{s}{s}", .{ search_dir, name, ext });
         try checked_paths.append(try arena.dupe(u8, test_path.items));
-        std.fs.cwd().access(test_path.items, .{}) catch |err| switch (err) {
+        fs.cwd().access(test_path.items, .{}) catch |err| switch (err) {
             error.FileNotFound => continue,
             else => |e| return e,
         };
@@ -1133,7 +1133,7 @@ fn accessFrameworkPath(
             ext,
         });
         try checked_paths.append(try arena.dupe(u8, test_path.items));
-        std.fs.cwd().access(test_path.items, .{}) catch |err| switch (err) {
+        fs.cwd().access(test_path.items, .{}) catch |err| switch (err) {
             error.FileNotFound => continue,
             else => |e| return e,
         };
@@ -1181,7 +1181,7 @@ fn parseDependentDylibs(self: *MachO) !void {
 
             const full_path = full_path: {
                 {
-                    const stem = std.fs.path.stem(id.name);
+                    const stem = fs.path.stem(id.name);
 
                     // Framework
                     for (framework_dirs) |dir| {
@@ -1197,18 +1197,18 @@ fn parseDependentDylibs(self: *MachO) !void {
                     }
                 }
 
-                if (std.fs.path.isAbsolute(id.name)) {
-                    const existing_ext = std.fs.path.extension(id.name);
+                if (fs.path.isAbsolute(id.name)) {
+                    const existing_ext = fs.path.extension(id.name);
                     const path = if (existing_ext.len > 0) id.name[0 .. id.name.len - existing_ext.len] else id.name;
                     for (&[_][]const u8{ ".tbd", ".dylib", "" }) |ext| {
                         test_path.clearRetainingCapacity();
                         if (self.base.comp.sysroot) |root| {
-                            try test_path.writer().print("{s}" ++ std.fs.path.sep_str ++ "{s}{s}", .{ root, path, ext });
+                            try test_path.writer().print("{s}" ++ fs.path.sep_str ++ "{s}{s}", .{ root, path, ext });
                         } else {
                             try test_path.writer().print("{s}{s}", .{ path, ext });
                         }
                         try checked_paths.append(try arena.dupe(u8, test_path.items));
-                        std.fs.cwd().access(test_path.items, .{}) catch |err| switch (err) {
+                        fs.cwd().access(test_path.items, .{}) catch |err| switch (err) {
                             error.FileNotFound => continue,
                             else => |e| return e,
                         };
@@ -1220,10 +1220,10 @@ fn parseDependentDylibs(self: *MachO) !void {
                     const dylib = self.getFile(dylib_index).?.dylib;
                     for (self.getFile(dylib.umbrella).?.dylib.rpaths.keys()) |rpath| {
                         const prefix = eatPrefix(rpath, "@loader_path/") orelse rpath;
-                        const rel_path = try std.fs.path.join(arena, &.{ prefix, path });
+                        const rel_path = try fs.path.join(arena, &.{ prefix, path });
                         try checked_paths.append(rel_path);
-                        var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
-                        const full_path = std.fs.realpath(rel_path, &buffer) catch continue;
+                        var buffer: [fs.MAX_PATH_BYTES]u8 = undefined;
+                        const full_path = fs.realpath(rel_path, &buffer) catch continue;
                         break :full_path try arena.dupe(u8, full_path);
                     }
                 } else if (eatPrefix(id.name, "@loader_path/")) |_| {
@@ -1235,8 +1235,8 @@ fn parseDependentDylibs(self: *MachO) !void {
                 }
 
                 try checked_paths.append(try arena.dupe(u8, id.name));
-                var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
-                if (std.fs.realpath(id.name, &buffer)) |full_path| {
+                var buffer: [fs.MAX_PATH_BYTES]u8 = undefined;
+                if (fs.realpath(id.name, &buffer)) |full_path| {
                     break :full_path try arena.dupe(u8, full_path);
                 } else |_| {
                     try self.reportMissingDependencyError(
@@ -3651,7 +3651,7 @@ pub fn getTarget(self: MachO) std.Target {
 /// into a new inode, remove the original file, and rename the copy to match
 /// the original file. This is super messy, but there doesn't seem any other
 /// way to please the XNU.
-pub fn invalidateKernelCache(dir: std.fs.Dir, sub_path: []const u8) !void {
+pub fn invalidateKernelCache(dir: fs.Dir, sub_path: []const u8) !void {
     if (comptime builtin.target.isDarwin() and builtin.target.cpu.arch == .aarch64) {
         try dir.copyFile(sub_path, dir, sub_path, .{});
     }
@@ -3839,7 +3839,7 @@ pub fn getInternalObject(self: *MachO) ?*InternalObject {
     return self.getFile(index).?.internal;
 }
 
-pub fn addFileHandle(self: *MachO, file: std.fs.File) !File.HandleIndex {
+pub fn addFileHandle(self: *MachO, file: fs.File) !File.HandleIndex {
     const gpa = self.base.comp.gpa;
     const index: File.HandleIndex = @intCast(self.file_handles.items.len);
     const fh = try self.file_handles.addOne(gpa);
@@ -4530,7 +4530,7 @@ fn inferSdkVersion(comp: *Compilation, sdk_layout: SdkLayout) ?std.SemanticVersi
 
     const sdk_dir = switch (sdk_layout) {
         .sdk => comp.sysroot.?,
-        .vendored => std.fs.path.join(arena, &.{ comp.zig_lib_directory.path.?, "libc", "darwin" }) catch return null,
+        .vendored => fs.path.join(arena, &.{ comp.zig_lib_directory.path.?, "libc", "darwin" }) catch return null,
     };
     if (readSdkVersionFromSettings(arena, sdk_dir)) |ver| {
         return parseSdkVersion(ver);
@@ -4541,7 +4541,7 @@ fn inferSdkVersion(comp: *Compilation, sdk_layout: SdkLayout) ?std.SemanticVersi
     }
 
     // infer from pathname
-    const stem = std.fs.path.stem(sdk_dir);
+    const stem = fs.path.stem(sdk_dir);
     const start = for (stem, 0..) |c, i| {
         if (std.ascii.isDigit(c)) break i;
     } else stem.len;
@@ -4556,8 +4556,8 @@ fn inferSdkVersion(comp: *Compilation, sdk_layout: SdkLayout) ?std.SemanticVersi
 // Use property `MinimalDisplayName` to determine version.
 // The file/property is also available with vendored libc.
 fn readSdkVersionFromSettings(arena: Allocator, dir: []const u8) ![]const u8 {
-    const sdk_path = try std.fs.path.join(arena, &.{ dir, "SDKSettings.json" });
-    const contents = try std.fs.cwd().readFileAlloc(arena, sdk_path, std.math.maxInt(u16));
+    const sdk_path = try fs.path.join(arena, &.{ dir, "SDKSettings.json" });
+    const contents = try fs.cwd().readFileAlloc(arena, sdk_path, std.math.maxInt(u16));
     const parsed = try std.json.parseFromSlice(std.json.Value, arena, contents, .{});
     if (parsed.value.object.get("MinimalDisplayName")) |ver| return ver.string;
     return error.SdkVersionFailure;
src/link/Plan9.zig
@@ -368,7 +368,7 @@ fn putFn(self: *Plan9, decl_index: InternPool.DeclIndex, out: FnDeclOutput) !voi
         // getting the full file path
         var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
         const full_path = try std.fs.path.join(arena, &.{
-            file.mod.root.root_dir.path orelse try std.os.getcwd(&buf),
+            file.mod.root.root_dir.path orelse try std.posix.getcwd(&buf),
             file.mod.root.sub_path,
             file.sub_file_path,
         });
@@ -722,7 +722,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: *std.Progress.Node
     defer gpa.free(got_table);
 
     // + 4 for header, got, symbols, linecountinfo
-    var iovecs = try gpa.alloc(std.os.iovec_const, self.atomCount() + 4 - self.externCount());
+    var iovecs = try gpa.alloc(std.posix.iovec_const, self.atomCount() + 4 - self.externCount());
     defer gpa.free(iovecs);
 
     const file = self.base.file.?;
src/link/Wasm.zig
@@ -3046,7 +3046,7 @@ fn writeToFile(
     }
 
     // finally, write the entire binary into the file.
-    var iovec = [_]std.os.iovec_const{.{
+    var iovec = [_]std.posix.iovec_const{.{
         .iov_base = binary_bytes.items.ptr,
         .iov_len = binary_bytes.items.len,
     }};
@@ -3709,7 +3709,7 @@ fn linkWithLLD(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) !vo
             // report a nice error here with the file path if it fails instead of
             // just returning the error code.
             // chmod does not interact with umask, so we use a conservative -rwxr--r-- here.
-            std.os.fchmodat(fs.cwd().fd, full_out_path, 0o744, 0) catch |err| switch (err) {
+            std.posix.fchmodat(fs.cwd().fd, full_out_path, 0o744, 0) catch |err| switch (err) {
                 error.OperationNotSupported => unreachable, // Not a symlink.
                 else => |e| return e,
             };
src/Package/Fetch.zig
@@ -482,7 +482,7 @@ fn runResource(
         // Compute the package hash based on the remaining files in the temporary
         // directory.
 
-        if (builtin.os.tag == .linux and f.job_queue.work_around_btrfs_bug) {
+        if (native_os == .linux and f.job_queue.work_around_btrfs_bug) {
             // https://github.com/ziglang/zig/issues/17095
             tmp_directory.handle.close();
             tmp_directory.handle = cache_root.handle.makeOpenPath(tmp_dir_sub_path, .{
@@ -1153,11 +1153,7 @@ fn unpackTarball(f: *Fetch, out_dir: fs.Dir, reader: anytype) RunError!void {
     std.tar.pipeToFileSystem(out_dir, reader, .{
         .diagnostics = &diagnostics,
         .strip_components = 1,
-        // TODO: we would like to set this to executable_bit_only, but two
-        // things need to happen before that:
-        // 1. the tar implementation needs to support it
-        // 2. the hashing algorithm here needs to support detecting the is_executable
-        //    bit on Windows from the ACLs (see the isExecutable function).
+        // https://github.com/ziglang/zig/issues/17463
         .mode_mode = .ignore,
         .exclude_empty_directories = true,
     }) catch |err| return f.fail(f.location_tok, try eb.printString(
@@ -1542,6 +1538,8 @@ fn hashFileFallible(dir: fs.Dir, hashed_file: *HashedFile) HashedFile.Error!void
         .file => {
             var file = try dir.openFile(hashed_file.fs_path, .{});
             defer file.close();
+            // When implementing https://github.com/ziglang/zig/issues/17463
+            // this will change to hard-coded `false`.
             hasher.update(&.{ 0, @intFromBool(try isExecutable(file)) });
             while (true) {
                 const bytes_read = try file.read(&buf);
@@ -1568,15 +1566,17 @@ fn deleteFileFallible(dir: fs.Dir, deleted_file: *DeletedFile) DeletedFile.Error
 }
 
 fn isExecutable(file: fs.File) !bool {
-    if (builtin.os.tag == .windows) {
-        // TODO check the ACL on Windows.
+    // When implementing https://github.com/ziglang/zig/issues/17463
+    // this function will not check the mode but instead check if the file is an ELF
+    // file or has a shebang line.
+    if (native_os == .windows) {
         // Until this is implemented, this could be a false negative on
         // Windows, which is why we do not yet set executable_bit_only above
         // when unpacking the tarball.
         return false;
     } else {
         const stat = try file.stat();
-        return (stat.mode & std.os.S.IXUSR) != 0;
+        return (stat.mode & std.posix.S.IXUSR) != 0;
     }
 }
 
@@ -1694,6 +1694,7 @@ const git = @import("Fetch/git.zig");
 const Package = @import("../Package.zig");
 const Manifest = Package.Manifest;
 const ErrorBundle = std.zig.ErrorBundle;
+const native_os = builtin.os.tag;
 
 test {
     _ = Filter;
src/Compilation.zig
@@ -1137,7 +1137,7 @@ fn addModuleTableToCacheHash(
     root_mod: *Package.Module,
     main_mod: *Package.Module,
     hash_type: union(enum) { path_bytes, files: *Cache.Manifest },
-) (error{OutOfMemory} || std.os.GetCwdError)!void {
+) (error{OutOfMemory} || std.process.GetCwdError)!void {
     var seen_table: std.AutoArrayHashMapUnmanaged(*Package.Module, void) = .{};
     defer seen_table.deinit(gpa);
 
@@ -2741,7 +2741,7 @@ const Header = extern struct {
 /// saved, such as the target and most CLI flags. A cache hit will only occur
 /// when subsequent compiler invocations use the same set of flags.
 pub fn saveState(comp: *Compilation) !void {
-    var bufs_list: [19]std.os.iovec_const = undefined;
+    var bufs_list: [19]std.posix.iovec_const = undefined;
     var bufs_len: usize = 0;
 
     const lf = comp.bin_file orelse return;
@@ -2808,7 +2808,7 @@ pub fn saveState(comp: *Compilation) !void {
     try af.finish();
 }
 
-fn addBuf(bufs_list: []std.os.iovec_const, bufs_len: *usize, buf: []const u8) void {
+fn addBuf(bufs_list: []std.posix.iovec_const, bufs_len: *usize, buf: []const u8) void {
     const i = bufs_len.*;
     bufs_len.* = i + 1;
     bufs_list[i] = .{
@@ -3791,7 +3791,7 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void {
             break :p padding_buffer[0..n];
         };
 
-        var header_and_trailer: [2]std.os.iovec_const = .{
+        var header_and_trailer: [2]std.posix.iovec_const = .{
             .{ .iov_base = header_bytes.ptr, .iov_len = header_bytes.len },
             .{ .iov_base = padding.ptr, .iov_len = padding.len },
         };
src/crash_report.zig
@@ -2,9 +2,10 @@ const std = @import("std");
 const builtin = @import("builtin");
 const build_options = @import("build_options");
 const debug = std.debug;
-const os = std.os;
 const io = std.io;
 const print_zir = @import("print_zir.zig");
+const windows = std.os.windows;
+const posix = std.posix;
 const native_os = builtin.os.tag;
 
 const Module = @import("Module.zig");
@@ -156,14 +157,14 @@ pub fn attachSegfaultHandler() void {
     if (!debug.have_segfault_handling_support) {
         @compileError("segfault handler not supported for this target");
     }
-    if (builtin.os.tag == .windows) {
-        _ = os.windows.kernel32.AddVectoredExceptionHandler(0, handleSegfaultWindows);
+    if (native_os == .windows) {
+        _ = windows.kernel32.AddVectoredExceptionHandler(0, handleSegfaultWindows);
         return;
     }
-    var act = os.Sigaction{
+    var act: posix.Sigaction = .{
         .handler = .{ .sigaction = handleSegfaultPosix },
-        .mask = os.empty_sigset,
-        .flags = (os.SA.SIGINFO | os.SA.RESTART | os.SA.RESETHAND),
+        .mask = posix.empty_sigset,
+        .flags = (posix.SA.SIGINFO | posix.SA.RESTART | posix.SA.RESETHAND),
     };
 
     debug.updateSegfaultHandler(&act) catch {
@@ -171,11 +172,11 @@ pub fn attachSegfaultHandler() void {
     };
 }
 
-fn handleSegfaultPosix(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const anyopaque) callconv(.C) noreturn {
+fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*const anyopaque) callconv(.C) noreturn {
     // TODO: use alarm() here to prevent infinite loops
     PanicSwitch.preDispatch();
 
-    const addr = switch (builtin.os.tag) {
+    const addr = switch (native_os) {
         .linux => @intFromPtr(info.fields.sigfault.addr),
         .freebsd, .macos => @intFromPtr(info.addr),
         .netbsd => @intFromPtr(info.info.reason.fault.addr),
@@ -186,9 +187,9 @@ fn handleSegfaultPosix(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const any
 
     var err_buffer: [128]u8 = undefined;
     const error_msg = switch (sig) {
-        os.SIG.SEGV => std.fmt.bufPrint(&err_buffer, "Segmentation fault at address 0x{x}", .{addr}) catch "Segmentation fault",
-        os.SIG.ILL => std.fmt.bufPrint(&err_buffer, "Illegal instruction at address 0x{x}", .{addr}) catch "Illegal instruction",
-        os.SIG.BUS => std.fmt.bufPrint(&err_buffer, "Bus error at address 0x{x}", .{addr}) catch "Bus error",
+        posix.SIG.SEGV => std.fmt.bufPrint(&err_buffer, "Segmentation fault at address 0x{x}", .{addr}) catch "Segmentation fault",
+        posix.SIG.ILL => std.fmt.bufPrint(&err_buffer, "Illegal instruction at address 0x{x}", .{addr}) catch "Illegal instruction",
+        posix.SIG.BUS => std.fmt.bufPrint(&err_buffer, "Bus error at address 0x{x}", .{addr}) catch "Bus error",
         else => std.fmt.bufPrint(&err_buffer, "Unknown error (signal {}) at address 0x{x}", .{ sig, addr }) catch "Unknown error",
     };
 
@@ -210,20 +211,20 @@ const WindowsSegfaultMessage = union(enum) {
     illegal_instruction: void,
 };
 
-fn handleSegfaultWindows(info: *os.windows.EXCEPTION_POINTERS) callconv(os.windows.WINAPI) c_long {
+fn handleSegfaultWindows(info: *windows.EXCEPTION_POINTERS) callconv(windows.WINAPI) c_long {
     switch (info.ExceptionRecord.ExceptionCode) {
-        os.windows.EXCEPTION_DATATYPE_MISALIGNMENT => handleSegfaultWindowsExtra(info, .{ .literal = "Unaligned Memory Access" }),
-        os.windows.EXCEPTION_ACCESS_VIOLATION => handleSegfaultWindowsExtra(info, .segfault),
-        os.windows.EXCEPTION_ILLEGAL_INSTRUCTION => handleSegfaultWindowsExtra(info, .illegal_instruction),
-        os.windows.EXCEPTION_STACK_OVERFLOW => handleSegfaultWindowsExtra(info, .{ .literal = "Stack Overflow" }),
-        else => return os.windows.EXCEPTION_CONTINUE_SEARCH,
+        windows.EXCEPTION_DATATYPE_MISALIGNMENT => handleSegfaultWindowsExtra(info, .{ .literal = "Unaligned Memory Access" }),
+        windows.EXCEPTION_ACCESS_VIOLATION => handleSegfaultWindowsExtra(info, .segfault),
+        windows.EXCEPTION_ILLEGAL_INSTRUCTION => handleSegfaultWindowsExtra(info, .illegal_instruction),
+        windows.EXCEPTION_STACK_OVERFLOW => handleSegfaultWindowsExtra(info, .{ .literal = "Stack Overflow" }),
+        else => return windows.EXCEPTION_CONTINUE_SEARCH,
     }
 }
 
-fn handleSegfaultWindowsExtra(info: *os.windows.EXCEPTION_POINTERS, comptime msg: WindowsSegfaultMessage) noreturn {
+fn handleSegfaultWindowsExtra(info: *windows.EXCEPTION_POINTERS, comptime msg: WindowsSegfaultMessage) noreturn {
     PanicSwitch.preDispatch();
 
-    const stack_ctx = if (@hasDecl(os.windows, "CONTEXT"))
+    const stack_ctx = if (@hasDecl(windows, "CONTEXT"))
         StackContext{ .exception = info.ContextRecord }
     else ctx: {
         const addr = @intFromPtr(info.ExceptionRecord.ExceptionAddress);
@@ -488,7 +489,7 @@ const PanicSwitch = struct {
     }
 
     noinline fn abort() noreturn {
-        os.abort();
+        std.process.abort();
     }
 
     inline fn goTo(comptime func: anytype, args: anytype) noreturn {
src/DarwinPosixSpawn.zig
@@ -0,0 +1,224 @@
+const errno = std.posix.errno;
+const unexpectedErrno = std.posix.unexpectedErrno;
+
+pub const Error = error{
+    SystemResources,
+    InvalidFileDescriptor,
+    NameTooLong,
+    TooBig,
+    PermissionDenied,
+    InputOutput,
+    FileSystem,
+    FileNotFound,
+    InvalidExe,
+    NotDir,
+    FileBusy,
+    /// Returned when the child fails to execute either in the pre-exec() initialization step, or
+    /// when exec(3) is invoked.
+    ChildExecFailed,
+} || std.posix.UnexpectedError;
+
+pub const Attr = struct {
+    attr: std.c.posix_spawnattr_t,
+
+    pub fn init() Error!Attr {
+        var attr: std.c.posix_spawnattr_t = undefined;
+        switch (errno(std.c.posix_spawnattr_init(&attr))) {
+            .SUCCESS => return Attr{ .attr = attr },
+            .NOMEM => return error.SystemResources,
+            .INVAL => unreachable,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+
+    pub fn deinit(self: *Attr) void {
+        defer self.* = undefined;
+        switch (errno(std.c.posix_spawnattr_destroy(&self.attr))) {
+            .SUCCESS => return,
+            .INVAL => unreachable, // Invalid parameters.
+            else => unreachable,
+        }
+    }
+
+    pub fn get(self: Attr) Error!u16 {
+        var flags: c_short = undefined;
+        switch (errno(std.c.posix_spawnattr_getflags(&self.attr, &flags))) {
+            .SUCCESS => return @as(u16, @bitCast(flags)),
+            .INVAL => unreachable,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+
+    pub fn set(self: *Attr, flags: u16) Error!void {
+        switch (errno(std.c.posix_spawnattr_setflags(&self.attr, @as(c_short, @bitCast(flags))))) {
+            .SUCCESS => return,
+            .INVAL => unreachable,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+};
+
+pub const Actions = struct {
+    actions: std.c.posix_spawn_file_actions_t,
+
+    pub fn init() Error!Actions {
+        var actions: std.c.posix_spawn_file_actions_t = undefined;
+        switch (errno(std.c.posix_spawn_file_actions_init(&actions))) {
+            .SUCCESS => return Actions{ .actions = actions },
+            .NOMEM => return error.SystemResources,
+            .INVAL => unreachable,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+
+    pub fn deinit(self: *Actions) void {
+        defer self.* = undefined;
+        switch (errno(std.c.posix_spawn_file_actions_destroy(&self.actions))) {
+            .SUCCESS => return,
+            .INVAL => unreachable, // Invalid parameters.
+            else => unreachable,
+        }
+    }
+
+    pub fn open(self: *Actions, fd: std.c.fd_t, path: []const u8, flags: u32, mode: std.c.mode_t) Error!void {
+        const posix_path = try std.os.toPosixPath(path);
+        return self.openZ(fd, &posix_path, flags, mode);
+    }
+
+    pub fn openZ(self: *Actions, fd: std.c.fd_t, path: [*:0]const u8, flags: u32, mode: std.c.mode_t) Error!void {
+        switch (errno(std.c.posix_spawn_file_actions_addopen(&self.actions, fd, path, @as(c_int, @bitCast(flags)), mode))) {
+            .SUCCESS => return,
+            .BADF => return error.InvalidFileDescriptor,
+            .NOMEM => return error.SystemResources,
+            .NAMETOOLONG => return error.NameTooLong,
+            .INVAL => unreachable, // the value of file actions is invalid
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+
+    pub fn close(self: *Actions, fd: std.c.fd_t) Error!void {
+        switch (errno(std.c.posix_spawn_file_actions_addclose(&self.actions, fd))) {
+            .SUCCESS => return,
+            .BADF => return error.InvalidFileDescriptor,
+            .NOMEM => return error.SystemResources,
+            .INVAL => unreachable, // the value of file actions is invalid
+            .NAMETOOLONG => unreachable,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+
+    pub fn dup2(self: *Actions, fd: std.c.fd_t, newfd: std.c.fd_t) Error!void {
+        switch (errno(std.c.posix_spawn_file_actions_adddup2(&self.actions, fd, newfd))) {
+            .SUCCESS => return,
+            .BADF => return error.InvalidFileDescriptor,
+            .NOMEM => return error.SystemResources,
+            .INVAL => unreachable, // the value of file actions is invalid
+            .NAMETOOLONG => unreachable,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+
+    pub fn inherit(self: *Actions, fd: std.c.fd_t) Error!void {
+        switch (errno(std.c.posix_spawn_file_actions_addinherit_np(&self.actions, fd))) {
+            .SUCCESS => return,
+            .BADF => return error.InvalidFileDescriptor,
+            .NOMEM => return error.SystemResources,
+            .INVAL => unreachable, // the value of file actions is invalid
+            .NAMETOOLONG => unreachable,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+
+    pub fn chdir(self: *Actions, path: []const u8) Error!void {
+        const posix_path = try std.os.toPosixPath(path);
+        return self.chdirZ(&posix_path);
+    }
+
+    pub fn chdirZ(self: *Actions, path: [*:0]const u8) Error!void {
+        switch (errno(std.c.posix_spawn_file_actions_addchdir_np(&self.actions, path))) {
+            .SUCCESS => return,
+            .NOMEM => return error.SystemResources,
+            .NAMETOOLONG => return error.NameTooLong,
+            .BADF => unreachable,
+            .INVAL => unreachable, // the value of file actions is invalid
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+
+    pub fn fchdir(self: *Actions, fd: std.c.fd_t) Error!void {
+        switch (errno(std.c.posix_spawn_file_actions_addfchdir_np(&self.actions, fd))) {
+            .SUCCESS => return,
+            .BADF => return error.InvalidFileDescriptor,
+            .NOMEM => return error.SystemResources,
+            .INVAL => unreachable, // the value of file actions is invalid
+            .NAMETOOLONG => unreachable,
+            else => |err| return unexpectedErrno(err),
+        }
+    }
+};
+
+pub fn spawn(
+    path: []const u8,
+    actions: ?Actions,
+    attr: ?Attr,
+    argv: [*:null]?[*:0]const u8,
+    envp: [*:null]?[*:0]const u8,
+) Error!std.c.pid_t {
+    const posix_path = try std.os.toPosixPath(path);
+    return spawnZ(&posix_path, actions, attr, argv, envp);
+}
+
+pub fn spawnZ(
+    path: [*:0]const u8,
+    actions: ?Actions,
+    attr: ?Attr,
+    argv: [*:null]?[*:0]const u8,
+    envp: [*:null]?[*:0]const u8,
+) Error!std.c.pid_t {
+    var pid: std.c.pid_t = undefined;
+    switch (errno(std.c.posix_spawn(
+        &pid,
+        path,
+        if (actions) |a| &a.actions else null,
+        if (attr) |a| &a.attr else null,
+        argv,
+        envp,
+    ))) {
+        .SUCCESS => return pid,
+        .@"2BIG" => return error.TooBig,
+        .NOMEM => return error.SystemResources,
+        .BADF => return error.InvalidFileDescriptor,
+        .ACCES => return error.PermissionDenied,
+        .IO => return error.InputOutput,
+        .LOOP => return error.FileSystem,
+        .NAMETOOLONG => return error.NameTooLong,
+        .NOENT => return error.FileNotFound,
+        .NOEXEC => return error.InvalidExe,
+        .NOTDIR => return error.NotDir,
+        .TXTBSY => return error.FileBusy,
+        .BADARCH => return error.InvalidExe,
+        .BADEXEC => return error.InvalidExe,
+        .FAULT => unreachable,
+        .INVAL => unreachable,
+        else => |err| return unexpectedErrno(err),
+    }
+}
+
+pub fn waitpid(pid: std.c.pid_t, flags: u32) Error!std.os.WaitPidResult {
+    var status: c_int = undefined;
+    while (true) {
+        const rc = waitpid(pid, &status, @as(c_int, @intCast(flags)));
+        switch (errno(rc)) {
+            .SUCCESS => return std.os.WaitPidResult{
+                .pid = @as(std.c.pid_t, @intCast(rc)),
+                .status = @as(u32, @bitCast(status)),
+            },
+            .INTR => continue,
+            .CHILD => return error.ChildExecFailed,
+            .INVAL => unreachable, // Invalid flags.
+            else => unreachable,
+        }
+    }
+}
+
+const std = @import("std");
src/link.zig
@@ -254,7 +254,7 @@ pub const File = struct {
                         try emit.directory.handle.copyFile(emit.sub_path, emit.directory.handle, tmp_sub_path, .{});
                         try emit.directory.handle.rename(tmp_sub_path, emit.sub_path);
                         switch (builtin.os.tag) {
-                            .linux => std.os.ptrace(std.os.linux.PTRACE.ATTACH, pid, 0, 0) catch |err| {
+                            .linux => std.posix.ptrace(std.os.linux.PTRACE.ATTACH, pid, 0, 0) catch |err| {
                                 log.warn("ptrace failure: {s}", .{@errorName(err)});
                             },
                             .macos => base.cast(MachO).?.ptraceAttach(pid) catch |err| {
@@ -305,7 +305,7 @@ pub const File = struct {
 
                 if (base.child_pid) |pid| {
                     switch (builtin.os.tag) {
-                        .linux => std.os.ptrace(std.os.linux.PTRACE.DETACH, pid, 0, 0) catch |err| {
+                        .linux => std.posix.ptrace(std.os.linux.PTRACE.DETACH, pid, 0, 0) catch |err| {
                             log.warn("ptrace failure: {s}", .{@errorName(err)});
                         },
                         else => return error.HotSwapUnavailableOnHostOperatingSystem,
src/main.zig
@@ -48,7 +48,7 @@ pub const panic = crash_report.panic;
 var wasi_preopens: fs.wasi.Preopens = undefined;
 pub fn wasi_cwd() std.os.wasi.fd_t {
     // Expect the first preopen to be current working directory.
-    const cwd_fd: std.os.fd_t = 3;
+    const cwd_fd: std.posix.fd_t = 3;
     assert(mem.eql(u8, wasi_preopens.names[cwd_fd], "."));
     return cwd_fd;
 }
@@ -222,7 +222,7 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
         fatal("expected command argument", .{});
     }
 
-    if (process.can_execv and std.os.getenvZ("ZIG_IS_DETECTING_LIBC_PATHS") != null) {
+    if (process.can_execv and std.posix.getenvZ("ZIG_IS_DETECTING_LIBC_PATHS") != null) {
         // In this case we have accidentally invoked ourselves as "the system C compiler"
         // to figure out where libc is installed. This is essentially infinite recursion
         // via child process execution due to the CC environment variable pointing to Zig.
@@ -4434,16 +4434,16 @@ fn runOrTestHotSwap(
 
     switch (builtin.target.os.tag) {
         .macos, .ios, .tvos, .watchos => {
-            const PosixSpawn = std.os.darwin.PosixSpawn;
+            const PosixSpawn = @import("DarwinPosixSpawn.zig");
 
             var attr = try PosixSpawn.Attr.init();
             defer attr.deinit();
 
             // ASLR is probably a good default for better debugging experience/programming
             // with hot-code updates in mind. However, we can also make it work with ASLR on.
-            const flags: u16 = std.os.darwin.POSIX_SPAWN.SETSIGDEF |
-                std.os.darwin.POSIX_SPAWN.SETSIGMASK |
-                std.os.darwin.POSIX_SPAWN.DISABLE_ASLR;
+            const flags: u16 = std.c.POSIX_SPAWN.SETSIGDEF |
+                std.c.POSIX_SPAWN.SETSIGMASK |
+                std.c.POSIX_SPAWN.DISABLE_ASLR;
             try attr.set(flags);
 
             var arena_allocator = std.heap.ArenaAllocator.init(gpa);
@@ -5985,8 +5985,8 @@ fn parseCodeModel(arg: []const u8) std.builtin.CodeModel {
 /// garbage collector to run concurrently to zig processes, and to allow multiple
 /// zig processes to run concurrently with each other, without clobbering each other.
 fn gimmeMoreOfThoseSweetSweetFileDescriptors() void {
-    if (!@hasDecl(std.os.system, "rlimit")) return;
-    const posix = std.os;
+    const posix = std.posix;
+    if (!@hasDecl(posix, "rlimit")) return;
 
     var lim = posix.getrlimit(.NOFILE) catch return; // Oh well; we tried.
     if (comptime builtin.target.isDarwin()) {
src/Module.zig
@@ -2396,7 +2396,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void {
         .stat_inode = stat.inode,
         .stat_mtime = stat.mtime,
     };
-    var iovecs = [_]std.os.iovec_const{
+    var iovecs = [_]std.posix.iovec_const{
         .{
             .iov_base = @as([*]const u8, @ptrCast(&header)),
             .iov_len = @sizeOf(Zir.Header),
@@ -2484,7 +2484,7 @@ fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_file: std.fs.File)
     else
         @as([*]u8, @ptrCast(zir.instructions.items(.data).ptr));
 
-    var iovecs = [_]std.os.iovec{
+    var iovecs = [_]std.posix.iovec{
         .{
             .iov_base = @as([*]u8, @ptrCast(zir.instructions.items(.tag).ptr)),
             .iov_len = header.instructions_len,
build.zig
@@ -882,7 +882,7 @@ fn findConfigH(b: *std.Build, config_h_path_option: ?[]const u8) ?[]const u8 {
             return path;
         } else |_| {
             std.log.err("Could not open provided config.h: \"{s}\"", .{path});
-            std.os.exit(1);
+            std.process.exit(1);
         }
     }
 
CMakeLists.txt
@@ -286,7 +286,6 @@ set(ZIG_STAGE2_SOURCES
     "${CMAKE_SOURCE_DIR}/lib/std/multi_array_list.zig"
     "${CMAKE_SOURCE_DIR}/lib/std/os.zig"
     "${CMAKE_SOURCE_DIR}/lib/std/os/linux.zig"
-    "${CMAKE_SOURCE_DIR}/lib/std/os/linux/errno/generic.zig"
     "${CMAKE_SOURCE_DIR}/lib/std/os/linux/x86_64.zig"
     "${CMAKE_SOURCE_DIR}/lib/std/os/linux.zig"
     "${CMAKE_SOURCE_DIR}/lib/std/os/linux/IoUring.zig"