const std = @import("std");
const builtin = @import("builtin");
const native_arch = builtin.target.cpu.arch;
const assert = std.debug.assert;
const AF = std.c.AF;
const PROT = std.c.PROT;
const caddr_t = std.c.caddr_t;
const fd_t = std.c.fd_t;
const iovec_const = std.posix.iovec_const;
const mode_t = std.c.mode_t;
const off_t = std.c.off_t;
const pid_t = std.c.pid_t;
const pthread_attr_t = std.c.pthread_attr_t;
const timespec = std.c.timespec;
const sf_hdtr = std.c.sf_hdtr;

comptime {
    assert(builtin.os.tag.isDarwin()); // Prevent access of std.c symbols on wrong OS.
}

// Grand Central Dispatch is exposed by libSystem.
pub const dispatch = @import("darwin/dispatch.zig");

pub const mach_port_t = c_uint;

pub const EXC = enum(exception_type_t) {
    NULL = 0,
    /// Could not access memory
    BAD_ACCESS = 1,
    /// Instruction failed
    BAD_INSTRUCTION = 2,
    /// Arithmetic exception
    ARITHMETIC = 3,
    /// Emulation instruction
    EMULATION = 4,
    /// Software generated exception
    SOFTWARE = 5,
    /// Trace, breakpoint, etc.
    BREAKPOINT = 6,
    /// System calls.
    SYSCALL = 7,
    /// Mach system calls.
    MACH_SYSCALL = 8,
    /// RPC alert
    RPC_ALERT = 9,
    /// Abnormal process exit
    CRASH = 10,
    /// Hit resource consumption limit
    RESOURCE = 11,
    /// Violated guarded resource protections
    GUARD = 12,
    /// Abnormal process exited to corpse state
    CORPSE_NOTIFY = 13,

    _,

    pub const TYPES_COUNT = @typeInfo(EXC).@"enum".field_names.len;
    pub const SOFT_SIGNAL = 0x10003;

    pub const MASK = packed struct(u32) {
        _0: u1 = 0,
        BAD_ACCESS: bool = false,
        BAD_INSTRUCTION: bool = false,
        ARITHMETIC: bool = false,
        EMULATION: bool = false,
        SOFTWARE: bool = false,
        BREAKPOINT: bool = false,
        SYSCALL: bool = false,
        MACH_SYSCALL: bool = false,
        RPC_ALERT: bool = false,
        CRASH: bool = false,
        RESOURCE: bool = false,
        GUARD: bool = false,
        CORPSE_NOTIFY: bool = false,
        _14: u18 = 0,

        pub const MACHINE: MASK = @bitCast(@as(u32, 0));

        pub const ALL: MASK = .{
            .BAD_ACCESS = true,
            .BAD_INSTRUCTION = true,
            .ARITHMETIC = true,
            .EMULATION = true,
            .SOFTWARE = true,
            .BREAKPOINT = true,
            .SYSCALL = true,
            .MACH_SYSCALL = true,
            .RPC_ALERT = true,
            .CRASH = true,
            .RESOURCE = true,
            .GUARD = true,
            .CORPSE_NOTIFY = true,
        };
    };
};

pub const EXCEPTION = enum(u32) {
    /// Send a catch_exception_raise message including the identity.
    DEFAULT = 1,
    /// Send a catch_exception_raise_state message including the
    /// thread state.
    STATE = 2,
    /// Send a catch_exception_raise_state_identity message including
    /// the thread identity and state.
    STATE_IDENTITY = 3,
    /// Send a catch_exception_raise_identity_protected message including protected task
    /// and thread identity.
    IDENTITY_PROTECTED = 4,

    _,
};

pub const KEVENT = struct {
    /// Used as the `flags` arg for `kevent64`.
    pub const FLAG = packed struct(c_uint) {
        /// immediate timeout
        IMMEDIATE: bool = false,
        /// output events only include change
        ERROR_EVENTS: bool = false,
        _: u30 = 0,

        /// no flag value
        pub const NONE: KEVENT.FLAG = .{
            .IMMEDIATE = false,
            .ERROR_EVENTS = false,
        };
    };
};

pub const MACH = struct {
    pub const EXCEPTION = packed struct(exception_mask_t) {
        _: u29 = 0,
        /// Prefer sending a catch_exception_raice_backtrace message, if applicable.
        BACKTRACE_PREFERRED: bool = false,
        /// include additional exception specific errors, not used yet.
        ERRORS: bool = false,
        /// Send 64-bit code and subcode in the exception header */
        CODES: bool = false,

        pub const MASK: exception_mask_t = @bitCast(MACH.EXCEPTION{
            .BACKTRACE_PREFERRED = true,
            .ERRORS = true,
            .CODES = true,
        });
    };

    pub const MSG = packed struct(kern_return_t) {
        _0: u10 = 0,
        /// Kernel resource shortage handling an IPC capability.
        VM_KERNEL: bool = false,
        /// Kernel resource shortage handling out-of-line memory.
        IPC_KERNEL: bool = false,
        /// No room in VM address space for out-of-line memory.
        VM_SPACE: bool = false,
        /// No room in IPC name space for another capability name.
        IPC_SPACE: bool = false,
        _14: u18 = 0,

        pub const MASK: kern_return_t = @bitCast(MACH.MSG{
            .VM_KERNEL = true,
            .IPC_KERNEL = true,
            .VM_SPACE = true,
            .IPC_SPACE = true,
        });

        pub const TIMEOUT_NONE: mach_msg_timeout_t = .NONE;
        pub const OPTION_NONE: mach_msg_option_t = .NONE;
        pub const STRICT_REPLY = @compileError("use MACH.RCV.STRICT_REPLY and/or MACH.SEND.STRICT_REPLY");

        pub const TYPE = mach_msg_type_name_t;
    };

    pub const PORT = struct {
        pub const NULL: mach_port_t = 0;
        pub const RIGHT = mach_port_right_t;
    };

    pub const RCV = packed struct(integer_t) {
        _0: u1 = 0,
        /// Other flags are only valid if this one is set.
        MSG: bool = true,
        LARGE: bool = false,
        LARGE_IDENTITY: bool = false,
        _4: u4 = 0,
        TIMEOUT: bool = false,
        /// Shared between `RCV` and `SEND`. Used to be `MACH_RCV_NOTIFY`.
        STRICT_REPLY: bool = false,
        INTERRUPT: bool = false,
        VOUCHER: bool = false,
        GUARDED_DESC: bool = false,
        _13: u1 = 0,
        SYNC_WAIT: bool = false,
        SYNC_PEEK: bool = false,
        _16: u16 = 0,
    };

    pub const SEND = packed struct(integer_t) {
        /// Other flags are only valid if this one is set.
        MSG: bool = true,
        _1: u3 = 0,
        TIMEOUT: bool = false,
        OVERRIDE: bool = false,
        INTERRUPT: bool = false,
        NOTIFY: bool = false,
        _8: u1 = 0,
        /// Shared between `RCV` and `SEND`.
        STRICT_REPLY: bool = false,
        _10: u6 = 0,
        /// User-only. If you're the kernel, this bit is `MACH_SEND_ALWAYS`.
        FILTER_NONFATAL: bool = false,
        TRAILER: bool = false,
        /// Synonymous to `MACH_SEND_NODENAP`.
        NOIMPORTANCE: bool = false,
        /// Kernel-only.
        IMPORTANCE: bool = false,
        SYNC_OVERRIDE: bool = false,
        /// Synonymous to `MACH_SEND_SYNC_USE_THRPRI`.
        PROPAGATE_QOS: bool = false,
        /// Kernel-only.
        KERNEL: bool = false,
        SYNC_BOOTSTRAP_CHECKIN: bool = false,
        _24: u8 = 0,
    };

    pub const TASK = struct {
        pub const BASIC = struct {
            pub const INFO = 20;
            pub const INFO_COUNT: mach_msg_type_number_t = @sizeOf(mach_task_basic_info) / @sizeOf(natural_t);
        };
    };
};

pub const MACH_MSG_TYPE = @compileError("use MACH.MSG.TYPE");
pub const MACH_PORT_RIGHT = @compileError("use MACH.PORT.RIGHT");
pub const MACH_TASK_BASIC_INFO = @compileError("use MACH.TASK.BASIC.INFO");
pub const MACH_TASK_BASIC_INFO_COUNT = @compileError("use MACH.TASK.BASIC.INFO_COUNT");

