//! Cross-platform "system call" abstractions. On linux, many of these functions
//! emit direct system calls directly (std.os.linux). Others call `libc` APIs.
//! Windows uses a mix of `libuv`, `kernel32` and `ntdll`. macOS uses `libc`.
//!
//! Sometimes this namespace is referred to as "Syscall", prefer "bun.sys"/"sys"
//
// TODO: Split and organize this file. It is likely worth moving many functions
// into methods on `bun.FD`, and keeping this namespace to just overall stuff
// like `Error`, `Maybe`, `Tag`, and so on.
const sys = @This(); // to avoid ambiguous references.
const platform_defs = switch (Environment.os) {
    .windows => @import("errno/windows_errno.zig"),
    .linux => @import("errno/linux_errno.zig"),
    .mac => @import("errno/darwin_errno.zig"),
    .wasm => {},
};
pub const workaround_symbols = @import("workaround_missing_symbols.zig").current;
/// Enum of `errno` values
pub const E = platform_defs.E;
/// Namespace of (potentially polyfilled) libuv `errno` values.
/// Polyfilled on posix, mirrors the real libuv definitions on Windows.
pub const UV_E = platform_defs.UV_E;
pub const S = platform_defs.S;
/// TODO: The way we do errors in Bun needs to get cleaned up. This enum is way
/// too complicated; It's duplicated three times, and inside of it it has tons
/// of re-listings of all errno codes. Why is SystemErrno different than `E`? ...etc!
///
/// The problem is because we use libc in some cases and we use zig's std lib in
/// other places and other times we go direct. So we end up with a lot of
/// redundant code.
pub const SystemErrno = platform_defs.SystemErrno;
pub const getErrno = platform_defs.getErrno;

comptime {
    _ = &workaround_symbols; // execute comptime logic to export any needed symbols
}

const std = @import("std");
const builtin = @import("builtin");

const bun = @import("bun");
const c = bun.c; // translated c headers
const posix = std.posix;

const assertIsValidWindowsPath = bun.strings.assertIsValidWindowsPath;
const default_allocator = bun.default_allocator;
const kernel32 = bun.windows.kernel32;
const ntdll = bun.windows.ntdll;
const mem = std.mem;
const page_size_min = std.heap.page_size_min;
const mode_t = posix.mode_t;
const libc = std.posix.system;

const windows = bun.windows;

const Environment = bun.Environment;
const JSC = bun.JSC;
const MAX_PATH_BYTES = bun.MAX_PATH_BYTES;
const SystemError = JSC.SystemError;

const linux = syscall;

pub const sys_uv = if (Environment.isWindows) @import("./sys_uv.zig") else sys;

pub const F_OK = 0;
pub const X_OK = 1;
pub const W_OK = 2;
pub const R_OK = 4;

const log = bun.Output.scoped(.SYS, false);
pub const syslog = log;

pub const syscall = switch (Environment.os) {
    .linux => std.os.linux,
    // macOS requires using libc
    .mac => std.c,
    else => @compileError("not implemented"),
};

const darwin_nocancel = bun.darwin.nocancel;

fn toPackedO(number: anytype) std.posix.O {
    return @bitCast(number);
}

pub const Mode = std.posix.mode_t;

pub const O = switch (Environment.os) {
    .mac => struct {
        pub const PATH = 0x0000;
        pub const RDONLY = 0x0000;
        pub const WRONLY = 0x0001;
        pub const RDWR = 0x0002;
        pub const NONBLOCK = 0x0004;
        pub const APPEND = 0x0008;
        pub const CREAT = 0x0200;
        pub const TRUNC = 0x0400;
        pub const EXCL = 0x0800;
        pub const SHLOCK = 0x0010;
        pub const EXLOCK = 0x0020;
        pub const NOFOLLOW = 0x0100;
        pub const SYMLINK = 0x200000;
        pub const EVTONLY = 0x8000;
        pub const CLOEXEC = 0x01000000;
        pub const ACCMODE = 3;
        pub const ALERT = 536870912;
        pub const ASYNC = 64;
        pub const DIRECTORY = 0x00100000;
        pub const DP_GETRAWENCRYPTED = 1;
        pub const DP_GETRAWUNENCRYPTED = 2;
        pub const DSYNC = 4194304;
        pub const FSYNC = SYNC;
        pub const NOCTTY = 131072;
        pub const POPUP = 2147483648;
        pub const SYNC = 128;

        pub const toPacked = toPackedO;
    },
    .linux, .wasm => switch (Environment.isX86) {
        true => struct {
            pub const RDONLY = 0x0000;
            pub const WRONLY = 0x0001;
            pub const RDWR = 0x0002;

            pub const CREAT = 0o100;
            pub const EXCL = 0o200;
            pub const NOCTTY = 0o400;
            pub const TRUNC = 0o1000;
            pub const APPEND = 0o2000;
            pub const NONBLOCK = 0o4000;
            pub const DSYNC = 0o10000;
            pub const SYNC = 0o4010000;
            pub const RSYNC = 0o4010000;
            pub const DIRECTORY = 0o200000;
            pub const NOFOLLOW = 0o400000;
            pub const CLOEXEC = 0o2000000;

            pub const ASYNC = 0o20000;
            pub const DIRECT = 0o40000;
            pub const LARGEFILE = 0;
            pub const NOATIME = 0o1000000;
            pub const PATH = 0o10000000;
            pub const TMPFILE = 0o20200000;
            pub const NDELAY = NONBLOCK;

            pub const toPacked = toPackedO;
        },
        false => struct {
            pub const RDONLY = 0x0000;
            pub const WRONLY = 0x0001;
            pub const RDWR = 0x0002;

            pub const CREAT = 0o100;
            pub const EXCL = 0o200;
            pub const NOCTTY = 0o400;
            pub const TRUNC = 0o1000;
            pub const APPEND = 0o2000;
            pub const NONBLOCK = 0o4000;
            pub const DSYNC = 0o10000;
            pub const SYNC = 0o4010000;
            pub const RSYNC = 0o4010000;
            pub const DIRECTORY = 0o40000;
            pub const NOFOLLOW = 0o100000;
            pub const CLOEXEC = 0o2000000;

            pub const ASYNC = 0o20000;
            pub const DIRECT = 0o200000;
            pub const LARGEFILE = 0o400000;
            pub const NOATIME = 0o1000000;
            pub const PATH = 0o10000000;
            pub const TMPFILE = 0o20040000;
            pub const NDELAY = NONBLOCK;

            pub const SYMLINK = c.O_SYMLINK;

            pub const toPacked = toPackedO;
        },
    },
    .windows => struct {
        pub const RDONLY = 0o0;
        pub const WRONLY = 0o1;
        pub const RDWR = 0o2;

        pub const CREAT = 0o100;
        pub const EXCL = 0o200;
        pub const NOCTTY = 0;
        pub const TRUNC = 0o1000;
        pub const APPEND = 0o2000;
        pub const NONBLOCK = 0o4000;
        pub const DSYNC = 0o10000;
        pub const SYNC = 0o4010000;
        pub const RSYNC = 0o4010000;
        pub const DIRECTORY = 0o200000;
        pub const NOFOLLOW = 0o400000;
        pub const CLOEXEC = 0o2000000;

        pub const ASYNC = 0o20000;
        pub const DIRECT = 0o40000;
        pub const LARGEFILE = 0;
        pub const NOATIME = 0o1000000;
        pub const PATH = 0o10000000;
        pub const TMPFILE = 0o20200000;
        pub const NDELAY = NONBLOCK;

        pub const toPacked = toPackedO;
    },
};

pub const Tag = enum(u8) {
    TODO,

    dup,
    access,
    connect,
    chmod,
    chown,
    clonefile,
    close,
    copy_file_range,
    copyfile,
    fchmod,
    fchmodat,
    fchown,
    fcntl,
    fdatasync,
    fstat,
    fstatat,
    fsync,
    ftruncate,
    futimens,
    getdents64,
    getdirentries64,
    lchmod,
    lchown,
    link,
    lseek,
    lstat,
    lutime,
    mkdir,
    mkdtemp,
    fnctl,
    memfd_create,
    mmap,
    munmap,
    open,
    pread,
    pwrite,
    read,
    readlink,
    rename,
    stat,
    statfs,
    symlink,
    symlinkat,
    unlink,
    utime,
    utimensat,
    write,
    getcwd,
    getenv,
    chdir,
    fcopyfile,
    recv,
    send,
    sendfile,
    sendmmsg,
    splice,
    rmdir,
    truncate,
    realpath,
    futime,
    pidfd_open,
    poll,
    watch,
    scandir,

    kevent,
    kqueue,
    epoll_ctl,
    kill,
    waitpid,
    posix_spawn,
    getaddrinfo,
    writev,
    pwritev,
    readv,
    preadv,
    ioctl_ficlone,
    accept,
    bind2,
    connect2,
    listen,
    pipe,
    try_write,
    socketpair,
    setsockopt,
    statx,
    rm,

    uv_spawn,
    uv_pipe,
    uv_tty_set_mode,
    uv_open_osfhandle,
    uv_os_homedir,

    // Below this line are Windows API calls only.

    WriteFile,
    NtQueryDirectoryFile,
    NtSetInformationFile,
    GetFinalPathNameByHandle,
    CloseHandle,
    SetFilePointerEx,
    SetEndOfFile,

    pub fn isWindows(this: Tag) bool {
        return @intFromEnum(this) > @intFromEnum(Tag.WriteFile);
    }

    pub var strings = std.EnumMap(Tag, JSC.C.JSStringRef).initFull(null);
};

pub const Error = struct {
    const retry_errno = if (Environment.isLinux)
        @as(Int, @intCast(@intFromEnum(E.AGAIN)))
    else if (Environment.isMac)
        @as(Int, @intCast(@intFromEnum(E.AGAIN)))
    else
        @as(Int, @intCast(@intFromEnum(E.INTR)));

    const todo_errno = std.math.maxInt(Int) - 1;

    pub const Int = u16;

    /// TODO: convert to function
    pub const oom = fromCode(E.NOMEM, .read);

    errno: Int = todo_errno,
    fd: bun.FileDescriptor = bun.invalid_fd,
    from_libuv: if (Environment.isWindows) bool else void = if (Environment.isWindows) false else undefined,
    path: []const u8 = "",
    syscall: sys.Tag = sys.Tag.TODO,
    dest: []const u8 = "",

    pub fn clone(this: *const Error, allocator: std.mem.Allocator) !Error {
        var copy = this.*;
        copy.path = try allocator.dupe(u8, copy.path);
        copy.dest = try allocator.dupe(u8, copy.dest);
        return copy;
    }

    pub fn fromCode(errno: E, syscall_tag: sys.Tag) Error {
        return .{
            .errno = @as(Int, @intCast(@intFromEnum(errno))),
            .syscall = syscall_tag,
        };
    }

    pub fn fromCodeInt(errno: anytype, syscall_tag: sys.Tag) Error {
        return .{
            .errno = @as(Int, @intCast(if (Environment.isWindows) @abs(errno) else errno)),
            .syscall = syscall_tag,
        };
    }

    pub fn format(self: Error, comptime fmt: []const u8, opts: std.fmt.FormatOptions, writer: anytype) !void {
        // We want to reuse the code from SystemError for formatting.
        // But, we do not want to call String.createUTF8 on the path/dest strings
        // because we're intending to pass them to writer.print()
        // which will convert them back into UTF*.
        var that = self.withoutPath().toShellSystemError();
        bun.debugAssert(that.path.tag != .WTFStringImpl);
        bun.debugAssert(that.dest.tag != .WTFStringImpl);
        that.path = bun.String.fromUTF8(self.path);
        that.dest = bun.String.fromUTF8(self.dest);
        bun.debugAssert(that.path.tag != .WTFStringImpl);
        bun.debugAssert(that.dest.tag != .WTFStringImpl);

        return that.format(fmt, opts, writer);
    }

    pub inline fn getErrno(this: Error) E {
        return @as(E, @enumFromInt(this.errno));
    }

    pub inline fn isRetry(this: *const Error) bool {
        return this.getErrno() == .AGAIN;
    }

    pub const retry = Error{
        .errno = retry_errno,
        .syscall = .read,
    };

    pub inline fn withFd(this: Error, fd: anytype) Error {
        if (Environment.allow_assert) bun.assert(fd != bun.invalid_fd);
        return Error{
            .errno = this.errno,
            .syscall = this.syscall,
            .fd = fd,
        };
    }

    pub inline fn withPath(this: Error, path: anytype) Error {
        if (std.meta.Child(@TypeOf(path)) == u16) {
            @compileError("Do not pass WString path to withPath, it needs the path encoded as utf8");
        }
        return Error{
            .errno = this.errno,
            .syscall = this.syscall,
            .path = bun.span(path),
        };
    }

    pub inline fn withPathAndSyscall(this: Error, path: anytype, syscall_: sys.Tag) Error {
        if (std.meta.Child(@TypeOf(path)) == u16) {
            @compileError("Do not pass WString path to withPath, it needs the path encoded as utf8");
        }
        return Error{
            .errno = this.errno,
            .syscall = syscall_,
            .path = bun.span(path),
        };
    }

    pub inline fn withPathDest(this: Error, path: anytype, dest: anytype) Error {
        if (std.meta.Child(@TypeOf(path)) == u16) {
            @compileError("Do not pass WString path to withPathDest, it needs the path encoded as utf8 (path)");
        }
        if (std.meta.Child(@TypeOf(dest)) == u16) {
            @compileError("Do not pass WString path to withPathDest, it needs the path encoded as utf8 (dest)");
        }
        return Error{
            .errno = this.errno,
            .syscall = this.syscall,
            .path = bun.span(path),
            .dest = bun.span(dest),
        };
    }

    pub inline fn withPathLike(this: Error, pathlike: anytype) Error {
        return switch (pathlike) {
            .fd => |fd| this.withFd(fd),
            .path => |path| this.withPath(path.slice()),
        };
    }

    /// When the memory of the path/dest buffer is unsafe to use, call this function to clone the error without the path/dest.
    pub fn withoutPath(this: *const Error) Error {
        var copy = this.*;
        copy.path = "";
        copy.dest = "";
        return copy;
    }

    pub fn name(this: *const Error) []const u8 {
        if (comptime Environment.isWindows) {
            const system_errno = brk: {
                // setRuntimeSafety(false) because we use tagName function, which will be null on invalid enum value.
                @setRuntimeSafety(false);
                if (this.from_libuv) {
                    break :brk @as(SystemErrno, @enumFromInt(@intFromEnum(bun.windows.libuv.translateUVErrorToE(this.errno))));
                }

                break :brk @as(SystemErrno, @enumFromInt(this.errno));
            };
            if (bun.tagName(SystemErrno, system_errno)) |errname| {
                return errname;
            }
        } else if (this.errno > 0 and this.errno < SystemErrno.max) {
            const system_errno = @as(SystemErrno, @enumFromInt(this.errno));
            if (bun.tagName(SystemErrno, system_errno)) |errname| {
                return errname;
            }
        }

        return "UNKNOWN";
    }

    pub fn toZigErr(this: Error) anyerror {
        return bun.errnoToZigErr(this.errno);
    }

    /// 1. Convert libuv errno values into libc ones.
    /// 2. Get the tag name as a string for printing.
    pub fn getErrorCodeTagName(err: *const Error) ?struct { [:0]const u8, SystemErrno } {
        if (!Environment.isWindows) {
            if (err.errno > 0 and err.errno < SystemErrno.max) {
                const system_errno = @as(SystemErrno, @enumFromInt(err.errno));
                return .{ @tagName(system_errno), system_errno };
            }
        } else {
            const system_errno: SystemErrno = brk: {
                // setRuntimeSafety(false) because we use tagName function, which will be null on invalid enum value.
                @setRuntimeSafety(false);
                if (err.from_libuv) {
                    break :brk @enumFromInt(@intFromEnum(bun.windows.libuv.translateUVErrorToE(@as(c_int, err.errno) * -1)));
                }

                break :brk @enumFromInt(err.errno);
            };
            if (bun.tagName(SystemErrno, system_errno)) |errname| {
                return .{ errname, system_errno };
            }
        }
        return null;
    }

    /// Simpler formatting which does not allocate a message
    pub fn toShellSystemError(this: Error) SystemError {
        @setEvalBranchQuota(1_000_000);
        var err = SystemError{
            .errno = @as(c_int, this.errno) * -1,
            .syscall = bun.String.static(@tagName(this.syscall)),
        };

        // errno label
        if (this.getErrorCodeTagName()) |resolved_errno| {
            const code, const system_errno = resolved_errno;
            err.code = bun.String.static(code);
            if (coreutils_error_map.get(system_errno)) |label| {
                err.message = bun.String.static(label);
            }
        }

        if (this.path.len > 0) {
            err.path = bun.String.createUTF8(this.path);
        }

        if (this.dest.len > 0) {
            err.dest = bun.String.createUTF8(this.dest);
        }

        if (this.fd.unwrapValid()) |valid| {
            // When the FD is a windows handle, there is no sane way to report this.
            if (!Environment.isWindows or valid.kind == .uv) {
                err.fd = valid.uv();
            }
        }

        return err;
    }

    /// More complex formatting to precisely match the printing that Node.js emits.
    /// Use this whenever the error will be sent to JavaScript instead of the shell variant above.
    pub fn toSystemError(this: Error) SystemError {
        var err = SystemError{
            .errno = -%@as(c_int, this.errno),
            .syscall = bun.String.static(@tagName(this.syscall)),
        };

        // errno label
        var maybe_code: ?[:0]const u8 = null;
        var label: ?[]const u8 = null;
        if (this.getErrorCodeTagName()) |resolved_errno| {
            maybe_code, const system_errno = resolved_errno;
            err.code = bun.String.static(maybe_code.?);
            label = libuv_error_map.get(system_errno);
        }

        // format taken from Node.js 'exceptions.cc'
        // search keyword: `Local<Value> UVException(Isolate* isolate,`
        var message_buf: [4096]u8 = undefined;
        const message = message: {
            var stream = std.io.fixedBufferStream(&message_buf);
            const writer = stream.writer();
            brk: {
                if (maybe_code) |code| {
                    writer.writeAll(code) catch break :brk;
                    writer.writeAll(": ") catch break :brk;
                }
                writer.writeAll(label orelse "Unknown Error") catch break :brk;
                writer.writeAll(", ") catch break :brk;
                writer.writeAll(@tagName(this.syscall)) catch break :brk;
                if (this.path.len > 0) {
                    writer.writeAll(" '") catch break :brk;
                    writer.writeAll(this.path) catch break :brk;
                    writer.writeAll("'") catch break :brk;

                    if (this.dest.len > 0) {
                        writer.writeAll(" -> '") catch break :brk;
                        writer.writeAll(this.dest) catch break :brk;
                        writer.writeAll("'") catch break :brk;
                    }
                }
            }
            break :message stream.getWritten();
        };
        err.message = bun.String.createUTF8(message);

        if (this.path.len > 0) {
            err.path = bun.String.createUTF8(this.path);
        }

        if (this.dest.len > 0) {
            err.dest = bun.String.createUTF8(this.dest);
        }

        if (this.fd.unwrapValid()) |valid| {
            // When the FD is a windows handle, there is no sane way to report this.
            if (!Environment.isWindows or valid.kind == .uv) {
                err.fd = valid.uv();
            }
        }

        return err;
    }

    pub inline fn todo() Error {
        if (Environment.isDebug) {
            @panic("Error.todo() was called");
        }
        return Error{ .errno = todo_errno, .syscall = .TODO };
    }

    pub fn toJS(this: Error, ctx: *JSC.JSGlobalObject) JSC.C.JSObjectRef {
        return this.toSystemError().toErrorInstance(ctx).asObjectRef();
    }

    pub fn toJSC(this: Error, ptr: *JSC.JSGlobalObject) JSC.JSValue {
        return this.toSystemError().toErrorInstance(ptr);
    }
};

pub fn Maybe(comptime ReturnTypeT: type) type {
    return bun.api.node.Maybe(ReturnTypeT, Error);
}

pub fn getcwd(buf: *bun.PathBuffer) Maybe([]const u8) {
    const Result = Maybe([]const u8);
    return switch (getcwdZ(buf)) {
        .err => |err| Result{ .err = err },
        .result => |cwd| Result{ .result = cwd },
    };
}

pub fn getcwdZ(buf: *bun.PathBuffer) Maybe([:0]const u8) {
    const Result = Maybe([:0]const u8);
    buf[0] = 0;

    if (comptime Environment.isWindows) {
        var wbuf = bun.WPathBufferPool.get();
        defer bun.WPathBufferPool.put(wbuf);
        const len: windows.DWORD = kernel32.GetCurrentDirectoryW(wbuf.len, wbuf);
        if (Result.errnoSysP(len, .getcwd, buf)) |err| return err;
        return Result{ .result = bun.strings.fromWPath(buf, wbuf[0..len]) };
    }

    const rc: ?[*:0]u8 = @ptrCast(std.c.getcwd(buf, bun.MAX_PATH_BYTES));
    return if (rc != null)
        Result{ .result = rc.?[0..std.mem.len(rc.?) :0] }
    else
        Result.errnoSysP(@as(c_int, 0), .getcwd, buf).?;
}

const syscall_or_c = if (Environment.isLinux) syscall else bun.c;

pub fn fchown(fd: bun.FileDescriptor, uid: JSC.Node.uid_t, gid: JSC.Node.gid_t) Maybe(void) {
    if (comptime Environment.isWindows) {
        return sys_uv.fchown(fd, uid, gid);
    }

    while (true) {
        const rc = syscall_or_c.fchown(fd.cast(), uid, gid);
        if (Maybe(void).errnoSysFd(rc, .fchown, fd)) |err| {
            if (err.getErrno() == .INTR) continue;
            return err;
        }

        return Maybe(void).success;
    }

    unreachable;
}

pub fn fchmod(fd: bun.FileDescriptor, mode: bun.Mode) Maybe(void) {
    if (comptime Environment.isWindows) {
        return sys_uv.fchmod(fd, mode);
    }

    while (true) {
        const rc = syscall_or_c.fchmod(fd.cast(), mode);
        if (Maybe(void).errnoSysFd(rc, .fchmod, fd)) |err| {
            if (err.getErrno() == .INTR) continue;
            return err;
        }

        return Maybe(void).success;
    }

    unreachable;
}

pub fn fchmodat(fd: bun.FileDescriptor, path: [:0]const u8, mode: bun.Mode, flags: if (Environment.isLinux) u32 else i32) Maybe(void) {
    if (comptime Environment.isWindows) @compileError("Use fchmod instead");

    while (true) {
        const rc = syscall_or_c.fchmodat(fd.cast(), path.ptr, mode, flags);
        if (Maybe(void).errnoSysFd(rc, .fchmodat, fd)) |err| {
            if (err.getErrno() == .INTR) continue;
            return err;
        }

        return Maybe(void).success;
    }

    unreachable;
}

pub fn chmod(path: [:0]const u8, mode: bun.Mode) Maybe(void) {
    if (comptime Environment.isWindows) {
        return sys_uv.chmod(path, mode);
    }

    while (true) {
        const rc = syscall_or_c.chmod(path.ptr, mode);
        if (Maybe(void).errnoSysP(rc, .chmod, path)) |err| {
            if (err.getErrno() == .INTR) continue;
            return err;
        }

        return Maybe(void).success;
    }

    unreachable;
}

pub fn chdirOSPath(path: bun.stringZ, destination: if (Environment.isPosix) bun.stringZ else bun.string) Maybe(void) {
    if (comptime Environment.isPosix) {
        const rc = syscall.chdir(destination);
        return Maybe(void).errnoSysPD(rc, .chdir, path, destination) orelse Maybe(void).success;
    }

    if (comptime Environment.isWindows) {
        const wbuf = bun.WPathBufferPool.get();
        defer bun.WPathBufferPool.put(wbuf);
        if (c.SetCurrentDirectoryW(bun.strings.toWDirPath(wbuf, destination)) == windows.FALSE) {
            log("SetCurrentDirectory({s}) = {d}", .{ destination, kernel32.GetLastError() });
            return Maybe(void).errnoSysPD(0, .chdir, path, destination) orelse Maybe(void).success;
        }

        log("SetCurrentDirectory({s}) = {d}", .{ destination, 0 });

        return Maybe(void).success;
    }

    @compileError("Not implemented yet");
}

pub fn chdir(path: anytype, destination: anytype) Maybe(void) {
    const Type = @TypeOf(destination);

    if (comptime Environment.isPosix) {
        if (comptime Type == []u8 or Type == []const u8) {
            return chdirOSPath(
                &(std.posix.toPosixPath(path) catch return .{ .err = .{
                    .errno = @intFromEnum(SystemErrno.EINVAL),
                    .syscall = .chdir,
                } }),
                &(std.posix.toPosixPath(destination) catch return .{ .err = .{
                    .errno = @intFromEnum(SystemErrno.EINVAL),
                    .syscall = .chdir,
                } }),
            );
        }

        return chdirOSPath(path, destination);
    }

    if (comptime Environment.isWindows) {
        if (comptime Type == *[*:0]u16) {
            if (kernel32.SetCurrentDirectory(destination) != 0) {
                return Maybe(void).errnoSysPD(0, .chdir, path, destination) orelse Maybe(void).success;
            }

            return Maybe(void).success;
        }

        if (comptime Type == bun.OSPathSliceZ or Type == [:0]u16) {
            return chdirOSPath(path, @as(bun.OSPathSliceZ, destination));
        }

        return chdirOSPath(path, destination);
    }

    return Maybe(void).todo();
}

pub fn sendfile(src: bun.FileDescriptor, dest: bun.FileDescriptor, len: usize) Maybe(usize) {
    while (true) {
        const rc = std.os.linux.sendfile(
            dest.cast(),
            src.cast(),
            null,
            // we set a maximum to avoid EINVAL
            @min(len, std.math.maxInt(i32) - 1),
        );
        if (Maybe(usize).errnoSysFd(rc, .sendfile, src)) |err| {
            if (err.getErrno() == .INTR) continue;
            return err;
        }

        return .{ .result = rc };
    }
}

pub fn stat(path: [:0]const u8) Maybe(bun.Stat) {
    if (Environment.isWindows) {
        return sys_uv.stat(path);
    } else {
        var stat_ = mem.zeroes(bun.Stat);
        const rc = if (Environment.isLinux)
            // aarch64 linux doesn't implement a "stat" syscall. It's all fstatat.
            linux.fstatat(std.posix.AT.FDCWD, path, &stat_, 0)
        else
            workaround_symbols.stat(path, &stat_);

        if (comptime Environment.allow_assert)
            log("stat({s}) = {d}", .{ bun.asByteSlice(path), rc });

        if (Maybe(bun.Stat).errnoSysP(rc, .stat, path)) |err| return err;
        return Maybe(bun.Stat){ .result = stat_ };
    }
}

pub fn statfs(path: [:0]const u8) Maybe(bun.StatFS) {
    if (Environment.isWindows) {
        return .{ .err = Error.fromCode(.ENOSYS, .statfs) };
    } else {
        var statfs_ = mem.zeroes(bun.StatFS);
        const rc = if (Environment.isLinux)
            c.statfs(path, &statfs_)
        else if (Environment.isMac)
            c.statfs(path, &statfs_)
        else
            @compileError("Unsupported platform");

        if (comptime Environment.allow_assert)
            log("statfs({s}) = {d}", .{ bun.asByteSlice(path), rc });

        if (Maybe(bun.StatFS).errnoSysP(rc, .statfs, path)) |err| return err;
        return Maybe(bun.StatFS){ .result = statfs_ };
    }
}

pub fn lstat(path: [:0]const u8) Maybe(bun.Stat) {
    if (Environment.isWindows) {
        return sys_uv.lstat(path);
    } else {
        var stat_buf = mem.zeroes(bun.Stat);
        if (Maybe(bun.Stat).errnoSysP(workaround_symbols.lstat(path, &stat_buf), .lstat, path)) |err| return err;
        return Maybe(bun.Stat){ .result = stat_buf };
    }
}

pub fn fstat(fd: bun.FileDescriptor) Maybe(bun.Stat) {
    if (Environment.isWindows) {
        // TODO: this is a bad usage of makeLibUVOwned
        const uvfd = fd.makeLibUVOwned() catch
            return .{ .err = Error.fromCode(.MFILE, .uv_open_osfhandle) };
        return sys_uv.fstat(uvfd);
    }

    var stat_ = mem.zeroes(bun.Stat);

    const rc = workaround_symbols.fstat(fd.cast(), &stat_);

    if (comptime Environment.allow_assert)
        log("fstat({}) = {d}", .{ fd, rc });

    if (Maybe(bun.Stat).errnoSysFd(rc, .fstat, fd)) |err| return err;
    return Maybe(bun.Stat){ .result = stat_ };
}
pub fn lutimes(path: [:0]const u8, atime: JSC.Node.TimeLike, mtime: JSC.Node.TimeLike) Maybe(void) {
    if (comptime Environment.isWindows) {
        return sys_uv.lutimes(path, atime, mtime);
    }

    return utimensWithFlags(path, atime, mtime, std.posix.AT.SYMLINK_NOFOLLOW);
}

pub fn mkdiratA(dir_fd: bun.FileDescriptor, file_path: []const u8) Maybe(void) {
    const buf = bun.WPathBufferPool.get();
    defer bun.WPathBufferPool.put(buf);
    return mkdiratW(dir_fd, bun.strings.toWPathNormalized(buf, file_path));
}

pub fn mkdiratZ(dir_fd: bun.FileDescriptor, file_path: [*:0]const u8, mode: mode_t) Maybe(void) {
    return switch (Environment.os) {
        .mac => Maybe(void).errnoSysP(syscall.mkdirat(@intCast(dir_fd.cast()), file_path, mode), .mkdir, file_path) orelse Maybe(void).success,
        .linux => Maybe(void).errnoSysP(linux.mkdirat(@intCast(dir_fd.cast()), file_path, mode), .mkdir, file_path) orelse Maybe(void).success,
        else => @compileError("mkdir is not implemented on this platform"),
    };
}

fn mkdiratPosix(dir_fd: bun.FileDescriptor, file_path: []const u8, mode: mode_t) Maybe(void) {
    return mkdiratZ(
        dir_fd,
        &(std.posix.toPosixPath(file_path) catch return .{ .err = Error.fromCode(.NAMETOOLONG, .mkdir) }),
        mode,
    );
}

pub const mkdirat = if (Environment.isWindows)
    mkdiratW
else
    mkdiratPosix;

pub fn mkdiratW(dir_fd: bun.FileDescriptor, file_path: []const u16, _: i32) Maybe(void) {
    const dir_to_make = openDirAtWindowsNtPath(dir_fd, file_path, .{ .iterable = false, .can_rename_or_delete = true, .create = true });
    if (dir_to_make == .err) {
        return .{ .err = dir_to_make.err };
    }
    dir_to_make.result.close();
    return .{ .result = {} };
}

pub fn fstatat(fd: bun.FileDescriptor, path: [:0]const u8) Maybe(bun.Stat) {
    if (Environment.isWindows) {
        return switch (openatWindowsA(fd, path, 0, 0)) {
            .result => |file| {
                defer file.close();
                return fstat(file);
            },
            .err => |err| Maybe(bun.Stat){ .err = err },
        };
    }
    var stat_buf = mem.zeroes(bun.Stat);
    const fd_valid = if (fd == bun.invalid_fd) std.posix.AT.FDCWD else fd.native();
    if (Maybe(bun.Stat).errnoSysFP(syscall.fstatat(fd_valid, path, &stat_buf, 0), .fstatat, fd, path)) |err| {
        log("fstatat({}, {s}) = {s}", .{ fd, path, @tagName(err.getErrno()) });
        return err;
    }
    log("fstatat({}, {s}) = 0", .{ fd, path });
    return Maybe(bun.Stat){ .result = stat_buf };
}

pub fn mkdir(file_path: [:0]const u8, flags: mode_t) Maybe(void) {
    return switch (Environment.os) {
        .mac => Maybe(void).errnoSysP(syscall.mkdir(file_path, flags), .mkdir, file_path) orelse Maybe(void).success,

        .linux => Maybe(void).errnoSysP(syscall.mkdir(file_path, flags), .mkdir, file_path) orelse Maybe(void).success,

        .windows => {
            const wbuf = bun.WPathBufferPool.get();
            defer bun.WPathBufferPool.put(wbuf);
            return Maybe(void).errnoSysP(
                bun.windows.CreateDirectoryW(bun.strings.toKernel32Path(wbuf, file_path).ptr, null),
                .mkdir,
                file_path,
            ) orelse Maybe(void).success;
        },

        else => @compileError("mkdir is not implemented on this platform"),
    };
}

pub fn mkdirA(file_path: []const u8, flags: mode_t) Maybe(void) {
    if (comptime Environment.isMac) {
        return Maybe(void).errnoSysP(syscall.mkdir(&(std.posix.toPosixPath(file_path) catch return Maybe(void){
            .err = .{
                .errno = @intFromEnum(E.NOMEM),
                .syscall = .open,
            },
        }), flags), .mkdir, file_path) orelse Maybe(void).success;
    }

    if (comptime Environment.isLinux) {
        return Maybe(void).errnoSysP(linux.mkdir(&(std.posix.toPosixPath(file_path) catch return Maybe(void){
            .err = .{
                .errno = @intFromEnum(E.NOMEM),
                .syscall = .open,
            },
        }), flags), .mkdir, file_path) orelse Maybe(void).success;
    }

    if (comptime Environment.isWindows) {
        const wbuf = bun.WPathBufferPool.get();
        defer bun.WPathBufferPool.put(wbuf);
        const wpath = bun.strings.toKernel32Path(wbuf, file_path);
        assertIsValidWindowsPath(u16, wpath);
        return Maybe(void).errnoSysP(
            kernel32.CreateDirectoryW(wpath.ptr, null),
            .mkdir,
            file_path,
        ) orelse Maybe(void).success;
    }
}

pub fn mkdirOSPath(file_path: bun.OSPathSliceZ, flags: mode_t) Maybe(void) {
    return switch (Environment.os) {
        else => mkdir(file_path, flags),
        .windows => {
            const rc = c.CreateDirectoryW(file_path, null);
            if (Maybe(void).errnoSys(
                rc,
                .mkdir,
            )) |err| {
                log("CreateDirectoryW({}) = {s}", .{ bun.fmt.fmtOSPath(file_path, .{}), err.err.name() });
                return err;
            }

            log("CreateDirectoryW({}) = 0", .{bun.fmt.fmtOSPath(file_path, .{})});
            return Maybe(void).success;
        },
    };
}

const fnctl_int = if (Environment.isLinux) usize else c_int;
pub fn fcntl(fd: bun.FileDescriptor, cmd: i32, arg: anytype) Maybe(fnctl_int) {
    while (true) {
        const result = switch (@TypeOf(arg)) {
            i32, comptime_int, c_int => fcntl_symbol(fd.native(), cmd, @as(c_int, arg)),
            i64 => fcntl_symbol(fd.cast(), cmd, @as(c_long, @bitCast(arg))),
            *const anyopaque, *anyopaque, usize => fcntl_symbol(fd.cast(), cmd, arg),
            else => @compileError("Unsupported argument type for fcntl"),
        };
        if (Maybe(fnctl_int).errnoSysFd(result, .fcntl, fd)) |err| {
            if (err.getErrno() == .INTR) continue;
            return err;
        }
        return .{ .result = @intCast(result) };
    }

    unreachable;
}

const w = std.os.windows;

/// Normalizes for ntdll.dll APIs. Replaces long-path prefixes with nt object
/// prefixes, which may not function properly in kernel32 APIs.
// TODO: Rename to normalizePathWindowsForNtdll
pub fn normalizePathWindows(
    comptime T: type,
    dir_fd: bun.FileDescriptor,
    path_: []const T,
    buf: *bun.WPathBuffer,
    comptime opts: struct { add_nt_prefix: bool = true },
) Maybe([:0]const u16) {
    if (comptime T != u8 and T != u16) {
        @compileError("normalizePathWindows only supports u8 and u16 character types");
    }
    const wbuf = if (T != u16) bun.WPathBufferPool.get();
    defer if (T != u16) bun.WPathBufferPool.put(wbuf);
    var path = if (T == u16) path_ else bun.strings.convertUTF8toUTF16InBuffer(wbuf, path_);

    if (std.fs.path.isAbsoluteWindowsWTF16(path)) {
        if (path_.len >= 4) {
            if ((bun.strings.eqlComptimeT(T, path_[path_.len - "\\nul".len ..], "\\nul") or
                bun.strings.eqlComptimeT(T, path_[path_.len - "\\NUL".len ..], "\\NUL")))
            {
                @memcpy(buf[0..bun.strings.w("\\??\\NUL").len], bun.strings.w("\\??\\NUL"));
                buf[bun.strings.w("\\??\\NUL").len] = 0;
                return .{ .result = buf[0..bun.strings.w("\\??\\NUL").len :0] };
            }
            if ((path[1] == '/' or path[1] == '\\') and
                (path[3] == '/' or path[3] == '\\'))
            {
                // Preserve the device path, instead of resolving '.' as a relative
                // path. This prevents simplifying the path '\\.\pipe' into '\pipe'
                if (path[2] == '.') {
                    buf[0..4].* = .{ '\\', '\\', '.', '\\' };
                    const rest = path[4..];
                    @memcpy(buf[4..][0..rest.len], rest);
                    buf[path.len] = 0;
                    return .{ .result = buf[0..path.len :0] };
                }
                // For long paths and nt object paths, conver the prefix into an nt object, then resolve.
                // TODO: NT object paths technically mean they are already resolved. Will that break?
                if (path[2] == '?' and (path[1] == '?' or path[1] == '/' or path[1] == '\\')) {
                    path = path[4..];
                }
            }
        }

        const norm = bun.path.normalizeStringGenericTZ(u16, path, buf, .{ .add_nt_prefix = opts.add_nt_prefix, .zero_terminate = true });
        return .{ .result = norm };
    }

    if (bun.strings.indexOfAnyT(T, path_, &.{ '\\', '/', '.' }) == null) {
        if (buf.len < path.len) {
            return .{
                .err = .{
                    .errno = @intFromEnum(E.NOMEM),
                    .syscall = .open,
                },
            };
        }

        // Skip the system call to get the final path name if it doesn't have any of the above characters.
        @memcpy(buf[0..path.len], path);
        buf[path.len] = 0;
        return .{
            .result = buf[0..path.len :0],
        };
    }

    const base_fd = if (dir_fd == bun.invalid_fd)
        std.fs.cwd().fd
    else
        dir_fd.cast();

    const base_path = bun.windows.GetFinalPathNameByHandle(base_fd, w.GetFinalPathNameByHandleFormat{}, buf) catch {
        return .{ .err = .{
            .errno = @intFromEnum(E.BADFD),
            .syscall = .open,
        } };
    };

    if (path.len >= 2 and bun.path.isDriveLetterT(u16, path[0]) and path[1] == ':') {
        path = path[2..];
    }

    const buf1 = bun.WPathBufferPool.get();
    defer bun.WPathBufferPool.put(buf1);
    @memcpy(buf1[0..base_path.len], base_path);
    buf1[base_path.len] = '\\';
    @memcpy(buf1[base_path.len + 1 .. base_path.len + 1 + path.len], path);
    const norm = bun.path.normalizeStringGenericTZ(u16, buf1[0 .. base_path.len + 1 + path.len], buf, .{ .add_nt_prefix = true, .zero_terminate = true });
    return .{
        .result = norm,
    };
}

fn openDirAtWindowsNtPath(
    dirFd: bun.FileDescriptor,
    path: [:0]const u16,
    options: WindowsOpenDirOptions,
) Maybe(bun.FileDescriptor) {
    const iterable = options.iterable;
    const no_follow = options.no_follow;
    const can_rename_or_delete = options.can_rename_or_delete;
    const read_only = options.read_only;
    assertIsValidWindowsPath(u16, path);
    const base_flags = w.STANDARD_RIGHTS_READ | w.FILE_READ_ATTRIBUTES | w.FILE_READ_EA |
        w.SYNCHRONIZE | w.FILE_TRAVERSE;
    const iterable_flag: u32 = if (iterable) w.FILE_LIST_DIRECTORY else 0;
    const rename_flag: u32 = if (can_rename_or_delete) w.DELETE else 0;
    const read_only_flag: u32 = if (read_only) 0 else w.FILE_ADD_FILE | w.FILE_ADD_SUBDIRECTORY;
    const flags: u32 = iterable_flag | base_flags | rename_flag | read_only_flag;
    const open_reparse_point: w.DWORD = if (no_follow) w.FILE_OPEN_REPARSE_POINT else 0x0;

    // NtCreateFile seems to not function on device paths.
    // Since it is absolute, it can just use CreateFileW
    if (bun.strings.hasPrefixComptimeUTF16(path, "\\\\.\\"))
        return openWindowsDevicePath(
            path,
            flags,
            if (options.create) w.FILE_OPEN_IF else w.FILE_OPEN,
            w.FILE_DIRECTORY_FILE | w.FILE_SYNCHRONOUS_IO_NONALERT | w.FILE_OPEN_FOR_BACKUP_INTENT | open_reparse_point,
        );

    const path_len_bytes: u16 = @truncate(path.len * 2);
    var nt_name = w.UNICODE_STRING{
        .Length = path_len_bytes,
        .MaximumLength = path_len_bytes,
        .Buffer = @constCast(path.ptr),
    };
    var attr = w.OBJECT_ATTRIBUTES{
        .Length = @sizeOf(w.OBJECT_ATTRIBUTES),
        .RootDirectory = if (std.fs.path.isAbsoluteWindowsWTF16(path))
            null
        else if (dirFd == bun.invalid_fd)
            std.fs.cwd().fd
        else
            dirFd.cast(),
        .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here.
        .ObjectName = &nt_name,
        .SecurityDescriptor = null,
        .SecurityQualityOfService = null,
    };
    var fd: w.HANDLE = w.INVALID_HANDLE_VALUE;
    var io: w.IO_STATUS_BLOCK = undefined;

    const rc = w.ntdll.NtCreateFile(
        &fd,
        flags,
        &attr,
        &io,
        null,
        0,
        FILE_SHARE,
        if (options.create) w.FILE_OPEN_IF else w.FILE_OPEN,
        w.FILE_DIRECTORY_FILE | w.FILE_SYNCHRONOUS_IO_NONALERT | w.FILE_OPEN_FOR_BACKUP_INTENT | open_reparse_point,
        null,
        0,
    );

    if (comptime Environment.allow_assert) {
        if (rc == .INVALID_PARAMETER) {
            // Double check what flags you are passing to this
            //
            // - access_mask probably needs w.SYNCHRONIZE,
            // - options probably needs w.FILE_SYNCHRONOUS_IO_NONALERT
            // - disposition probably needs w.FILE_OPEN
            bun.Output.debugWarn("NtCreateFile({}, {}) = {s} (dir) = {d}\nYou are calling this function with the wrong flags!!!", .{ dirFd, bun.fmt.utf16(path), @tagName(rc), @intFromPtr(fd) });
        } else if (rc == .OBJECT_PATH_SYNTAX_BAD or rc == .OBJECT_NAME_INVALID) {
            bun.Output.debugWarn("NtCreateFile({}, {}) = {s} (dir) = {d}\nYou are calling this function without normalizing the path correctly!!!", .{ dirFd, bun.fmt.utf16(path), @tagName(rc), @intFromPtr(fd) });
        } else {
            log("NtCreateFile({}, {}) = {s} (dir) = {d}", .{ dirFd, bun.fmt.utf16(path), @tagName(rc), @intFromPtr(fd) });
        }
    }

    switch (windows.Win32Error.fromNTStatus(rc)) {
        .SUCCESS => {
            return .{ .result = .fromNative(fd) };
        },
        else => |code| {
            if (code.toSystemErrno()) |sys_err| {
                return .{
                    .err = .{
                        .errno = @intFromEnum(sys_err),
                        .syscall = .open,
                    },
                };
            }

            return .{
                .err = .{
                    .errno = @intFromEnum(E.UNKNOWN),
                    .syscall = .open,
                },
            };
        },
    }
}

fn openWindowsDevicePath(
    path: [:0]const u16,
    dwDesiredAccess: u32,
    dwCreationDisposition: u32,
    dwFlagsAndAttributes: u32,
) Maybe(bun.FileDescriptor) {
    const rc = std.os.windows.kernel32.CreateFileW(
        path,
        dwDesiredAccess,
        FILE_SHARE,
        null,
        dwCreationDisposition,
        dwFlagsAndAttributes,
        null,
    );
    if (rc == w.INVALID_HANDLE_VALUE) {
        return .{ .err = .{
            .errno = if (windows.Win32Error.get().toSystemErrno()) |e|
                @intFromEnum(e)
            else
                @intFromEnum(E.UNKNOWN),
            .syscall = .open,
        } };
    }
    return .{ .result = .fromNative(rc) };
}

pub const WindowsOpenDirOptions = packed struct {
    iterable: bool = false,
    no_follow: bool = false,
    can_rename_or_delete: bool = false,
    create: bool = false,
    read_only: bool = false,
};

fn openDirAtWindowsT(
    comptime T: type,
    dirFd: bun.FileDescriptor,
    path: []const T,
    options: WindowsOpenDirOptions,
) Maybe(bun.FileDescriptor) {
    const wbuf = bun.WPathBufferPool.get();
    defer bun.WPathBufferPool.put(wbuf);

    const norm = switch (normalizePathWindows(T, dirFd, path, wbuf, .{})) {
        .err => |err| return .{ .err = err },
        .result => |norm| norm,
    };

    if (comptime T == u8) {
        log("openDirAtWindows({s}) = {s}", .{ path, bun.fmt.utf16(norm) });
    } else {
        log("openDirAtWindowsT({s}) = {s}", .{ bun.fmt.utf16(path), bun.fmt.utf16(norm) });
    }
    return openDirAtWindowsNtPath(dirFd, norm, options);
}

pub fn openDirAtWindows(
    dirFd: bun.FileDescriptor,
    path: []const u16,
    options: WindowsOpenDirOptions,
) Maybe(bun.FileDescriptor) {
    return openDirAtWindowsT(u16, dirFd, path, options);
}

pub noinline fn openDirAtWindowsA(
    dirFd: bun.FileDescriptor,
    path: []const u8,
    options: WindowsOpenDirOptions,
) Maybe(bun.FileDescriptor) {
    return openDirAtWindowsT(u8, dirFd, path, options);
}

const NtCreateFileOptions = struct {
    access_mask: w.ULONG,
    disposition: w.ULONG,
    options: w.ULONG,
    attributes: w.ULONG = w.FILE_ATTRIBUTE_NORMAL,
    sharing_mode: w.ULONG = FILE_SHARE,
};