pub const MATTR = struct {
    /// Cachability
    pub const CACHE: vm_machine_attribute_t = 1;
    /// Migrability
    pub const MIGRATE: vm_machine_attribute_t = 2;
    /// Replicability
    pub const REPLICATE: vm_machine_attribute_t = 4;
    /// (Generic) turn attribute off
    pub const VAL_OFF: vm_machine_attribute_t = 0;
    /// (Generic) turn attribute on
    pub const VAL_ON: vm_machine_attribute_t = 1;
    /// (Generic) return current value
    pub const VAL_GET: vm_machine_attribute_t = 2;
    /// Flush from all caches
    pub const VAL_CACHE_FLUSH: vm_machine_attribute_t = 6;
    /// Flush from data caches
    pub const VAL_DCACHE_FLUSH: vm_machine_attribute_t = 7;
    /// Flush from instruction caches
    pub const VAL_ICACHE_FLUSH: vm_machine_attribute_t = 8;
    /// Sync I+D caches
    pub const VAL_CACHE_SYNC: vm_machine_attribute_t = 9;
    /// Get page info (stats)
    pub const VAL_GET_INFO: vm_machine_attribute_t = 10;
};

pub const OS = struct {
    pub const LOG_CATEGORY = struct {
        pub const POINTS_OF_INTEREST: *const u8 = "PointsOfInterest";
        pub const DYNAMIC_TRACING: *const u8 = "DynamicTracing";
        pub const DYNAMIC_STACK_TRACING: *const u8 = "DynamicStackTracing";
    };
};

pub const TASK = struct {
    pub const NULL: task_t = 0;

    pub const VM = struct {
        pub const INFO = 22;
        pub const INFO_COUNT: mach_msg_type_number_t = @sizeOf(task_vm_info_data_t) / @sizeOf(natural_t);
    };
};

pub const TASK_NULL = @compileError("use TASK.NULL");
pub const TASK_VM_INFO = @compileError("use TASK.VM.INFO");
pub const TASK_VM_INFO_COUNT = @compileError("use TASK.VM.INFO_COUNT");

pub const THREAD = struct {
    pub const NULL: thread_t = 0;

    pub const BASIC = struct {
        pub const INFO = 3;
        pub const INFO_COUNT: mach_msg_type_number_t = @sizeOf(thread_basic_info) / @sizeOf(natural_t);
    };

    pub const IDENTIFIER = struct {
        pub const INFO = 4;
        pub const INFO_COUNT: mach_msg_type_number_t = @sizeOf(thread_identifier_info) / @sizeOf(natural_t);
    };

    pub const STATE = struct {
        pub const NONE = switch (native_arch) {
            .aarch64 => 5,
            .x86_64 => 13,
            else => @compileError("unsupported arch"),
        };
    };
};

pub const THREAD_NULL = @compileError("use THREAD.NULL");
pub const THREAD_BASIC_INFO = @compileError("use THREAD.BASIC.INFO");
pub const THREAD_BASIC_INFO_COUNT = @compileError("use THREAD.BASIC.INFO_COUNT");
pub const THREAD_IDENTIFIER_INFO_COUNT = @compileError("use THREAD.IDENTIFIER.INFO_COUNT");
pub const THREAD_STATE_NONE = @compileError("use THREAD.STATE.NONE");

pub const VM = struct {
    pub const INHERIT = struct {
        pub const SHARE: vm_inherit_t = 0;
        pub const COPY: vm_inherit_t = 1;
        pub const NONE: vm_inherit_t = 2;
        pub const DONATE_COPY: vm_inherit_t = 3;
        pub const DEFAULT = VM.INHERIT.COPY;
    };

    pub const BEHAVIOR = struct {
        pub const DEFAULT: vm_behavior_t = 0;
        pub const RANDOM: vm_behavior_t = 1;
        pub const SEQUENTIAL: vm_behavior_t = 2;
        pub const RSEQNTL: vm_behavior_t = 3;
        pub const WILLNEED: vm_behavior_t = 4;
        pub const DONTNEED: vm_behavior_t = 5;
        pub const FREE: vm_behavior_t = 6;
        pub const ZERO_WIRED_PAGES: vm_behavior_t = 7;
        pub const REUSABLE: vm_behavior_t = 8;
        pub const REUSE: vm_behavior_t = 9;
        pub const CAN_REUSE: vm_behavior_t = 10;
        pub const PAGEOUT: vm_behavior_t = 11;
    };

    pub const REGION = struct {
        pub const BASIC_INFO_64 = 9;
        pub const EXTENDED_INFO = 13;
        pub const TOP_INFO = 12;
        pub const SUBMAP_INFO_COUNT_64: mach_msg_type_number_t = @sizeOf(vm_region_submap_info_64) / @sizeOf(natural_t);
        pub const SUBMAP_SHORT_INFO_COUNT_64: mach_msg_type_number_t = @sizeOf(vm_region_submap_short_info_64) / @sizeOf(natural_t);
        pub const BASIC_INFO_COUNT: mach_msg_type_number_t = @sizeOf(vm_region_basic_info_64) / @sizeOf(c_int);
        pub const EXTENDED_INFO_COUNT: mach_msg_type_number_t = @sizeOf(vm_region_extended_info) / @sizeOf(natural_t);
        pub const TOP_INFO_COUNT: mach_msg_type_number_t = @sizeOf(vm_region_top_info) / @sizeOf(natural_t);
    };

    pub fn MAKE_TAG(tag: u8) u32 {
        return @as(u32, tag) << 24;
    }
};

pub const exception_type_t = c_int;

pub extern "c" fn NSVersionOfRunTimeLibrary(library_name: [*:0]const u8) u32;
pub extern "c" fn _NSGetExecutablePath(buf: [*]u8, bufsize: *u32) c_int;
pub extern "c" fn _dyld_image_count() u32;
pub extern "c" fn _dyld_get_image_header(image_index: u32) ?*mach_header;
pub extern "c" fn _dyld_get_image_vmaddr_slide(image_index: u32) usize;
pub extern "c" fn _dyld_get_image_name(image_index: u32) [*:0]const u8;
pub extern "c" fn _dyld_get_image_header_containing_address(address: *const anyopaque) ?*mach_header;
pub extern "c" fn dyld_image_path_containing_address(address: *const anyopaque) ?[*:0]const u8;
pub extern "c" fn dladdr(addr: *const anyopaque, info: *dl_info) c_int;

pub const dl_info = extern struct {
    fname: [*:0]const u8,
    fbase: *anyopaque,
    sname: ?[*:0]const u8,
    saddr: ?*anyopaque,
};

pub const COPYFILE = packed struct(u32) {
    ACL: bool = false,
    STAT: bool = false,
    XATTR: bool = false,
    DATA: bool = false,
    _: u28 = 0,
};

pub const copyfile_state_t = *opaque {};
pub extern "c" fn fcopyfile(from: fd_t, to: fd_t, state: ?copyfile_state_t, flags: COPYFILE) c_int;
pub extern "c" fn __getdirentries64(fd: c_int, buf_ptr: [*]u8, buf_len: usize, basep: *i64) isize;

pub const RENAME = packed struct(u32) {
    SECLUDE: bool = false,
    SWAP: bool = false,
    EXCL: bool = false,
    RESERVED1: bool = false,
    NOFOLLOW_ANY: bool = false,
    RESOLVE_BENEATH: bool = false,
    _: u26 = 0,
};

pub extern "c" fn renameatx_np(fromfd: c_int, from: [*:0]const u8, tofd: c_int, to: [*:0]const u8, flags: RENAME) c_int;

pub extern "c" fn mach_absolute_time() u64;
pub extern "c" fn mach_continuous_time() u64;
pub extern "c" fn mach_timebase_info(tinfo: ?*mach_timebase_info_data) kern_return_t;

pub extern "c" fn kevent64(
    kq: c_int,
    changelist: [*]const kevent64_s,
    nchanges: c_int,
    eventlist: [*]kevent64_s,
    nevents: c_int,
    flags: KEVENT.FLAG,
    timeout: ?*const timespec,
) c_int;

pub const mach_hdr = if (@sizeOf(usize) == 8) mach_header_64 else mach_header;

pub const mach_header_64 = std.macho.mach_header_64;
pub const mach_header = std.macho.mach_header;

pub extern "c" fn @"close$NOCANCEL"(fd: fd_t) c_int;
pub extern "c" fn mach_host_self() mach_port_t;
pub extern "c" fn clock_get_time(clock_serv: clock_serv_t, cur_time: *mach_timespec_t) kern_return_t;
pub extern "c" fn shm_open(name: [*:0]const u8, flag: c_int, ...) c_int;