/// For this function to open an absolute path, it must start with "\??\". Otherwise
/// you need a reference file descriptor the "invalid_fd" file descriptor is used
/// to signify that the current working directory should be used.
///
/// When using this function I highly recommend reading this first:
/// https://learn.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntcreatefile
///
/// It is very very very easy to mess up flags here. Please review existing
/// examples to this call and the above function that maps unix flags to
/// the windows ones.
///
/// It is very easy to waste HOURS on the subtle semantics of this function.
///
/// In the zig standard library, messing up the input to their equivalent
/// will trigger `unreachable`. Here there will be a debug log with the path.
pub fn openFileAtWindowsNtPath(
    dir: bun.FileDescriptor,
    path: []const u16,
    options: NtCreateFileOptions,
) Maybe(bun.FileDescriptor) {
    // Another problem re: normalization is that you can use relative paths, but no leading '.\' or './''
    // this path is probably already backslash normalized so we're only going to check for '.\'
    // const path = if (bun.strings.hasPrefixComptimeUTF16(path_maybe_leading_dot, ".\\")) path_maybe_leading_dot[2..] else path_maybe_leading_dot;
    // bun.assert(!bun.strings.hasPrefixComptimeUTF16(path_maybe_leading_dot, "./"));
    assertIsValidWindowsPath(u16, path);

    var result: windows.HANDLE = undefined;

    const path_len_bytes = std.math.cast(u16, path.len * 2) orelse return .{
        .err = .{
            .errno = @intFromEnum(E.NOMEM),
            .syscall = .open,
        },
    };
    var nt_name = windows.UNICODE_STRING{
        .Length = path_len_bytes,
        .MaximumLength = path_len_bytes,
        .Buffer = @constCast(path.ptr),
    };
    var attr = windows.OBJECT_ATTRIBUTES{
        .Length = @sizeOf(windows.OBJECT_ATTRIBUTES),
        // From the Windows Documentation:
        //
        // [ObjectName] must be a fully qualified file specification or the name of a device object,
        // unless it is the name of a file relative to the directory specified by RootDirectory.
        // For example, \Device\Floppy1\myfile.dat or \??\B:\myfile.dat could be the fully qualified
        // file specification, provided that the floppy driver and overlying file system are already
        // loaded. For more information, see File Names, Paths, and Namespaces.
        .ObjectName = &nt_name,
        .RootDirectory = if (bun.strings.hasPrefixComptimeType(u16, path, windows.nt_object_prefix))
            null
        else if (dir == bun.invalid_fd)
            std.fs.cwd().fd
        else
            dir.cast(),
        .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here.
        .SecurityDescriptor = null,
        .SecurityQualityOfService = null,
    };
    var io: windows.IO_STATUS_BLOCK = undefined;

    var attributes = options.attributes;
    while (true) {
        const rc = windows.ntdll.NtCreateFile(
            &result,
            options.access_mask,
            &attr,
            &io,
            null,
            attributes,
            options.sharing_mode,
            options.disposition,
            options.options,
            null,
            0,
        );

        if (Environment.allow_assert and Environment.enable_logs) {
            if (rc == .INVALID_PARAMETER) {
                // Double check what flags you are passing to this
                //
                // - access_mask probably needs w.SYNCHRONIZE,
                // - options probably needs w.FILE_SYNCHRONOUS_IO_NONALERT
                // - disposition probably needs w.FILE_OPEN
                bun.Output.debugWarn("NtCreateFile({}, {}) = {s} (file) = {d}\nYou are calling this function with the wrong flags!!!", .{ dir, bun.fmt.utf16(path), @tagName(rc), @intFromPtr(result) });
            } else if (rc == .OBJECT_PATH_SYNTAX_BAD or rc == .OBJECT_NAME_INVALID) {
                // See above comment. For absolute paths you must have \??\ at the start.
                bun.Output.debugWarn("NtCreateFile({}, {}) = {s} (file) = {d}\nYou are calling this function without normalizing the path correctly!!!", .{ dir, bun.fmt.utf16(path), @tagName(rc), @intFromPtr(result) });
            } else {
                if (rc == .SUCCESS) {
                    log("NtCreateFile({}, {}) = {s} (file) = {}", .{ dir, bun.fmt.utf16(path), @tagName(rc), bun.FD.fromNative(result) });
                } else {
                    log("NtCreateFile({}, {}) = {s} (file) = {}", .{ dir, bun.fmt.utf16(path), @tagName(rc), rc });
                }
            }
        }

        if (rc == .ACCESS_DENIED and
            attributes == w.FILE_ATTRIBUTE_NORMAL and
            (options.access_mask & (w.GENERIC_READ | w.GENERIC_WRITE)) == w.GENERIC_WRITE)
        {
            // > If CREATE_ALWAYS and FILE_ATTRIBUTE_NORMAL are specified,
            // > CreateFile fails and sets the last error to ERROR_ACCESS_DENIED
            // > if the file exists and has the FILE_ATTRIBUTE_HIDDEN or
            // > FILE_ATTRIBUTE_SYSTEM attribute. To avoid the error, specify the
            // > same attributes as the existing file.
            //
            // The above also applies to NtCreateFile. In order to make this work,
            // we retry but only in the case that the file was opened for writing.
            //
            // See https://github.com/oven-sh/bun/issues/6820
            //     https://github.com/libuv/libuv/pull/3380
            attributes = w.FILE_ATTRIBUTE_HIDDEN;
            continue;
        }

        switch (windows.Win32Error.fromNTStatus(rc)) {
            .SUCCESS => {
                if (options.access_mask & w.FILE_APPEND_DATA != 0) {
                    // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-setfilepointerex
                    const FILE_END = 2;
                    if (kernel32.SetFilePointerEx(result, 0, null, FILE_END) == 0) {
                        return .{
                            .err = .{
                                .errno = @intFromEnum(E.UNKNOWN),
                                .syscall = .SetFilePointerEx,
                            },
                        };
                    }
                }
                return .{ .result = .fromNative(result) };
            },
            else => |code| {
                if (code.toSystemErrno()) |sys_err| {
                    return .{
                        .err = .{
                            .errno = @intFromEnum(sys_err),
                            .syscall = .open,
                        },
                    };
                }

                return .{
                    .err = .{
                        .errno = @intFromEnum(E.UNKNOWN),
                        .syscall = .open,
                    },
                };
            },
        }
    }
}

// Delete: this doesnt apply to NtCreateFile :(
// pub const WindowsOpenFlags = struct {
//     access: w.DWORD,
//     share: w.DWORD,
//     disposition: w.DWORD,
//     attributes: w.DWORD,

//     pub fn fromLibUV(flags_in: c_int) error{EINVAL}!WindowsOpenFlags {
//         const uv = bun.windows.libuv;

//         var flags = flags_in;

//         // Adjust flags to be compatible with the memory file mapping. Save the
//         // original flags to emulate the correct behavior
//         if (flags & uv.UV_FS_O_FILEMAP != 0) {
//             if (flags & (O.RDONLY | O.WRONLY | O.RDWR) != 0) {
//                 flags = (flags & ~@as(c_int, O.WRONLY)) | O.RDWR;
//             }
//             if (flags & O.APPEND != 0) {
//                 flags &= ~@as(c_int, O.APPEND);
//                 flags &= ~@as(c_int, O.RDONLY | O.WRONLY | O.RDWR);
//                 flags |= O.RDWR;
//             }
//         }

//         var access_flag: w.DWORD = switch (flags & (uv.UV_FS_O_RDONLY | uv.UV_FS_O_WRONLY | uv.UV_FS_O_RDWR)) {
//             uv.UV_FS_O_RDONLY => w.FILE_GENERIC_READ,
//             uv.UV_FS_O_WRONLY => w.FILE_GENERIC_WRITE,
//             uv.UV_FS_O_RDWR => w.FILE_GENERIC_READ | w.FILE_GENERIC_WRITE,
//             else => return error.EINVAL,
//         };
//         if (flags & O.APPEND != 0) {
//             access_flag &= ~@as(u32, w.FILE_WRITE_DATA);
//             access_flag |= w.FILE_APPEND_DATA;
//         }
//         access_flag |= w.SYNCHRONIZE;

//         const share: w.DWORD = if (flags & uv.UV_FS_O_EXLOCK != 0) 0 else FILE_SHARE;

//         const disposition: w.DWORD = switch (flags & uv.UV_FS_O_CREAT | uv.UV_FS_O_EXCL | uv.UV_FS_O_TRUNC) {
//             0,
//             uv.UV_FS_O_EXCL,
//             => w.OPEN_EXISTING,
//             uv.UV_FS_O_CREAT,
//             => w.OPEN_ALWAYS,
//             uv.UV_FS_O_CREAT | uv.UV_FS_O_EXCL,
//             uv.UV_FS_O_CREAT | uv.UV_FS_O_EXCL | uv.UV_FS_O_TRUNC,
//             => w.CREATE_NEW,
//             uv.UV_FS_O_TRUNC,
//             uv.UV_FS_O_TRUNC | uv.UV_FS_O_EXCL,
//             => w.TRUNCATE_EXISTING,
//             uv.UV_FS_O_CREAT | uv.UV_FS_O_TRUNC,
//             => w.TRUNCATE_EXISTING,
//             else => return error.EINVAL,
//         };
//         var attributes: w.DWORD = w.FILE_ATTRIBUTE_NORMAL;
//         if (flags & uv.UV_FS_O_CREAT != 0) {
//             // if (!((req->fs.info.mode & ~current_umask) & _S_IWRITE)) {
//         }
//         if (flags & uv.UV_FS_O_TEMPORARY != 0) {
//             attributes |= w.FILE_DELETE_ON_CLOSE;
//             access_flag |= w.DELETE;
//         }
//         if (flags & uv.UV_FS_O_SHORT_LIVED != 0) {
//             attributes |= w.FILE_ATTRIBUTE_TEMPORARY;
//         }

//         switch (flags & (uv.UV_FS_O_SEQUENTIAL | uv.UV_FS_O_RANDOM)) {
//             0 => {},
//             uv.UV_FS_O_SEQUENTIAL => attributes |= w.FILE_FLAG_SEQUENTIAL_SCAN,
//             uv.UV_FS_O_RANDOM => attributes |= w.FILE_FLAG_SEQUENTIAL_SCAN,
//             else => return error.EINVAL,
//         }

//         if (flags & uv.UV_FS_O_DIRECT != 0) {
//             // FILE_APPEND_DATA and FILE_FLAG_NO_BUFFERING are mutually exclusive.
//             // Windows returns 87, ERROR_INVALID_PARAMETER if these are combined.
//             //
//             // FILE_APPEND_DATA is included in FILE_GENERIC_WRITE:
//             //
//             // FILE_GENERIC_WRITE = STANDARD_RIGHTS_WRITE |
//             //                      FILE_WRITE_DATA |
//             //                      FILE_WRITE_ATTRIBUTES |
//             //                      FILE_WRITE_EA |
//             //                      FILE_APPEND_DATA |
//             //                      SYNCHRONIZE
//             //
//             // Note: Appends are also permitted by FILE_WRITE_DATA.
//             //
//             // In order for direct writes and direct appends to succeed, we therefore
//             // exclude FILE_APPEND_DATA if FILE_WRITE_DATA is specified, and otherwise
//             // fail if the user's sole permission is a direct append, since this
//             // particular combination is invalid.
//             if (access_flag & w.FILE_APPEND_DATA != 0) {
//                 if (access_flag & w.FILE_WRITE_DATA != 0) {
//                     access_flag &= @as(u32, w.FILE_APPEND_DATA);
//                 } else {
//                     return error.EINVAL;
//                 }
//             }
//             attributes |= w.FILE_FLAG_NO_BUFFERING;
//         }

//         switch (flags & uv.UV_FS_O_DSYNC | uv.UV_FS_O_SYNC) {
//             0 => {},
//             else => attributes |= w.FILE_FLAG_WRITE_THROUGH,
//         }

//         // Setting this flag makes it possible to open a directory.
//         attributes |= w.FILE_FLAG_BACKUP_SEMANTICS;

//         return .{
//             .access = access_flag,
//             .share = share,
//             .disposition = disposition,
//             .attributes = attributes,
//         };
//     }
// };

pub fn openFileAtWindowsT(
    comptime T: type,
    dirFd: bun.FileDescriptor,
    path: []const T,
    options: NtCreateFileOptions,
) Maybe(bun.FileDescriptor) {
    const wbuf = bun.WPathBufferPool.get();
    defer bun.WPathBufferPool.put(wbuf);

    const norm = switch (normalizePathWindows(T, dirFd, path, wbuf, .{})) {
        .err => |err| return .{ .err = err },
        .result => |norm| norm,
    };

    return openFileAtWindowsNtPath(dirFd, norm, options);
}

pub fn openFileAtWindows(
    dirFd: bun.FileDescriptor,
    path: []const u16,
    opts: NtCreateFileOptions,
) Maybe(bun.FileDescriptor) {
    return openFileAtWindowsT(u16, dirFd, path, opts);
}

pub noinline fn openFileAtWindowsA(
    dirFd: bun.FileDescriptor,
    path: []const u8,
    opts: NtCreateFileOptions,
) Maybe(bun.FileDescriptor) {
    return openFileAtWindowsT(u8, dirFd, path, opts);
}

pub fn openatWindowsT(comptime T: type, dir: bun.FileDescriptor, path: []const T, flags: i32, perm: bun.Mode) Maybe(bun.FileDescriptor) {
    return openatWindowsTMaybeNormalize(T, dir, path, flags, perm, true);
}

fn openatWindowsTMaybeNormalize(comptime T: type, dir: bun.FileDescriptor, path: []const T, flags: i32, perm: bun.Mode, comptime normalize: bool) Maybe(bun.FileDescriptor) {
    if (flags & O.DIRECTORY != 0) {
        const windows_options: WindowsOpenDirOptions = .{
            .iterable = flags & O.PATH == 0,
            .no_follow = flags & O.NOFOLLOW != 0,
            .can_rename_or_delete = false,
        };
        if (comptime !normalize and T == u16) {
            return openDirAtWindowsNtPath(dir, path, windows_options);
        }

        // we interpret O_PATH as meaning that we don't want iteration
        return openDirAtWindowsT(
            T,
            dir,
            path,
            windows_options,
        );
    }

    const nonblock = flags & O.NONBLOCK != 0;
    const overwrite = flags & O.WRONLY != 0 and flags & O.APPEND == 0;

    var access_mask: w.ULONG = w.READ_CONTROL | w.FILE_WRITE_ATTRIBUTES | w.SYNCHRONIZE;
    if (flags & O.RDWR != 0) {
        access_mask |= w.GENERIC_READ | w.GENERIC_WRITE;
    } else if (flags & O.APPEND != 0) {
        access_mask |= w.GENERIC_WRITE | w.FILE_APPEND_DATA;
    } else if (flags & O.WRONLY != 0) {
        access_mask |= w.GENERIC_WRITE;
    } else {
        access_mask |= w.GENERIC_READ;
    }

    const disposition: w.ULONG = blk: {
        if (flags & O.CREAT != 0) {
            if (flags & O.EXCL != 0) {
                break :blk w.FILE_CREATE;
            }
            break :blk if (overwrite) w.FILE_OVERWRITE_IF else w.FILE_OPEN_IF;
        }
        break :blk if (overwrite) w.FILE_OVERWRITE else w.FILE_OPEN;
    };

    const blocking_flag: windows.ULONG = if (!nonblock) windows.FILE_SYNCHRONOUS_IO_NONALERT else 0;
    const file_or_dir_flag: windows.ULONG = switch (flags & O.DIRECTORY != 0) {
        // .file_only => windows.FILE_NON_DIRECTORY_FILE,
        true => windows.FILE_DIRECTORY_FILE,
        false => 0,
    };
    const follow_symlinks = flags & O.NOFOLLOW == 0;

    const options: windows.ULONG = if (follow_symlinks) file_or_dir_flag | blocking_flag else file_or_dir_flag | windows.FILE_OPEN_REPARSE_POINT;

    var attributes: w.DWORD = windows.FILE_ATTRIBUTE_NORMAL;
    if (flags & O.CREAT != 0 and perm & 0x80 == 0 and perm != 0) {
        attributes |= windows.FILE_ATTRIBUTE_READONLY;
    }

    const open_options: NtCreateFileOptions = .{
        .access_mask = access_mask,
        .disposition = disposition,
        .options = options,
        .attributes = attributes,
    };

    if (comptime !normalize and T == u16) {
        return openFileAtWindowsNtPath(dir, path, open_options);
    }

    return openFileAtWindowsT(T, dir, path, open_options);
}

pub fn openatWindows(
    dir: bun.FileDescriptor,
    path: []const u16,
    flags: i32,
    perm: bun.Mode,
) Maybe(bun.FileDescriptor) {
    return openatWindowsT(u16, dir, path, flags, perm);
}

pub fn openatWindowsA(
    dir: bun.FileDescriptor,
    path: []const u8,
    flags: i32,
    perm: bun.Mode,
) Maybe(bun.FileDescriptor) {
    return openatWindowsT(u8, dir, path, flags, perm);
}

pub fn openatOSPath(dirfd: bun.FileDescriptor, file_path: bun.OSPathSliceZ, flags: i32, perm: bun.Mode) Maybe(bun.FileDescriptor) {
    if (comptime Environment.isMac) {
        // https://opensource.apple.com/source/xnu/xnu-7195.81.3/libsyscall/wrappers/open-base.c
        const rc = darwin_nocancel.@"openat$NOCANCEL"(dirfd.cast(), file_path.ptr, @bitCast(bun.O.toPacked(flags)), perm);
        if (comptime Environment.allow_assert)
            log("openat({}, {s}, {d}) = {d}", .{ dirfd, bun.sliceTo(file_path, 0), flags, rc });

        return Maybe(bun.FileDescriptor).errnoSysFP(rc, .open, dirfd, file_path) orelse .{ .result = .fromNative(rc) };
    } else if (comptime Environment.isWindows) {
        return openatWindowsT(bun.OSPathChar, dirfd, file_path, flags, perm);
    }

    while (true) {
        const rc = syscall.openat(dirfd.cast(), file_path, bun.O.toPacked(flags), perm);
        if (comptime Environment.allow_assert)
            log("openat({}, {s}, {d}) = {d}", .{ dirfd, bun.sliceTo(file_path, 0), flags, rc });

        return switch (sys.getErrno(rc)) {
            .SUCCESS => .{ .result = .fromNative(@intCast(rc)) },
            .INTR => continue,
            else => |err| {
                return .{
                    .err = .{
                        .errno = @truncate(@intFromEnum(err)),
                        .syscall = .open,
                    },
                };
            },
        };
    }
}

pub fn access(path: bun.OSPathSliceZ, mode: i32) Maybe(void) {
    if (Environment.isWindows) {
        const attrs = getFileAttributes(path) orelse {
            return .{ .err = .{
                .errno = @intFromEnum(bun.windows.getLastErrno()),
                .syscall = .access,
            } };
        };

        if (!((mode & W_OK) > 0) or
            !(attrs.is_readonly) or
            (attrs.is_directory))
        {
            return .{ .result = {} };
        } else {
            return .{ .err = .{
                .errno = @intFromEnum(E.PERM),
                .syscall = .access,
            } };
        }
    }
    // TODO: fix that bun's std library fork has a different parameter type.
    return Maybe(void).errnoSysP(syscall.access(path, @bitCast(mode)), .access, path) orelse .{ .result = {} };
}

pub fn openat(dirfd: bun.FileDescriptor, file_path: [:0]const u8, flags: i32, perm: bun.Mode) Maybe(bun.FileDescriptor) {
    if (comptime Environment.isWindows) {
        return openatWindowsT(u8, dirfd, file_path, flags, perm);
    } else {
        return openatOSPath(dirfd, file_path, flags, perm);
    }
}

pub fn openatFileWithLibuvFlags(dirfd: bun.FileDescriptor, file_path: [:0]const u8, flags: bun.JSC.Node.FileSystemFlags, perm: bun.Mode) Maybe(bun.FileDescriptor) {
    if (comptime Environment.isWindows) {
        const f = flags.toWindows() catch return .{ .err = .{
            .errno = @intFromEnum(E.INVAL),
            .syscall = .open,
            .path = file_path,
        } };
        // TODO: pass f.share
        return openFileAtWindowsT(u8, dirfd, file_path, f.access, f.disposition, f.attributes);
    } else {
        return openatOSPath(dirfd, file_path, flags.asPosix(), perm);
    }
}

pub fn openatA(dirfd: bun.FileDescriptor, file_path: []const u8, flags: i32, perm: bun.Mode) Maybe(bun.FileDescriptor) {
    if (comptime Environment.isWindows) {
        return openatWindowsT(u8, dirfd, file_path, flags, perm);
    }

    const pathZ = std.posix.toPosixPath(file_path) catch return Maybe(bun.FileDescriptor){
        .err = .{
            .errno = @intFromEnum(E.NAMETOOLONG),
            .syscall = .open,
        },
    };

    return openatOSPath(
        dirfd,
        &pathZ,
        flags,
        perm,
    );
}

pub fn openA(file_path: []const u8, flags: i32, perm: bun.Mode) Maybe(bun.FileDescriptor) {
    // this is what open() does anyway.
    return openatA(.cwd(), file_path, flags, perm);
}

pub fn open(file_path: [:0]const u8, flags: i32, perm: bun.Mode) Maybe(bun.FileDescriptor) {
    // TODO(@paperclover): this should not use libuv; when the libuv path is
    // removed here, the call sites in node_fs.zig should make sure they parse
    // the libuv specific file flags using the WindowsOpenFlags structure.
    if (comptime Environment.isWindows) {
        return sys_uv.open(file_path, flags, perm);
    }

    // this is what open() does anyway.
    return openat(.cwd(), file_path, flags, perm);
}

pub const max_count = switch (builtin.os.tag) {
    .linux => 0x7ffff000,
    .macos, .ios, .watchos, .tvos => std.math.maxInt(i32),
    .windows => std.math.maxInt(u32),
    else => std.math.maxInt(isize),
};

pub fn write(fd: bun.FileDescriptor, bytes: []const u8) Maybe(usize) {
    const adjusted_len = @min(max_count, bytes.len);
    var debug_timer = bun.Output.DebugTimer.start();

    defer {
        if (Environment.isDebug) {
            if (debug_timer.timer.read() > std.time.ns_per_ms) {
                log("write({}, {d}) blocked for {}", .{ fd, bytes.len, debug_timer });
            }
        }
    }

    return switch (Environment.os) {
        .mac => {
            const rc = darwin_nocancel.@"write$NOCANCEL"(fd.cast(), bytes.ptr, adjusted_len);
            log("write({}, {d}) = {d} ({})", .{ fd, adjusted_len, rc, debug_timer });

            if (Maybe(usize).errnoSysFd(rc, .write, fd)) |err| {
                return err;
            }

            return Maybe(usize){ .result = @intCast(rc) };
        },
        .linux => {
            while (true) {
                const rc = syscall.write(fd.cast(), bytes.ptr, adjusted_len);
                log("write({}, {d}) = {d} {}", .{ fd, adjusted_len, rc, debug_timer });

                if (Maybe(usize).errnoSysFd(rc, .write, fd)) |err| {
                    if (err.getErrno() == .INTR) continue;
                    return err;
                }

                return Maybe(usize){ .result = @intCast(rc) };
            }
        },
        .windows => {
            // "WriteFile sets this value to zero before doing any work or error checking."
            var bytes_written: u32 = undefined;
            bun.assert(bytes.len > 0);
            const rc = kernel32.WriteFile(
                fd.cast(),
                bytes.ptr,
                adjusted_len,
                &bytes_written,
                null,
            );
            if (rc == 0) {
                log("WriteFile({}, {d}) = {s}", .{ fd, adjusted_len, @tagName(bun.windows.getLastErrno()) });
                const er = std.os.windows.kernel32.GetLastError();
                if (er == .ACCESS_DENIED) {
                    // file is not writable
                    return .{ .err = .{
                        .errno = @intFromEnum(SystemErrno.EBADF),
                        .syscall = .write,
                        .fd = fd,
                    } };
                }
                const errno = (SystemErrno.init(bun.windows.kernel32.GetLastError()) orelse SystemErrno.EUNKNOWN).toE();
                return .{
                    .err = sys.Error{
                        .errno = @intFromEnum(errno),
                        .syscall = .write,
                        .fd = fd,
                    },
                };
            }

            log("WriteFile({}, {d}) = {d}", .{ fd, adjusted_len, bytes_written });

            return Maybe(usize){ .result = bytes_written };
        },
        else => @compileError("Not implemented yet"),
    };
}

fn veclen(buffers: anytype) usize {
    var len: usize = 0;
    for (buffers) |buffer| {
        len += buffer.len;
    }
    return len;
}

pub fn writev(fd: bun.FileDescriptor, buffers: []std.posix.iovec) Maybe(usize) {
    if (comptime Environment.isMac) {
        const rc = writev_sym(fd.cast(), @as([*]std.posix.iovec_const, @ptrCast(buffers.ptr)), @as(i32, @intCast(buffers.len)));
        if (comptime Environment.allow_assert)
            log("writev({}, {d}) = {d}", .{ fd, veclen(buffers), rc });

        if (Maybe(usize).errnoSysFd(rc, .writev, fd)) |err| {
            return err;
        }

        return Maybe(usize){ .result = @as(usize, @intCast(rc)) };
    } else {
        while (true) {
            const rc = writev_sym(fd.cast(), @as([*]std.posix.iovec_const, @ptrCast(buffers.ptr)), buffers.len);
            if (comptime Environment.allow_assert)
                log("writev({}, {d}) = {d}", .{ fd, veclen(buffers), rc });

            if (Maybe(usize).errnoSysFd(rc, .writev, fd)) |err| {
                if (err.getErrno() == .INTR) continue;
                return err;
            }

            return Maybe(usize){ .result = @as(usize, @intCast(rc)) };
        }
        unreachable;
    }
}