pub const exception_data_type_t = integer_t;
pub const exception_data_t = ?*mach_exception_data_type_t;
pub const mach_exception_data_type_t = i64;
pub const mach_exception_data_t = ?*mach_exception_data_type_t;
pub const vm_map_t = mach_port_t;
pub const vm_map_read_t = mach_port_t;
pub const vm_region_flavor_t = c_int;
pub const vm_region_info_t = *c_int;
pub const vm_region_recurse_info_t = *c_int;
pub const mach_vm_address_t = usize;
pub const vm_offset_t = usize;
pub const mach_vm_size_t = u64;
pub const mach_msg_bits_t = c_uint;
pub const mach_msg_id_t = integer_t;
pub const mach_msg_type_number_t = natural_t;
pub const mach_msg_size_t = natural_t;
pub const task_t = mach_port_t;
pub const thread_port_t = task_t;
pub const thread_t = thread_port_t;
pub const exception_mask_t = c_uint;
pub const exception_mask_array_t = [*]exception_mask_t;
pub const exception_handler_t = mach_port_t;
pub const exception_handler_array_t = [*]exception_handler_t;
pub const exception_port_t = exception_handler_t;
pub const exception_port_array_t = exception_handler_array_t;
pub const exception_flavor_array_t = [*]thread_state_flavor_t;
pub const exception_behavior_t = c_uint;
pub const exception_behavior_array_t = [*]exception_behavior_t;
pub const thread_state_flavor_t = c_int;
pub const ipc_space_t = mach_port_t;
pub const ipc_space_port_t = ipc_space_t;

pub const mach_msg_option_t = packed union(integer_t) {
    RCV: MACH.RCV,
    SEND: MACH.SEND,

    pub const NONE: mach_msg_option_t = @bitCast(@as(integer_t, 0));

    pub fn sendAndRcv(send: MACH.SEND, rcv: MACH.RCV) mach_msg_option_t {
        return @bitCast(@as(integer_t, @bitCast(send)) | @as(integer_t, @bitCast(rcv)));
    }
};

pub const mach_msg_timeout_t = enum(natural_t) {
    NONE = 0,
    _,
};

pub const mach_msg_type_name_t = enum(c_uint) {
    /// Must hold receive right
    MOVE_RECEIVE = 16,
    /// Must hold send right(s)
    MOVE_SEND = 17,
    /// Must hold sendonce right
    MOVE_SEND_ONCE = 18,
    /// Must hold send right(s)
    COPY_SEND = 19,
    /// Must hold receive right
    MAKE_SEND = 20,
    /// Must hold receive right
    MAKE_SEND_ONCE = 21,
    /// NOT VALID
    COPY_RECEIVE = 22,
    /// Must hold receive right
    DISPOSE_RECEIVE = 24,
    /// Must hold send right(s)
    DISPOSE_SEND = 25,
    /// Must hold sendonce right
    DISPOSE_SEND_ONCE = 26,

    _,
};

pub const mach_port_right_t = enum(natural_t) {
    SEND = 0,
    RECEIVE = 1,
    SEND_ONCE = 2,
    PORT_SET = 3,
    DEAD_NAME = 4,
    /// Obsolete right
    LABELH = 5,
    /// Right not implemented
    NUMBER = 6,

    _,
};

extern "c" var mach_task_self_: mach_port_t;
pub fn mach_task_self() callconv(.c) mach_port_t {
    return mach_task_self_;
}

pub extern "c" fn mach_msg(
    msg: ?*mach_msg_header_t,
    option: mach_msg_option_t,
    send_size: mach_msg_size_t,
    rcv_size: mach_msg_size_t,
    rcv_name: mach_port_name_t,
    timeout: mach_msg_timeout_t,
    notify: mach_port_name_t,
) mach_msg_return_t;

pub const mach_msg_header_t = extern struct {
    msgh_bits: mach_msg_bits_t,
    msgh_size: mach_msg_size_t,
    msgh_remote_port: mach_port_t,
    msgh_local_port: mach_port_t,
    msgh_voucher_port: mach_port_name_t,
    msgh_id: mach_msg_id_t,
};

pub extern "c" fn task_get_exception_ports(
    task: task_t,
    exception_mask: exception_mask_t,
    masks: exception_mask_array_t,
    masks_cnt: *mach_msg_type_number_t,
    old_handlers: exception_handler_array_t,
    old_behaviors: exception_behavior_array_t,
    old_flavors: exception_flavor_array_t,
) kern_return_t;
pub extern "c" fn task_set_exception_ports(
    task: task_t,
    exception_mask: exception_mask_t,
    new_port: mach_port_t,
    behavior: exception_behavior_t,
    new_flavor: thread_state_flavor_t,
) kern_return_t;

pub const task_read_t = mach_port_t;

pub extern "c" fn task_resume(target_task: task_read_t) kern_return_t;
pub extern "c" fn task_suspend(target_task: task_read_t) kern_return_t;

pub extern "c" fn task_for_pid(target_tport: mach_port_name_t, pid: pid_t, t: *mach_port_name_t) kern_return_t;
pub extern "c" fn pid_for_task(target_tport: mach_port_name_t, pid: *pid_t) kern_return_t;
pub extern "c" fn mach_vm_read(
    target_task: vm_map_read_t,
    address: mach_vm_address_t,
    size: mach_vm_size_t,
    data: *vm_offset_t,
    data_cnt: *mach_msg_type_number_t,
) kern_return_t;
pub extern "c" fn mach_vm_write(
    target_task: vm_map_t,
    address: mach_vm_address_t,
    data: vm_offset_t,
    data_cnt: mach_msg_type_number_t,
) kern_return_t;
pub extern "c" fn mach_vm_region(
    target_task: vm_map_t,
    address: *mach_vm_address_t,
    size: *mach_vm_size_t,
    flavor: vm_region_flavor_t,
    info: vm_region_info_t,
    info_cnt: *mach_msg_type_number_t,
    object_name: *mach_port_t,
) kern_return_t;
pub extern "c" fn mach_vm_region_recurse(
    target_task: vm_map_t,
    address: *mach_vm_address_t,
    size: *mach_vm_size_t,
    nesting_depth: *natural_t,
    info: vm_region_recurse_info_t,
    info_cnt: *mach_msg_type_number_t,
) kern_return_t;

pub const vm_inherit_t = u32;
pub const memory_object_offset_t = u64;
pub const vm_behavior_t = i32;
pub const vm32_object_id_t = u32;
pub const vm_object_id_t = u64;

pub const vm_region_basic_info_64 = extern struct {
    protection: vm_prot_t,
    max_protection: vm_prot_t,
    inheritance: vm_inherit_t,
    shared: boolean_t,
    reserved: boolean_t,
    offset: memory_object_offset_t,
    behavior: vm_behavior_t,
    user_wired_count: u16,
};

pub const vm_region_extended_info = extern struct {
    protection: vm_prot_t,
    user_tag: u32,
    pages_resident: u32,
    pages_shared_now_private: u32,
    pages_swapped_out: u32,
    pages_dirtied: u32,
    ref_count: u32,
    shadow_depth: u16,
    external_pager: u8,
    share_mode: u8,
    pages_reusable: u32,
};

pub const vm_region_top_info = extern struct {
    obj_id: u32,
    ref_count: u32,
    private_pages_resident: u32,
    shared_pages_resident: u32,
    share_mode: u8,
};

pub const vm_region_submap_info_64 = extern struct {
    // present across protection
    protection: vm_prot_t,
    // max avail through vm_prot
    max_protection: vm_prot_t,
    // behavior of map/obj on fork
    inheritance: vm_inherit_t,
    // offset into object/map
    offset: memory_object_offset_t,
    // user tag on map entry
    user_tag: u32,
    // only valid for objects
    pages_resident: u32,
    // only for objects
    pages_shared_now_private: u32,
    // only for objects
    pages_swapped_out: u32,
    // only for objects
    pages_dirtied: u32,
    // obj/map mappers, etc.
    ref_count: u32,
    // only for obj
    shadow_depth: u16,
    // only for obj
    external_pager: u8,
    // see enumeration
    share_mode: u8,
    // submap vs obj
    is_submap: boolean_t,
    // access behavior hint
    behavior: vm_behavior_t,
    // obj/map name, not a handle
    object_id: vm32_object_id_t,
    user_wired_count: u16,
    pages_reusable: u32,
    object_id_full: vm_object_id_t,
};

pub const vm_region_submap_short_info_64 = extern struct {
    // present access protection
    protection: vm_prot_t,
    // max avail through vm_prot
    max_protection: vm_prot_t,
    // behavior of map/obj on fork
    inheritance: vm_inherit_t,
    // offset into object/map
    offset: memory_object_offset_t,
    // user tag on map entry
    user_tag: u32,
    // obj/map mappers, etc
    ref_count: u32,
    // only for obj
    shadow_depth: u16,
    // only for obj
    external_pager: u8,
    // see enumeration
    share_mode: u8,
    //  submap vs obj
    is_submap: boolean_t,
    // access behavior hint
    behavior: vm_behavior_t,
    // obj/map name, not a handle
    object_id: vm32_object_id_t,
    user_wired_count: u16,
};

pub const thread_act_t = mach_port_t;
pub const thread_state_t = *natural_t;
pub const mach_port_array_t = [*]mach_port_t;