pub fn pwritev(fd: bun.FileDescriptor, buffers: []const bun.PlatformIOVecConst, position: isize) Maybe(usize) {
    if (comptime Environment.isWindows) {
        return sys_uv.pwritev(fd, buffers, position);
    }
    if (comptime Environment.isMac) {
        const rc = pwritev_sym(fd.cast(), buffers.ptr, @as(i32, @intCast(buffers.len)), position);
        if (comptime Environment.allow_assert)
            log("pwritev({}, {d}) = {d}", .{ fd, veclen(buffers), rc });

        if (Maybe(usize).errnoSysFd(rc, .pwritev, fd)) |err| {
            return err;
        }

        return Maybe(usize){ .result = @as(usize, @intCast(rc)) };
    } else {
        while (true) {
            const rc = pwritev_sym(fd.cast(), buffers.ptr, buffers.len, position);
            if (comptime Environment.allow_assert)
                log("pwritev({}, {d}) = {d}", .{ fd, veclen(buffers), rc });

            if (Maybe(usize).errnoSysFd(rc, .pwritev, fd)) |err| {
                if (err.getErrno() == .INTR) continue;
                return err;
            }

            return Maybe(usize){ .result = @as(usize, @intCast(rc)) };
        }
        unreachable;
    }
}

pub fn readv(fd: bun.FileDescriptor, buffers: []std.posix.iovec) Maybe(usize) {
    if (comptime Environment.allow_assert) {
        if (buffers.len == 0) {
            bun.Output.debugWarn("readv() called with 0 length buffer", .{});
        }
    }

    if (comptime Environment.isMac) {
        const rc = readv_sym(fd.cast(), buffers.ptr, @as(i32, @intCast(buffers.len)));
        if (comptime Environment.allow_assert)
            log("readv({}, {d}) = {d}", .{ fd, veclen(buffers), rc });

        if (Maybe(usize).errnoSysFd(rc, .readv, fd)) |err| {
            return err;
        }

        return Maybe(usize){ .result = @as(usize, @intCast(rc)) };
    } else {
        while (true) {
            const rc = readv_sym(fd.cast(), buffers.ptr, buffers.len);
            if (comptime Environment.allow_assert)
                log("readv({}, {d}) = {d}", .{ fd, veclen(buffers), rc });

            if (Maybe(usize).errnoSysFd(rc, .readv, fd)) |err| {
                if (err.getErrno() == .INTR) continue;
                return err;
            }

            return Maybe(usize){ .result = @as(usize, @intCast(rc)) };
        }
        unreachable;
    }
}

pub fn preadv(fd: bun.FileDescriptor, buffers: []std.posix.iovec, position: isize) Maybe(usize) {
    if (comptime Environment.allow_assert) {
        if (buffers.len == 0) {
            bun.Output.debugWarn("preadv() called with 0 length buffer", .{});
        }
    }

    if (comptime Environment.isMac) {
        const rc = preadv_sym(fd.cast(), buffers.ptr, @as(i32, @intCast(buffers.len)), position);
        if (comptime Environment.allow_assert)
            log("preadv({}, {d}) = {d}", .{ fd, veclen(buffers), rc });

        if (Maybe(usize).errnoSysFd(rc, .preadv, fd)) |err| {
            return err;
        }

        return Maybe(usize){ .result = @as(usize, @intCast(rc)) };
    } else {
        while (true) {
            const rc = preadv_sym(fd.cast(), buffers.ptr, buffers.len, position);
            if (comptime Environment.allow_assert)
                log("preadv({}, {d}) = {d}", .{ fd, veclen(buffers), rc });

            if (Maybe(usize).errnoSysFd(rc, .preadv, fd)) |err| {
                if (err.getErrno() == .INTR) continue;
                return err;
            }

            return Maybe(usize){ .result = @as(usize, @intCast(rc)) };
        }
        unreachable;
    }
}

const preadv_sym = if (builtin.os.tag == .linux and builtin.link_libc)
    std.os.linux.preadv
else if (builtin.os.tag.isDarwin())
    darwin_nocancel.@"preadv$NOCANCEL"
else
    syscall.preadv;

const readv_sym = if (builtin.os.tag == .linux and builtin.link_libc)
    std.os.linux.readv
else if (builtin.os.tag.isDarwin())
    darwin_nocancel.@"readv$NOCANCEL"
else
    syscall.readv;

const pwritev_sym = if (builtin.os.tag == .linux and builtin.link_libc)
    std.os.linux.pwritev
else if (builtin.os.tag.isDarwin())
    darwin_nocancel.@"pwritev$NOCANCEL"
else
    syscall.pwritev;

const writev_sym = if (builtin.os.tag.isDarwin())
    darwin_nocancel.@"writev$NOCANCEL"
else
    syscall.writev;

const pread_sym = if (builtin.os.tag.isDarwin())
    darwin_nocancel.@"pread$NOCANCEL"
else
    syscall.pread;

const fcntl_symbol = syscall.fcntl;

pub fn pread(fd: bun.FileDescriptor, buf: []u8, offset: i64) Maybe(usize) {
    const adjusted_len = @min(buf.len, max_count);

    if (comptime Environment.allow_assert) {
        if (adjusted_len == 0) {
            bun.Output.debugWarn("pread() called with 0 length buffer", .{});
        }
    }

    const ioffset = @as(i64, @bitCast(offset)); // the OS treats this as unsigned
    while (true) {
        const rc = pread_sym(fd.cast(), buf.ptr, adjusted_len, ioffset);
        if (Maybe(usize).errnoSysFd(rc, .pread, fd)) |err| {
            if (err.getErrno() == .INTR) continue;
            return err;
        }
        return Maybe(usize){ .result = @as(usize, @intCast(rc)) };
    }
}

const pwrite_sym = if (builtin.os.tag == .linux and builtin.link_libc and !bun.Environment.isMusl)
    libc.pwrite64
else
    syscall.pwrite;

pub fn pwrite(fd: bun.FileDescriptor, bytes: []const u8, offset: i64) Maybe(usize) {
    if (comptime Environment.allow_assert) {
        if (bytes.len == 0) {
            bun.Output.debugWarn("pwrite() called with 0 length buffer", .{});
        }
    }

    const adjusted_len = @min(bytes.len, max_count);

    const ioffset = @as(i64, @bitCast(offset)); // the OS treats this as unsigned
    while (true) {
        const rc = pwrite_sym(fd.cast(), bytes.ptr, adjusted_len, ioffset);
        return if (Maybe(usize).errnoSysFd(rc, .pwrite, fd)) |err| {
            switch (err.getErrno()) {
                .INTR => continue,
                else => return err,
            }
        } else Maybe(usize){ .result = @as(usize, @intCast(rc)) };
    }
}

pub fn read(fd: bun.FileDescriptor, buf: []u8) Maybe(usize) {
    if (comptime Environment.allow_assert) {
        if (buf.len == 0) {
            bun.Output.debugWarn("read() called with 0 length buffer", .{});
        }
    }
    const debug_timer = bun.Output.DebugTimer.start();
    const adjusted_len = @min(buf.len, max_count);
    return switch (Environment.os) {
        .mac => {
            const rc = darwin_nocancel.@"read$NOCANCEL"(fd.cast(), buf.ptr, adjusted_len);

            if (Maybe(usize).errnoSysFd(rc, .read, fd)) |err| {
                log("read({}, {d}) = {s} ({any})", .{ fd, adjusted_len, err.err.name(), debug_timer });
                return err;
            }
            log("read({}, {d}) = {d} ({any})", .{ fd, adjusted_len, rc, debug_timer });

            return Maybe(usize){ .result = @as(usize, @intCast(rc)) };
        },
        .linux => {
            while (true) {
                const rc = syscall.read(fd.cast(), buf.ptr, adjusted_len);
                log("read({}, {d}) = {d} ({any})", .{ fd, adjusted_len, rc, debug_timer });

                if (Maybe(usize).errnoSysFd(rc, .read, fd)) |err| {
                    if (err.getErrno() == .INTR) continue;
                    return err;
                }
                return Maybe(usize){ .result = @as(usize, @intCast(rc)) };
            }
        },
        .windows => if (fd.kind == .uv)
            sys_uv.read(fd, buf)
        else {
            var amount_read: u32 = 0;
            const rc = kernel32.ReadFile(fd.native(), buf.ptr, @as(u32, @intCast(adjusted_len)), &amount_read, null);
            if (rc == windows.FALSE) {
                const ret: Maybe(usize) = .{
                    .err = sys.Error{
                        .errno = @intFromEnum(bun.windows.getLastErrno()),
                        .syscall = .read,
                        .fd = fd,
                    },
                };

                if (comptime Environment.isDebug) {
                    log("ReadFile({}, {d}) = {s} ({})", .{ fd, adjusted_len, ret.err.name(), debug_timer });
                }

                return ret;
            }
            log("ReadFile({}, {d}) = {d} ({})", .{ fd, adjusted_len, amount_read, debug_timer });

            return Maybe(usize){ .result = amount_read };
        },
        else => @compileError("read is not implemented on this platform"),
    };
}

pub fn readAll(fd: bun.FileDescriptor, buf: []u8) Maybe(usize) {
    var rest = buf;
    var total_read: usize = 0;
    while (rest.len > 0) {
        switch (read(fd, rest)) {
            .result => |len| {
                if (len == 0) break;
                rest = rest[len..];
                total_read += len;
            },
            .err => |err| return .{ .err = err },
        }
    }
    return .{ .result = total_read };
}

const socket_flags_nonblock = c.MSG_DONTWAIT | c.MSG_NOSIGNAL;

pub fn recvNonBlock(fd: bun.FileDescriptor, buf: []u8) Maybe(usize) {
    return recv(fd, buf, socket_flags_nonblock);
}

pub fn recv(fd: bun.FileDescriptor, buf: []u8, flag: u32) Maybe(usize) {
    const adjusted_len = @min(buf.len, max_count);
    const debug_timer = bun.Output.DebugTimer.start();
    if (comptime Environment.allow_assert) {
        if (adjusted_len == 0) {
            bun.Output.debugWarn("recv() called with 0 length buffer", .{});
        }
    }

    if (comptime Environment.isMac) {
        const rc = darwin_nocancel.@"recvfrom$NOCANCEL"(fd.cast(), buf.ptr, adjusted_len, flag, null, null);

        if (Maybe(usize).errnoSysFd(rc, .recv, fd)) |err| {
            log("recv({}, {d}) = {s} {}", .{ fd, adjusted_len, err.err.name(), debug_timer });
            return err;
        }

        log("recv({}, {d}) = {d} {}", .{ fd, adjusted_len, rc, debug_timer });

        return Maybe(usize){ .result = @as(usize, @intCast(rc)) };
    } else {
        while (true) {
            const rc = linux.recvfrom(fd.cast(), buf.ptr, adjusted_len, flag, null, null);

            if (Maybe(usize).errnoSysFd(rc, .recv, fd)) |err| {
                if (err.getErrno() == .INTR) continue;
                log("recv({}, {d}) = {s} {}", .{ fd, adjusted_len, err.err.name(), debug_timer });
                return err;
            }
            log("recv({}, {d}) = {d} {}", .{ fd, adjusted_len, rc, debug_timer });
            return Maybe(usize){ .result = @as(usize, @intCast(rc)) };
        }
    }
}

pub fn sendNonBlock(fd: bun.FileDescriptor, buf: []const u8) Maybe(usize) {
    return send(fd, buf, socket_flags_nonblock);
}

pub fn send(fd: bun.FileDescriptor, buf: []const u8, flag: u32) Maybe(usize) {
    if (comptime Environment.isMac) {
        const rc = darwin_nocancel.@"sendto$NOCANCEL"(fd.cast(), buf.ptr, buf.len, flag, null, 0);

        if (Maybe(usize).errnoSysFd(rc, .send, fd)) |err| {
            syslog("send({}, {d}) = {s}", .{ fd, buf.len, err.err.name() });
            return err;
        }

        syslog("send({}, {d}) = {d}", .{ fd, buf.len, rc });

        return Maybe(usize){ .result = @as(usize, @intCast(rc)) };
    } else {
        while (true) {
            const rc = linux.sendto(fd.cast(), buf.ptr, buf.len, flag, null, 0);

            if (Maybe(usize).errnoSysFd(rc, .send, fd)) |err| {
                if (err.getErrno() == .INTR) continue;
                syslog("send({}, {d}) = {s}", .{ fd, buf.len, err.err.name() });
                return err;
            }

            syslog("send({}, {d}) = {d}", .{ fd, buf.len, rc });
            return Maybe(usize){ .result = @as(usize, @intCast(rc)) };
        }
    }
}

pub fn pidfd_open(pid: std.os.linux.pid_t, flags: u32) Maybe(i32) {
    while (true) {
        const rc = linux.pidfd_open(pid, flags);

        if (Maybe(i32).errnoSys(rc, .pidfd_open)) |err| {
            if (err.getErrno() == .INTR) continue;
            return err;
        }

        return Maybe(i32){ .result = @intCast(rc) };
    }

    unreachable;
}

pub fn lseek(fd: bun.FileDescriptor, offset: i64, whence: usize) Maybe(usize) {
    while (true) {
        const rc = syscall.lseek(fd.cast(), offset, whence);
        if (Maybe(usize).errnoSysFd(rc, .lseek, fd)) |err| {
            if (err.getErrno() == .INTR) continue;
            return err;
        }

        return Maybe(usize){ .result = rc };
    }
}

pub fn readlink(in: [:0]const u8, buf: []u8) Maybe([:0]u8) {
    if (comptime Environment.isWindows) {
        return sys_uv.readlink(in, buf);
    }

    while (true) {
        const rc = syscall.readlink(in, buf.ptr, buf.len);

        if (Maybe([:0]u8).errnoSysP(rc, .readlink, in)) |err| {
            if (err.getErrno() == .INTR) continue;
            return err;
        }
        buf[@intCast(rc)] = 0;
        return .{ .result = buf[0..@intCast(rc) :0] };
    }
}

pub fn readlinkat(fd: bun.FileDescriptor, in: [:0]const u8, buf: []u8) Maybe([:0]u8) {
    while (true) {
        const rc = syscall.readlinkat(fd.cast(), in, buf.ptr, buf.len);

        if (Maybe([:0]u8).errnoSysFP(rc, .readlink, fd, in)) |err| {
            if (err.getErrno() == .INTR) continue;
            return err;
        }
        buf[@intCast(rc)] = 0;
        return Maybe([:0]u8){ .result = buf[0..@intCast(rc) :0] };
    }
}

pub fn ftruncate(fd: bun.FileDescriptor, size: isize) Maybe(void) {
    if (comptime Environment.isWindows) {
        var io_status_block: std.os.windows.IO_STATUS_BLOCK = undefined;
        var eof_info = std.os.windows.FILE_END_OF_FILE_INFORMATION{
            .EndOfFile = @bitCast(size),
        };

        const rc = windows.ntdll.NtSetInformationFile(
            fd.cast(),
            &io_status_block,
            &eof_info,
            @sizeOf(std.os.windows.FILE_END_OF_FILE_INFORMATION),
            .FileEndOfFileInformation,
        );

        return Maybe(void).errnoSysFd(rc, .ftruncate, fd) orelse Maybe(void).success;
    }

    return while (true) {
        if (Maybe(void).errnoSysFd(syscall.ftruncate(fd.cast(), size), .ftruncate, fd)) |err| {
            if (err.getErrno() == .INTR) continue;
            return err;
        }
        return Maybe(void).success;
    };
}

pub fn rename(from: [:0]const u8, to: [:0]const u8) Maybe(void) {
    while (true) {
        if (Maybe(void).errnoSys(syscall.rename(from, to), .rename)) |err| {
            if (err.getErrno() == .INTR) continue;
            return err;
        }
        return Maybe(void).success;
    }
}

pub const RenameAt2Flags = packed struct {
    exchange: bool = false,
    exclude: bool = false,
    nofollow: bool = false,

    pub fn int(self: RenameAt2Flags) u32 {
        var flags: u32 = 0;

        if (comptime Environment.isMac) {
            if (self.exchange) flags |= c.RENAME_SWAP;
            if (self.exclude) flags |= c.RENAME_EXCL;
            if (self.nofollow) flags |= c.RENAME_NOFOLLOW_ANY;
        } else {
            if (self.exchange) flags |= c.RENAME_EXCHANGE;
            if (self.exclude) flags |= c.RENAME_NOREPLACE;
        }

        return flags;
    }
};

pub fn renameatConcurrently(
    from_dir_fd: bun.FileDescriptor,
    from: [:0]const u8,
    to_dir_fd: bun.FileDescriptor,
    to: [:0]const u8,
    comptime opts: struct { move_fallback: bool = false },
) Maybe(void) {
    switch (renameatConcurrentlyWithoutFallback(from_dir_fd, from, to_dir_fd, to)) {
        .result => return Maybe(void).success,
        .err => |e| {
            if (opts.move_fallback and e.getErrno() == E.XDEV) {
                bun.Output.debugWarn("renameatConcurrently() failed with E.XDEV, falling back to moveFileZSlowMaybe()", .{});
                return moveFileZSlowMaybe(from_dir_fd, from, to_dir_fd, to);
            }
            return .{ .err = e };
        },
    }
}

pub fn renameatConcurrentlyWithoutFallback(
    from_dir_fd: bun.FileDescriptor,
    from: [:0]const u8,
    to_dir_fd: bun.FileDescriptor,
    to: [:0]const u8,
) Maybe(void) {
    var did_atomically_replace = false;

    attempt_atomic_rename_and_fallback_to_racy_delete: {
        {
            // Happy path: the folder doesn't exist in the cache dir, so we can
            // just rename it. We don't need to delete anything.
            var err = switch (renameat2(from_dir_fd, from, to_dir_fd, to, .{
                .exclude = true,
            })) {
                // if ENOENT don't retry
                .err => |err| if (err.getErrno() == .NOENT) return .{ .err = err } else err,
                .result => break :attempt_atomic_rename_and_fallback_to_racy_delete,
            };

            // Windows doesn't have any equivalent with renameat with swap
            if (!bun.Environment.isWindows) {
                // Fallback path: the folder exists in the cache dir, it might be in a strange state
                // let's attempt to atomically replace it with the temporary folder's version
                if (switch (err.getErrno()) {
                    .EXIST, .NOTEMPTY, .OPNOTSUPP => true,
                    else => false,
                }) {
                    did_atomically_replace = true;
                    switch (renameat2(from_dir_fd, from, to_dir_fd, to, .{
                        .exchange = true,
                    })) {
                        .err => {},
                        .result => break :attempt_atomic_rename_and_fallback_to_racy_delete,
                    }
                    did_atomically_replace = false;
                }
            }
        }

        //  sad path: let's try to delete the folder and then rename it
        if (to_dir_fd.isValid()) {
            var to_dir = to_dir_fd.stdDir();
            to_dir.deleteTree(to) catch {};
        } else {
            std.fs.deleteTreeAbsolute(to) catch {};
        }
        switch (renameat(from_dir_fd, from, to_dir_fd, to)) {
            .err => |err| {
                return .{ .err = err };
            },
            .result => {},
        }
    }

    return Maybe(void).success;
}

pub fn renameat2(from_dir: bun.FileDescriptor, from: [:0]const u8, to_dir: bun.FileDescriptor, to: [:0]const u8, flags: RenameAt2Flags) Maybe(void) {
    if (Environment.isWindows) {
        return renameat(from_dir, from, to_dir, to);
    }

    while (true) {
        const rc = switch (comptime Environment.os) {
            .linux => std.os.linux.renameat2(@intCast(from_dir.cast()), from.ptr, @intCast(to_dir.cast()), to.ptr, flags.int()),
            .mac => bun.c.renameatx_np(@intCast(from_dir.cast()), from.ptr, @intCast(to_dir.cast()), to.ptr, flags.int()),
            else => @compileError("renameat2() is not implemented on this platform"),
        };

        if (Maybe(void).errnoSys(rc, .rename)) |err| {
            if (err.getErrno() == .INTR) continue;
            if (comptime Environment.allow_assert)
                log("renameat2({}, {s}, {}, {s}) = {d}", .{ from_dir, from, to_dir, to, @intFromEnum(err.getErrno()) });
            return err;
        }
        if (comptime Environment.allow_assert)
            log("renameat2({}, {s}, {}, {s}) = {d}", .{ from_dir, from, to_dir, to, 0 });
        return Maybe(void).success;
    }
}

pub fn renameat(from_dir: bun.FileDescriptor, from: [:0]const u8, to_dir: bun.FileDescriptor, to: [:0]const u8) Maybe(void) {
    if (Environment.isWindows) {
        const w_buf_from = bun.WPathBufferPool.get();
        const w_buf_to = bun.WPathBufferPool.get();
        defer {
            bun.WPathBufferPool.put(w_buf_from);
            bun.WPathBufferPool.put(w_buf_to);
        }

        const rc = bun.windows.renameAtW(
            from_dir,
            bun.strings.toNTPath(w_buf_from, from),
            to_dir,
            bun.strings.toNTPath(w_buf_to, to),
            true,
        );

        return rc;
    }
    while (true) {
        if (Maybe(void).errnoSys(syscall.renameat(from_dir.cast(), from, to_dir.cast(), to), .rename)) |err| {
            if (err.getErrno() == .INTR) continue;
            if (comptime Environment.allow_assert)
                log("renameat({}, {s}, {}, {s}) = {d}", .{ from_dir, from, to_dir, to, @intFromEnum(err.getErrno()) });
            return err;
        }
        if (comptime Environment.allow_assert)
            log("renameat({}, {s}, {}, {s}) = {d}", .{ from_dir, from, to_dir, to, 0 });
        return Maybe(void).success;
    }
}

pub fn chown(path: [:0]const u8, uid: posix.uid_t, gid: posix.gid_t) Maybe(void) {
    while (true) {
        if (Maybe(void).errnoSysP(c.chown(path, uid, gid), .chown, path)) |err| {
            if (err.getErrno() == .INTR) continue;
            return err;
        }
        return Maybe(void).success;
    }
}

pub fn symlink(target: [:0]const u8, dest: [:0]const u8) Maybe(void) {
    while (true) {
        if (Maybe(void).errnoSys(syscall.symlink(target, dest), .symlink)) |err| {
            if (err.getErrno() == .INTR) continue;
            return err;
        }
        return Maybe(void).success;
    }
}

pub fn symlinkat(target: [:0]const u8, dirfd: bun.FileDescriptor, dest: [:0]const u8) Maybe(void) {
    while (true) {
        if (Maybe(void).errnoSys(syscall.symlinkat(target, dirfd.cast(), dest), .symlinkat)) |err| {
            if (err.getErrno() == .INTR) continue;
            return err;
        }
        return Maybe(void).success;
    }
}

pub const WindowsSymlinkOptions = packed struct {
    directory: bool = false,

    var symlink_flags: u32 = w.SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
    pub fn flags(this: WindowsSymlinkOptions) u32 {
        if (this.directory) {
            symlink_flags |= w.SYMBOLIC_LINK_FLAG_DIRECTORY;
        }

        return symlink_flags;
    }

    pub fn denied() void {
        symlink_flags = 0;
    }

    pub var has_failed_to_create_symlink = false;
};

pub fn symlinkOrJunction(dest: [:0]const u8, target: [:0]const u8) Maybe(void) {
    if (comptime !Environment.isWindows) @compileError("symlinkOrJunction is windows only");

    if (!WindowsSymlinkOptions.has_failed_to_create_symlink) {
        const sym16 = bun.WPathBufferPool.get();
        const target16 = bun.WPathBufferPool.get();
        defer {
            bun.WPathBufferPool.put(sym16);
            bun.WPathBufferPool.put(target16);
        }
        const sym_path = bun.strings.toWPathNormalizeAutoExtend(sym16, dest);
        const target_path = bun.strings.toWPathNormalizeAutoExtend(target16, target);
        switch (symlinkW(sym_path, target_path, .{ .directory = true })) {
            .result => {
                return Maybe(void).success;
            },
            .err => |err| {
                if (err.getErrno() == .EXIST) {
                    return .{ .err = err };
                }
            },
        }
    }

    return sys_uv.symlinkUV(target, dest, bun.windows.libuv.UV_FS_SYMLINK_JUNCTION);
}

pub fn symlinkW(dest: [:0]const u16, target: [:0]const u16, options: WindowsSymlinkOptions) Maybe(void) {
    while (true) {
        const flags = options.flags();

        if (windows.CreateSymbolicLinkW(dest, target, flags) == 0) {
            const errno = bun.windows.Win32Error.get();
            log("CreateSymbolicLinkW({}, {}, {any}) = {s}", .{
                bun.fmt.fmtPath(u16, dest, .{}),
                bun.fmt.fmtPath(u16, target, .{}),
                flags,
                @tagName(errno),
            });
            switch (errno) {
                .INVALID_PARAMETER => {
                    if ((flags & w.SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE) != 0) {
                        WindowsSymlinkOptions.denied();
                        continue;
                    }
                },
                else => {},
            }

            if (errno.toSystemErrno()) |err| {
                WindowsSymlinkOptions.has_failed_to_create_symlink = true;
                return .{
                    .err = .{
                        .errno = @intFromEnum(err),
                        .syscall = .symlink,
                    },
                };
            }
        }

        log("CreateSymbolicLinkW({}, {}, {any}) = 0", .{
            bun.fmt.fmtPath(u16, dest, .{}),
            bun.fmt.fmtPath(u16, target, .{}),
            flags,
        });

        return Maybe(void).success;
    }

    unreachable;
}