pub extern "c" fn task_threads(
    target_task: mach_port_t,
    init_port_set: *mach_port_array_t,
    init_port_count: *mach_msg_type_number_t,
) kern_return_t;
pub extern "c" fn thread_get_state(
    thread: thread_act_t,
    flavor: thread_flavor_t,
    state: thread_state_t,
    count: *mach_msg_type_number_t,
) kern_return_t;
pub extern "c" fn thread_set_state(
    thread: thread_act_t,
    flavor: thread_flavor_t,
    new_state: thread_state_t,
    count: mach_msg_type_number_t,
) kern_return_t;
pub extern "c" fn thread_info(
    thread: thread_act_t,
    flavor: thread_flavor_t,
    info: thread_info_t,
    count: *mach_msg_type_number_t,
) kern_return_t;
pub extern "c" fn thread_resume(thread: thread_act_t) kern_return_t;

pub const thread_flavor_t = natural_t;
pub const thread_info_t = *integer_t;
pub const time_value_t = time_value;
pub const task_policy_flavor_t = natural_t;
pub const task_policy_t = *integer_t;
pub const policy_t = c_int;

pub const time_value = extern struct {
    seconds: integer_t,
    microseconds: integer_t,
};

pub const thread_basic_info = extern struct {
    // user run time
    user_time: time_value_t,
    // system run time
    system_time: time_value_t,
    // scaled cpu usage percentage
    cpu_usage: integer_t,
    // scheduling policy in effect
    policy: policy_t,
    // run state
    run_state: integer_t,
    // various flags
    flags: integer_t,
    // suspend count for thread
    suspend_count: integer_t,
    // number of seconds that thread has been sleeping
    sleep_time: integer_t,
};

pub const thread_identifier_info = extern struct {
    /// System-wide unique 64-bit thread id
    thread_id: u64,

    /// Handle to be used by libproc
    thread_handle: u64,

    /// libdispatch queue address
    dispatch_qaddr: u64,
};

pub const task_vm_info = extern struct {
    // virtual memory size (bytes)
    virtual_size: mach_vm_size_t,
    // number of memory regions
    region_count: integer_t,
    page_size: integer_t,
    // resident memory size (bytes)
    resident_size: mach_vm_size_t,
    // peak resident size (bytes)
    resident_size_peak: mach_vm_size_t,

    device: mach_vm_size_t,
    device_peak: mach_vm_size_t,
    internal: mach_vm_size_t,
    internal_peak: mach_vm_size_t,
    external: mach_vm_size_t,
    external_peak: mach_vm_size_t,
    reusable: mach_vm_size_t,
    reusable_peak: mach_vm_size_t,
    purgeable_volatile_pmap: mach_vm_size_t,
    purgeable_volatile_resident: mach_vm_size_t,
    purgeable_volatile_virtual: mach_vm_size_t,
    compressed: mach_vm_size_t,
    compressed_peak: mach_vm_size_t,
    compressed_lifetime: mach_vm_size_t,

    // added for rev1
    phys_footprint: mach_vm_size_t,

    // added for rev2
    min_address: mach_vm_address_t,
    max_address: mach_vm_address_t,

    // added for rev3
    ledger_phys_footprint_peak: i64,
    ledger_purgeable_nonvolatile: i64,
    ledger_purgeable_novolatile_compressed: i64,
    ledger_purgeable_volatile: i64,
    ledger_purgeable_volatile_compressed: i64,
    ledger_tag_network_nonvolatile: i64,
    ledger_tag_network_nonvolatile_compressed: i64,
    ledger_tag_network_volatile: i64,
    ledger_tag_network_volatile_compressed: i64,
    ledger_tag_media_footprint: i64,
    ledger_tag_media_footprint_compressed: i64,
    ledger_tag_media_nofootprint: i64,
    ledger_tag_media_nofootprint_compressed: i64,
    ledger_tag_graphics_footprint: i64,
    ledger_tag_graphics_footprint_compressed: i64,
    ledger_tag_graphics_nofootprint: i64,
    ledger_tag_graphics_nofootprint_compressed: i64,
    ledger_tag_neural_footprint: i64,
    ledger_tag_neural_footprint_compressed: i64,
    ledger_tag_neural_nofootprint: i64,
    ledger_tag_neural_nofootprint_compressed: i64,

    // added for rev4
    limit_bytes_remaining: u64,

    // added for rev5
    decompressions: integer_t,
};

pub const task_vm_info_data_t = task_vm_info;

pub const vm_prot_t = std.macho.vm_prot_t;
pub const boolean_t = c_int;

pub extern "c" fn mach_vm_protect(
    target_task: vm_map_t,
    address: mach_vm_address_t,
    size: mach_vm_size_t,
    set_maximum: boolean_t,
    new_protection: vm_prot_t,
) kern_return_t;

pub extern "c" fn mach_port_allocate(
    task: ipc_space_t,
    right: mach_port_right_t,
    name: *mach_port_name_t,
) kern_return_t;
pub extern "c" fn mach_port_deallocate(task: ipc_space_t, name: mach_port_name_t) kern_return_t;
pub extern "c" fn mach_port_insert_right(
    task: ipc_space_t,
    name: mach_port_name_t,
    right: mach_port_t,
    right_type: mach_msg_type_name_t,
) kern_return_t;

pub extern "c" fn task_info(
    target_task: task_name_t,
    flavor: task_flavor_t,
    task_info_out: task_info_t,
    task_info_outCnt: *mach_msg_type_number_t,
) kern_return_t;

pub const mach_task_basic_info = extern struct {
    /// Virtual memory size (bytes)
    virtual_size: mach_vm_size_t,
    /// Resident memory size (bytes)
    resident_size: mach_vm_size_t,
    /// Total user run time for terminated threads
    user_time: time_value_t,
    /// Total system run time for terminated threads
    system_time: time_value_t,
    /// Default policy for new threads
    policy: policy_t,
    /// Suspend count for task
    suspend_count: mach_vm_size_t,
};

pub extern "c" fn _host_page_size(task: mach_port_t, size: *vm_size_t) kern_return_t;
pub extern "c" fn vm_deallocate(target_task: vm_map_t, address: vm_address_t, size: vm_size_t) kern_return_t;
pub extern "c" fn vm_machine_attribute(
    target_task: vm_map_t,
    address: vm_address_t,
    size: vm_size_t,
    attribute: vm_machine_attribute_t,
    value: *vm_machine_attribute_val_t,
) kern_return_t;

pub extern "c" fn sendfile(
    in_fd: fd_t,
    out_fd: fd_t,
    offset: off_t,
    len: *off_t,
    sf_hdtr: ?*sf_hdtr,
    flags: u32,
) c_int;

// https://github.com/apple/darwin-xnu/blob/2ff845c2e033bd0ff64b5b6aa6063a1f8f65aa32/bsd/sys/_types.h#L74
pub const sigset_t = u32;

// https://github.com/apple/darwin-xnu/blob/2ff845c2e033bd0ff64b5b6aa6063a1f8f65aa32/bsd/sys/signal.h#L76
pub const NSIG = 32;

pub const qos_class_t = enum(c_uint) {
    /// highest priority QOS class for critical tasks
    USER_INTERACTIVE = 0x21,
    /// slightly more moderate priority QOS class
    USER_INITIATED = 0x19,
    /// default QOS class when none is set
    DEFAULT = 0x15,
    /// more energy efficient QOS class than default
    UTILITY = 0x11,
    /// QOS class more appropriate for background tasks
    BACKGROUND = 0x09,
    /// QOS class as a return value
    UNSPECIFIED = 0x00,

    _,
};

/// Undocumented futex-like API available on darwin 16+
/// (macOS 10.12+, iOS 10.0+, tvOS 10.0+, watchOS 3.0+, catalyst 13.0+).
///
/// [ulock.h]: https://github.com/apple/darwin-xnu/blob/master/bsd/sys/ulock.h
/// [sys_ulock.c]: https://github.com/apple/darwin-xnu/blob/master/bsd/kern/sys_ulock.c
pub const UL = packed struct(u32) {
    op: Op,
    WAKE_ALL: bool = false,
    WAKE_THREAD: bool = false,
    _10: u6 = 0,
    WAIT_WORKQ_DATA_CONTENTION: bool = false,
    WAIT_CANCEL_POINT: bool = false,
    WAIT_ADAPTIVE_SPIN: bool = false,
    _19: u5 = 0,
    NO_ERRNO: bool = false,
    _: u7 = 0,

    pub const Op = enum(u8) {
        COMPARE_AND_WAIT = 1,
        UNFAIR_LOCK = 2,
        COMPARE_AND_WAIT_SHARED = 3,
        UNFAIR_LOCK64_SHARED = 4,
        COMPARE_AND_WAIT64 = 5,
        COMPARE_AND_WAIT64_SHARED = 6,
        _,
    };
};