pub fn clonefile(from: [:0]const u8, to: [:0]const u8) Maybe(void) {
    if (comptime !Environment.isMac) @compileError("macOS only");

    while (true) {
        if (Maybe(void).errnoSys(c.clonefile(from, to, 0), .clonefile)) |err| {
            if (err.getErrno() == .INTR) continue;
            return err;
        }
        return Maybe(void).success;
    }
}

pub fn copyfile(from: [:0]const u8, to: [:0]const u8, flags: posix.system.COPYFILE) Maybe(void) {
    if (comptime !Environment.isMac) @compileError("macOS only");

    while (true) {
        if (Maybe(void).errnoSys(c.copyfile(from, to, null, flags), .copyfile)) |err| {
            if (err.getErrno() == .INTR) continue;
            return err;
        }
        return Maybe(void).success;
    }
}

pub fn fcopyfile(fd_in: bun.FileDescriptor, fd_out: bun.FileDescriptor, flags: posix.system.COPYFILE) Maybe(void) {
    if (comptime !Environment.isMac) @compileError("macOS only");

    while (true) {
        if (Maybe(void).errnoSys(syscall.fcopyfile(fd_in.cast(), fd_out.cast(), null, flags), .fcopyfile)) |err| {
            if (err.getErrno() == .INTR) continue;
            return err;
        }
        return Maybe(void).success;
    }
}

pub fn unlinkW(from: [:0]const u16) Maybe(void) {
    if (windows.DeleteFileW(from.ptr) != 0) {
        return .{ .err = Error.fromCode(bun.windows.getLastErrno(), .unlink) };
    }

    return Maybe(void).success;
}

pub fn unlink(from: [:0]const u8) Maybe(void) {
    if (comptime Environment.isWindows) {
        const w_buf = bun.WPathBufferPool.get();
        defer bun.WPathBufferPool.put(w_buf);
        return unlinkW(bun.strings.toNTPath(w_buf, from));
    }

    while (true) {
        if (Maybe(void).errnoSysP(syscall.unlink(from), .unlink, from)) |err| {
            if (err.getErrno() == .INTR) continue;
            return err;
        }

        log("unlink({s}) = 0", .{from});
        return Maybe(void).success;
    }
}

pub fn rmdirat(dirfd: bun.FileDescriptor, to: anytype) Maybe(void) {
    return unlinkatWithFlags(dirfd, to, std.posix.AT.REMOVEDIR);
}

pub fn unlinkatWithFlags(dirfd: bun.FileDescriptor, to: anytype, flags: c_uint) Maybe(void) {
    if (Environment.isWindows) {
        if (comptime std.meta.Elem(@TypeOf(to)) == u8) {
            const w_buf = bun.WPathBufferPool.get();
            defer bun.WPathBufferPool.put(w_buf);
            return unlinkatWithFlags(dirfd, bun.strings.toNTPath(w_buf, bun.span(to)), flags);
        }

        return bun.windows.DeleteFileBun(to, .{
            .dir = if (dirfd != bun.invalid_fd) dirfd.cast() else null,
            .remove_dir = flags & std.posix.AT.REMOVEDIR != 0,
        });
    }

    while (true) {
        if (Maybe(void).errnoSysFP(syscall.unlinkat(dirfd.cast(), to, flags), .unlink, dirfd, to)) |err| {
            if (err.getErrno() == .INTR) continue;
            if (comptime Environment.allow_assert)
                log("unlinkat({}, {s}) = {d}", .{ dirfd, bun.sliceTo(to, 0), @intFromEnum(err.getErrno()) });
            return err;
        }
        if (comptime Environment.allow_assert)
            log("unlinkat({}, {s}) = 0", .{ dirfd, bun.sliceTo(to, 0) });
        return Maybe(void).success;
    }
    unreachable;
}

pub fn unlinkat(dirfd: bun.FileDescriptor, to: anytype) Maybe(void) {
    if (Environment.isWindows) {
        return unlinkatWithFlags(dirfd, to, 0);
    }
    while (true) {
        if (Maybe(void).errnoSysFP(syscall.unlinkat(dirfd.cast(), to, 0), .unlink, dirfd, to)) |err| {
            if (err.getErrno() == .INTR) continue;
            if (comptime Environment.allow_assert)
                log("unlinkat({}, {s}) = {d}", .{ dirfd, bun.sliceTo(to, 0), @intFromEnum(err.getErrno()) });
            return err;
        }
        if (comptime Environment.allow_assert)
            log("unlinkat({}, {s}) = 0", .{ dirfd, bun.sliceTo(to, 0) });
        return Maybe(void).success;
    }
}

pub fn getFdPath(fd: bun.FileDescriptor, out_buffer: *bun.PathBuffer) Maybe([]u8) {
    switch (comptime builtin.os.tag) {
        .windows => {
            var wide_buf: [windows.PATH_MAX_WIDE]u16 = undefined;
            const wide_slice = bun.windows.GetFinalPathNameByHandle(fd.cast(), .{}, wide_buf[0..]) catch {
                return Maybe([]u8){ .err = .{ .errno = @intFromEnum(SystemErrno.EBADF), .syscall = .GetFinalPathNameByHandle } };
            };

            // Trust that Windows gives us valid UTF-16LE.
            return .{ .result = @constCast(bun.strings.fromWPath(out_buffer, wide_slice)) };
        },
        .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..out_buffer.*.len], 0);
            switch (fcntl(fd, posix.F.GETPATH, @intFromPtr(out_buffer))) {
                .err => |err| return .{ .err = err },
                .result => {},
            }

            return .{ .result = bun.sliceTo(out_buffer, 0) };
        },
        .linux => {
            // TODO: alpine linux may not have /proc/self
            var procfs_buf: ["/proc/self/fd/-2147483648".len + 1:0]u8 = undefined;
            const proc_path = std.fmt.bufPrintZ(&procfs_buf, "/proc/self/fd/{d}", .{fd.cast()}) catch unreachable;
            return switch (readlink(proc_path, out_buffer)) {
                .err => |err| return .{ .err = err },
                .result => |result| .{ .result = result },
            };
        },
        else => @compileError("querying for canonical path of a handle is unsupported on this host"),
    }
}

/// 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(page_size_min) u8,
    length: usize,
    prot: u32,
    flags: std.posix.MAP,
    fd: bun.FileDescriptor,
    offset: u64,
) Maybe([]align(page_size_min) u8) {
    const ioffset = @as(i64, @bitCast(offset)); // the OS treats this as unsigned
    const rc = std.c.mmap(ptr, length, prot, flags, fd.cast(), ioffset);
    const fail = std.c.MAP_FAILED;
    if (rc == fail) {
        return .initErr(.{
            .errno = @as(sys.Error.Int, @truncate(@intFromEnum(getErrno(@as(i64, @bitCast(@intFromPtr(fail))))))),
            .syscall = .mmap,
        });
    }

    return .initResult(@as([*]align(page_size_min) u8, @ptrCast(@alignCast(rc)))[0..length]);
}

pub fn mmapFile(path: [:0]const u8, flags: std.c.MAP, wanted_size: ?usize, offset: usize) Maybe([]align(page_size_min) u8) {
    assertIsValidWindowsPath(u8, path);
    const fd = switch (open(path, bun.O.RDWR, 0)) {
        .result => |fd| fd,
        .err => |err| return .{ .err = err },
    };
    defer fd.close();

    var size = std.math.sub(usize, @as(usize, @intCast(switch (fstat(fd)) {
        .result => |result| result.size,
        .err => |err| {
            return .{ .err = err };
        },
    })), offset) catch 0;

    if (wanted_size) |size_| size = @min(size, size_);

    const map = switch (mmap(null, size, posix.PROT.READ | posix.PROT.WRITE, flags, fd, offset)) {
        .result => |map| map,

        .err => |err| {
            return .{ .err = err };
        },
    };

    return .{ .result = map };
}

pub fn setCloseOnExec(fd: bun.FileDescriptor) Maybe(void) {
    switch (fcntl(fd, std.posix.F.GETFD, 0)) {
        .result => |fl| {
            switch (fcntl(fd, std.posix.F.SETFD, fl | std.posix.FD_CLOEXEC)) {
                .result => {},
                .err => |err| return .{ .err = err },
            }
        },
        .err => |err| return .{ .err = err },
    }

    return .{ .result = {} };
}

pub fn setsockopt(fd: bun.FileDescriptor, level: c_int, optname: u32, value: i32) Maybe(i32) {
    while (true) {
        const rc = syscall.setsockopt(fd.cast(), level, optname, &value, @sizeOf(i32));
        if (Maybe(i32).errnoSysFd(rc, .setsockopt, fd)) |err| {
            if (err.getErrno() == .INTR) continue;
            log("setsockopt() = {d} {s}", .{ err.err.errno, err.err.name() });
            return err;
        }
        log("setsockopt({d}, {d}, {d}) = {d}", .{ fd.cast(), level, optname, rc });
        return .{ .result = @intCast(rc) };
    }

    unreachable;
}

pub fn setNoSigpipe(fd: bun.FileDescriptor) Maybe(void) {
    if (comptime Environment.isMac) {
        return switch (setsockopt(fd, std.posix.SOL.SOCKET, std.posix.SO.NOSIGPIPE, 1)) {
            .result => .{ .result = {} },
            .err => |err| .{ .err = err },
        };
    }

    return .{ .result = {} };
}

const socketpair_t = if (Environment.isLinux) i32 else c_uint;

/// libc socketpair() except it defaults to:
/// - SOCK_CLOEXEC on Linux
/// - SO_NOSIGPIPE on macOS
///
/// On POSIX it otherwise makes it do O_CLOEXEC.
pub fn socketpair(domain: socketpair_t, socktype: socketpair_t, protocol: socketpair_t, nonblocking_status: enum { blocking, nonblocking }) Maybe([2]bun.FileDescriptor) {
    if (comptime !Environment.isPosix) @compileError("linux only!");

    var fds_i: [2]syscall.fd_t = .{ 0, 0 };

    if (comptime Environment.isLinux) {
        while (true) {
            const nonblock_flag: i32 = if (nonblocking_status == .nonblocking) linux.SOCK.NONBLOCK else 0;
            const rc = std.os.linux.socketpair(domain, socktype | linux.SOCK.CLOEXEC | nonblock_flag, protocol, &fds_i);
            if (Maybe([2]bun.FileDescriptor).errnoSys(rc, .socketpair)) |err| {
                if (err.getErrno() == .INTR) continue;

                log("socketpair() = {d} {s}", .{ err.err.errno, err.err.name() });
                return err;
            }

            break;
        }
    } else {
        while (true) {
            const err = libc.socketpair(domain, socktype, protocol, &fds_i);

            if (Maybe([2]bun.FileDescriptor).errnoSys(err, .socketpair)) |err2| {
                if (err2.getErrno() == .INTR) continue;
                log("socketpair() = {d} {s}", .{ err2.err.errno, err2.err.name() });
                return err2;
            }

            break;
        }

        const err: ?sys.Error = err: {

            // Set O_CLOEXEC first.
            inline for (0..2) |i| {
                switch (setCloseOnExec(.fromNative(fds_i[i]))) {
                    .err => |err| break :err err,
                    .result => {},
                }
            }

            if (comptime Environment.isMac) {
                inline for (0..2) |i| {
                    switch (setNoSigpipe(.fromNative(fds_i[i]))) {
                        .err => |err| break :err err,
                        else => {},
                    }
                }
            }

            if (nonblocking_status == .nonblocking) {
                inline for (0..2) |i| {
                    switch (setNonblocking(.fromNative(fds_i[i]))) {
                        .err => |err| break :err err,
                        .result => {},
                    }
                }
            }

            break :err null;
        };

        // On any error after socketpair(), we need to close it.
        if (err) |errr| {
            inline for (0..2) |i| {
                bun.FD.fromNative(fds_i[i]).close();
            }

            log("socketpair() = {d} {s}", .{ errr.errno, errr.name() });

            return .{ .err = errr };
        }
    }

    log("socketpair() = [{d} {d}]", .{ fds_i[0], fds_i[1] });

    return Maybe([2]bun.FileDescriptor){ .result = .{ .fromNative(fds_i[0]), .fromNative(fds_i[1]) } };
}

pub fn munmap(memory: []align(page_size_min) const u8) Maybe(void) {
    if (Maybe(void).errnoSys(syscall.munmap(memory.ptr, memory.len), .munmap)) |err| {
        return err;
    } else return Maybe(void).success;
}

pub fn memfd_create(name: [:0]const u8, flags: u32) Maybe(bun.FileDescriptor) {
    if (comptime !Environment.isLinux) @compileError("linux only!");

    const rc = std.os.linux.memfd_create(name, flags);

    log("memfd_create({s}, {d}) = {d}", .{ name, flags, rc });

    return Maybe(bun.FileDescriptor).errnoSys(rc, .memfd_create) orelse
        .{ .result = .fromNative(@intCast(rc)) };
}

pub fn setPipeCapacityOnLinux(fd: bun.FileDescriptor, capacity: usize) Maybe(usize) {
    if (comptime !Environment.isLinux) @compileError("Linux-only");
    bun.assert(capacity > 0);

    // In  Linux  versions  before 2.6.11, the capacity of a
    // pipe was the same as the system page size (e.g., 4096
    // bytes on i386).  Since Linux 2.6.11, the pipe
    // capacity is 16 pages (i.e., 65,536 bytes in a system
    // with a page size of 4096 bytes).  Since Linux 2.6.35,
    // the default pipe capacity is 16 pages, but the
    // capacity can be queried  and  set  using  the
    // fcntl(2) F_GETPIPE_SZ and F_SETPIPE_SZ operations.
    // See fcntl(2) for more information.
    //:# define F_SETPIPE_SZ    1031    /* Set pipe page size array.
    const F_SETPIPE_SZ = 1031;
    const F_GETPIPE_SZ = 1032;

    // We don't use glibc here
    // It didn't work. Always returned 0.
    const pipe_len = switch (fcntl(fd, F_GETPIPE_SZ, 0)) {
        .result => |result| result,
        .err => |err| return err,
    };
    if (pipe_len == 0) return Maybe(usize){ .result = 0 };
    if (pipe_len >= capacity) return Maybe(usize){ .result = pipe_len };

    const new_pipe_len = switch (fcntl(fd, F_SETPIPE_SZ, capacity)) {
        .result => |result| result,
        .err => |err| return err,
    };
    return Maybe(usize){ .result = new_pipe_len };
}

pub fn getMaxPipeSizeOnLinux() usize {
    return @as(
        usize,
        @intCast(bun.once(struct {
            fn once() c_int {
                const strings = bun.strings;
                const default_out_size = 512 * 1024;
                const pipe_max_size_fd = switch (open("/proc/sys/fs/pipe-max-size", bun.O.RDONLY, 0)) {
                    .result => |fd2| fd2,
                    .err => |err| {
                        log("Failed to open /proc/sys/fs/pipe-max-size: {d}\n", .{err.errno});
                        return default_out_size;
                    },
                };
                defer pipe_max_size_fd.close();
                var max_pipe_size_buf: [128]u8 = undefined;
                const max_pipe_size = switch (read(pipe_max_size_fd, max_pipe_size_buf[0..])) {
                    .result => |bytes_read| std.fmt.parseInt(i64, strings.trim(max_pipe_size_buf[0..bytes_read], "\n"), 10) catch |err| {
                        log("Failed to parse /proc/sys/fs/pipe-max-size: {any}\n", .{@errorName(err)});
                        return default_out_size;
                    },
                    .err => |err| {
                        log("Failed to read /proc/sys/fs/pipe-max-size: {d}\n", .{err.errno});
                        return default_out_size;
                    },
                };

                // we set the absolute max to 8 MB because honestly that's a huge pipe
                // my current linux machine only goes up to 1 MB, so that's very unlikely to be hit
                return @min(@as(c_int, @truncate(max_pipe_size -| 32)), 1024 * 1024 * 8);
            }
        }.once, c_int)),
    );
}

pub const WindowsFileAttributes = packed struct(windows.DWORD) {
    //1 0x00000001 FILE_ATTRIBUTE_READONLY
    is_readonly: bool,
    //2 0x00000002 FILE_ATTRIBUTE_HIDDEN
    is_hidden: bool,
    //4 0x00000004 FILE_ATTRIBUTE_SYSTEM
    is_system: bool,
    //8
    _03: bool,
    //1 0x00000010 FILE_ATTRIBUTE_DIRECTORY
    is_directory: bool,
    //2 0x00000020 FILE_ATTRIBUTE_ARCHIVE
    is_archive: bool,
    //4 0x00000040 FILE_ATTRIBUTE_DEVICE
    is_device: bool,
    //8 0x00000080 FILE_ATTRIBUTE_NORMAL
    is_normal: bool,
    //1 0x00000100 FILE_ATTRIBUTE_TEMPORARY
    is_temporary: bool,
    //2 0x00000200 FILE_ATTRIBUTE_SPARSE_FILE
    is_sparse_file: bool,
    //4 0x00000400 FILE_ATTRIBUTE_REPARSE_POINT
    is_reparse_point: bool,
    //8 0x00000800 FILE_ATTRIBUTE_COMPRESSED
    is_compressed: bool,
    //1 0x00001000 FILE_ATTRIBUTE_OFFLINE
    is_offline: bool,
    //2 0x00002000 FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
    is_not_content_indexed: bool,
    //4 0x00004000 FILE_ATTRIBUTE_ENCRYPTED
    is_encrypted: bool,
    //8 0x00008000 FILE_ATTRIBUTE_INTEGRITY_STREAM
    is_integrity_stream: bool,
    //1 0x00010000 FILE_ATTRIBUTE_VIRTUAL
    is_virtual: bool,
    //2 0x00020000 FILE_ATTRIBUTE_NO_SCRUB_DATA
    is_no_scrub_data: bool,
    //4 0x00040000 FILE_ATTRIBUTE_EA
    is_ea: bool,
    //8 0x00080000 FILE_ATTRIBUTE_PINNED
    is_pinned: bool,
    //1 0x00100000 FILE_ATTRIBUTE_UNPINNED
    is_unpinned: bool,
    //2
    _21: bool,
    //4 0x00040000 FILE_ATTRIBUTE_RECALL_ON_OPEN
    is_recall_on_open: bool,
    //8
    _23: bool,
    //1
    _24: bool,
    //2
    _25: bool,
    //4 0x00400000 FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS
    is_recall_on_data_access: bool,
    //
    __: u5,
};

pub fn getFileAttributes(path: anytype) ?WindowsFileAttributes {
    if (comptime !Environment.isWindows) @compileError("Windows only");

    const T = std.meta.Child(@TypeOf(path));
    if (T == u16) {
        // Win32 API does file path normalization, so we do not need the valid path assertion here.
        const dword = kernel32.GetFileAttributesW(path.ptr);
        if (comptime Environment.isDebug) {
            log("GetFileAttributesW({}) = {d}", .{ bun.fmt.utf16(path), dword });
        }
        if (dword == windows.INVALID_FILE_ATTRIBUTES) {
            return null;
        }
        const attributes: WindowsFileAttributes = @bitCast(dword);
        return attributes;
    } else {
        const wbuf = bun.WPathBufferPool.get();
        defer bun.WPathBufferPool.put(wbuf);
        const path_to_use = bun.strings.toKernel32Path(wbuf, path);
        return getFileAttributes(path_to_use);
    }
}

pub fn existsOSPath(path: bun.OSPathSliceZ, file_only: bool) bool {
    if (Environment.isPosix) {
        // access() may not work correctly on NFS file systems with UID
        // mapping enabled, because UID mapping is done on the server and
        // hidden from the client, which checks permissions. Similar
        // problems can occur to FUSE mounts.
        return syscall.access(path, 0) == 0;
    }

    if (Environment.isWindows) {
        const attributes = getFileAttributes(path) orelse return false;
        if (file_only and attributes.is_directory) {
            return false;
        }
        if (attributes.is_reparse_point) {
            // Check if the underlying file exists by opening it.
            const rc = std.os.windows.kernel32.CreateFileW(
                path,
                0,
                0,
                null,
                w.OPEN_EXISTING,
                w.FILE_FLAG_BACKUP_SEMANTICS,
                null,
            );
            if (rc == w.INVALID_HANDLE_VALUE) return false;
            defer _ = bun.windows.CloseHandle(rc);
            return true;
        }
        return true;
    }

    @compileError("TODO: existsOSPath");
}

pub fn exists(path: []const u8) bool {
    if (comptime Environment.isPosix) {
        return syscall.access(&(std.posix.toPosixPath(path) catch return false), 0) == 0;
    }

    if (comptime Environment.isWindows) {
        return getFileAttributes(path) != null;
    }

    @compileError("TODO: existsOSPath");
}

pub fn existsZ(path: [:0]const u8) bool {
    if (comptime Environment.isPosix) {
        return syscall.access(path, 0) == 0;
    }

    if (comptime Environment.isWindows) {
        return getFileAttributes(path) != null;
    }
}

pub fn faccessat(dir_fd: bun.FileDescriptor, subpath: anytype) JSC.Maybe(bool) {
    const has_sentinel = std.meta.sentinel(@TypeOf(subpath)) != null;

    if (comptime !has_sentinel) {
        const path = std.os.toPosixPath(subpath) catch return JSC.Maybe(bool){ .err = Error.fromCode(.NAMETOOLONG, .access) };
        return faccessat(dir_fd, path);
    }

    if (comptime Environment.isLinux) {
        // avoid loading the libc symbol for this to reduce chances of GLIBC minimum version requirements
        const rc = linux.faccessat(dir_fd.cast(), subpath, linux.F_OK, 0);
        syslog("faccessat({}, {}, O_RDONLY, 0) = {d}", .{ dir_fd, bun.fmt.fmtOSPath(subpath, .{}), if (rc == 0) 0 else @intFromEnum(getErrno(rc)) });
        if (rc == 0) {
            return JSC.Maybe(bool){ .result = true };
        }

        return JSC.Maybe(bool){ .result = false };
    }

    // on other platforms use faccessat from libc
    const rc = std.c.faccessat(dir_fd.cast(), subpath, std.posix.F_OK, 0);
    syslog("faccessat({}, {}, O_RDONLY, 0) = {d}", .{ dir_fd, bun.fmt.fmtOSPath(subpath, .{}), if (rc == 0) 0 else @intFromEnum(getErrno(rc)) });
    if (rc == 0) {
        return JSC.Maybe(bool){ .result = true };
    }

    return JSC.Maybe(bool){ .result = false };
}

pub fn directoryExistsAt(dir: bun.FileDescriptor, subpath: anytype) JSC.Maybe(bool) {
    return switch (existsAtType(dir, subpath)) {
        //
        .err => |err| if (err.getErrno() == .NOENT)
            .{ .result = false }
        else
            .{ .err = err },
        .result => |result| .{ .result = result == .directory },
    };
}

pub fn futimens(fd: bun.FileDescriptor, atime: JSC.Node.TimeLike, mtime: JSC.Node.TimeLike) Maybe(void) {
    if (comptime Environment.isWindows) @compileError("TODO: futimes");

    while (true) {
        const rc = syscall.futimens(fd.cast(), &[2]syscall.timespec{
            .{ .sec = @intCast(atime.sec), .nsec = atime.nsec },
            .{ .sec = @intCast(mtime.sec), .nsec = mtime.nsec },
        });

        log("futimens({}, accessed=({d}, {d}), modified=({d}, {d})) = {d}", .{ fd, atime.sec, atime.nsec, mtime.sec, mtime.nsec, rc });

        if (rc == 0) {
            return Maybe(void).success;
        }

        switch (getErrno(rc)) {
            .INTR => continue,
            else => return Maybe(void).errnoSysFd(rc, .futimens, fd).?,
        }
    }

    unreachable;
}

fn utimensWithFlags(path: bun.OSPathSliceZ, atime: JSC.Node.TimeLike, mtime: JSC.Node.TimeLike, flags: u32) Maybe(void) {
    if (comptime Environment.isWindows) @compileError("TODO: utimens");

    while (true) {
        var times: [2]syscall.timespec = .{
            .{ .sec = @intCast(atime.sec), .nsec = atime.nsec },
            .{ .sec = @intCast(mtime.sec), .nsec = mtime.nsec },
        };
        const rc = syscall.utimensat(
            std.fs.cwd().fd,
            path,
            // this var should be a const, the zig type definition is wrong.
            &times,
            flags,
        );

        log("utimensat({d}, atime=({d}, {d}), mtime=({d}, {d})) = {d}", .{ std.fs.cwd().fd, atime.sec, atime.nsec, mtime.sec, mtime.nsec, rc });

        if (rc == 0) {
            return Maybe(void).success;
        }

        switch (getErrno(rc)) {
            .INTR => continue,
            else => return Maybe(void).errnoSysP(rc, .utimensat, path).?,
        }
    }

    unreachable;
}

pub fn getFcntlFlags(fd: bun.FileDescriptor) Maybe(fnctl_int) {
    return switch (fcntl(
        fd,
        std.posix.F.GETFL,
        0,
    )) {
        .result => |f| .{ .result = f },
        .err => |err| .{ .err = err },
    };
}

pub fn utimens(path: bun.OSPathSliceZ, atime: JSC.Node.TimeLike, mtime: JSC.Node.TimeLike) Maybe(void) {
    return utimensWithFlags(path, atime, mtime, 0);
}

pub fn setNonblocking(fd: bun.FileDescriptor) Maybe(void) {
    return updateNonblocking(fd, true);
}

pub fn updateNonblocking(fd: bun.FileDescriptor, nonblocking: bool) Maybe(void) {
    const current_flags: i32 = switch (getFcntlFlags(fd)) {
        .result => |f| @intCast(f),
        .err => |err| return .{ .err = err },
    };

    const new_flags: i32 = if (nonblocking) current_flags | @as(i32, bun.O.NONBLOCK) else current_flags & ~@as(i32, bun.O.NONBLOCK);

    if (new_flags != current_flags) {
        switch (fcntl(fd, std.posix.F.SETFL, @as(fnctl_int, @intCast(new_flags)))) {
            .err => |err| return .{ .err = err },
            .result => {},
        }
    }

    return Maybe(void).success;
}

pub const ExistsAtType = enum {
    file,
    directory,
};
pub fn existsAtType(fd: bun.FileDescriptor, subpath: anytype) Maybe(ExistsAtType) {
    if (comptime Environment.isWindows) {
        const wbuf = bun.WPathBufferPool.get();
        defer bun.WPathBufferPool.put(wbuf);
        const path = if (std.meta.Child(@TypeOf(subpath)) == u16)
            bun.strings.toNTPath16(wbuf, subpath)
        else
            bun.strings.toNTPath(wbuf, subpath);

        const path_len_bytes: u16 = @truncate(path.len * 2);
        var nt_name = w.UNICODE_STRING{
            .Length = path_len_bytes,
            .MaximumLength = path_len_bytes,
            .Buffer = @constCast(path.ptr),
        };
        var attr = w.OBJECT_ATTRIBUTES{
            .Length = @sizeOf(w.OBJECT_ATTRIBUTES),
            .RootDirectory = if (std.fs.path.isAbsoluteWindowsWTF16(path))
                null
            else if (fd == bun.invalid_fd)
                std.fs.cwd().fd
            else
                fd.cast(),
            .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here.
            .ObjectName = &nt_name,
            .SecurityDescriptor = null,
            .SecurityQualityOfService = null,
        };
        var basic_info: w.FILE_BASIC_INFORMATION = undefined;
        const rc = ntdll.NtQueryAttributesFile(&attr, &basic_info);
        if (JSC.Maybe(bool).errnoSys(rc, .access)) |err| {
            syslog("NtQueryAttributesFile({}, O_RDONLY, 0) = {}", .{ bun.fmt.fmtOSPath(path, .{}), err });
            return .{ .err = err.err };
        }

        const is_regular_file = basic_info.FileAttributes != c.INVALID_FILE_ATTRIBUTES and
            // from libuv: directories cannot be read-only
            // https://github.com/libuv/libuv/blob/eb5af8e3c0ea19a6b0196d5db3212dae1785739b/src/win/fs.c#L2144-L2146
            (basic_info.FileAttributes & c.FILE_ATTRIBUTE_DIRECTORY == 0 or
                basic_info.FileAttributes & c.FILE_ATTRIBUTE_READONLY == 0);

        const is_dir = basic_info.FileAttributes != c.INVALID_FILE_ATTRIBUTES and
            basic_info.FileAttributes & c.FILE_ATTRIBUTE_DIRECTORY != 0 and
            basic_info.FileAttributes & c.FILE_ATTRIBUTE_READONLY == 0;

        return if (is_dir) {
            syslog("NtQueryAttributesFile({}, O_RDONLY, 0) = directory", .{bun.fmt.fmtOSPath(path, .{})});
            return .{ .result = .directory };
        } else if (is_regular_file) {
            syslog("NtQueryAttributesFile({}, O_RDONLY, 0) = file", .{bun.fmt.fmtOSPath(path, .{})});
            return .{ .result = .file };
        } else {
            syslog("NtQueryAttributesFile({}, O_RDONLY, 0) = {d}", .{ bun.fmt.fmtOSPath(path, .{}), basic_info.FileAttributes });
            return .{ .err = Error.fromCode(.UNKNOWN, .access) };
        };
    }

    if (std.meta.sentinel(@TypeOf(subpath)) == null) {
        const path_buf = bun.PathBufferPool.get();
        defer bun.PathBufferPool.put(path_buf);
        @memcpy(path_buf[0..subpath.len], subpath);
        path_buf[subpath.len] = 0;
        const slice: [:0]const u8 = @ptrCast(path_buf);
        return existsAtType(fd, slice);
    }

    return switch (fstatat(fd, subpath)) {
        .err => |err| .{ .err = err },
        .result => |result| if (S.ISDIR(result.mode)) .{ .result = .directory } else .{ .result = .file },
    };
}

pub fn existsAt(fd: bun.FileDescriptor, subpath: [:0]const u8) bool {
    if (comptime Environment.isPosix) {
        return switch (faccessat(fd, subpath)) {
            .err => false,
            .result => |r| r,
        };
    }

    if (comptime Environment.isWindows) {
        if (existsAtType(fd, subpath).asValue()) |exists_at_type| {
            return exists_at_type == .file;
        }
        return false;
    }

    @compileError("TODO: existsAtOSPath");
}

pub extern "c" fn is_executable_file(path: [*:0]const u8) bool;

pub fn isExecutableFileOSPath(path: bun.OSPathSliceZ) bool {
    if (comptime Environment.isPosix) {
        return is_executable_file(path);
    }

    if (comptime Environment.isWindows) {
        // Rationale: `GetBinaryTypeW` does not work on .cmd files.
        // Windows does not have executable permission like posix does, instead we
        // can just look at the file extension to determine executable status.
        @compileError("Do not use isExecutableFilePath on Windows");

        // var out: windows.DWORD = 0;
        // const rc = kernel32.GetBinaryTypeW(path, &out);

        // const result = if (rc == windows.FALSE)
        //     false
        // else switch (out) {
        //     kernel32.SCS_32BIT_BINARY,
        //     kernel32.SCS_64BIT_BINARY,
        //     kernel32.SCS_DOS_BINARY,
        //     kernel32.SCS_OS216_BINARY,
        //     kernel32.SCS_PIF_BINARY,
        //     kernel32.SCS_POSIX_BINARY,
        //     => true,
        //     else => false,
        // };

        // log("GetBinaryTypeW({}) = {d}. isExecutable={}", .{ bun.fmt.utf16(path), out, result });

        // return result;
    }

    @compileError("TODO: isExecutablePath");
}

pub fn isExecutableFilePath(path: anytype) bool {
    const Type = @TypeOf(path);
    if (comptime Environment.isPosix) {
        switch (Type) {
            *[*:0]const u8, *[*:0]u8, [*:0]const u8, [*:0]u8 => return is_executable_file(path),
            [:0]const u8, [:0]u8 => return is_executable_file(path.ptr),
            []const u8, []u8 => return is_executable_file(
                &(std.posix.toPosixPath(path) catch return false),
            ),
            else => @compileError("TODO: isExecutableFilePath"),
        }
    }

    if (comptime Environment.isWindows) {
        var buf: [(bun.MAX_PATH_BYTES / 2) + 1]u16 = undefined;
        return isExecutableFileOSPath(bun.strings.toWPath(&buf, path));
    }

    @compileError("TODO: isExecutablePath");
}

pub fn setFileOffset(fd: bun.FileDescriptor, offset: usize) Maybe(void) {
    if (comptime Environment.isLinux) {
        return Maybe(void).errnoSysFd(
            linux.lseek(fd.cast(), @intCast(offset), posix.SEEK.SET),
            .lseek,
            fd,
        ) orelse Maybe(void).success;
    }

    if (comptime Environment.isMac) {
        return Maybe(void).errnoSysFd(
            std.c.lseek(fd.cast(), @intCast(offset), posix.SEEK.SET),
            .lseek,
            fd,
        ) orelse Maybe(void).success;
    }

    if (comptime Environment.isWindows) {
        const offset_high: u64 = @as(u32, @intCast(offset >> 32));
        const offset_low: u64 = @as(u32, @intCast(offset & 0xFFFFFFFF));
        var plarge_integer: i64 = @bitCast(offset_high);
        const rc = kernel32.SetFilePointerEx(
            fd.cast(),
            @as(windows.LARGE_INTEGER, @bitCast(offset_low)),
            &plarge_integer,
            windows.FILE_BEGIN,
        );
        if (rc == windows.FALSE) {
            return Maybe(void).errnoSysFd(0, .lseek, fd) orelse Maybe(void).success;
        }
        return Maybe(void).success;
    }
}

pub fn setFileOffsetToEndWindows(fd: bun.FileDescriptor) Maybe(usize) {
    if (comptime Environment.isWindows) {
        var new_ptr: std.os.windows.LARGE_INTEGER = undefined;
        const rc = kernel32.SetFilePointerEx(fd.cast(), 0, &new_ptr, windows.FILE_END);
        if (rc == windows.FALSE) {
            return Maybe(usize).errnoSysFd(0, .lseek, fd) orelse Maybe(usize){ .result = 0 };
        }
        return Maybe(usize){ .result = @intCast(new_ptr) };
    }
    @compileError("Not Implemented");
}

extern fn Bun__disableSOLinger(fd: if (Environment.isWindows) windows.HANDLE else i32) void;
pub fn disableLinger(fd: bun.FileDescriptor) void {
    Bun__disableSOLinger(fd.cast());
}

pub fn pipe() Maybe([2]bun.FileDescriptor) {
    if (comptime Environment.isWindows) {
        @panic("TODO: Implement `pipe()` for Windows");
    }

    var fds: [2]i32 = undefined;
    const rc = syscall.pipe(&fds);
    if (Maybe([2]bun.FileDescriptor).errnoSys(rc, .pipe)) |err| {
        return err;
    }
    log("pipe() = [{d}, {d}]", .{ fds[0], fds[1] });
    return .{ .result = .{ .fromNative(fds[0]), .fromNative(fds[1]) } };
}

pub fn openNullDevice() Maybe(bun.FileDescriptor) {
    if (comptime Environment.isWindows) {
        return sys_uv.open("nul", 0, 0);
    }

    return open("/dev/null", bun.O.RDWR, 0);
}

pub fn dupWithFlags(fd: bun.FileDescriptor, _: i32) Maybe(bun.FileDescriptor) {
    if (comptime Environment.isWindows) {
        var target: windows.HANDLE = undefined;
        const process = kernel32.GetCurrentProcess();
        const out = kernel32.DuplicateHandle(
            process,
            fd.cast(),
            process,
            &target,
            0,
            w.TRUE,
            w.DUPLICATE_SAME_ACCESS,
        );
        if (out == 0) {
            if (Maybe(bun.FileDescriptor).errnoSysFd(0, .dup, fd)) |err| {
                log("dup({}) = {}", .{ fd, err });
                return err;
            }
        }
        const duplicated_fd = bun.FD.fromNative(target);
        log("dup({}) = {}", .{ fd, duplicated_fd });
        return Maybe(bun.FileDescriptor){ .result = duplicated_fd };
    }

    const ArgType = if (comptime Environment.isLinux) usize else c_int;
    const out = switch (fcntl(fd, @as(i32, bun.c.F_DUPFD_CLOEXEC), @as(ArgType, 0))) {
        .result => |result| result,
        .err => |err| return .{ .err = err },
    };

    return .initResult(.fromNative(@intCast(out)));
}

pub fn dup(fd: bun.FileDescriptor) Maybe(bun.FileDescriptor) {
    return dupWithFlags(fd, 0);
}

pub fn linkat(dir_fd: bun.FileDescriptor, basename: []const u8, dest_dir_fd: bun.FileDescriptor, dest_name: []const u8) Maybe(void) {
    return Maybe(void).errnoSysP(
        std.c.linkat(
            @intCast(dir_fd),
            &(std.posix.toPosixPath(basename) catch return .{
                .err = .{
                    .errno = @intFromEnum(E.NOMEM),
                    .syscall = .open,
                },
            }),
            @intCast(dest_dir_fd),
            &(std.posix.toPosixPath(dest_name) catch return .{
                .err = .{
                    .errno = @intFromEnum(E.NOMEM),
                    .syscall = .open,
                },
            }),
            0,
        ),
        .link,
        basename,
    ) orelse Maybe(void).success;
}

pub fn linkatTmpfile(tmpfd: bun.FileDescriptor, dirfd: bun.FileDescriptor, name: [:0]const u8) Maybe(void) {
    if (comptime !Environment.isLinux) {
        @compileError("Linux only.");
    }

    const CAP_DAC_READ_SEARCH = struct {
        pub var status = std.atomic.Value(i32).init(0);
    };

    while (true) {
        // This is racy but it's fine if we call linkat() with an empty path multiple times.
        const current_status = CAP_DAC_READ_SEARCH.status.load(.monotonic);

        const rc = if (current_status != -1) std.os.linux.linkat(
            tmpfd.cast(),
            "",
            dirfd.cast(),
            name,
            posix.AT.EMPTY_PATH,
        ) else brk: {
            //
            // snprintf(path, PATH_MAX,  "/proc/self/fd/%d", fd);
            // linkat(AT_FDCWD, path, AT_FDCWD, "/path/for/file",
            //        AT_SYMLINK_FOLLOW);
            //
            var procfs_buf: ["/proc/self/fd/-2147483648".len + 1:0]u8 = undefined;
            const path = std.fmt.bufPrintZ(&procfs_buf, "/proc/self/fd/{d}", .{tmpfd.cast()}) catch unreachable;

            break :brk std.os.linux.linkat(
                posix.AT.FDCWD,
                path,
                dirfd.cast(),
                name,
                posix.AT.SYMLINK_FOLLOW,
            );
        };

        if (Maybe(void).errnoSysFd(rc, .link, tmpfd)) |err| {
            switch (err.getErrno()) {
                .INTR => continue,
                .ISDIR, .NOENT, .OPNOTSUPP, .PERM, .INVAL => {
                    // CAP_DAC_READ_SEARCH is required to linkat with an empty path.
                    if (current_status == 0) {
                        CAP_DAC_READ_SEARCH.status.store(-1, .monotonic);
                        continue;
                    }
                },
                else => {},
            }

            return err;
        }

        if (current_status == 0) {
            CAP_DAC_READ_SEARCH.status.store(1, .monotonic);
        }

        return Maybe(void).success;
    }
}

/// c-bindings.cpp
extern "c" fn sys_preadv2(
    fd: c_int,
    iov: [*]const std.posix.iovec,
    iovcnt: c_int,
    offset: std.posix.off_t,
    flags: c_uint,
) isize;

/// On Linux, this `preadv2(2)` to attempt to read a blocking file descriptor without blocking.
///
/// On other platforms, this is just a wrapper around `read(2)`.
pub fn readNonblocking(fd: bun.FileDescriptor, buf: []u8) Maybe(usize) {
    if (Environment.isLinux) {
        while (bun.linux.RWFFlagSupport.isMaybeSupported()) {
            const iovec = [1]std.posix.iovec{.{
                .base = buf.ptr,
                .len = buf.len,
            }};
            var debug_timer = bun.Output.DebugTimer.start();

            // Note that there is a bug on Linux Kernel 5
            const rc = sys_preadv2(fd.native(), &iovec, 1, -1, std.os.linux.RWF.NOWAIT);

            if (comptime Environment.isDebug) {
                log("preadv2({}, {d}) = {d} ({})", .{ fd, buf.len, rc, debug_timer });

                if (debug_timer.timer.read() > std.time.ns_per_ms) {
                    bun.Output.debugWarn("preadv2({}, {d}) blocked for {}", .{ fd, buf.len, debug_timer });
                }
            }

            if (Maybe(usize).errnoSysFd(rc, .read, fd)) |err| {
                switch (err.getErrno()) {
                    .OPNOTSUPP, .NOSYS => {
                        bun.linux.RWFFlagSupport.disable();
                        switch (bun.isReadable(fd)) {
                            .hup, .ready => return read(fd, buf),
                            else => return .{ .err = Error.retry },
                        }
                    },
                    .INTR => continue,
                    else => return err,
                }
            }

            return .{ .result = @as(usize, @intCast(rc)) };
        }
    }

    return read(fd, buf);
}

/// c-bindings.cpp
pub extern "c" fn sys_pwritev2(
    fd: c_int,
    iov: [*]const std.posix.iovec_const,
    iovcnt: c_int,
    offset: std.posix.off_t,
    flags: c_uint,
) isize;

/// On Linux, this `pwritev(2)` to attempt to read a blocking file descriptor without blocking.
///
/// On other platforms, this is just a wrapper around `read(2)`.
pub fn writeNonblocking(fd: bun.FileDescriptor, buf: []const u8) Maybe(usize) {
    if (Environment.isLinux) {
        while (bun.linux.RWFFlagSupport.isMaybeSupported()) {
            const iovec = [1]std.posix.iovec_const{.{
                .base = buf.ptr,
                .len = buf.len,
            }};

            var debug_timer = bun.Output.DebugTimer.start();

            const rc = sys_pwritev2(fd.native(), &iovec, 1, -1, std.os.linux.RWF.NOWAIT);

            if (comptime Environment.isDebug) {
                log("pwritev2({}, {d}) = {d} ({})", .{ fd, buf.len, rc, debug_timer });

                if (debug_timer.timer.read() > std.time.ns_per_ms) {
                    bun.Output.debugWarn("pwritev2({}, {d}) blocked for {}", .{ fd, buf.len, debug_timer });
                }
            }

            if (Maybe(usize).errnoSysFd(rc, .write, fd)) |err| {
                switch (err.getErrno()) {
                    .OPNOTSUPP, .NOSYS => {
                        bun.linux.RWFFlagSupport.disable();
                        switch (bun.isWritable(fd)) {
                            .hup, .ready => return write(fd, buf),
                            else => return .{ .err = Error.retry },
                        }
                    },
                    .INTR => continue,
                    else => return err,
                }
            }

            return .{ .result = @as(usize, @intCast(rc)) };
        }
    }

    return write(fd, buf);
}

pub fn getFileSize(fd: bun.FileDescriptor) Maybe(usize) {
    if (Environment.isWindows) {
        var size: windows.LARGE_INTEGER = undefined;
        if (windows.kernel32.GetFileSizeEx(fd.cast(), &size) == windows.FALSE) {
            const err = Error.fromCode(windows.getLastErrno(), .fstat);
            log("GetFileSizeEx({}) = {s}", .{ fd, err.name() });
            return .{ .err = err };
        }
        log("GetFileSizeEx({}) = {d}", .{ fd, size });
        return .{ .result = @intCast(@max(size, 0)) };
    }

    switch (fstat(fd)) {
        .result => |*stat_| {
            return .{ .result = @intCast(@max(stat_.size, 0)) };
        },
        .err => |err| {
            return .{ .err = err };
        },
    }
}

pub fn isPollable(mode: mode_t) bool {
    return posix.S.ISFIFO(mode) or posix.S.ISSOCK(mode);
}

const This = @This();