pub extern "c" fn __ulock_wait2(op: UL, addr: ?*const anyopaque, val: u64, timeout_ns: u64, val2: u64) c_int;
pub extern "c" fn __ulock_wait(op: UL, addr: ?*const anyopaque, val: u64, timeout_us: u32) c_int;
pub extern "c" fn __ulock_wake(op: UL, addr: ?*const anyopaque, val: u64) c_int;

pub const os_unfair_lock_t = *os_unfair_lock;
pub const os_unfair_lock = extern struct {
    _os_unfair_lock_opaque: u32 = 0,
};

pub extern "c" fn os_unfair_lock_lock(o: os_unfair_lock_t) void;
pub extern "c" fn os_unfair_lock_unlock(o: os_unfair_lock_t) void;
pub extern "c" fn os_unfair_lock_trylock(o: os_unfair_lock_t) bool;
pub extern "c" fn os_unfair_lock_assert_owner(o: os_unfair_lock_t) void;
pub extern "c" fn os_unfair_lock_assert_not_owner(o: os_unfair_lock_t) void;

pub const os_signpost_id_t = enum(u64) {
    NULL = 0,
    INVALID = !0,
    EXCLUSIVE = 0xeeeeb0b5b2b2eeee,
    _,
};

pub const os_log_t = *opaque {};
pub const os_log_type_t = enum(u8) {
    /// default messages always captures
    DEFAULT = 0x00,
    /// messages with additional infos
    INFO = 0x01,
    /// debug messages
    DEBUG = 0x02,
    /// error messages
    ERROR = 0x10,
    /// unexpected conditions messages
    FAULT = 0x11,

    _,
};

pub extern "c" fn os_log_create(subsystem: [*]const u8, category: [*]const u8) os_log_t;
pub extern "c" fn os_log_type_enabled(log: os_log_t, tpe: os_log_type_t) bool;
pub extern "c" fn os_signpost_id_generate(log: os_log_t) os_signpost_id_t;
pub extern "c" fn os_signpost_interval_begin(log: os_log_t, signpos: os_signpost_id_t, func: [*]const u8, ...) void;
pub extern "c" fn os_signpost_interval_end(log: os_log_t, signpos: os_signpost_id_t, func: [*]const u8, ...) void;
pub extern "c" fn os_signpost_id_make_with_pointer(log: os_log_t, ptr: ?*anyopaque) os_signpost_id_t;
pub extern "c" fn os_signpost_enabled(log: os_log_t) bool;

pub extern "c" fn pthread_setname_np(name: [*:0]const u8) c_int;
pub extern "c" fn pthread_attr_set_qos_class_np(attr: *pthread_attr_t, qos_class: qos_class_t, relative_priority: c_int) c_int;
pub extern "c" fn pthread_attr_get_qos_class_np(attr: *pthread_attr_t, qos_class: *qos_class_t, relative_priority: *c_int) c_int;
pub extern "c" fn pthread_set_qos_class_self_np(qos_class: qos_class_t, relative_priority: c_int) c_int;
pub extern "c" fn pthread_get_qos_class_np(pthread: std.c.pthread_t, qos_class: *qos_class_t, relative_priority: *c_int) c_int;

pub const mach_timebase_info_data = extern struct {
    numer: u32,
    denom: u32,
};

pub const kevent64_s = extern struct {
    ident: u64,
    filter: i16,
    flags: u16,
    fflags: u32,
    data: i64,
    udata: u64,
    ext: [2]u64,
};

// sys/types.h on macos uses #pragma pack() so these checks are
// to make sure the struct is laid out the same. These values were
// produced from C code using the offsetof macro.
comptime {
    if (builtin.target.os.tag.isDarwin()) {
        assert(@offsetOf(kevent64_s, "ident") == 0);
        assert(@offsetOf(kevent64_s, "filter") == 8);
        assert(@offsetOf(kevent64_s, "flags") == 10);
        assert(@offsetOf(kevent64_s, "fflags") == 12);
        assert(@offsetOf(kevent64_s, "data") == 16);
        assert(@offsetOf(kevent64_s, "udata") == 24);
        assert(@offsetOf(kevent64_s, "ext") == 32);
    }
}

pub const clock_serv_t = mach_port_t;
pub const clock_res_t = c_int;
pub const mach_port_name_t = natural_t;
pub const natural_t = c_uint;
pub const mach_timespec_t = extern struct {
    sec: c_uint,
    nsec: clock_res_t,
};
pub const kern_return_t = c_int;
pub const host_t = mach_port_t;
pub const integer_t = c_int;
pub const task_flavor_t = natural_t;
pub const task_info_t = *integer_t;
pub const task_name_t = mach_port_name_t;
pub const vm_address_t = vm_offset_t;
pub const vm_size_t = mach_vm_size_t;
pub const vm_machine_attribute_t = usize;
pub const vm_machine_attribute_val_t = isize;

pub const CALENDAR_CLOCK = 1;

pub const SYSPROTO_EVENT = 1;
pub const SYSPROTO_CONTROL = 2;

/// Mach msg return values
pub const mach_msg_return_t = enum(kern_return_t) {
    SUCCESS = 0x00000000,

    /// Thread is waiting to send.  (Internal use only.)
    SEND_IN_PROGRESS = 0x10000001,
    /// Bogus in-line data.
    SEND_INVALID_DATA = 0x10000002,
    /// Bogus destination port.
    SEND_INVALID_DEST = 0x10000003,
    ///  Message not sent before timeout expired.
    SEND_TIMED_OUT = 0x10000004,
    ///  Bogus voucher port.
    SEND_INVALID_VOUCHER = 0x10000005,
    ///  Software interrupt.
    SEND_INTERRUPTED = 0x10000007,
    ///  Data doesn't contain a complete message.
    SEND_MSG_TOO_SMALL = 0x10000008,
    ///  Bogus reply port.
    SEND_INVALID_REPLY = 0x10000009,
    ///  Bogus port rights in the message body.
    SEND_INVALID_RIGHT = 0x1000000a,
    ///  Bogus notify port argument.
    SEND_INVALID_NOTIFY = 0x1000000b,
    ///  Invalid out-of-line memory pointer.
    SEND_INVALID_MEMORY = 0x1000000c,
    ///  No message buffer is available.
    SEND_NO_BUFFER = 0x1000000d,
    ///  Send is too large for port
    SEND_TOO_LARGE = 0x1000000e,
    ///  Invalid msg-type specification.
    SEND_INVALID_TYPE = 0x1000000f,
    ///  A field in the header had a bad value.
    SEND_INVALID_HEADER = 0x10000010,
    ///  The trailer to be sent does not match kernel format.
    SEND_INVALID_TRAILER = 0x10000011,
    ///  The sending thread context did not match the context on the dest port
    SEND_INVALID_CONTEXT = 0x10000012,
    ///  compatibility: no longer a returned error
    SEND_INVALID_RT_OOL_SIZE = 0x10000015,
    ///  The destination port doesn't accept ports in body
    SEND_NO_GRANT_DEST = 0x10000016,
    ///  Message send was rejected by message filter
    SEND_MSG_FILTERED = 0x10000017,

    ///  Thread is waiting for receive.  (Internal use only.)
    RCV_IN_PROGRESS = 0x10004001,
    ///  Bogus name for receive port/port-set.
    RCV_INVALID_NAME = 0x10004002,
    ///  Didn't get a message within the timeout value.
    RCV_TIMED_OUT = 0x10004003,
    ///  Message buffer is not large enough for inline data.
    RCV_TOO_LARGE = 0x10004004,
    ///  Software interrupt.
    RCV_INTERRUPTED = 0x10004005,
    ///  compatibility: no longer a returned error
    RCV_PORT_CHANGED = 0x10004006,
    ///  Bogus notify port argument.
    RCV_INVALID_NOTIFY = 0x10004007,
    ///  Bogus message buffer for inline data.
    RCV_INVALID_DATA = 0x10004008,
    ///  Port/set was sent away/died during receive.
    RCV_PORT_DIED = 0x10004009,
    ///  compatibility: no longer a returned error
    RCV_IN_SET = 0x1000400a,
    ///  Error receiving message header.  See special bits (use `extractResourceError`).
    RCV_HEADER_ERROR = 0x1000400b,
    ///  Error receiving message body.  See special bits (use `extractResourceError`).
    RCV_BODY_ERROR = 0x1000400c,
    ///  Invalid msg-type specification in scatter list.
    RCV_INVALID_TYPE = 0x1000400d,
    ///  Out-of-line overwrite region is not large enough
    RCV_SCATTER_SMALL = 0x1000400e,
    ///  trailer type or number of trailer elements not supported
    RCV_INVALID_TRAILER = 0x1000400f,
    ///  Waiting for receive with timeout. (Internal use only.)
    RCV_IN_PROGRESS_TIMED = 0x10004011,
    ///  invalid reply port used in a STRICT_REPLY message
    RCV_INVALID_REPLY = 0x10004012,

    _,

    pub fn extractResourceError(ret: mach_msg_return_t) struct {
        error_code: mach_msg_return_t,
        resource_error: ?MACH.MSG,
    } {
        const return_code: mach_msg_return_t = @enumFromInt(@intFromEnum(ret) & ~MACH.MSG.MASK);
        switch (return_code) {
            .RCV_HEADER_ERROR, .RCV_BODY_ERROR => {
                const resource_error: MACH.MSG = @bitCast(@intFromEnum(ret) & MACH.MSG.MASK);
                return .{
                    .error_code = return_code,
                    .resource_error = resource_error,
                };
            },
            else => return .{
                .error_code = ret,
                .resource_error = null,
            },
        }
    }
};