/// TODO: make these all methods on `bun.FD`, and define them as methods `bun.FD`
pub const File = struct {
    // "handle" matches std.fs.File
    handle: bun.FileDescriptor,

    pub fn openat(dir: bun.FileDescriptor, path: [:0]const u8, flags: i32, mode: bun.Mode) Maybe(File) {
        return switch (This.openat(dir, path, flags, mode)) {
            .result => |fd| .{ .result = .{ .handle = fd } },
            .err => |err| .{ .err = err },
        };
    }

    pub fn open(path: [:0]const u8, flags: i32, mode: bun.Mode) Maybe(File) {
        return File.openat(bun.FD.cwd(), path, flags, mode);
    }

    pub fn makeOpen(path: [:0]const u8, flags: i32, mode: bun.Mode) Maybe(File) {
        return File.makeOpenat(bun.FD.cwd(), path, flags, mode);
    }

    pub fn makeOpenat(other: bun.FD, path: [:0]const u8, flags: i32, mode: bun.Mode) Maybe(File) {
        const fd = switch (This.openat(other, path, flags, mode)) {
            .result => |fd| fd,
            .err => |err| fd: {
                if (std.fs.path.dirname(path)) |dir_path| {
                    bun.makePath(other.stdDir(), dir_path) catch {};
                    break :fd switch (This.openat(other, path, flags, mode)) {
                        .result => |fd| fd,
                        .err => |err2| return .{ .err = err2 },
                    };
                }

                return .{ .err = err };
            },
        };

        return .{ .result = .{ .handle = fd } };
    }

    pub fn openatOSPath(other: bun.FD, path: bun.OSPathSliceZ, flags: i32, mode: bun.Mode) Maybe(File) {
        return switch (This.openatOSPath(other, path, flags, mode)) {
            .result => |fd| .{ .result = .{ .handle = fd } },
            .err => |err| .{ .err = err },
        };
    }

    pub fn from(other: anytype) File {
        const T = @TypeOf(other);

        if (T == File) {
            return other;
        }

        if (T == std.posix.fd_t) {
            return .{ .handle = .fromNative(other) };
        }

        if (T == bun.FileDescriptor) {
            return .{ .handle = other };
        }

        if (T == std.fs.File) {
            return .{ .handle = .fromStdFile(other) };
        }

        if (T == std.fs.Dir) {
            return File{ .handle = .fromStdDir(other) };
        }

        if (comptime Environment.isLinux) {
            if (T == u64) {
                return File{ .handle = .fromNative(@intCast(other)) };
            }
        }

        @compileError("Unsupported type " ++ bun.meta.typeName(T));
    }

    pub fn write(self: File, buf: []const u8) Maybe(usize) {
        return This.write(self.handle, buf);
    }

    pub fn read(self: File, buf: []u8) Maybe(usize) {
        return This.read(self.handle, buf);
    }

    pub fn readAll(self: File, buf: []u8) Maybe(usize) {
        return This.readAll(self.handle, buf);
    }

    pub fn writeAll(self: File, buf: []const u8) Maybe(void) {
        var remain = buf;
        while (remain.len > 0) {
            const rc = This.write(self.handle, remain);
            switch (rc) {
                .err => |err| return .{ .err = err },
                .result => |amt| {
                    if (amt == 0) {
                        return .{ .result = {} };
                    }
                    remain = remain[amt..];
                },
            }
        }

        return .{ .result = {} };
    }

    pub fn writeFile(
        relative_dir_or_cwd: anytype,
        path: bun.OSPathSliceZ,
        data: []const u8,
    ) Maybe(void) {
        const file = switch (File.openatOSPath(relative_dir_or_cwd, path, bun.O.WRONLY | bun.O.CREAT | bun.O.TRUNC, 0o664)) {
            .err => |err| return .{ .err = err },
            .result => |fd| fd,
        };
        defer file.close();
        switch (file.writeAll(data)) {
            .err => |err| return .{ .err = err },
            .result => {},
        }
        return .{ .result = {} };
    }

    pub const ReadError = anyerror;

    pub fn closeAndMoveTo(this: File, src: [:0]const u8, dest: [:0]const u8) !void {
        // On POSIX, close the file after moving it.
        defer if (Environment.isPosix) this.close();
        // On Windows, close the file before moving it.
        if (Environment.isWindows) this.close();
        const cwd = bun.FD.cwd();
        try bun.sys.moveFileZWithHandle(this.handle, cwd, src, cwd, dest);
    }

    fn stdIoRead(this: File, buf: []u8) ReadError!usize {
        return try this.read(buf).unwrap();
    }

    pub const Reader = std.io.Reader(File, anyerror, stdIoRead);

    pub fn reader(self: File) Reader {
        return Reader{ .context = self };
    }

    pub const WriteError = anyerror;
    fn stdIoWrite(this: File, bytes: []const u8) WriteError!usize {
        try this.writeAll(bytes).unwrap();

        return bytes.len;
    }

    fn stdIoWriteQuietDebug(this: File, bytes: []const u8) WriteError!usize {
        bun.Output.disableScopedDebugWriter();
        defer bun.Output.enableScopedDebugWriter();
        try this.writeAll(bytes).unwrap();

        return bytes.len;
    }

    pub const Writer = std.io.Writer(File, anyerror, stdIoWrite);
    pub const QuietWriter = if (Environment.isDebug) std.io.Writer(File, anyerror, stdIoWriteQuietDebug) else Writer;

    pub fn writer(self: File) Writer {
        return Writer{ .context = self };
    }

    pub fn quietWriter(self: File) QuietWriter {
        return QuietWriter{ .context = self };
    }

    pub fn isTty(self: File) bool {
        return std.posix.isatty(self.handle.cast());
    }

    /// Asserts in debug that this File object is valid
    pub fn close(self: File) void {
        self.handle.close();
    }

    pub fn getEndPos(self: File) Maybe(usize) {
        return getFileSize(self.handle);
    }

    pub fn stat(self: File) Maybe(bun.Stat) {
        return fstat(self.handle);
    }

    /// Be careful about using this on Linux or macOS.
    ///
    /// This calls stat() internally.
    pub fn kind(self: File) Maybe(std.fs.File.Kind) {
        if (Environment.isWindows) {
            const rt = windows.GetFileType(self.handle.cast());
            if (rt == windows.FILE_TYPE_UNKNOWN) {
                switch (windows.GetLastError()) {
                    .SUCCESS => {},
                    else => |err| {
                        return .{ .err = Error.fromCode((SystemErrno.init(err) orelse SystemErrno.EUNKNOWN).toE(), .fstat) };
                    },
                }
            }

            return .{
                .result = switch (rt) {
                    windows.FILE_TYPE_CHAR => .character_device,
                    windows.FILE_TYPE_REMOTE, windows.FILE_TYPE_DISK => .file,
                    windows.FILE_TYPE_PIPE => .named_pipe,
                    windows.FILE_TYPE_UNKNOWN => .unknown,
                    else => .file,
                },
            };
        }

        const st = switch (self.stat()) {
            .err => |err| return .{ .err = err },
            .result => |s| s,
        };

        const m = st.mode & posix.S.IFMT;
        switch (m) {
            posix.S.IFBLK => return .{ .result = .block_device },
            posix.S.IFCHR => return .{ .result = .character_device },
            posix.S.IFDIR => return .{ .result = .directory },
            posix.S.IFIFO => return .{ .result = .named_pipe },
            posix.S.IFLNK => return .{ .result = .sym_link },
            posix.S.IFREG => return .{ .result = .file },
            posix.S.IFSOCK => return .{ .result = .unix_domain_socket },
            else => {
                return .{ .result = .file };
            },
        }
    }

    pub const ReadToEndResult = struct {
        bytes: std.ArrayList(u8) = std.ArrayList(u8).init(default_allocator),
        err: ?Error = null,

        pub fn unwrap(self: *const ReadToEndResult) ![]u8 {
            if (self.err) |err| {
                try (JSC.Maybe(void){ .err = err }).unwrap();
            }
            return self.bytes.items;
        }
    };

    pub fn readFillBuf(this: File, buf: []u8) Maybe([]u8) {
        var read_amount: usize = 0;
        while (read_amount < buf.len) {
            switch (if (comptime Environment.isPosix)
                pread(this.handle, buf[read_amount..], @intCast(read_amount))
            else
                sys.read(this.handle, buf[read_amount..])) {
                .err => |err| {
                    return .{ .err = err };
                },
                .result => |bytes_read| {
                    if (bytes_read == 0) {
                        break;
                    }

                    read_amount += bytes_read;
                },
            }
        }

        return .{ .result = buf[0..read_amount] };
    }

    pub fn readToEndWithArrayList(this: File, list: *std.ArrayList(u8), probably_small: bool) Maybe(usize) {
        if (probably_small) {
            list.ensureUnusedCapacity(64) catch bun.outOfMemory();
        } else {
            list.ensureTotalCapacityPrecise(
                switch (this.getEndPos()) {
                    .err => |err| {
                        return .{ .err = err };
                    },
                    .result => |s| s,
                } + 16,
            ) catch bun.outOfMemory();
        }

        var total: i64 = 0;
        while (true) {
            if (list.unusedCapacitySlice().len == 0) {
                list.ensureUnusedCapacity(16) catch bun.outOfMemory();
            }

            switch (if (comptime Environment.isPosix)
                pread(this.handle, list.unusedCapacitySlice(), total)
            else
                sys.read(this.handle, list.unusedCapacitySlice())) {
                .err => |err| {
                    return .{ .err = err };
                },
                .result => |bytes_read| {
                    if (bytes_read == 0) {
                        break;
                    }

                    list.items.len += bytes_read;
                    total += @intCast(bytes_read);
                },
            }
        }

        return .{ .result = @intCast(total) };
    }

    /// Use this function on potentially large files.
    /// Calls fstat() on the file to get the size of the file and avoids reallocations + extra read() calls.
    pub fn readToEnd(this: File, allocator: std.mem.Allocator) ReadToEndResult {
        var list = std.ArrayList(u8).init(allocator);
        return switch (readToEndWithArrayList(this, &list, false)) {
            .err => |err| .{ .err = err, .bytes = list },
            .result => .{ .err = null, .bytes = list },
        };
    }

    /// Use this function on small files <= 1024 bytes.
    /// This will skip the fstat() call, preallocating 64 bytes instead of the file's size.
    pub fn readToEndSmall(this: File, allocator: std.mem.Allocator) ReadToEndResult {
        var list = std.ArrayList(u8).init(allocator);
        return switch (readToEndWithArrayList(this, &list, true)) {
            .err => |err| .{ .err = err, .bytes = list },
            .result => .{ .err = null, .bytes = list },
        };
    }

    pub fn getPath(this: File, out_buffer: *bun.PathBuffer) Maybe([]u8) {
        return getFdPath(this.handle, out_buffer);
    }

    /// 1. Normalize the file path
    /// 2. Open a file for reading
    /// 2. Read the file to a buffer
    /// 3. Return the File handle and the buffer
    pub fn readFromUserInput(dir_fd: anytype, input_path: anytype, allocator: std.mem.Allocator) Maybe([]u8) {
        var buf: bun.PathBuffer = undefined;
        const normalized = bun.path.joinAbsStringBufZ(
            bun.fs.FileSystem.instance.top_level_dir,
            &buf,
            &.{input_path},
            .loose,
        );
        return readFrom(dir_fd, normalized, allocator);
    }

    /// 1. Open a file for reading
    /// 2. Read the file to a buffer
    /// 3. Return the File handle and the buffer
    pub fn readFileFrom(dir_fd: anytype, path: anytype, allocator: std.mem.Allocator) Maybe(struct { File, []u8 }) {
        const ElementType = std.meta.Elem(@TypeOf(path));

        const rc = brk: {
            if (comptime Environment.isWindows and ElementType == u16) {
                break :brk openatWindowsTMaybeNormalize(u16, from(dir_fd).handle, path, O.RDONLY, false);
            }

            if (comptime ElementType == u8 and std.meta.sentinel(@TypeOf(path)) == null) {
                break :brk sys.openatA(from(dir_fd).handle, path, O.RDONLY, 0);
            }

            break :brk sys.openat(from(dir_fd).handle, path, O.RDONLY, 0);
        };

        const this = switch (rc) {
            .err => |err| return .{ .err = err },
            .result => |fd| from(fd),
        };

        var result = this.readToEnd(allocator);

        if (result.err) |err| {
            this.close();
            result.bytes.deinit();
            return .{ .err = err };
        }

        if (result.bytes.items.len == 0) {
            // Don't allocate an empty string.
            // We won't be modifying an empty slice, anyway.
            return .{ .result = .{ this, @ptrCast(@constCast("")) } };
        }

        return .{ .result = .{ this, result.bytes.items } };
    }

    /// 1. Open a file for reading relative to a directory
    /// 2. Read the file to a buffer
    /// 3. Close the file
    /// 4. Return the buffer
    pub fn readFrom(dir_fd: anytype, path: anytype, allocator: std.mem.Allocator) Maybe([]u8) {
        const file, const bytes = switch (readFileFrom(dir_fd, path, allocator)) {
            .err => |err| return .{ .err = err },
            .result => |result| result,
        };

        file.close();
        return .{ .result = bytes };
    }

    const ToSourceOptions = struct {
        convert_bom: bool = false,
    };

    pub fn toSourceAt(dir_fd: anytype, path: anytype, allocator: std.mem.Allocator, opts: ToSourceOptions) Maybe(bun.logger.Source) {
        var bytes = switch (readFrom(dir_fd, path, allocator)) {
            .err => |err| return .{ .err = err },
            .result => |bytes| bytes,
        };

        if (opts.convert_bom) {
            if (bun.strings.BOM.detect(bytes)) |bom| {
                bytes = bom.removeAndConvertToUTF8AndFree(allocator, bytes) catch bun.outOfMemory();
            }
        }

        return .{ .result = bun.logger.Source.initPathString(path, bytes) };
    }

    pub fn toSource(path: anytype, allocator: std.mem.Allocator, opts: ToSourceOptions) Maybe(bun.logger.Source) {
        return toSourceAt(std.fs.cwd(), path, allocator, opts);
    }
};

pub const Dir = @import("./dir.zig");
const FILE_SHARE = w.FILE_SHARE_WRITE | w.FILE_SHARE_READ | w.FILE_SHARE_DELETE;

/// This map is derived off of uv.h's definitions, and is what Node.js uses in printing errors.
pub const libuv_error_map = brk: {
    const entries: []const struct { [:0]const u8, [:0]const u8 } = &.{
        .{ "E2BIG", "argument list too long" },
        .{ "EACCES", "permission denied" },
        .{ "EADDRINUSE", "address already in use" },
        .{ "EADDRNOTAVAIL", "address not available" },
        .{ "EAFNOSUPPORT", "address family not supported" },
        .{ "EAGAIN", "resource temporarily unavailable" },
        .{ "EAI_ADDRFAMILY", "address family not supported" },
        .{ "EAI_AGAIN", "temporary failure" },
        .{ "EAI_BADFLAGS", "bad ai_flags value" },
        .{ "EAI_BADHINTS", "invalid value for hints" },
        .{ "EAI_CANCELED", "request canceled" },
        .{ "EAI_FAIL", "permanent failure" },
        .{ "EAI_FAMILY", "ai_family not supported" },
        .{ "EAI_MEMORY", "out of memory" },
        .{ "EAI_NODATA", "no address" },
        .{ "EAI_NONAME", "unknown node or service" },
        .{ "EAI_OVERFLOW", "argument buffer overflow" },
        .{ "EAI_PROTOCOL", "resolved protocol is unknown" },
        .{ "EAI_SERVICE", "service not available for socket type" },
        .{ "EAI_SOCKTYPE", "socket type not supported" },
        .{ "EALREADY", "connection already in progress" },
        .{ "EBADF", "bad file descriptor" },
        .{ "EBUSY", "resource busy or locked" },
        .{ "ECANCELED", "operation canceled" },
        .{ "ECHARSET", "invalid Unicode character" },
        .{ "ECONNABORTED", "software caused connection abort" },
        .{ "ECONNREFUSED", "connection refused" },
        .{ "ECONNRESET", "connection reset by peer" },
        .{ "EDESTADDRREQ", "destination address required" },
        .{ "EEXIST", "file already exists" },
        .{ "EFAULT", "bad address in system call argument" },
        .{ "EFBIG", "file too large" },
        .{ "EHOSTUNREACH", "host is unreachable" },
        .{ "EINTR", "interrupted system call" },
        .{ "EINVAL", "invalid argument" },
        .{ "EIO", "i/o error" },
        .{ "EISCONN", "socket is already connected" },
        .{ "EISDIR", "illegal operation on a directory" },
        .{ "ELOOP", "too many symbolic links encountered" },
        .{ "EMFILE", "too many open files" },
        .{ "EMSGSIZE", "message too long" },
        .{ "ENAMETOOLONG", "name too long" },
        .{ "ENETDOWN", "network is down" },
        .{ "ENETUNREACH", "network is unreachable" },
        .{ "ENFILE", "file table overflow" },
        .{ "ENOBUFS", "no buffer space available" },
        .{ "ENODEV", "no such device" },
        .{ "ENOENT", "no such file or directory" },
        .{ "ENOMEM", "not enough memory" },
        .{ "ENONET", "machine is not on the network" },
        .{ "ENOPROTOOPT", "protocol not available" },
        .{ "ENOSPC", "no space left on device" },
        .{ "ENOSYS", "function not implemented" },
        .{ "ENOTCONN", "socket is not connected" },
        .{ "ENOTDIR", "not a directory" },
        .{ "ENOTEMPTY", "directory not empty" },
        .{ "ENOTSOCK", "socket operation on non-socket" },
        .{ "ENOTSUP", "operation not supported on socket" },
        .{ "EOVERFLOW", "value too large for defined data type" },
        .{ "EPERM", "operation not permitted" },
        .{ "EPIPE", "broken pipe" },
        .{ "EPROTO", "protocol error" },
        .{ "EPROTONOSUPPORT", "protocol not supported" },
        .{ "EPROTOTYPE", "protocol wrong type for socket" },
        .{ "ERANGE", "result too large" },
        .{ "EROFS", "read-only file system" },
        .{ "ESHUTDOWN", "cannot send after transport endpoint shutdown" },
        .{ "ESPIPE", "invalid seek" },
        .{ "ESRCH", "no such process" },
        .{ "ETIMEDOUT", "connection timed out" },
        .{ "ETXTBSY", "text file is busy" },
        .{ "EXDEV", "cross-device link not permitted" },
        .{ "UNKNOWN", "unknown error" },
        .{ "EOF", "end of file" },
        .{ "ENXIO", "no such device or address" },
        .{ "EMLINK", "too many links" },
        .{ "EHOSTDOWN", "host is down" },
        .{ "EREMOTEIO", "remote I/O error" },
        .{ "ENOTTY", "inappropriate ioctl for device" },
        .{ "EFTYPE", "inappropriate file type or format" },
        .{ "EILSEQ", "illegal byte sequence" },
        .{ "ESOCKTNOSUPPORT", "socket type not supported" },
        .{ "ENODATA", "no data available" },
        .{ "EUNATCH", "protocol driver not attached" },
    };
    var map = std.EnumMap(SystemErrno, [:0]const u8).initFull("unknown error");
    for (entries) |entry| {
        const key, const text = entry;
        if (@hasField(SystemErrno, key)) {
            map.put(@field(SystemErrno, key), text);
        }
    }

    // sanity check
    bun.assert(std.mem.eql(u8, map.get(SystemErrno.ENOENT).?, "no such file or directory"));

    break :brk map;
};

/// This map is derived off of what coreutils uses in printing errors. This is
/// equivalent to `strerror`, but as strings with constant lifetime.
pub const coreutils_error_map = brk: {
    // macOS and Linux have slightly different error messages.
    const entries: []const struct { [:0]const u8, [:0]const u8 } = switch (Environment.os) {
        // Since windows is just an emulation of linux, it will derive the linux error messages.
        .linux, .windows, .wasm => &.{
            .{ "EPERM", "Operation not permitted" },
            .{ "ENOENT", "No such file or directory" },
            .{ "ESRCH", "No such process" },
            .{ "EINTR", "Interrupted system call" },
            .{ "EIO", "Input/output error" },
            .{ "ENXIO", "No such device or address" },
            .{ "E2BIG", "Argument list too long" },
            .{ "ENOEXEC", "Exec format error" },
            .{ "EBADF", "Bad file descriptor" },
            .{ "ECHILD", "No child processes" },
            .{ "EAGAIN", "Resource temporarily unavailable" },
            .{ "ENOMEM", "Cannot allocate memory" },
            .{ "EACCES", "Permission denied" },
            .{ "EFAULT", "Bad address" },
            .{ "ENOTBLK", "Block device required" },
            .{ "EBUSY", "Device or resource busy" },
            .{ "EEXIST", "File exists" },
            .{ "EXDEV", "Invalid cross-device link" },
            .{ "ENODEV", "No such device" },
            .{ "ENOTDIR", "Not a directory" },
            .{ "EISDIR", "Is a directory" },
            .{ "EINVAL", "Invalid argument" },
            .{ "ENFILE", "Too many open files in system" },
            .{ "EMFILE", "Too many open files" },
            .{ "ENOTTY", "Inappropriate ioctl for device" },
            .{ "ETXTBSY", "Text file busy" },
            .{ "EFBIG", "File too large" },
            .{ "ENOSPC", "No space left on device" },
            .{ "ESPIPE", "Illegal seek" },
            .{ "EROFS", "Read-only file system" },
            .{ "EMLINK", "Too many links" },
            .{ "EPIPE", "Broken pipe" },
            .{ "EDOM", "Numerical argument out of domain" },
            .{ "ERANGE", "Numerical result out of range" },
            .{ "EDEADLK", "Resource deadlock avoided" },
            .{ "ENAMETOOLONG", "File name too long" },
            .{ "ENOLCK", "No locks available" },
            .{ "ENOSYS", "Function not implemented" },
            .{ "ENOTEMPTY", "Directory not empty" },
            .{ "ELOOP", "Too many levels of symbolic links" },
            .{ "ENOMSG", "No message of desired type" },
            .{ "EIDRM", "Identifier removed" },
            .{ "ECHRNG", "Channel number out of range" },
            .{ "EL2NSYNC", "Level 2 not synchronized" },
            .{ "EL3HLT", "Level 3 halted" },
            .{ "EL3RST", "Level 3 reset" },
            .{ "ELNRNG", "Link number out of range" },
            .{ "EUNATCH", "Protocol driver not attached" },
            .{ "ENOCSI", "No CSI structure available" },
            .{ "EL2HLT", "Level 2 halted" },
            .{ "EBADE", "Invalid exchange" },
            .{ "EBADR", "Invalid request descriptor" },
            .{ "EXFULL", "Exchange full" },
            .{ "ENOANO", "No anode" },
            .{ "EBADRQC", "Invalid request code" },
            .{ "EBADSLT", "Invalid slot" },
            .{ "EBFONT", "Bad font file format" },
            .{ "ENOSTR", "Device not a stream" },
            .{ "ENODATA", "No data available" },
            .{ "ETIME", "Timer expired" },
            .{ "ENOSR", "Out of streams resources" },
            .{ "ENONET", "Machine is not on the network" },
            .{ "ENOPKG", "Package not installed" },
            .{ "EREMOTE", "Object is remote" },
            .{ "ENOLINK", "Link has been severed" },
            .{ "EADV", "Advertise error" },
            .{ "ESRMNT", "Srmount error" },
            .{ "ECOMM", "Communication error on send" },
            .{ "EPROTO", "Protocol error" },
            .{ "EMULTIHOP", "Multihop attempted" },
            .{ "EDOTDOT", "RFS specific error" },
            .{ "EBADMSG", "Bad message" },
            .{ "EOVERFLOW", "Value too large for defined data type" },
            .{ "ENOTUNIQ", "Name not unique on network" },
            .{ "EBADFD", "File descriptor in bad state" },
            .{ "EREMCHG", "Remote address changed" },
            .{ "ELIBACC", "Can not access a needed shared library" },
            .{ "ELIBBAD", "Accessing a corrupted shared library" },
            .{ "ELIBSCN", ".lib section in a.out corrupted" },
            .{ "ELIBMAX", "Attempting to link in too many shared libraries" },
            .{ "ELIBEXEC", "Cannot exec a shared library directly" },
            .{ "EILSEQ", "Invalid or incomplete multibyte or wide character" },
            .{ "ERESTART", "Interrupted system call should be restarted" },
            .{ "ESTRPIPE", "Streams pipe error" },
            .{ "EUSERS", "Too many users" },
            .{ "ENOTSOCK", "Socket operation on non-socket" },
            .{ "EDESTADDRREQ", "Destination address required" },
            .{ "EMSGSIZE", "Message too long" },
            .{ "EPROTOTYPE", "Protocol wrong type for socket" },
            .{ "ENOPROTOOPT", "Protocol not available" },
            .{ "EPROTONOSUPPORT", "Protocol not supported" },
            .{ "ESOCKTNOSUPPORT", "Socket type not supported" },
            .{ "EOPNOTSUPP", "Operation not supported" },
            .{ "EPFNOSUPPORT", "Protocol family not supported" },
            .{ "EAFNOSUPPORT", "Address family not supported by protocol" },
            .{ "EADDRINUSE", "Address already in use" },
            .{ "EADDRNOTAVAIL", "Cannot assign requested address" },
            .{ "ENETDOWN", "Network is down" },
            .{ "ENETUNREACH", "Network is unreachable" },
            .{ "ENETRESET", "Network dropped connection on reset" },
            .{ "ECONNABORTED", "Software caused connection abort" },
            .{ "ECONNRESET", "Connection reset by peer" },
            .{ "ENOBUFS", "No buffer space available" },
            .{ "EISCONN", "Transport endpoint is already connected" },
            .{ "ENOTCONN", "Transport endpoint is not connected" },
            .{ "ESHUTDOWN", "Cannot send after transport endpoint shutdown" },
            .{ "ETOOMANYREFS", "Too many references: cannot splice" },
            .{ "ETIMEDOUT", "Connection timed out" },
            .{ "ECONNREFUSED", "Connection refused" },
            .{ "EHOSTDOWN", "Host is down" },
            .{ "EHOSTUNREACH", "No route to host" },
            .{ "EALREADY", "Operation already in progress" },
            .{ "EINPROGRESS", "Operation now in progress" },
            .{ "ESTALE", "Stale file handle" },
            .{ "EUCLEAN", "Structure needs cleaning" },
            .{ "ENOTNAM", "Not a XENIX named type file" },
            .{ "ENAVAIL", "No XENIX semaphores available" },
            .{ "EISNAM", "Is a named type file" },
            .{ "EREMOTEIO", "Remote I/O error" },
            .{ "EDQUOT", "Disk quota exceeded" },
            .{ "ENOMEDIUM", "No medium found" },
            .{ "EMEDIUMTYPE", "Wrong medium type" },
            .{ "ECANCELED", "Operation canceled" },
            .{ "ENOKEY", "Required key not available" },
            .{ "EKEYEXPIRED", "Key has expired" },
            .{ "EKEYREVOKED", "Key has been revoked" },
            .{ "EKEYREJECTED", "Key was rejected by service" },
            .{ "EOWNERDEAD", "Owner died" },
            .{ "ENOTRECOVERABLE", "State not recoverable" },
            .{ "ERFKILL", "Operation not possible due to RF-kill" },
            .{ "EHWPOISON", "Memory page has hardware error" },
        },
        // Mac has slightly different messages. To keep it consistent with bash/coreutils,
        // it will use those altered messages.
        .mac => &.{
            .{ "E2BIG", "Argument list too long" },
            .{ "EACCES", "Permission denied" },
            .{ "EADDRINUSE", "Address already in use" },
            .{ "EADDRNOTAVAIL", "Can't assign requested address" },
            .{ "EAFNOSUPPORT", "Address family not supported by protocol family" },
            .{ "EAGAIN", "non-blocking and interrupt i/o. Resource temporarily unavailable" },
            .{ "EALREADY", "Operation already in progress" },
            .{ "EAUTH", "Authentication error" },
            .{ "EBADARCH", "Bad CPU type in executable" },
            .{ "EBADEXEC", "Program loading errors. Bad executable" },
            .{ "EBADF", "Bad file descriptor" },
            .{ "EBADMACHO", "Malformed Macho file" },
            .{ "EBADMSG", "Bad message" },
            .{ "EBADRPC", "RPC struct is bad" },
            .{ "EBUSY", "Device / Resource busy" },
            .{ "ECANCELED", "Operation canceled" },
            .{ "ECHILD", "No child processes" },
            .{ "ECONNABORTED", "Software caused connection abort" },
            .{ "ECONNREFUSED", "Connection refused" },
            .{ "ECONNRESET", "Connection reset by peer" },
            .{ "EDEADLK", "Resource deadlock avoided" },
            .{ "EDESTADDRREQ", "Destination address required" },
            .{ "EDEVERR", "Device error, for example paper out" },
            .{ "EDOM", "math software. Numerical argument out of domain" },
            .{ "EDQUOT", "Disc quota exceeded" },
            .{ "EEXIST", "File or folder exists" },
            .{ "EFAULT", "Bad address" },
            .{ "EFBIG", "File too large" },
            .{ "EFTYPE", "Inappropriate file type or format" },
            .{ "EHOSTDOWN", "Host is down" },
            .{ "EHOSTUNREACH", "No route to host" },
            .{ "EIDRM", "Identifier removed" },
            .{ "EILSEQ", "Illegal byte sequence" },
            .{ "EINPROGRESS", "Operation now in progress" },
            .{ "EINTR", "Interrupted system call" },
            .{ "EINVAL", "Invalid argument" },
            .{ "EIO", "Input/output error" },
            .{ "EISCONN", "Socket is already connected" },
            .{ "EISDIR", "Is a directory" },
            .{ "ELOOP", "Too many levels of symbolic links" },
            .{ "EMFILE", "Too many open files" },
            .{ "EMLINK", "Too many links" },
            .{ "EMSGSIZE", "Message too long" },
            .{ "EMULTIHOP", "Reserved" },
            .{ "ENAMETOOLONG", "File name too long" },
            .{ "ENEEDAUTH", "Need authenticator" },
            .{ "ENETDOWN", "ipc/network software - operational errors Network is down" },
            .{ "ENETRESET", "Network dropped connection on reset" },
            .{ "ENETUNREACH", "Network is unreachable" },
            .{ "ENFILE", "Too many open files in system" },
            .{ "ENOATTR", "Attribute not found" },
            .{ "ENOBUFS", "No buffer space available" },
            .{ "ENODATA", "No message available on STREAM" },
            .{ "ENODEV", "Operation not supported by device" },
            .{ "ENOENT", "No such file or directory" },
            .{ "ENOEXEC", "Exec format error" },
            .{ "ENOLCK", "No locks available" },
            .{ "ENOLINK", "Reserved" },
            .{ "ENOMEM", "Out of memory" },
            .{ "ENOMSG", "No message of desired type" },
            .{ "ENOPOLICY", "No such policy registered" },
            .{ "ENOPROTOOPT", "Protocol not available" },
            .{ "ENOSPC", "No space left on device" },
            .{ "ENOSR", "No STREAM resources" },
            .{ "ENOSTR", "Not a STREAM" },
            .{ "ENOSYS", "Function not implemented" },
            .{ "ENOTBLK", "Block device required" },
            .{ "ENOTCONN", "Socket is not connected" },
            .{ "ENOTDIR", "Not a directory" },
            .{ "ENOTEMPTY", "Directory not empty" },
            .{ "ENOTRECOVERABLE", "State not recoverable" },
            .{ "ENOTSOCK", "ipc/network software - argument errors. Socket operation on non-socket" },
            .{ "ENOTSUP", "Operation not supported" },
            .{ "ENOTTY", "Inappropriate ioctl for device" },
            .{ "ENXIO", "Device not configured" },
            .{ "EOVERFLOW", "Value too large to be stored in data type" },
            .{ "EOWNERDEAD", "Previous owner died" },
            .{ "EPERM", "Operation not permitted" },
            .{ "EPFNOSUPPORT", "Protocol family not supported" },
            .{ "EPIPE", "Broken pipe" },
            .{ "EPROCLIM", "quotas & mush. Too many processes" },
            .{ "EPROCUNAVAIL", "Bad procedure for program" },
            .{ "EPROGMISMATCH", "Program version wrong" },
            .{ "EPROGUNAVAIL", "RPC prog. not avail" },
            .{ "EPROTO", "Protocol error" },
            .{ "EPROTONOSUPPORT", "Protocol not supported" },
            .{ "EPROTOTYPE", "Protocol wrong type for socket" },
            .{ "EPWROFF", "Intelligent device errors. Device power is off" },
            .{ "EQFULL", "Interface output queue is full" },
            .{ "ERANGE", "Result too large" },
            .{ "EREMOTE", "Too many levels of remote in path" },
            .{ "EROFS", "Read-only file system" },
            .{ "ERPCMISMATCH", "RPC version wrong" },
            .{ "ESHLIBVERS", "Shared library version mismatch" },
            .{ "ESHUTDOWN", "Can't send after socket shutdown" },
            .{ "ESOCKTNOSUPPORT", "Socket type not supported" },
            .{ "ESPIPE", "Illegal seek" },
            .{ "ESRCH", "No such process" },
            .{ "ESTALE", "Network File System. Stale NFS file handle" },
            .{ "ETIME", "STREAM ioctl timeout" },
            .{ "ETIMEDOUT", "Operation timed out" },
            .{ "ETOOMANYREFS", "Too many references: can't splice" },
            .{ "ETXTBSY", "Text file busy" },
            .{ "EUSERS", "Too many users" },
            .{ "EWOULDBLOCK", "Operation would block" },
            .{ "EXDEV", "Cross-device link" },
        },
    };

    var map = std.EnumMap(SystemErrno, [:0]const u8).initFull("unknown error");
    for (entries) |entry| {
        const key, const text = entry;
        if (@hasField(SystemErrno, key)) {
            map.put(@field(SystemErrno, key), text);
        }
    }

    // sanity check
    bun.assert(std.mem.eql(u8, map.get(SystemErrno.ENOENT).?, "No such file or directory"));

    break :brk map;
};