pub const FCNTL_FS_SPECIFIC_BASE = 0x00010000;

/// Max open files per process
/// https://opensource.apple.com/source/xnu/xnu-4903.221.2/bsd/sys/syslimits.h.auto.html
pub const OPEN_MAX = 10240;

// CPU families mapping
pub const CPUFAMILY = enum(u32) {
    UNKNOWN = 0,
    POWERPC_G3 = 0xcee41549,
    POWERPC_G4 = 0x77c184ae,
    POWERPC_G5 = 0xed76d8aa,
    INTEL_6_13 = 0xaa33392b,
    INTEL_PENRYN = 0x78ea4fbc,
    INTEL_NEHALEM = 0x6b5a4cd2,
    INTEL_WESTMERE = 0x573b5eec,
    INTEL_SANDYBRIDGE = 0x5490b78c,
    INTEL_IVYBRIDGE = 0x1f65e835,
    INTEL_HASWELL = 0x10b282dc,
    INTEL_BROADWELL = 0x582ed09c,
    INTEL_SKYLAKE = 0x37fc219f,
    INTEL_KABYLAKE = 0x0f817246,
    ARM_9 = 0xe73283ae,
    ARM_11 = 0x8ff620d8,
    ARM_XSCALE = 0x53b005f5,
    ARM_12 = 0xbd1b0ae9,
    ARM_13 = 0x0cc90e64,
    ARM_14 = 0x96077ef1,
    ARM_15 = 0xa8511bca,
    ARM_SWIFT = 0x1e2d6381,
    ARM_CYCLONE = 0x37a09642,
    ARM_TYPHOON = 0x2c91a47e,
    ARM_TWISTER = 0x92fb37c8,
    ARM_HURRICANE = 0x67ceee93,
    ARM_MONSOON_MISTRAL = 0xe81e7ef6,
    ARM_VORTEX_TEMPEST = 0x07d34b9f,
    ARM_LIGHTNING_THUNDER = 0x462504d2,
    ARM_FIRESTORM_ICESTORM = 0x1b588bb3,
    ARM_BLIZZARD_AVALANCHE = 0xda33d83d,
    ARM_EVEREST_SAWTOOTH = 0x8765edea,
    ARM_COLL = 0x2876f5b5,
    ARM_IBIZA = 0xfa33415e,
    ARM_LOBOS = 0x5f4dea93,
    ARM_PALMA = 0x72015832,
    ARM_DONAN = 0x6f5129ac,
    ARM_BRAVA = 0x17d5b93a,
    ARM_TAHITI = 0x75d4acb9,
    ARM_TUPAI = 0x204526d0,
    ARM_HIDRA = 0x1d5a87e8,
    ARM_SOTRA = 0xf76c5b1a,
    ARM_THERA = 0xab345f09,
    ARM_TILOS = 0x01d7a72b,
    _,
};

pub const PT = enum(c_int) {
    TRACE_ME = 0,
    READ_I = 1,
    READ_D = 2,
    READ_U = 3,
    WRITE_I = 4,
    WRITE_D = 5,
    WRITE_U = 6,
    CONTINUE = 7,
    KILL = 8,
    STEP = 9,
    DETACH = 11,
    SIGEXC = 12,
    THUPDATE = 13,
    ATTACHEXC = 14,
    FORCEQUOTA = 30,
    DENY_ATTACH = 31,
    _,
};

pub extern "c" fn ptrace(request: PT, pid: pid_t, addr: caddr_t, data: c_int) c_int;

pub const POSIX_SPAWN = packed struct(c_short) {
    RESETIDS: bool = false,
    SETPGROUP: bool = false,
    SETSIGDEF: bool = false,
    SETSIGMASK: bool = false,
    _4: u2 = 0,
    SETEXEC: bool = false,
    START_SUSPENDED: bool = false,
    DISABLE_ASLR: bool = false,
    _9: u1 = 0,
    SETSID: bool = false,
    RESLIDE: bool = false,
    _12: u2 = 0,
    CLOEXEC_DEFAULT: bool = false,
    _15: u1 = 0,
};

pub const posix_spawnattr_t = *opaque {};
pub const posix_spawn_file_actions_t = *opaque {};
pub extern "c" fn posix_spawnattr_init(attr: *posix_spawnattr_t) c_int;
pub extern "c" fn posix_spawnattr_destroy(attr: *posix_spawnattr_t) c_int;
pub extern "c" fn posix_spawnattr_setflags(attr: *posix_spawnattr_t, flags: POSIX_SPAWN) c_int;
pub extern "c" fn posix_spawnattr_getflags(attr: *const posix_spawnattr_t, flags: *POSIX_SPAWN) c_int;
pub extern "c" fn posix_spawn_file_actions_init(actions: *posix_spawn_file_actions_t) c_int;
pub extern "c" fn posix_spawn_file_actions_destroy(actions: *posix_spawn_file_actions_t) c_int;
pub extern "c" fn posix_spawn_file_actions_addclose(actions: *posix_spawn_file_actions_t, filedes: fd_t) c_int;
pub extern "c" fn posix_spawn_file_actions_addopen(
    actions: *posix_spawn_file_actions_t,
    filedes: fd_t,
    path: [*:0]const u8,
    oflag: c_int,
    mode: mode_t,
) c_int;
pub extern "c" fn posix_spawn_file_actions_adddup2(
    actions: *posix_spawn_file_actions_t,
    filedes: fd_t,
    newfiledes: fd_t,
) c_int;
pub extern "c" fn posix_spawn_file_actions_addinherit_np(actions: *posix_spawn_file_actions_t, filedes: fd_t) c_int;
pub extern "c" fn posix_spawn_file_actions_addchdir_np(actions: *posix_spawn_file_actions_t, path: [*:0]const u8) c_int;
pub extern "c" fn posix_spawn_file_actions_addfchdir_np(actions: *posix_spawn_file_actions_t, filedes: fd_t) c_int;
pub extern "c" fn posix_spawn(
    pid: *pid_t,
    path: [*:0]const u8,
    actions: ?*const posix_spawn_file_actions_t,
    attr: ?*const posix_spawnattr_t,
    argv: [*:null]const ?[*:0]const u8,
    env: [*:null]const ?[*:0]const u8,
) c_int;
pub extern "c" fn posix_spawnp(
    pid: *pid_t,
    path: [*:0]const u8,
    actions: ?*const posix_spawn_file_actions_t,
    attr: ?*const posix_spawnattr_t,
    argv: [*:null]const ?[*:0]const u8,
    env: [*:null]const ?[*:0]const u8,
) c_int;