extern fn getRSS(rss: *usize) c_int;
pub fn selfProcessMemoryUsage() ?usize {
    var rss: usize = undefined;
    if (getRSS(&rss) != 0) {
        return null;
    }
    return rss;
}

export fn Bun__errnoName(err: c_int) ?[*:0]const u8 {
    return @tagName(SystemErrno.init(err) orelse return null);
}

/// Small "fire and forget" wrapper around unlink for c usage that handles EINTR, windows path conversion, etc.
export fn Bun__unlink(ptr: [*:0]const u8, len: usize) void {
    _ = unlink(ptr[0..len :0]);
}

// TODO: this is wrong on Windows
const libc_stat = bun.Stat;
const Stat = std.fs.File.Stat;

pub fn lstat_absolute(path: [:0]const u8) !Stat {
    if (builtin.os.tag == .windows) {
        @compileError("Not implemented yet, consider using lstat()");
    }

    var st = std.mem.zeroes(libc_stat);
    switch (std.posix.errno(workaround_symbols.lstat(path.ptr, &st))) {
        .SUCCESS => {},
        .NOENT => return error.FileNotFound,
        // .EINVAL => unreachable,
        .BADF => unreachable, // Always a race condition.
        .NOMEM => return error.SystemResources,
        .ACCES => return error.AccessDenied,
        else => |err| return posix.unexpectedErrno(err),
    }

    const atime = st.atime();
    const mtime = st.mtime();
    const ctime = st.ctime();
    const Kind = std.fs.File.Kind;
    return Stat{
        .inode = st.ino,
        .size = @as(u64, @bitCast(st.size)),
        .mode = st.mode,
        .kind = switch (builtin.os.tag) {
            .wasi => switch (st.filetype) {
                posix.FILETYPE_BLOCK_DEVICE => Kind.block_device,
                posix.FILETYPE_CHARACTER_DEVICE => Kind.character_device,
                posix.FILETYPE_DIRECTORY => Kind.directory,
                posix.FILETYPE_SYMBOLIC_LINK => Kind.sym_link,
                posix.FILETYPE_REGULAR_FILE => Kind.file,
                posix.FILETYPE_SOCKET_STREAM, posix.FILETYPE_SOCKET_DGRAM => Kind.unix_domain_socket,
                else => Kind.unknown,
            },
            else => switch (st.mode & posix.S.IFMT) {
                posix.S.IFBLK => Kind.block_device,
                posix.S.IFCHR => Kind.character_device,
                posix.S.IFDIR => Kind.directory,
                posix.S.IFIFO => Kind.named_pipe,
                posix.S.IFLNK => Kind.sym_link,
                posix.S.IFREG => Kind.file,
                posix.S.IFSOCK => Kind.unix_domain_socket,
                else => Kind.unknown,
            },
        },
        .atime = @as(i128, atime.sec) * std.time.ns_per_s + atime.nsec,
        .mtime = @as(i128, mtime.sec) * std.time.ns_per_s + mtime.nsec,
        .ctime = @as(i128, ctime.sec) * std.time.ns_per_s + ctime.nsec,
    };
}

// renameatZ fails when renaming across mount points
// we assume that this is relatively uncommon
pub fn moveFileZ(from_dir: bun.FileDescriptor, filename: [:0]const u8, to_dir: bun.FileDescriptor, destination: [:0]const u8) !void {
    switch (renameatConcurrentlyWithoutFallback(from_dir, filename, to_dir, destination)) {
        .err => |err| {
            // allow over-writing an empty directory
            if (err.getErrno() == .ISDIR) {
                _ = rmdirat(to_dir, destination.ptr);
                try renameat(from_dir, filename, to_dir, destination).unwrap();
                return;
            }

            if (err.getErrno() == .XDEV) {
                try moveFileZSlow(from_dir, filename, to_dir, destination);
            } else {
                return bun.errnoToZigErr(err.errno);
            }
        },
        .result => {},
    }
}

pub fn moveFileZWithHandle(from_handle: bun.FileDescriptor, from_dir: bun.FileDescriptor, filename: [:0]const u8, to_dir: bun.FileDescriptor, destination: [:0]const u8) !void {
    switch (renameat(from_dir, filename, to_dir, destination)) {
        .err => |err| {
            // allow over-writing an empty directory
            if (err.getErrno() == .ISDIR) {
                _ = rmdirat(to_dir, destination.ptr);

                try (renameat(from_dir, filename, to_dir, destination).unwrap());
                return;
            }

            if (err.getErrno() == .XDEV) {
                try copyFileZSlowWithHandle(from_handle, to_dir, destination).unwrap();
                _ = unlinkat(from_dir, filename);
            }

            return bun.errnoToZigErr(err.errno);
        },
        .result => {},
    }
}

// On Linux, this will be fast because sendfile() supports copying between two file descriptors on disk
// macOS & BSDs will be slow because
pub fn moveFileZSlow(from_dir: bun.FileDescriptor, filename: [:0]const u8, to_dir: bun.FileDescriptor, destination: [:0]const u8) !void {
    return try moveFileZSlowMaybe(from_dir, filename, to_dir, destination).unwrap();
}

pub fn moveFileZSlowMaybe(from_dir: bun.FileDescriptor, filename: [:0]const u8, to_dir: bun.FileDescriptor, destination: [:0]const u8) Maybe(void) {
    const in_handle = switch (openat(from_dir, filename, bun.O.RDONLY | bun.O.CLOEXEC, if (Environment.isWindows) 0 else 0o644)) {
        .result => |f| f,
        .err => |e| return .{ .err = e },
    };
    defer in_handle.close();
    _ = from_dir.unlinkat(filename);
    return copyFileZSlowWithHandle(in_handle, to_dir, destination);
}

pub fn copyFileZSlowWithHandle(in_handle: bun.FileDescriptor, to_dir: bun.FileDescriptor, destination: [:0]const u8) Maybe(void) {
    if (comptime Environment.isWindows) {
        var buf0: bun.WPathBuffer = undefined;
        var buf1: bun.WPathBuffer = undefined;

        const dest = switch (normalizePathWindows(u8, to_dir, destination, &buf0, .{})) {
            .result => |x| x,
            .err => |e| return .{ .err = e },
        };
        const src_len = bun.windows.GetFinalPathNameByHandleW(in_handle.cast(), &buf1, buf1.len, 0);
        if (src_len == 0) {
            return Maybe(void).errno(bun.sys.E.BUSY, .GetFinalPathNameByHandle);
        } else if (src_len >= buf1.len) {
            return Maybe(void).errno(bun.sys.E.NAMETOOLONG, .GetFinalPathNameByHandle);
        }
        const src = buf1[0..src_len :0];
        return bun.copyFile(src, dest);
    } else {
        const stat_ = switch (fstat(in_handle)) {
            .result => |s| s,
            .err => |e| return .{ .err = e },
        };

        // Attempt to delete incase it already existed.
        // This fixes ETXTBUSY on Linux
        _ = unlinkat(to_dir, destination);

        const out_handle = switch (openat(
            to_dir,
            destination,
            bun.O.WRONLY | bun.O.CREAT | bun.O.CLOEXEC | bun.O.TRUNC,
            if (comptime Environment.isPosix) 0o644 else 0,
        )) {
            .result => |fd| fd,
            .err => |e| return .{ .err = e },
        };
        defer out_handle.close();

        if (comptime Environment.isLinux) {
            _ = std.os.linux.fallocate(out_handle.cast(), 0, 0, @intCast(stat_.size));
        }

        switch (bun.copyFile(in_handle, out_handle)) {
            .err => |e| return .{ .err = e },
            .result => {},
        }

        if (comptime Environment.isPosix) {
            _ = bun.c.fchmod(out_handle.cast(), stat_.mode);
            _ = bun.c.fchown(out_handle.cast(), stat_.uid, stat_.gid);
        }

        return Maybe(void).success;
    }
}

pub fn kindFromMode(mode: mode_t) std.fs.File.Kind {
    return switch (mode & bun.S.IFMT) {
        bun.S.IFBLK => std.fs.File.Kind.block_device,
        bun.S.IFCHR => std.fs.File.Kind.character_device,
        bun.S.IFDIR => std.fs.File.Kind.directory,
        bun.S.IFIFO => std.fs.File.Kind.named_pipe,
        bun.S.IFLNK => std.fs.File.Kind.sym_link,
        bun.S.IFREG => std.fs.File.Kind.file,
        bun.S.IFSOCK => std.fs.File.Kind.unix_domain_socket,
        else => .unknown,
    };
}

pub fn getSelfExeSharedLibPaths(allocator: std.mem.Allocator) error{OutOfMemory}![][:0]u8 {
    const List = std.ArrayList([:0]u8);
    switch (builtin.os.tag) {
        .linux,
        .freebsd,
        .netbsd,
        .dragonfly,
        .openbsd,
        .solaris,
        => {
            var paths = List.init(allocator);
            errdefer {
                const slice = paths.toOwnedSlice() catch &.{};
                for (slice) |item| {
                    allocator.free(item);
                }
                allocator.free(slice);
            }
            try posix.dl_iterate_phdr(&paths, error{OutOfMemory}, struct {
                fn callback(info: *posix.dl_phdr_info, size: usize, list: *List) !void {
                    _ = size;
                    const name = info.dlpi_name orelse return;
                    if (name[0] == '/') {
                        const item = try list.allocator.dupeZ(u8, mem.sliceTo(name, 0));
                        errdefer list.allocator.free(item);
                        try list.append(item);
                    }
                }
            }.callback);
            return try paths.toOwnedSlice();
        },
        .macos, .ios, .watchos, .tvos => {
            var paths = List.init(allocator);
            errdefer {
                const slice = paths.toOwnedSlice() catch &.{};
                for (slice) |item| {
                    allocator.free(item);
                }
                allocator.free(slice);
            }
            const img_count = std.c._dyld_image_count();
            for (0..img_count) |i| {
                const name = std.c._dyld_get_image_name(i);
                const item = try allocator.dupeZ(u8, mem.sliceTo(name, 0));
                errdefer allocator.free(item);
                try paths.append(item);
            }
            return try paths.toOwnedSlice();
        },
        // revisit if Haiku implements dl_iterat_phdr (https://dev.haiku-os.org/ticket/15743)
        .haiku => {
            var paths = List.init(allocator);
            errdefer {
                const slice = paths.toOwnedSlice() catch &.{};
                for (slice) |item| {
                    allocator.free(item);
                }
                allocator.free(slice);
            }

            const b = "/boot/system/runtime_loader";
            const item = try allocator.dupeZ(u8, mem.sliceTo(b, 0));
            errdefer allocator.free(item);
            try paths.append(item);

            return try paths.toOwnedSlice();
        },
        else => @compileError("getSelfExeSharedLibPaths unimplemented for this target"),
    }
}

pub const preallocate_length = switch (bun.Environment.os) {
    .linux => 2048 * 1024,
    else => {},
};
pub const preallocate_supported = @TypeOf(preallocate_length) != void;

// https://gist.github.com/Jarred-Sumner/b37b93399b63cbfd86e908c59a0a37df
//  ext4 NVME Linux kernel 5.17.0-1016-oem x86_64
//
// hyperfine "./micro 1024 temp" "./micro 1024 temp --preallocate" --prepare="rm -rf temp && free && sync && echo 3 > /proc/sys/vm/drop_caches && free"
// Benchmark 1: ./micro 1024 temp
//   Time (mean ± σ):       1.8 ms ±   0.2 ms    [User: 0.6 ms, System: 0.1 ms]
//   Range (min … max):     1.2 ms …   2.3 ms    67 runs
// Benchmark 2: ./micro 1024 temp --preallocate
//   Time (mean ± σ):       1.8 ms ±   0.1 ms    [User: 0.6 ms, System: 0.1 ms]
//   Range (min … max):     1.4 ms …   2.2 ms    121 runs
// Summary
//   './micro 1024 temp --preallocate' ran
//     1.01 ± 0.13 times faster than './micro 1024 temp'
//
// hyperfine "./micro 65432 temp" "./micro 65432 temp --preallocate" --prepare="rm -rf temp && free && sync && echo 3 > /proc/sys/vm/drop_caches && free"
// Benchmark 1: ./micro 65432 temp
//   Time (mean ± σ):       1.8 ms ±   0.2 ms    [User: 0.7 ms, System: 0.1 ms]
//   Range (min … max):     1.2 ms …   2.3 ms    94 runs
// Benchmark 2: ./micro 65432 temp --preallocate
//   Time (mean ± σ):       2.0 ms ±   0.1 ms    [User: 0.6 ms, System: 0.1 ms]
//   Range (min … max):     1.7 ms …   2.3 ms    108 runs
// Summary
//   './micro 65432 temp' ran
//     1.08 ± 0.12 times faster than './micro 65432 temp --preallocate'
//
// hyperfine "./micro 654320 temp" "./micro 654320 temp --preallocate" --prepare="rm -rf temp && free && sync && echo 3 > /proc/sys/vm/drop_caches && free"
// Benchmark 1: ./micro 654320 temp
//   Time (mean ± σ):       2.3 ms ±   0.2 ms    [User: 0.9 ms, System: 0.3 ms]
//   Range (min … max):     1.9 ms …   2.9 ms    96 runs
//
// Benchmark 2: ./micro 654320 temp --preallocate
//   Time (mean ± σ):       2.2 ms ±   0.1 ms    [User: 0.9 ms, System: 0.2 ms]
//   Range (min … max):     1.9 ms …   2.7 ms    115 runs
//
//   Warning: Command took less than 5 ms to complete. Results might be inaccurate.
//
// Summary
//   './micro 654320 temp --preallocate' ran
//     1.04 ± 0.10 times faster than './micro 654320 temp'
//
// hyperfine "./micro 6543200 temp" "./micro 6543200 temp --preallocate" --prepare="rm -rf temp && free && sync && echo 3 > /proc/sys/vm/drop_caches && free"
// Benchmark 1: ./micro 6543200 temp
//   Time (mean ± σ):       6.3 ms ±   0.4 ms    [User: 0.4 ms, System: 4.9 ms]
//   Range (min … max):     5.8 ms …   8.6 ms    84 runs
//
// Benchmark 2: ./micro 6543200 temp --preallocate
//   Time (mean ± σ):       5.5 ms ±   0.3 ms    [User: 0.5 ms, System: 3.9 ms]
//   Range (min … max):     5.1 ms …   7.1 ms    93 runs
//
// Summary
//   './micro 6543200 temp --preallocate' ran
//     1.14 ± 0.09 times faster than './micro 6543200 temp'
//
// hyperfine "./micro 65432000 temp" "./micro 65432000 temp --preallocate" --prepare="rm -rf temp && free && sync && echo 3 > /proc/sys/vm/drop_caches && free"
// Benchmark 1: ./micro 65432000 temp
//   Time (mean ± σ):      52.9 ms ±   0.4 ms    [User: 3.1 ms, System: 48.7 ms]
//   Range (min … max):    52.4 ms …  54.4 ms    36 runs
//
// Benchmark 2: ./micro 65432000 temp --preallocate
//   Time (mean ± σ):      44.6 ms ±   0.8 ms    [User: 2.3 ms, System: 41.2 ms]
//   Range (min … max):    44.0 ms …  47.3 ms    37 runs
//
// Summary
//   './micro 65432000 temp --preallocate' ran
//     1.19 ± 0.02 times faster than './micro 65432000 temp'
//
// hyperfine "./micro 65432000 temp" "./micro 65432000 temp --preallocate" --prepare="rm -rf temp"
// Benchmark 1: ./micro 65432000 temp
//   Time (mean ± σ):      51.7 ms ±   0.9 ms    [User: 2.1 ms, System: 49.6 ms]
//   Range (min … max):    50.7 ms …  54.1 ms    49 runs
//
// Benchmark 2: ./micro 65432000 temp --preallocate
//   Time (mean ± σ):      43.8 ms ±   2.3 ms    [User: 2.2 ms, System: 41.4 ms]
//   Range (min … max):    42.7 ms …  54.7 ms    56 runs
//
// Summary
//   './micro 65432000 temp --preallocate' ran
//     1.18 ± 0.06 times faster than './micro 65432000 temp'
//
pub fn preallocate_file(fd: std.posix.fd_t, offset: std.posix.off_t, len: std.posix.off_t) anyerror!void {
    switch (Environment.os) {
        .linux => {
            _ = std.os.linux.fallocate(fd, 0, @as(i64, @intCast(offset)), len);
        },
        .mac => {
            // benchmarking this did nothing on macOS
            // i verified it wasn't returning -1

            // Based on https://api.kde.org/frameworks/kcoreaddons/html/posix__fallocate__mac_8h_source.html
            // var fstore = zeroes(fstore_t);
            // fstore.fst_flags = F_ALLOCATECONTIG;
            // fstore.fst_posmode = F_PEOFPOSMODE;
            // fstore.fst_offset = 0;
            // fstore.fst_length = len + offset;
            // var rc = os.system.fcntl(fd, os.F.PREALLOCATE, &fstore);
        },
        else => {}, // not tested,
    }
}

pub fn dlopen(filename: [:0]const u8, flags: std.c.RTLD) ?*anyopaque {
    if (comptime Environment.isWindows) {
        return bun.windows.LoadLibraryA(filename);
    }

    return std.c.dlopen(filename, flags);
}

pub fn dlsymImpl(handle: ?*anyopaque, name: [:0]const u8) ?*anyopaque {
    if (comptime Environment.isWindows) {
        return bun.windows.GetProcAddressA(handle, name);
    } else if (comptime Environment.isMac or Environment.isLinux) {
        return std.c.dlsym(handle, name.ptr);
    }

    @compileError("dlsym unimplemented for this target");
}

pub fn dlsymWithHandle(comptime Type: type, comptime name: [:0]const u8, comptime handle_getter: fn () ?*anyopaque) ?Type {
    if (comptime @typeInfo(Type) != .pointer) {
        @compileError("dlsym must be a pointer type (e.g. ?const *fn()). Received " ++ @typeName(Type) ++ ".");
    }

    const Wrapper = struct {
        pub var function: Type = undefined;
        var failed = false;
        pub var once = std.once(loadOnce);
        fn loadOnce() void {
            function = bun.cast(Type, dlsymImpl(@call(bun.callmod_inline, handle_getter, .{}), name) orelse {
                failed = true;
                return;
            });
        }
    };
    Wrapper.once.call();
    if (Wrapper.failed) {
        return null;
    }
    return Wrapper.function;
}

pub const umask = switch (Environment.os) {
    else => bun.c.umask,
    // Using the same typedef and define for `mode_t` and `umask` as node on windows.
    // https://github.com/nodejs/node/blob/ad5e2dab4c8306183685973387829c2f69e793da/src/node_process_methods.cc#L29
    .windows => @extern(*const fn (mode: u16) callconv(.c) u16, .{ .name = "_umask" }),
};