pub const E = enum(u16) {
    /// No error occurred.
    SUCCESS = 0,
    /// Operation not permitted
    PERM = 1,
    /// No such file or directory
    NOENT = 2,
    /// No such process
    SRCH = 3,
    /// Interrupted system call
    INTR = 4,
    /// Input/output error
    IO = 5,
    /// Device not configured
    NXIO = 6,
    /// Argument list too long
    @"2BIG" = 7,
    /// Exec format error
    NOEXEC = 8,
    /// Bad file descriptor
    BADF = 9,
    /// No child processes
    CHILD = 10,
    /// Resource deadlock avoided
    DEADLK = 11,
    /// Cannot allocate memory
    NOMEM = 12,
    /// Permission denied
    ACCES = 13,
    /// Bad address
    FAULT = 14,
    /// Block device required
    NOTBLK = 15,
    /// Device / Resource busy
    BUSY = 16,
    /// File exists
    EXIST = 17,
    /// Cross-device link
    XDEV = 18,
    /// Operation not supported by device
    NODEV = 19,
    /// Not a directory
    NOTDIR = 20,
    /// Is a directory
    ISDIR = 21,
    /// Invalid argument
    INVAL = 22,
    /// Too many open files in system
    NFILE = 23,
    /// Too many open files
    MFILE = 24,
    /// Inappropriate ioctl for device
    NOTTY = 25,
    /// Text file busy
    TXTBSY = 26,
    /// File too large
    FBIG = 27,
    /// No space left on device
    NOSPC = 28,
    /// Illegal seek
    SPIPE = 29,
    /// Read-only file system
    ROFS = 30,
    /// Too many links
    MLINK = 31,
    /// Broken pipe
    PIPE = 32,
    // math software
    /// Numerical argument out of domain
    DOM = 33,
    /// Result too large
    RANGE = 34,
    // non-blocking and interrupt i/o
    /// Resource temporarily unavailable
    /// This is the same code used for `WOULDBLOCK`.
    AGAIN = 35,
    /// Operation now in progress
    INPROGRESS = 36,
    /// Operation already in progress
    ALREADY = 37,
    // ipc/network software -- argument errors
    /// Socket operation on non-socket
    NOTSOCK = 38,
    /// Destination address required
    DESTADDRREQ = 39,
    /// Message too long
    MSGSIZE = 40,
    /// Protocol wrong type for socket
    PROTOTYPE = 41,
    /// Protocol not available
    NOPROTOOPT = 42,
    /// Protocol not supported
    PROTONOSUPPORT = 43,
    /// Socket type not supported
    SOCKTNOSUPPORT = 44,
    /// Operation not supported
    /// The same code is used for `NOTSUP`.
    OPNOTSUPP = 45,
    /// Protocol family not supported
    PFNOSUPPORT = 46,
    /// Address family not supported by protocol family
    AFNOSUPPORT = 47,
    /// Address already in use
    ADDRINUSE = 48,
    /// Can't assign requested address
    // ipc/network software -- operational errors
    ADDRNOTAVAIL = 49,
    /// Network is down
    NETDOWN = 50,
    /// Network is unreachable
    NETUNREACH = 51,
    /// Network dropped connection on reset
    NETRESET = 52,
    /// Software caused connection abort
    CONNABORTED = 53,
    /// Connection reset by peer
    CONNRESET = 54,
    /// No buffer space available
    NOBUFS = 55,
    /// Socket is already connected
    ISCONN = 56,
    /// Socket is not connected
    NOTCONN = 57,
    /// Can't send after socket shutdown
    SHUTDOWN = 58,
    /// Too many references: can't splice
    TOOMANYREFS = 59,
    /// Operation timed out
    TIMEDOUT = 60,
    /// Connection refused
    CONNREFUSED = 61,
    /// Too many levels of symbolic links
    LOOP = 62,
    /// File name too long
    NAMETOOLONG = 63,
    /// Host is down
    HOSTDOWN = 64,
    /// No route to host
    HOSTUNREACH = 65,
    /// Directory not empty
    // quotas & mush
    NOTEMPTY = 66,
    /// Too many processes
    PROCLIM = 67,
    /// Too many users
    USERS = 68,
    /// Disc quota exceeded
    // Network File System
    DQUOT = 69,
    /// Stale NFS file handle
    STALE = 70,
    /// Too many levels of remote in path
    REMOTE = 71,
    /// RPC struct is bad
    BADRPC = 72,
    /// RPC version wrong
    RPCMISMATCH = 73,
    /// RPC prog. not avail
    PROGUNAVAIL = 74,
    /// Program version wrong
    PROGMISMATCH = 75,
    /// Bad procedure for program
    PROCUNAVAIL = 76,
    /// No locks available
    NOLCK = 77,
    /// Function not implemented
    NOSYS = 78,
    /// Inappropriate file type or format
    FTYPE = 79,
    /// Authentication error
    AUTH = 80,
    /// Need authenticator
    NEEDAUTH = 81,
    // Intelligent device errors
    /// Device power is off
    PWROFF = 82,
    /// Device error, e.g. paper out
    DEVERR = 83,
    /// Value too large to be stored in data type
    OVERFLOW = 84,
    // Program loading errors
    /// Bad executable
    BADEXEC = 85,
    /// Bad CPU type in executable
    BADARCH = 86,
    /// Shared library version mismatch
    SHLIBVERS = 87,
    /// Malformed Macho file
    BADMACHO = 88,
    /// Operation canceled
    CANCELED = 89,
    /// Identifier removed
    IDRM = 90,
    /// No message of desired type
    NOMSG = 91,
    /// Illegal byte sequence
    ILSEQ = 92,
    /// Attribute not found
    NOATTR = 93,
    /// Bad message
    BADMSG = 94,
    /// Reserved
    MULTIHOP = 95,
    /// No message available on STREAM
    NODATA = 96,
    /// Reserved
    NOLINK = 97,
    /// No STREAM resources
    NOSR = 98,
    /// Not a STREAM
    NOSTR = 99,
    /// Protocol error
    PROTO = 100,
    /// STREAM ioctl timeout
    TIME = 101,
    /// No such policy registered
    NOPOLICY = 103,
    /// State not recoverable
    NOTRECOVERABLE = 104,
    /// Previous owner died
    OWNERDEAD = 105,
    /// Interface output queue is full
    QFULL = 106,
    /// Capabilities insufficient
    NOTCAPABLE = 107,
    _,
};

/// From Common Security Services Manager
/// Security.framework/Headers/cssm*.h
pub const DB_RECORDTYPE = enum(u32) {
    // Record Types defined in the Schema Management Name Space
    SCHEMA_INFO = SCHEMA_START + 0,
    SCHEMA_INDEXES = SCHEMA_START + 1,
    SCHEMA_ATTRIBUTES = SCHEMA_START + 2,
    SCHEMA_PARSING_MODULE = SCHEMA_START + 3,

    // Record Types defined in the Open Group Application Name Space
    ANY = OPEN_GROUP_START + 0,
    CERT = OPEN_GROUP_START + 1,
    CRL = OPEN_GROUP_START + 2,
    POLICY = OPEN_GROUP_START + 3,
    GENERIC = OPEN_GROUP_START + 4,
    PUBLIC_KEY = OPEN_GROUP_START + 5,
    PRIVATE_KEY = OPEN_GROUP_START + 6,
    SYMMETRIC_KEY = OPEN_GROUP_START + 7,
    ALL_KEYS = OPEN_GROUP_START + 8,

    // AppleFileDL record types
    GENERIC_PASSWORD = APP_DEFINED_START + 0,
    INTERNET_PASSWORD = APP_DEFINED_START + 1,
    APPLESHARE_PASSWORD = APP_DEFINED_START + 2,

    X509_CERTIFICATE = APP_DEFINED_START + 0x1000,
    USER_TRUST,
    X509_CRL,
    UNLOCK_REFERRAL,
    EXTENDED_ATTRIBUTE,
    METADATA = APP_DEFINED_START + 0x8000,

    _,

    // Schema Management Name Space Range Definition
    pub const SCHEMA_START = 0x00000000;
    pub const SCHEMA_END = SCHEMA_START + 4;

    // Open Group Application Name Space Range Definition
    pub const OPEN_GROUP_START = 0x0000000A;
    pub const OPEN_GROUP_END = OPEN_GROUP_START + 8;

    // Industry At Large Application Name Space Range Definition
    pub const APP_DEFINED_START = 0x80000000;
    pub const APP_DEFINED_END = 0xffffffff;
};

pub const TCP = struct {
    /// Turn off Nagle's algorithm
    pub const NODELAY = 0x01;
    /// Limit MSS
    pub const MAXSEG = 0x02;
    /// Don't push last block of write
    pub const NOPUSH = 0x04;
    /// Don't use TCP options
    pub const NOOPT = 0x08;
    /// Idle time used when SO_KEEPALIVE is enabled
    pub const KEEPALIVE = 0x10;
    /// Connection timeout
    pub const CONNECTIONTIMEOUT = 0x20;
    /// Time after which a conection in persist timeout will terminate.
    pub const PERSIST_TIMEOUT = 0x40;
    /// Time after which TCP retransmissions will be stopped and the connection will be dropped.
    pub const RXT_CONNDROPTIME = 0x80;
    /// Drop a connection after retransmitting the FIN 3 times.
    pub const RXT_FINDROP = 0x100;
    /// Interval between keepalives
    pub const KEEPINTVL = 0x101;
    /// Number of keepalives before clsoe
    pub const KEEPCNT = 0x102;
    /// Always ack every other packet
    pub const SENDMOREACKS = 0x103;
    /// Enable ECN on a connection
    pub const ENABLE_ECN = 0x104;
    /// Enable/Disable TCP Fastopen on this socket
    pub const FASTOPEN = 0x105;
    /// State of the TCP connection
    pub const CONNECTION_INFO = 0x106;
};

pub const MSG = struct {
    /// process out-of-band data
    pub const OOB = 0x1;
    /// peek at incoming message
    pub const PEEK = 0x2;
    /// send without using routing tables
    pub const DONTROUTE = 0x4;
    /// data completes record
    pub const EOR = 0x8;
    /// data discarded before delivery
    pub const TRUNC = 0x10;
    /// control data lost before delivery
    pub const CTRUNC = 0x20;
    /// wait for full request or error
    pub const WAITALL = 0x40;
    /// this message should be nonblocking
    pub const DONTWAIT = 0x80;
    /// data completes connection
    pub const EOF = 0x100;
    /// wait up to full request, may return partial
    pub const WAITSTREAM = 0x200;
    /// Start of 'hold' seq; dump so_temp, deprecated
    pub const FLUSH = 0x400;
    /// Hold frag in so_temp, deprecated
    pub const HOLD = 0x800;
    /// Send the packet in so_temp, deprecated
    pub const SEND = 0x1000;
    /// Data ready to be read
    pub const HAVEMORE = 0x2000;
    /// Data remains in current pkt
    pub const RCVMORE = 0x4000;
    /// Fail receive if socket address cannot be allocated
    pub const NEEDSA = 0x10000;
    /// do not generate SIGPIPE on EOF
    pub const NOSIGNAL = 0x80000;
    /// Inherit upcall in sock_accept
    pub const USEUPCALL = 0x80000000;
};

// https://github.com/apple/darwin-xnu/blob/2ff845c2e033bd0ff64b5b6aa6063a1f8f65aa32/bsd/netinet/in.h#L454
pub const IP = struct {
    pub const OPTIONS = 1;
    pub const HDRINCL = 2;
    pub const TOS = 3;
    pub const TTL = 4;
    pub const RECVOPTS = 5;
    pub const RECVRETOPTS = 6;
    pub const RECVDSTADDR = 7;
    pub const RETOPTS = 8;
    pub const MULTICAST_IF = 9;
    pub const MULTICAST_TTL = 10;
    pub const MULTICAST_LOOP = 11;
    pub const ADD_MEMBERSHIP = 12;
    pub const DROP_MEMBERSHIP = 13;
    pub const MULTICAST_VIF = 14;
    pub const RSVP_ON = 15;
    pub const RSVP_OFF = 16;
    pub const RSVP_VIF_ON = 17;
    pub const RSVP_VIF_OFF = 18;
    pub const PORTRANGE = 19;
    pub const RECVIF = 20;
    pub const IPSEC_POLICY = 21;
    pub const FAITH = 22;
    pub const STRIPHDR = 23;
    pub const RECVTTL = 24;
    pub const BOUND_IF = 25;
    pub const PKTINFO = 26;
    pub const RECVPKTINFO = PKTINFO;
    pub const RECVTOS = 27;
    pub const DONTFRAG = 28;
    pub const FW_ADD = 40;
    pub const FW_DEL = 41;
    pub const FW_FLUSH = 42;
    pub const FW_ZERO = 43;
    pub const FW_GET = 44;
    pub const FW_RESETLOG = 45;
    pub const OLD_FW_ADD = 50;
    pub const OLD_FW_DEL = 51;
    pub const OLD_FW_FLUSH = 52;
    pub const OLD_FW_ZERO = 53;
    pub const OLD_FW_GET = 54;
    pub const OLD_FW_RESETLOG = 56;
    pub const DUMMYNET_CONFIGURE = 60;
    pub const DUMMYNET_DEL = 61;
    pub const DUMMYNET_FLUSH = 62;
    pub const DUMMYNET_GET = 64;
    pub const TRAFFIC_MGT_BACKGROUND = 65;
    pub const MULTICAST_IFINDEX = 66;
    pub const ADD_SOURCE_MEMBERSHIP = 70;
    pub const DROP_SOURCE_MEMBERSHIP = 71;
    pub const BLOCK_SOURCE = 72;
    pub const UNBLOCK_SOURCE = 73;
    pub const MSFILTER = 74;
    // Same namespace, but these are arguments rather than option names
    pub const DEFAULT_MULTICAST_TTL = 1;
    pub const DEFAULT_MULTICAST_LOOP = 1;
    pub const MIN_MEMBERSHIPS = 31;
    pub const MAX_MEMBERSHIPS = 4095;
    pub const MAX_GROUP_SRC_FILTER = 512;
    pub const MAX_SOCK_SRC_FILTER = 128;
    pub const MAX_SOCK_MUTE_FILTER = 128;
    pub const PORTRANGE_DEFAULT = 0;
    pub const PORTRANGE_HIGH = 1;
    pub const PORTRANGE_LOW = 2;
};

// https://github.com/apple/darwin-xnu/blob/2ff845c2e033bd0ff64b5b6aa6063a1f8f65aa32/bsd/netinet6/in6.h#L521
pub const IPV6 = struct {
    pub const UNICAST_HOPS = 4;
    pub const MULTICAST_IF = 9;
    pub const MULTICAST_HOPS = 10;
    pub const MULTICAST_LOOP = 11;
    pub const JOIN_GROUP = 12;
    pub const LEAVE_GROUP = 13;
    pub const PORTRANGE = 14;
    pub const @"2292PKTINFO" = 19;
    pub const @"2292HOPLIMIT" = 20;
    pub const @"2292NEXTHOP" = 21;
    pub const @"2292HOPOPTS" = 22;
    pub const @"2292DSTOPTS" = 23;
    pub const @"2292RTHDR" = 24;
    pub const @"2292PKTOPTIONS" = 25;
    pub const CHECKSUM = 26;
    pub const V6ONLY = 27;
    pub const BINDV6ONLY = V6ONLY;
    pub const IPSEC_POLICY = 28;
    pub const FAITH = 29;
    pub const FW_ADD = 30;
    pub const FW_DEL = 31;
    pub const FW_FLUSH = 32;
    pub const FW_ZERO = 33;
    pub const FW_GET = 34;
    pub const RECVTCLASS = 35;
    pub const TCLASS = 36;
    pub const RTHDRDSTOPTS = 57;
    pub const RECVPKTINFO = 61;
    pub const RECVHOPLIMIT = 37;
    pub const RECVRTHDR = 38;
    pub const RECVHOPOPTS = 39;
    pub const RECVDSTOPTS = 40;
    pub const RECVRTHDRDSTOPTS = 41;
    pub const USE_MIN_MTU = 42;
    pub const RECVPATHMTU = 43;
    pub const PATHMTU = 44;
    pub const REACHCONF = 45;
    pub const @"3542PKTINFO" = 46;
    pub const @"3542HOPLIMIT" = 47;
    pub const @"3542NEXTHOP" = 48;
    pub const @"3542HOPOPTS" = 49;
    pub const @"3542DSTOPTS" = 50;
    pub const @"3542RTHDR" = 51;
    pub const PKTINFO = @"3542PKTINFO";
    pub const HOPLIMIT = @"3542HOPLIMIT";
    pub const NEXTHOP = @"3542NEXTHOP";
    pub const HOPOPTS = @"3542HOPOPTS";
    pub const DSTOPTS = @"3542DSTOPTS";
    pub const RTHDR = @"3542RTHDR";
    pub const AUTOFLOWLABEL = 59;
    pub const DONTFRAG = 62;
    pub const PREFER_TEMPADDR = 63;
    pub const MSFILTER = 74;
    pub const BOUND_IF = 125;
    // Same namespace, but these are arguments rather than option names
    pub const RTHDR_LOOSE = 0;
    pub const RTHDR_STRICT = 1;
    pub const RTHDR_TYPE_0 = 0;
    pub const DEFAULT_MULTICAST_HOPS = 1;
    pub const DEFAULT_MULTICAST_LOOP = 1;
    pub const MIN_MEMBERSHIPS = 31;
    pub const MAX_MEMBERSHIPS = 4095;
    pub const MAX_GROUP_SRC_FILTER = 512;
    pub const MAX_SOCK_SRC_FILTER = 128;
    pub const PORTRANGE_DEFAULT = 0;
    pub const PORTRANGE_HIGH = 1;
    pub const PORTRANGE_LOW = 2;
};

// https://github.com/apple/darwin-xnu/blob/2ff845c2e033bd0ff64b5b6aa6063a1f8f65aa32/bsd/netinet/ip.h#L129
pub const IPTOS = struct {
    pub const LOWDELAY = 0x10;
    pub const THROUGHPUT = 0x08;
    pub const RELIABILITY = 0x04;
    pub const MINCOST = 0x02;
    pub const CE = 0x01;
    pub const ECT = 0x02;
    pub const DSCP_SHIFT = 2;
    pub const ECN_NOTECT = 0x00;
    pub const ECN_ECT1 = 0x01;
    pub const ECN_ECT0 = 0x02;
    pub const ECN_CE = 0x03;
    pub const ECN_MASK = 0x03;
    pub const PREC_NETCONTROL = 0xe0;
    pub const PREC_INTERNETCONTROL = 0xc0;
    pub const PREC_CRITIC_ECP = 0xa0;
    pub const PREC_FLASHOVERRIDE = 0x80;
    pub const PREC_FLASH = 0x60;
    pub const PREC_IMMEDIATE = 0x40;
    pub const PREC_PRIORITY = 0x20;
    pub const PREC_ROUTINE = 0x00;
};
