zig/lib/std / c/darwin.zig

const std = @import("../std.zig");
const builtin = @import("builtin");
const assert = std.debug.assert;
const macho = std.macho;
const native_arch = builtin.target.cpu.arch;
const maxInt = std.math.maxInt;
const iovec_const = std.os.iovec_const;

aarch64

darwin/aarch64.zig
pub const aarch64 = @import("darwin/aarch64.zig");

x86_64

darwin/x86_64.zig
pub const x86_64 = @import("darwin/x86_64.zig");

cssm

darwin/cssm.zig
pub const cssm = @import("darwin/cssm.zig");

const arch_bits = switch (native_arch) {
    .aarch64 => @import("darwin/aarch64.zig"),
    .x86_64 => @import("darwin/x86_64.zig"),
    else => struct {},
};

EXC_TYPES_COUNT

pub const EXC_TYPES_COUNT = arch_bits.EXC_TYPES_COUNT;

THREAD_STATE_NONE

pub const THREAD_STATE_NONE = arch_bits.THREAD_STATE_NONE;

EXC

pub const EXC = enum(exception_type_t) {
    NULL = 0,
    BAD_ACCESS = 1,
    BAD_INSTRUCTION = 2,
    ARITHMETIC = 3,
    EMULATION = 4,
    SOFTWARE = 5,
    BREAKPOINT = 6,
    SYSCALL = 7,
    MACH_SYSCALL = 8,
    RPC_ALERT = 9,
    CRASH = 10,
    RESOURCE = 11,
    GUARD = 12,
    CORPSE_NOTIFY = 13,
};

EXC_SOFT_SIGNAL

Could not access memory Instruction failed Arithmetic exception Emulation instruction Software generated exception Trace, breakpoint, etc. System calls. Mach system calls. RPC alert Abnormal process exit Hit resource consumption limit Violated guarded resource protections Abnormal process exited to corpse state

pub const EXC_SOFT_SIGNAL = 0x10003;

EXC_MASK_BAD_ACCESS

pub const EXC_MASK_BAD_ACCESS = 1 << @intFromEnum(EXC.BAD_ACCESS);

EXC_MASK_BAD_INSTRUCTION

pub const EXC_MASK_BAD_INSTRUCTION = 1 << @intFromEnum(EXC.BAD_INSTRUCTION);

EXC_MASK_ARITHMETIC

pub const EXC_MASK_ARITHMETIC = 1 << @intFromEnum(EXC.ARITHMETIC);

EXC_MASK_EMULATION

pub const EXC_MASK_EMULATION = 1 << @intFromEnum(EXC.EMULATION);

EXC_MASK_SOFTWARE

pub const EXC_MASK_SOFTWARE = 1 << @intFromEnum(EXC.SOFTWARE);

EXC_MASK_BREAKPOINT

pub const EXC_MASK_BREAKPOINT = 1 << @intFromEnum(EXC.BREAKPOINT);

EXC_MASK_SYSCALL

pub const EXC_MASK_SYSCALL = 1 << @intFromEnum(EXC.SYSCALL);

EXC_MASK_MACH_SYSCALL

pub const EXC_MASK_MACH_SYSCALL = 1 << @intFromEnum(EXC.MACH_SYSCALL);

EXC_MASK_RPC_ALERT

pub const EXC_MASK_RPC_ALERT = 1 << @intFromEnum(EXC.RPC_ALERT);

EXC_MASK_CRASH

pub const EXC_MASK_CRASH = 1 << @intFromEnum(EXC.CRASH);

EXC_MASK_RESOURCE

pub const EXC_MASK_RESOURCE = 1 << @intFromEnum(EXC.RESOURCE);

EXC_MASK_GUARD

pub const EXC_MASK_GUARD = 1 << @intFromEnum(EXC.GUARD);

EXC_MASK_CORPSE_NOTIFY

pub const EXC_MASK_CORPSE_NOTIFY = 1 << @intFromEnum(EXC.CORPSE_NOTIFY);

EXC_MASK_MACHINE

pub const EXC_MASK_MACHINE = arch_bits.EXC_MASK_MACHINE;

EXC_MASK_ALL

pub const EXC_MASK_ALL = EXC_MASK_BAD_ACCESS |
    EXC_MASK_BAD_INSTRUCTION |
    EXC_MASK_ARITHMETIC |
    EXC_MASK_EMULATION |
    EXC_MASK_SOFTWARE |
    EXC_MASK_BREAKPOINT |
    EXC_MASK_SYSCALL |
    EXC_MASK_MACH_SYSCALL |
    EXC_MASK_RPC_ALERT |
    EXC_MASK_RESOURCE |
    EXC_MASK_GUARD |
    EXC_MASK_MACHINE;

EXCEPTION_DEFAULT

Send a catch_exception_raise message including the identity.

pub const EXCEPTION_DEFAULT = 1;

EXCEPTION_STATE

Send a catch_exception_raise_state message including the thread state.

pub const EXCEPTION_STATE = 2;

EXCEPTION_STATE_IDENTITY

Send a catch_exception_raise_state_identity message including the thread identity and state.

pub const EXCEPTION_STATE_IDENTITY = 3;

EXCEPTION_IDENTITY_PROTECTED

Send a catch_exception_raise_identity_protected message including protected task and thread identity.

pub const EXCEPTION_IDENTITY_PROTECTED = 4;

MACH_EXCEPTION_BACKTRACE_PREFERRED

Prefer sending a catch_exception_raice_backtrace message, if applicable.

pub const MACH_EXCEPTION_BACKTRACE_PREFERRED = 0x20000000;

MACH_EXCEPTION_ERRORS

include additional exception specific errors, not used yet.

pub const MACH_EXCEPTION_ERRORS = 0x40000000;

MACH_EXCEPTION_CODES

Send 64-bit code and subcode in the exception header */

pub const MACH_EXCEPTION_CODES = 0x80000000;

MACH_EXCEPTION_MASK

pub const MACH_EXCEPTION_MASK = MACH_EXCEPTION_CODES |
    MACH_EXCEPTION_ERRORS |
    MACH_EXCEPTION_BACKTRACE_PREFERRED;

TASK_NULL

pub const TASK_NULL: task_t = 0;

THREAD_NULL

pub const THREAD_NULL: thread_t = 0;

MACH_PORT_NULL

pub const MACH_PORT_NULL: mach_port_t = 0;

MACH_MSG_TIMEOUT_NONE

pub const MACH_MSG_TIMEOUT_NONE: mach_msg_timeout_t = 0;

MACH_MSG_OPTION_NONE

pub const MACH_MSG_OPTION_NONE = 0x00000000;

MACH_SEND_MSG

pub const MACH_SEND_MSG = 0x00000001;

MACH_RCV_MSG

pub const MACH_RCV_MSG = 0x00000002;

MACH_RCV_LARGE

pub const MACH_RCV_LARGE = 0x00000004;

MACH_RCV_LARGE_IDENTITY

pub const MACH_RCV_LARGE_IDENTITY = 0x00000008;

MACH_SEND_TIMEOUT

pub const MACH_SEND_TIMEOUT = 0x00000010;

MACH_SEND_OVERRIDE

pub const MACH_SEND_OVERRIDE = 0x00000020;

MACH_SEND_INTERRUPT

pub const MACH_SEND_INTERRUPT = 0x00000040;

MACH_SEND_NOTIFY

pub const MACH_SEND_NOTIFY = 0x00000080;

MACH_SEND_ALWAYS

pub const MACH_SEND_ALWAYS = 0x00010000;

MACH_SEND_FILTER_NONFATAL

pub const MACH_SEND_FILTER_NONFATAL = 0x00010000;

MACH_SEND_TRAILER

pub const MACH_SEND_TRAILER = 0x00020000;

MACH_SEND_NOIMPORTANCE

pub const MACH_SEND_NOIMPORTANCE = 0x00040000;

MACH_SEND_NODENAP

pub const MACH_SEND_NODENAP = MACH_SEND_NOIMPORTANCE;

MACH_SEND_IMPORTANCE

pub const MACH_SEND_IMPORTANCE = 0x00080000;

MACH_SEND_SYNC_OVERRIDE

pub const MACH_SEND_SYNC_OVERRIDE = 0x00100000;

MACH_SEND_PROPAGATE_QOS

pub const MACH_SEND_PROPAGATE_QOS = 0x00200000;

MACH_SEND_SYNC_USE_THRPRI

pub const MACH_SEND_SYNC_USE_THRPRI = MACH_SEND_PROPAGATE_QOS;

MACH_SEND_KERNEL

pub const MACH_SEND_KERNEL = 0x00400000;

MACH_SEND_SYNC_BOOTSTRAP_CHECKIN

pub const MACH_SEND_SYNC_BOOTSTRAP_CHECKIN = 0x00800000;

MACH_RCV_TIMEOUT

pub const MACH_RCV_TIMEOUT = 0x00000100;

MACH_RCV_NOTIFY

pub const MACH_RCV_NOTIFY = 0x00000000;

MACH_RCV_INTERRUPT

pub const MACH_RCV_INTERRUPT = 0x00000400;

MACH_RCV_VOUCHER

pub const MACH_RCV_VOUCHER = 0x00000800;

MACH_RCV_OVERWRITE

pub const MACH_RCV_OVERWRITE = 0x00000000;

MACH_RCV_GUARDED_DESC

pub const MACH_RCV_GUARDED_DESC = 0x00001000;

MACH_RCV_SYNC_WAIT

pub const MACH_RCV_SYNC_WAIT = 0x00004000;

MACH_RCV_SYNC_PEEK

pub const MACH_RCV_SYNC_PEEK = 0x00008000;

MACH_MSG_STRICT_REPLY

pub const MACH_MSG_STRICT_REPLY = 0x00000200;

ucontext_t

pub const ucontext_t = extern struct {
    onstack: c_int,
    sigmask: sigset_t,
    stack: stack_t,
    link: ?*ucontext_t,
    mcsize: u64,
    mcontext: *mcontext_t,
    __mcontext_data: mcontext_t,
};

mcontext_t

pub const mcontext_t = arch_bits.mcontext_t;

extern "c" fn __error() *c_int;
pub extern "c" fn NSVersionOfRunTimeLibrary(library_name: [*:0]const u8) u32;
pub extern "c" fn _NSGetExecutablePath(buf: [*:0]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;

COPYFILE_ACL

pub const COPYFILE_ACL = 1 << 0;

COPYFILE_STAT

pub const COPYFILE_STAT = 1 << 1;

COPYFILE_XATTR

pub const COPYFILE_XATTR = 1 << 2;

COPYFILE_DATA

pub const COPYFILE_DATA = 1 << 3;

copyfile_state_t

pub const copyfile_state_t = *opaque {};
pub extern "c" fn fcopyfile(from: fd_t, to: fd_t, state: ?copyfile_state_t, flags: u32) c_int;

pub extern "c" fn @"realpath$DARWIN_EXTSN"(noalias file_name: [*:0]const u8, noalias resolved_name: [*]u8) ?[*:0]u8;

realpath

pub const realpath = @"realpath$DARWIN_EXTSN";

pub extern "c" fn __getdirentries64(fd: c_int, buf_ptr: [*]u8, buf_len: usize, basep: *i64) isize;

const private = struct {
    extern "c" fn fstat(fd: fd_t, buf: *Stat) c_int;
    extern "c" fn @"fstat$INODE64"(fd: fd_t, buf: *Stat) c_int;

    extern "c" fn fstatat(dirfd: fd_t, path: [*:0]const u8, stat_buf: *Stat, flags: u32) c_int;
    extern "c" fn @"fstatat$INODE64"(dirfd: fd_t, path_name: [*:0]const u8, buf: *Stat, flags: u32) c_int;

    extern "c" fn readdir(dir: *std.c.DIR) ?*dirent;
    extern "c" fn @"readdir$INODE64"(dir: *std.c.DIR) ?*dirent;
};

fstat

On x86_64 Darwin, fstat has to be manually linked with $INODE64 suffix to force 64bit version. Note that this is fixed on aarch64 and no longer necessary. On x86_64 Darwin, fstatat has to be manually linked with $INODE64 suffix to force 64bit version. Note that this is fixed on aarch64 and no longer necessary.

pub const fstat = if (native_arch == .aarch64) private.fstat else private.@"fstat$INODE64";

fstatat

pub const fstatat = if (native_arch == .aarch64) private.fstatat else private.@"fstatat$INODE64";

readdir

pub const readdir = if (native_arch == .aarch64) private.readdir else private.@"readdir$INODE64";

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 malloc_size(?*const anyopaque) usize;
pub extern "c" fn posix_memalign(memptr: *?*anyopaque, alignment: usize, size: usize) c_int;

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

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

var dummy_execute_header: mach_hdr = undefined;
pub extern var _mh_execute_header: mach_hdr;
comptime {
    if (builtin.target.isDarwin()) {
        @export(dummy_execute_header, .{ .name = "_mh_execute_header", .linkage = .Weak });
    }
}

mach_header_64

The value of the link editor defined symbol _MH_EXECUTE_SYM is the address of the mach header in a Mach-O executable file type. It does not appear in any file type other than a MH_EXECUTE file type. The type of the symbol is absolute as the header is not part of any section. This symbol is populated when linking the system's libc, which is guaranteed on this operating system. However when building object files or libraries, the system libc won't be linked until the final executable. So we export a weak symbol here, to be overridden by the real one.

pub const mach_header_64 = macho.mach_header_64;

mach_header

pub const mach_header = macho.mach_header;

_errno

pub const _errno = __error;

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;

exception_type_t

pub const exception_type_t = c_int;

exception_data_type_t

pub const exception_data_type_t = integer_t;

exception_data_t

pub const exception_data_t = ?*mach_exception_data_type_t;

mach_exception_data_type_t

pub const mach_exception_data_type_t = i64;

mach_exception_data_t

pub const mach_exception_data_t = ?*mach_exception_data_type_t;

vm_map_t

pub const vm_map_t = mach_port_t;

vm_map_read_t

pub const vm_map_read_t = mach_port_t;

vm_region_flavor_t

pub const vm_region_flavor_t = c_int;

vm_region_info_t

pub const vm_region_info_t = *c_int;

vm_region_recurse_info_t

pub const vm_region_recurse_info_t = *c_int;

mach_vm_address_t

pub const mach_vm_address_t = usize;

vm_offset_t

pub const vm_offset_t = usize;

mach_vm_size_t

pub const mach_vm_size_t = u64;

mach_msg_bits_t

pub const mach_msg_bits_t = c_uint;

mach_msg_id_t

pub const mach_msg_id_t = integer_t;

mach_msg_type_number_t

pub const mach_msg_type_number_t = natural_t;

mach_msg_type_name_t

pub const mach_msg_type_name_t = c_uint;

mach_msg_option_t

pub const mach_msg_option_t = integer_t;

mach_msg_size_t

pub const mach_msg_size_t = natural_t;

mach_msg_timeout_t

pub const mach_msg_timeout_t = natural_t;

mach_port_right_t

pub const mach_port_right_t = natural_t;

task_t

pub const task_t = mach_port_t;

thread_port_t

pub const thread_port_t = task_t;

thread_t

pub const thread_t = thread_port_t;

exception_mask_t

pub const exception_mask_t = c_uint;

exception_mask_array_t

pub const exception_mask_array_t = [*]exception_mask_t;

exception_handler_t

pub const exception_handler_t = mach_port_t;

exception_handler_array_t

pub const exception_handler_array_t = [*]exception_handler_t;

exception_port_t

pub const exception_port_t = exception_handler_t;

exception_port_array_t

pub const exception_port_array_t = exception_handler_array_t;

exception_flavor_array_t

pub const exception_flavor_array_t = [*]thread_state_flavor_t;

exception_behavior_t

pub const exception_behavior_t = c_uint;

exception_behavior_array_t

pub const exception_behavior_array_t = [*]exception_behavior_t;

thread_state_flavor_t

pub const thread_state_flavor_t = c_int;

ipc_space_t

pub const ipc_space_t = mach_port_t;

ipc_space_port_t

pub const ipc_space_port_t = ipc_space_t;

MACH_PORT_RIGHT

pub const MACH_PORT_RIGHT = enum(mach_port_right_t) {
    SEND = 0,
    RECEIVE = 1,
    SEND_ONCE = 2,
    PORT_SET = 3,
    DEAD_NAME = 4,
    LABELH = 5,
    NUMBER = 6,
};

MACH_MSG_TYPE

Obsolete right Right not implemented

pub const MACH_MSG_TYPE = enum(mach_msg_type_name_t) {
    MOVE_RECEIVE = 16,

    MOVE_SEND = 17,

    MOVE_SEND_ONCE = 18,

    COPY_SEND = 19,

    MAKE_SEND = 20,

    MAKE_SEND_ONCE = 21,

    COPY_RECEIVE = 22,

    DISPOSE_RECEIVE = 24,

    DISPOSE_SEND = 25,

    DISPOSE_SEND_ONCE = 26,
};

extern "c" var mach_task_self_: mach_port_t;

mach_task_self()

Must hold receive right Must hold send right(s) Must hold sendonce right Must hold send right(s) Must hold receive right Must hold receive right NOT VALID Must hold receive right Must hold send right(s) Must hold sendonce right

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,
) kern_return_t;

mach_msg_header_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;

task_read_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;

vm_inherit_t

pub const vm_inherit_t = u32;

memory_object_offset_t

pub const memory_object_offset_t = u64;

vm_behavior_t

pub const vm_behavior_t = i32;

vm32_object_id_t

pub const vm32_object_id_t = u32;

vm_object_id_t

pub const vm_object_id_t = u64;

VM_INHERIT_SHARE

pub const VM_INHERIT_SHARE: vm_inherit_t = 0;

VM_INHERIT_COPY

pub const VM_INHERIT_COPY: vm_inherit_t = 1;

VM_INHERIT_NONE

pub const VM_INHERIT_NONE: vm_inherit_t = 2;

VM_INHERIT_DONATE_COPY

pub const VM_INHERIT_DONATE_COPY: vm_inherit_t = 3;

VM_INHERIT_DEFAULT

pub const VM_INHERIT_DEFAULT = VM_INHERIT_COPY;

VM_BEHAVIOR_DEFAULT

pub const VM_BEHAVIOR_DEFAULT: vm_behavior_t = 0;

VM_BEHAVIOR_RANDOM

pub const VM_BEHAVIOR_RANDOM: vm_behavior_t = 1;

VM_BEHAVIOR_SEQUENTIAL

pub const VM_BEHAVIOR_SEQUENTIAL: vm_behavior_t = 2;

VM_BEHAVIOR_RSEQNTL

pub const VM_BEHAVIOR_RSEQNTL: vm_behavior_t = 3;

VM_BEHAVIOR_WILLNEED

pub const VM_BEHAVIOR_WILLNEED: vm_behavior_t = 4;

VM_BEHAVIOR_DONTNEED

pub const VM_BEHAVIOR_DONTNEED: vm_behavior_t = 5;

VM_BEHAVIOR_FREE

pub const VM_BEHAVIOR_FREE: vm_behavior_t = 6;

VM_BEHAVIOR_ZERO_WIRED_PAGES

pub const VM_BEHAVIOR_ZERO_WIRED_PAGES: vm_behavior_t = 7;

VM_BEHAVIOR_REUSABLE

pub const VM_BEHAVIOR_REUSABLE: vm_behavior_t = 8;

VM_BEHAVIOR_REUSE

pub const VM_BEHAVIOR_REUSE: vm_behavior_t = 9;

VM_BEHAVIOR_CAN_REUSE

pub const VM_BEHAVIOR_CAN_REUSE: vm_behavior_t = 10;

VM_BEHAVIOR_PAGEOUT

pub const VM_BEHAVIOR_PAGEOUT: vm_behavior_t = 11;

VM_REGION_BASIC_INFO_64

pub const VM_REGION_BASIC_INFO_64 = 9;

VM_REGION_EXTENDED_INFO

pub const VM_REGION_EXTENDED_INFO = 13;

VM_REGION_TOP_INFO

pub const VM_REGION_TOP_INFO = 12;

VM_REGION_SUBMAP_INFO_COUNT_64

pub const VM_REGION_SUBMAP_INFO_COUNT_64: mach_msg_type_number_t = @sizeOf(vm_region_submap_info_64) / @sizeOf(natural_t);

VM_REGION_SUBMAP_SHORT_INFO_COUNT_64

pub const VM_REGION_SUBMAP_SHORT_INFO_COUNT_64: mach_msg_type_number_t = @sizeOf(vm_region_submap_short_info_64) / @sizeOf(natural_t);

VM_REGION_BASIC_INFO_COUNT

pub const VM_REGION_BASIC_INFO_COUNT: mach_msg_type_number_t = @sizeOf(vm_region_basic_info_64) / @sizeOf(c_int);

VM_REGION_EXTENDED_INFO_COUNT

pub const VM_REGION_EXTENDED_INFO_COUNT: mach_msg_type_number_t = @sizeOf(vm_region_extended_info) / @sizeOf(natural_t);

VM_REGION_TOP_INFO_COUNT

pub const VM_REGION_TOP_INFO_COUNT: mach_msg_type_number_t = @sizeOf(vm_region_top_info) / @sizeOf(natural_t);

VM_MAKE_TAG()

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

vm_region_basic_info_64

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,
};

vm_region_extended_info

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,
};

vm_region_top_info

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,
};

vm_region_submap_info_64

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,
};

vm_region_submap_short_info_64

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,
};

thread_act_t

pub const thread_act_t = mach_port_t;

thread_state_t

pub const thread_state_t = *natural_t;

mach_port_array_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;

THREAD_BASIC_INFO

pub const THREAD_BASIC_INFO = 3;

THREAD_BASIC_INFO_COUNT

pub const THREAD_BASIC_INFO_COUNT: mach_msg_type_number_t = @sizeOf(thread_basic_info) / @sizeOf(natural_t);

THREAD_IDENTIFIER_INFO

pub const THREAD_IDENTIFIER_INFO = 4;

THREAD_IDENTIFIER_INFO_COUNT

pub const THREAD_IDENTIFIER_INFO_COUNT: mach_msg_type_number_t = @sizeOf(thread_identifier_info) / @sizeOf(natural_t);

thread_flavor_t

pub const thread_flavor_t = natural_t;

thread_info_t

pub const thread_info_t = *integer_t;

time_value_t

pub const time_value_t = time_value;

task_policy_flavor_t

pub const task_policy_flavor_t = natural_t;

task_policy_t

pub const task_policy_t = *integer_t;

policy_t

pub const policy_t = c_int;

time_value

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

thread_basic_info

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,
};

thread_identifier_info

pub const thread_identifier_info = extern struct {
    thread_id: u64,

    thread_handle: u64,

    dispatch_qaddr: u64,
};

MATTR_CACHE

System-wide unique 64-bit thread id Handle to be used by libproc libdispatch queue address Cachability

pub const MATTR_CACHE = 1;

MATTR_MIGRATE

Migrability

pub const MATTR_MIGRATE = 2;

MATTR_REPLICATE

Replicability

pub const MATTR_REPLICATE = 4;

MATTR_VAL_OFF

(Generic) turn attribute off

pub const MATTR_VAL_OFF = 0;

MATTR_VAL_ON

(Generic) turn attribute on

pub const MATTR_VAL_ON = 1;

MATTR_VAL_GET

(Generic) return current value

pub const MATTR_VAL_GET = 2;

MATTR_VAL_CACHE_FLUSH

Flush from all caches

pub const MATTR_VAL_CACHE_FLUSH = 6;

MATTR_VAL_DCACHE_FLUSH

Flush from data caches

pub const MATTR_VAL_DCACHE_FLUSH = 7;

MATTR_VAL_ICACHE_FLUSH

Flush from instruction caches

pub const MATTR_VAL_ICACHE_FLUSH = 8;

MATTR_VAL_CACHE_SYNC

Sync I+D caches

pub const MATTR_VAL_CACHE_SYNC = 9;

MATTR_VAL_GET_INFO

Get page info (stats)

pub const MATTR_VAL_GET_INFO = 10;

TASK_VM_INFO

pub const TASK_VM_INFO = 22;

TASK_VM_INFO_COUNT

pub const TASK_VM_INFO_COUNT: mach_msg_type_number_t = @sizeOf(task_vm_info_data_t) / @sizeOf(natural_t);

task_vm_info

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,
};

task_vm_info_data_t

pub const task_vm_info_data_t = task_vm_info;

vm_prot_t

pub const vm_prot_t = c_int;

boolean_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,
    poly: mach_port_t,
    poly_poly: 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;

mach_task_basic_info

pub const mach_task_basic_info = extern struct {
    virtual_size: mach_vm_size_t,

    resident_size: mach_vm_size_t,

    user_time: time_value_t,

    system_time: time_value_t,

    policy: policy_t,

    suspend_count: mach_vm_size_t,
};

MACH_TASK_BASIC_INFO

Virtual memory size (bytes) Resident memory size (bytes) Total user run time for terminated threads Total system run time for terminated threads Default policy for new threads Suspend count for task

pub const MACH_TASK_BASIC_INFO = 20;

MACH_TASK_BASIC_INFO_COUNT

pub const MACH_TASK_BASIC_INFO_COUNT: mach_msg_type_number_t = @sizeOf(mach_task_basic_info) / @sizeOf(natural_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;

sf_hdtr

pub const sf_hdtr = extern struct {
    headers: [*]const iovec_const,
    hdr_cnt: c_int,
    trailers: [*]const iovec_const,
    trl_cnt: c_int,
};

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;

sigaddset()

pub fn sigaddset(set: *sigset_t, signo: u5) void {
    set.* |= @as(u32, 1) << (signo - 1);
}

pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;

IFNAMESIZE

pub const IFNAMESIZE = 16;

AI

pub const AI = struct {
    pub const PASSIVE = 0x00000001;
    pub const CANONNAME = 0x00000002;
    pub const NUMERICHOST = 0x00000004;
    pub const NUMERICSERV = 0x00001000;
};

EAI

get address to use bind() fill ai_canonname prevent host name resolution prevent service name resolution

pub const EAI = enum(c_int) {
    ADDRFAMILY = 1,

    AGAIN = 2,

    BADFLAGS = 3,

    FAIL = 4,

    FAMILY = 5,

    MEMORY = 6,

    NODATA = 7,

    NONAME = 8,

    SERVICE = 9,

    SOCKTYPE = 10,

    SYSTEM = 11,

    BADHINTS = 12,

    PROTOCOL = 13,

    OVERFLOW = 14,

    _,
};

EAI_MAX

address family for hostname not supported temporary failure in name resolution invalid value for ai_flags non-recoverable failure in name resolution ai_family not supported memory allocation failure no address associated with hostname hostname nor servname provided, or not known servname not supported for ai_socktype ai_socktype not supported system error returned in errno invalid value for hints resolved protocol is unknown argument buffer overflow

pub const EAI_MAX = 15;

qos_class_t

pub const qos_class_t = enum(c_uint) {
    QOS_CLASS_USER_INTERACTIVE = 0x21,
    QOS_CLASS_USER_INITIATED = 0x19,
    QOS_CLASS_DEFAULT = 0x15,
    QOS_CLASS_UTILITY = 0x11,
    QOS_CLASS_BACKGROUND = 0x09,
    QOS_CLASS_UNSPECIFIED = 0x00,
};

pthread_mutex_t

highest priority QOS class for critical tasks slightly more moderate priority QOS class default QOS class when none is set more energy efficient QOS class than default QOS class more appropriate for background tasks QOS class as a return value

pub const pthread_mutex_t = extern struct {
    __sig: c_long = 0x32AAABA7,
    __opaque: [__PTHREAD_MUTEX_SIZE__]u8 = [_]u8{0} ** __PTHREAD_MUTEX_SIZE__,
};

pthread_cond_t

pub const pthread_cond_t = extern struct {
    __sig: c_long = 0x3CB0B1BB,
    __opaque: [__PTHREAD_COND_SIZE__]u8 = [_]u8{0} ** __PTHREAD_COND_SIZE__,
};

pthread_rwlock_t

pub const pthread_rwlock_t = extern struct {
    __sig: c_long = 0x2DA8B3B4,
    __opaque: [192]u8 = [_]u8{0} ** 192,
};

sem_t

pub const sem_t = c_int;
const __PTHREAD_MUTEX_SIZE__ = if (@sizeOf(usize) == 8) 56 else 40;
const __PTHREAD_COND_SIZE__ = if (@sizeOf(usize) == 8) 40 else 24;

pthread_attr_t

pub const pthread_attr_t = extern struct {
    __sig: c_long,
    __opaque: [56]u8,
};

pub extern "c" fn pthread_threadid_np(thread: ?std.c.pthread_t, thread_id: *u64) c_int;
pub extern "c" fn pthread_setname_np(name: [*:0]const u8) E;
pub extern "c" fn pthread_getname_np(thread: std.c.pthread_t, name: [*:0]u8, len: usize) E;
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 extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void;

// Grand Central Dispatch is exposed by libSystem.
pub extern "c" fn dispatch_release(object: *anyopaque) void;

dispatch_semaphore_t

pub const dispatch_semaphore_t = *opaque {};
pub extern "c" fn dispatch_semaphore_create(value: isize) ?dispatch_semaphore_t;
pub extern "c" fn dispatch_semaphore_wait(dsema: dispatch_semaphore_t, timeout: dispatch_time_t) isize;
pub extern "c" fn dispatch_semaphore_signal(dsema: dispatch_semaphore_t) isize;

dispatch_time_t

pub const dispatch_time_t = u64;

DISPATCH_TIME_NOW

pub const DISPATCH_TIME_NOW = @as(dispatch_time_t, 0);

DISPATCH_TIME_FOREVER

pub const DISPATCH_TIME_FOREVER = ~@as(dispatch_time_t, 0);
pub extern "c" fn dispatch_time(when: dispatch_time_t, delta: i64) dispatch_time_t;

const dispatch_once_t = usize;
const dispatch_function_t = fn (?*anyopaque) callconv(.C) void;
pub extern fn dispatch_once_f(
    predicate: *dispatch_once_t,
    context: ?*anyopaque,
    function: dispatch_function_t,
) void;

// 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

UL_COMPARE_AND_WAIT

pub const UL_COMPARE_AND_WAIT = 1;

UL_UNFAIR_LOCK

pub const UL_UNFAIR_LOCK = 2;

// Obsolete/deprecated

UL_OSSPINLOCK

pub const UL_OSSPINLOCK = UL_COMPARE_AND_WAIT;

UL_HANDOFFLOCK

pub const UL_HANDOFFLOCK = UL_UNFAIR_LOCK;

ULF_WAKE_ALL

pub const ULF_WAKE_ALL = 0x100;

ULF_WAKE_THREAD

pub const ULF_WAKE_THREAD = 0x200;

ULF_WAIT_WORKQ_DATA_CONTENTION

pub const ULF_WAIT_WORKQ_DATA_CONTENTION = 0x10000;

ULF_WAIT_CANCEL_POINT

pub const ULF_WAIT_CANCEL_POINT = 0x20000;

ULF_NO_ERRNO

pub const ULF_NO_ERRNO = 0x1000000;

// The following are only supported on darwin 19+
// (macOS 10.15+, iOS 13.0+)

UL_COMPARE_AND_WAIT_SHARED

pub const UL_COMPARE_AND_WAIT_SHARED = 3;

UL_UNFAIR_LOCK64_SHARED

pub const UL_UNFAIR_LOCK64_SHARED = 4;

UL_COMPARE_AND_WAIT64

pub const UL_COMPARE_AND_WAIT64 = 5;

UL_COMPARE_AND_WAIT64_SHARED

pub const UL_COMPARE_AND_WAIT64_SHARED = 6;

ULF_WAIT_ADAPTIVE_SPIN

pub const ULF_WAIT_ADAPTIVE_SPIN = 0x40000;

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

OS_UNFAIR_LOCK_INIT

pub const OS_UNFAIR_LOCK_INIT = os_unfair_lock{};

os_unfair_lock_t

pub const os_unfair_lock_t = *os_unfair_lock;

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;

// XXX: close -> close$NOCANCEL
// XXX: getdirentries -> _getdirentries64

// See: https://opensource.apple.com/source/xnu/xnu-6153.141.1/bsd/sys/_types.h.auto.html
// TODO: audit mode_t/pid_t, should likely be u16/i32

blkcnt_t

pub const blkcnt_t = i64;

blksize_t

pub const blksize_t = i32;

dev_t

pub const dev_t = i32;

fd_t

pub const fd_t = c_int;

pid_t

pub const pid_t = c_int;

mode_t

pub const mode_t = c_uint;

uid_t

pub const uid_t = u32;

gid_t

pub const gid_t = u32;

// machine/_types.h

clock_t

pub const clock_t = c_ulong;

time_t

pub const time_t = c_long;

in_port_t

pub const in_port_t = u16;

sa_family_t

pub const sa_family_t = u8;

socklen_t

pub const socklen_t = u32;

sockaddr

pub const sockaddr = extern struct {
    len: u8,
    family: sa_family_t,
    data: [14]u8,

    pub const SS_MAXSIZE = 128;
    pub const storage = extern struct {
        len: u8 align(8),
        family: sa_family_t,
        padding: [126]u8 = undefined,

        comptime {
            assert(@sizeOf(storage) == SS_MAXSIZE);
            assert(@alignOf(storage) == 8);
        }
    };
    pub const in = extern struct {
        len: u8 = @sizeOf(in),
        family: sa_family_t = AF.INET,
        port: in_port_t,
        addr: u32,
        zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
    };
    pub const in6 = extern struct {
        len: u8 = @sizeOf(in6),
        family: sa_family_t = AF.INET6,
        port: in_port_t,
        flowinfo: u32,
        addr: [16]u8,
        scope_id: u32,
    };

    pub const un = extern struct {
        len: u8 = @sizeOf(un),
        family: sa_family_t = AF.UNIX,
        path: [104]u8,
    };
};

timeval

UNIX domain socket

pub const timeval = extern struct {
    tv_sec: c_long,
    tv_usec: i32,
};

timezone

pub const timezone = extern struct {
    tz_minuteswest: i32,
    tz_dsttime: i32,
};

mach_timebase_info_data

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

off_t

pub const off_t = i64;

ino_t

pub const ino_t = u64;

Flock

pub const Flock = extern struct {
    start: off_t,
    len: off_t,
    pid: pid_t,
    type: i16,
    whence: i16,
};

Stat

pub const Stat = extern struct {
    dev: i32,
    mode: u16,
    nlink: u16,
    ino: ino_t,
    uid: uid_t,
    gid: gid_t,
    rdev: i32,
    atimespec: timespec,
    mtimespec: timespec,
    ctimespec: timespec,
    birthtimespec: timespec,
    size: off_t,
    blocks: i64,
    blksize: i32,
    flags: u32,
    gen: u32,
    lspare: i32,
    qspare: [2]i64,

atime()

    pub fn atime(self: @This()) timespec {
        return self.atimespec;
    }

mtime()

    pub fn mtime(self: @This()) timespec {
        return self.mtimespec;
    }

ctime()

    pub fn ctime(self: @This()) timespec {
        return self.ctimespec;
    }

birthtime()

    pub fn birthtime(self: @This()) timespec {
        return self.birthtimespec;
    }
};

timespec

pub const timespec = extern struct {
    tv_sec: isize,
    tv_nsec: isize,
};

sigset_t

pub const sigset_t = u32;

empty_sigset

pub const empty_sigset: sigset_t = 0;

SIG

pub const SIG = struct {
    pub const ERR = @as(?Sigaction.handler_fn, @ptrFromInt(maxInt(usize)));
    pub const DFL = @as(?Sigaction.handler_fn, @ptrFromInt(0));
    pub const IGN = @as(?Sigaction.handler_fn, @ptrFromInt(1));
    pub const HOLD = @as(?Sigaction.handler_fn, @ptrFromInt(5));

    pub const BLOCK = 1;
    pub const UNBLOCK = 2;
    pub const SETMASK = 3;
    pub const HUP = 1;
    pub const INT = 2;
    pub const QUIT = 3;
    pub const ILL = 4;
    pub const TRAP = 5;
    pub const ABRT = 6;
    pub const POLL = 7;
    pub const IOT = ABRT;
    pub const EMT = 7;
    pub const FPE = 8;
    pub const KILL = 9;
    pub const BUS = 10;
    pub const SEGV = 11;
    pub const SYS = 12;
    pub const PIPE = 13;
    pub const ALRM = 14;
    pub const TERM = 15;
    pub const URG = 16;
    pub const STOP = 17;
    pub const TSTP = 18;
    pub const CONT = 19;
    pub const CHLD = 20;
    pub const TTIN = 21;
    pub const TTOU = 22;
    pub const IO = 23;
    pub const XCPU = 24;
    pub const XFSZ = 25;
    pub const VTALRM = 26;
    pub const PROF = 27;
    pub const WINCH = 28;
    pub const INFO = 29;
    pub const USR1 = 30;
    pub const USR2 = 31;
};

siginfo_t

block specified signal set unblock specified signal set set specified signal set hangup interrupt quit illegal instruction (not reset when caught) trace trap (not reset when caught) abort() pollable event ([XSR] generated, not supported) compatibility EMT instruction floating point exception kill (cannot be caught or ignored) bus error segmentation violation bad argument to system call write on a pipe with no one to read it alarm clock software termination signal from kill urgent condition on IO channel sendable stop signal not from tty stop signal from tty continue a stopped process to parent on child stop or exit to readers pgrp upon background tty read like TTIN for output if (tp->t_local<OSTOP) input/output possible signal exceeded CPU time limit exceeded file size limit virtual time alarm profiling time alarm window size changes information request user defined signal 1 user defined signal 2

pub const siginfo_t = extern struct {
    signo: c_int,
    errno: c_int,
    code: c_int,
    pid: pid_t,
    uid: uid_t,
    status: c_int,
    addr: *anyopaque,
    value: extern union {
        int: c_int,
        ptr: *anyopaque,
    },
    si_band: c_long,
    _pad: [7]c_ulong,
};

Sigaction

Renamed from sigaction to Sigaction to avoid conflict with function name.

pub const Sigaction = extern struct {
    pub const handler_fn = *const fn (c_int) align(1) callconv(.C) void;
    pub const sigaction_fn = *const fn (c_int, *const siginfo_t, ?*const anyopaque) callconv(.C) void;

    handler: extern union {
        handler: ?handler_fn,
        sigaction: ?sigaction_fn,
    },
    mask: sigset_t,
    flags: c_uint,
};

dirent

pub const dirent = extern struct {
    d_ino: u64,
    d_seekoff: u64,
    d_reclen: u16,
    d_namlen: u16,
    d_type: u8,
    d_name: [1024]u8,

reclen()

    pub fn reclen(self: dirent) u16 {
        return self.d_reclen;
    }
};

Kevent

Renamed from kevent to Kevent to avoid conflict with function name.

pub const Kevent = extern struct {
    ident: usize,
    filter: i16,
    flags: u16,
    fflags: u32,
    data: isize,
    udata: usize,
};

// sys/types.h on macos uses #pragma pack(4) 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.isDarwin()) {
        assert(@offsetOf(Kevent, "ident") == 0);
        assert(@offsetOf(Kevent, "filter") == 8);
        assert(@offsetOf(Kevent, "flags") == 10);
        assert(@offsetOf(Kevent, "fflags") == 12);
        assert(@offsetOf(Kevent, "data") == 16);
        assert(@offsetOf(Kevent, "udata") == 24);
    }
}

kevent64_s

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.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);
    }
}

mach_port_t

pub const mach_port_t = c_uint;

clock_serv_t

pub const clock_serv_t = mach_port_t;

clock_res_t

pub const clock_res_t = c_int;

mach_port_name_t

pub const mach_port_name_t = natural_t;

natural_t

pub const natural_t = c_uint;

mach_timespec_t

pub const mach_timespec_t = extern struct {
    tv_sec: c_uint,
    tv_nsec: clock_res_t,
};

kern_return_t

pub const kern_return_t = c_int;

host_t

pub const host_t = mach_port_t;

integer_t

pub const integer_t = c_int;

task_flavor_t

pub const task_flavor_t = natural_t;

task_info_t

pub const task_info_t = *integer_t;

task_name_t

pub const task_name_t = mach_port_name_t;

vm_address_t

pub const vm_address_t = vm_offset_t;

vm_size_t

pub const vm_size_t = mach_vm_size_t;

vm_machine_attribute_t

pub const vm_machine_attribute_t = usize;

vm_machine_attribute_val_t

pub const vm_machine_attribute_val_t = isize;

CALENDAR_CLOCK

pub const CALENDAR_CLOCK = 1;

PATH_MAX

pub const PATH_MAX = 1024;

NAME_MAX

pub const NAME_MAX = 255;

IOV_MAX

pub const IOV_MAX = 16;

STDIN_FILENO

pub const STDIN_FILENO = 0;

STDOUT_FILENO

pub const STDOUT_FILENO = 1;

STDERR_FILENO

pub const STDERR_FILENO = 2;

PROT

pub const PROT = struct {
    pub const NONE: vm_prot_t = 0x00;
    pub const READ: vm_prot_t = 0x01;
    pub const WRITE: vm_prot_t = 0x02;
    pub const EXEC: vm_prot_t = 0x04;
    pub const COPY: vm_prot_t = 0x10;
};

MAP

[MC2] no permissions [MC2] pages can be read [MC2] pages can be written [MC2] pages can be executed When a caller finds that they cannot obtain write permission on a mapped entry, the following flag can be used. The entry will be made "needs copy" effectively copying the object (using COW), and write permission will be added to the maximum protections for the associated entry.

pub const MAP = struct {
    pub const ANONYMOUS = 0x1000;
    pub const FILE = 0x0000;
    pub const FIXED = 0x0010;
    pub const HASSEMAPHORE = 0x0200;
    pub const PRIVATE = 0x0002;
    pub const SHARED = 0x0001;
    pub const NOCACHE = 0x0400;
    pub const NORESERVE = 0x0040;
    pub const FAILED = @as(*anyopaque, @ptrFromInt(maxInt(usize)));
};

MSF

allocated from memory, swap space map from file (default) interpret addr exactly region may contain semaphores changes are private share changes don't cache pages for this mapping don't reserve needed swap area

pub const MSF = struct {
    pub const ASYNC = 0x1;
    pub const INVALIDATE = 0x2;
    // invalidate, leave mapped
    pub const KILLPAGES = 0x4;
    // deactivate, leave mapped
    pub const DEACTIVATE = 0x8;
    pub const SYNC = 0x10;
};

SA

pub const SA = struct {
    pub const ONSTACK = 0x0001;
    pub const RESTART = 0x0002;
    pub const RESETHAND = 0x0004;
    pub const NOCLDSTOP = 0x0008;
    pub const NODEFER = 0x0010;
    pub const NOCLDWAIT = 0x0020;
    pub const SIGINFO = 0x0040;
    pub const USERTRAMP = 0x0100;
    pub const @"64REGSET" = 0x0200;
};

F_OK

take signal on signal stack restart system on signal return reset to SIG.DFL when taking signal do not generate SIG.CHLD on child stop don't mask the signal we're delivering don't keep zombies around signal handler with SIGINFO args do not bounce off kernel's sigtramp signal handler with SIGINFO args with 64bit regs information

pub const F_OK = 0;

X_OK

pub const X_OK = 1;

W_OK

pub const W_OK = 2;

R_OK

pub const R_OK = 4;

O

pub const O = 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 = 0x1000000;
    pub const ACCMODE = 3;
    pub const ALERT = 536870912;
    pub const ASYNC = 64;
    pub const DIRECTORY = 1048576;
    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;
};

SEEK

open for reading only open for writing only open for reading and writing do not block on open or for data to become available append on each write create file if it does not exist truncate size to 0 error if CREAT and the file exists atomically obtain a shared lock atomically obtain an exclusive lock do not follow symlinks allow open of symlinks descriptor requested for event notifications only mark as close-on-exec

pub const SEEK = struct {
    pub const SET = 0x0;
    pub const CUR = 0x1;
    pub const END = 0x2;
};

DT

pub const DT = struct {
    pub const UNKNOWN = 0;
    pub const FIFO = 1;
    pub const CHR = 2;
    pub const DIR = 4;
    pub const BLK = 6;
    pub const REG = 8;
    pub const LNK = 10;
    pub const SOCK = 12;
    pub const WHT = 14;
};

KEVENT_FLAG_NONE

no flag value

pub const KEVENT_FLAG_NONE = 0x000;

KEVENT_FLAG_IMMEDIATE

immediate timeout

pub const KEVENT_FLAG_IMMEDIATE = 0x001;

KEVENT_FLAG_ERROR_EVENTS

output events only include change

pub const KEVENT_FLAG_ERROR_EVENTS = 0x002;

EV_ADD

add event to kq (implies enable)

pub const EV_ADD = 0x0001;

EV_DELETE

delete event from kq

pub const EV_DELETE = 0x0002;

EV_ENABLE

enable event

pub const EV_ENABLE = 0x0004;

EV_DISABLE

disable event (not reported)

pub const EV_DISABLE = 0x0008;

EV_ONESHOT

only report one occurrence

pub const EV_ONESHOT = 0x0010;

EV_CLEAR

clear event state after reporting

pub const EV_CLEAR = 0x0020;

EV_RECEIPT

force immediate event output ... with or without EV_ERROR ... use KEVENT_FLAG_ERROR_EVENTS on syscalls supporting flags

pub const EV_RECEIPT = 0x0040;

EV_DISPATCH

disable event after reporting

pub const EV_DISPATCH = 0x0080;

EV_UDATA_SPECIFIC

unique kevent per udata value

pub const EV_UDATA_SPECIFIC = 0x0100;

EV_DISPATCH2

... in combination with EV_DELETE will defer delete until udata-specific event enabled. EINPROGRESS will be returned to indicate the deferral

pub const EV_DISPATCH2 = EV_DISPATCH | EV_UDATA_SPECIFIC;

EV_VANISHED

report that source has vanished ... only valid with EV_DISPATCH2

pub const EV_VANISHED = 0x0200;

EV_SYSFLAGS

reserved by system

pub const EV_SYSFLAGS = 0xF000;

EV_FLAG0

filter-specific flag

pub const EV_FLAG0 = 0x1000;

EV_FLAG1

filter-specific flag

pub const EV_FLAG1 = 0x2000;

EV_EOF

EOF detected

pub const EV_EOF = 0x8000;

EV_ERROR

error, data contains errno

pub const EV_ERROR = 0x4000;

EV_POLL

pub const EV_POLL = EV_FLAG0;

EV_OOBAND

pub const EV_OOBAND = EV_FLAG1;

EVFILT_READ

pub const EVFILT_READ = -1;

EVFILT_WRITE

pub const EVFILT_WRITE = -2;

EVFILT_AIO

attached to aio requests

pub const EVFILT_AIO = -3;

EVFILT_VNODE

attached to vnodes

pub const EVFILT_VNODE = -4;

EVFILT_PROC

attached to struct proc

pub const EVFILT_PROC = -5;

EVFILT_SIGNAL

attached to struct proc

pub const EVFILT_SIGNAL = -6;

EVFILT_TIMER

timers

pub const EVFILT_TIMER = -7;

EVFILT_MACHPORT

Mach portsets

pub const EVFILT_MACHPORT = -8;

EVFILT_FS

Filesystem events

pub const EVFILT_FS = -9;

EVFILT_USER

User events

pub const EVFILT_USER = -10;

EVFILT_VM

Virtual memory events

pub const EVFILT_VM = -12;

EVFILT_EXCEPT

Exception events

pub const EVFILT_EXCEPT = -15;

EVFILT_SYSCOUNT

pub const EVFILT_SYSCOUNT = 17;

NOTE_TRIGGER

On input, NOTE_TRIGGER causes the event to be triggered for output.

pub const NOTE_TRIGGER = 0x01000000;

NOTE_FFNOP

ignore input fflags

pub const NOTE_FFNOP = 0x00000000;

NOTE_FFAND

and fflags

pub const NOTE_FFAND = 0x40000000;

NOTE_FFOR

or fflags

pub const NOTE_FFOR = 0x80000000;

NOTE_FFCOPY

copy fflags

pub const NOTE_FFCOPY = 0xc0000000;

NOTE_FFCTRLMASK

mask for operations

pub const NOTE_FFCTRLMASK = 0xc0000000;

NOTE_FFLAGSMASK

pub const NOTE_FFLAGSMASK = 0x00ffffff;

NOTE_LOWAT

low water mark

pub const NOTE_LOWAT = 0x00000001;

NOTE_OOB

OOB data

pub const NOTE_OOB = 0x00000002;

NOTE_DELETE

vnode was removed

pub const NOTE_DELETE = 0x00000001;

NOTE_WRITE

data contents changed

pub const NOTE_WRITE = 0x00000002;

NOTE_EXTEND

size increased

pub const NOTE_EXTEND = 0x00000004;

NOTE_ATTRIB

attributes changed

pub const NOTE_ATTRIB = 0x00000008;

NOTE_LINK

link count changed

pub const NOTE_LINK = 0x00000010;

NOTE_RENAME

vnode was renamed

pub const NOTE_RENAME = 0x00000020;

NOTE_REVOKE

vnode access was revoked

pub const NOTE_REVOKE = 0x00000040;

NOTE_NONE

No specific vnode event: to test for EVFILT_READ activation

pub const NOTE_NONE = 0x00000080;

NOTE_FUNLOCK

vnode was unlocked by flock(2)

pub const NOTE_FUNLOCK = 0x00000100;

NOTE_EXIT

process exited

pub const NOTE_EXIT = 0x80000000;

NOTE_FORK

process forked

pub const NOTE_FORK = 0x40000000;

NOTE_EXEC

process exec'd

pub const NOTE_EXEC = 0x20000000;

NOTE_SIGNAL

shared with EVFILT_SIGNAL

pub const NOTE_SIGNAL = 0x08000000;

NOTE_EXITSTATUS

exit status to be returned, valid for child process only

pub const NOTE_EXITSTATUS = 0x04000000;

NOTE_EXIT_DETAIL

provide details on reasons for exit

pub const NOTE_EXIT_DETAIL = 0x02000000;

NOTE_PDATAMASK

mask for signal & exit status

pub const NOTE_PDATAMASK = 0x000fffff;

NOTE_PCTRLMASK

pub const NOTE_PCTRLMASK = (~NOTE_PDATAMASK);

NOTE_EXIT_DETAIL_MASK

pub const NOTE_EXIT_DETAIL_MASK = 0x00070000;

NOTE_EXIT_DECRYPTFAIL

pub const NOTE_EXIT_DECRYPTFAIL = 0x00010000;

NOTE_EXIT_MEMORY

pub const NOTE_EXIT_MEMORY = 0x00020000;

NOTE_EXIT_CSERROR

pub const NOTE_EXIT_CSERROR = 0x00040000;

NOTE_VM_PRESSURE

will react on memory pressure

pub const NOTE_VM_PRESSURE = 0x80000000;

NOTE_VM_PRESSURE_TERMINATE

will quit on memory pressure, possibly after cleaning up dirty state

pub const NOTE_VM_PRESSURE_TERMINATE = 0x40000000;

NOTE_VM_PRESSURE_SUDDEN_TERMINATE

will quit immediately on memory pressure

pub const NOTE_VM_PRESSURE_SUDDEN_TERMINATE = 0x20000000;

NOTE_VM_ERROR

there was an error

pub const NOTE_VM_ERROR = 0x10000000;

NOTE_SECONDS

data is seconds

pub const NOTE_SECONDS = 0x00000001;

NOTE_USECONDS

data is microseconds

pub const NOTE_USECONDS = 0x00000002;

NOTE_NSECONDS

data is nanoseconds

pub const NOTE_NSECONDS = 0x00000004;

NOTE_ABSOLUTE

absolute timeout

pub const NOTE_ABSOLUTE = 0x00000008;

NOTE_LEEWAY

ext[1] holds leeway for power aware timers

pub const NOTE_LEEWAY = 0x00000010;

NOTE_CRITICAL

system does minimal timer coalescing

pub const NOTE_CRITICAL = 0x00000020;

NOTE_BACKGROUND

system does maximum timer coalescing

pub const NOTE_BACKGROUND = 0x00000040;

NOTE_MACH_CONTINUOUS_TIME

pub const NOTE_MACH_CONTINUOUS_TIME = 0x00000080;

NOTE_MACHTIME

data is mach absolute time units

pub const NOTE_MACHTIME = 0x00000100;

AF

pub const AF = struct {
    pub const UNSPEC = 0;
    pub const LOCAL = 1;
    pub const UNIX = LOCAL;
    pub const INET = 2;
    pub const SYS_CONTROL = 2;
    pub const IMPLINK = 3;
    pub const PUP = 4;
    pub const CHAOS = 5;
    pub const NS = 6;
    pub const ISO = 7;
    pub const OSI = ISO;
    pub const ECMA = 8;
    pub const DATAKIT = 9;
    pub const CCITT = 10;
    pub const SNA = 11;
    pub const DECnet = 12;
    pub const DLI = 13;
    pub const LAT = 14;
    pub const HYLINK = 15;
    pub const APPLETALK = 16;
    pub const ROUTE = 17;
    pub const LINK = 18;
    pub const XTP = 19;
    pub const COIP = 20;
    pub const CNT = 21;
    pub const RTIP = 22;
    pub const IPX = 23;
    pub const SIP = 24;
    pub const PIP = 25;
    pub const ISDN = 28;
    pub const E164 = ISDN;
    pub const KEY = 29;
    pub const INET6 = 30;
    pub const NATM = 31;
    pub const SYSTEM = 32;
    pub const NETBIOS = 33;
    pub const PPP = 34;
    pub const MAX = 40;
};

PF

pub const PF = struct {
    pub const UNSPEC = AF.UNSPEC;
    pub const LOCAL = AF.LOCAL;
    pub const UNIX = PF.LOCAL;
    pub const INET = AF.INET;
    pub const IMPLINK = AF.IMPLINK;
    pub const PUP = AF.PUP;
    pub const CHAOS = AF.CHAOS;
    pub const NS = AF.NS;
    pub const ISO = AF.ISO;
    pub const OSI = AF.ISO;
    pub const ECMA = AF.ECMA;
    pub const DATAKIT = AF.DATAKIT;
    pub const CCITT = AF.CCITT;
    pub const SNA = AF.SNA;
    pub const DECnet = AF.DECnet;
    pub const DLI = AF.DLI;
    pub const LAT = AF.LAT;
    pub const HYLINK = AF.HYLINK;
    pub const APPLETALK = AF.APPLETALK;
    pub const ROUTE = AF.ROUTE;
    pub const LINK = AF.LINK;
    pub const XTP = AF.XTP;
    pub const COIP = AF.COIP;
    pub const CNT = AF.CNT;
    pub const SIP = AF.SIP;
    pub const IPX = AF.IPX;
    pub const RTIP = AF.RTIP;
    pub const PIP = AF.PIP;
    pub const ISDN = AF.ISDN;
    pub const KEY = AF.KEY;
    pub const INET6 = AF.INET6;
    pub const NATM = AF.NATM;
    pub const SYSTEM = AF.SYSTEM;
    pub const NETBIOS = AF.NETBIOS;
    pub const PPP = AF.PPP;
    pub const MAX = AF.MAX;
};

SYSPROTO_EVENT

pub const SYSPROTO_EVENT = 1;

SYSPROTO_CONTROL

pub const SYSPROTO_CONTROL = 2;

SOCK

pub const SOCK = struct {
    pub const STREAM = 1;
    pub const DGRAM = 2;
    pub const RAW = 3;
    pub const RDM = 4;
    pub const SEQPACKET = 5;
    pub const MAXADDRLEN = 255;

    pub const CLOEXEC = 1 << 15;
    pub const NONBLOCK = 1 << 16;
};

IPPROTO

Not actually supported by Darwin, but Zig supplies a shim. This numerical value is not ABI-stable. It need only not conflict with any other SOCK bits. Not actually supported by Darwin, but Zig supplies a shim. This numerical value is not ABI-stable. It need only not conflict with any other SOCK bits.

pub const IPPROTO = struct {
    pub const ICMP = 1;
    pub const ICMPV6 = 58;
    pub const TCP = 6;
    pub const UDP = 17;
    pub const IP = 0;
    pub const IPV6 = 41;
};

SOL

pub const SOL = struct {
    pub const SOCKET = 0xffff;
};

SO

pub const SO = struct {
    pub const DEBUG = 0x0001;
    pub const ACCEPTCONN = 0x0002;
    pub const REUSEADDR = 0x0004;
    pub const KEEPALIVE = 0x0008;
    pub const DONTROUTE = 0x0010;
    pub const BROADCAST = 0x0020;
    pub const USELOOPBACK = 0x0040;
    pub const LINGER = 0x1080;
    pub const OOBINLINE = 0x0100;
    pub const REUSEPORT = 0x0200;
    pub const ACCEPTFILTER = 0x1000;
    pub const SNDBUF = 0x1001;
    pub const RCVBUF = 0x1002;
    pub const SNDLOWAT = 0x1003;
    pub const RCVLOWAT = 0x1004;
    pub const SNDTIMEO = 0x1005;
    pub const RCVTIMEO = 0x1006;
    pub const ERROR = 0x1007;
    pub const TYPE = 0x1008;

    pub const NREAD = 0x1020;
    pub const NKE = 0x1021;
    pub const NOSIGPIPE = 0x1022;
    pub const NOADDRERR = 0x1023;
    pub const NWRITE = 0x1024;
    pub const REUSESHAREUID = 0x1025;
};

W

pub const W = struct {
    pub const NOHANG = 0x00000001;
    pub const UNTRACED = 0x00000002;

EXITSTATUS()

[XSI] no hang in wait/no child to reap [XSI] notify on stop, untraced child

    pub fn EXITSTATUS(x: u32) u8 {
        return @as(u8, @intCast(x >> 8));
    }

TERMSIG()

    pub fn TERMSIG(x: u32) u32 {
        return status(x);
    }

STOPSIG()

    pub fn STOPSIG(x: u32) u32 {
        return x >> 8;
    }

IFEXITED()

    pub fn IFEXITED(x: u32) bool {
        return status(x) == 0;
    }

IFSTOPPED()

    pub fn IFSTOPPED(x: u32) bool {
        return status(x) == stopped and STOPSIG(x) != 0x13;
    }

IFSIGNALED()

    pub fn IFSIGNALED(x: u32) bool {
        return status(x) != stopped and status(x) != 0;
    }

    fn status(x: u32) u32 {
        return x & 0o177;
    }
    const stopped = 0o177;
};

E

pub const E = enum(u16) {
    SUCCESS = 0,

    PERM = 1,

    NOENT = 2,

    SRCH = 3,

    INTR = 4,

    IO = 5,

    NXIO = 6,

    @"2BIG" = 7,

    NOEXEC = 8,

    BADF = 9,

    CHILD = 10,

    DEADLK = 11,

    NOMEM = 12,

    ACCES = 13,

    FAULT = 14,

    NOTBLK = 15,

    BUSY = 16,

    EXIST = 17,

    XDEV = 18,

    NODEV = 19,

    NOTDIR = 20,

    ISDIR = 21,

    INVAL = 22,

    NFILE = 23,

    MFILE = 24,

    NOTTY = 25,

    TXTBSY = 26,

    FBIG = 27,

    NOSPC = 28,

    SPIPE = 29,

    ROFS = 30,

    MLINK = 31,

    PIPE = 32,

    // math software

    DOM = 33,

    RANGE = 34,

    // non-blocking and interrupt i/o

    AGAIN = 35,

    INPROGRESS = 36,

    ALREADY = 37,

    // ipc/network software -- argument errors

    NOTSOCK = 38,

    DESTADDRREQ = 39,

    MSGSIZE = 40,

    PROTOTYPE = 41,

    NOPROTOOPT = 42,

    PROTONOSUPPORT = 43,

    SOCKTNOSUPPORT = 44,

    OPNOTSUPP = 45,

    PFNOSUPPORT = 46,

    AFNOSUPPORT = 47,

    ADDRINUSE = 48,

    // ipc/network software -- operational errors
    ADDRNOTAVAIL = 49,

    NETDOWN = 50,

    NETUNREACH = 51,

    NETRESET = 52,

    CONNABORTED = 53,

    CONNRESET = 54,

    NOBUFS = 55,

    ISCONN = 56,

    NOTCONN = 57,

    SHUTDOWN = 58,

    TOOMANYREFS = 59,

    TIMEDOUT = 60,

    CONNREFUSED = 61,

    LOOP = 62,

    NAMETOOLONG = 63,

    HOSTDOWN = 64,

    HOSTUNREACH = 65,

    // quotas & mush
    NOTEMPTY = 66,

    PROCLIM = 67,

    USERS = 68,

    // Network File System
    DQUOT = 69,

    STALE = 70,

    REMOTE = 71,

    BADRPC = 72,

    RPCMISMATCH = 73,

    PROGUNAVAIL = 74,

    PROGMISMATCH = 75,

    PROCUNAVAIL = 76,

    NOLCK = 77,

    NOSYS = 78,

    FTYPE = 79,

    AUTH = 80,

    NEEDAUTH = 81,

    // Intelligent device errors

    PWROFF = 82,

    DEVERR = 83,

    OVERFLOW = 84,

    // Program loading errors

    BADEXEC = 85,

    BADARCH = 86,

    SHLIBVERS = 87,

    BADMACHO = 88,

    CANCELED = 89,

    IDRM = 90,

    NOMSG = 91,

    ILSEQ = 92,

    NOATTR = 93,

    BADMSG = 94,

    MULTIHOP = 95,

    NODATA = 96,

    NOLINK = 97,

    NOSR = 98,

    NOSTR = 99,

    PROTO = 100,

    TIME = 101,

    NOPOLICY = 103,

    NOTRECOVERABLE = 104,

    OWNERDEAD = 105,

    QFULL = 106,

    _,
};

KernE

No error occurred. Operation not permitted No such file or directory No such process Interrupted system call Input/output error Device not configured Argument list too long Exec format error Bad file descriptor No child processes Resource deadlock avoided Cannot allocate memory Permission denied Bad address Block device required Device / Resource busy File exists Cross-device link Operation not supported by device Not a directory Is a directory Invalid argument Too many open files in system Too many open files Inappropriate ioctl for device Text file busy File too large No space left on device Illegal seek Read-only file system Too many links Broken pipe Numerical argument out of domain Result too large Resource temporarily unavailable This is the same code used for WOULDBLOCK. Operation now in progress Operation already in progress Socket operation on non-socket Destination address required Message too long Protocol wrong type for socket Protocol not available Protocol not supported Socket type not supported Operation not supported The same code is used for NOTSUP. Protocol family not supported Address family not supported by protocol family Address already in use Can't assign requested address Network is down Network is unreachable Network dropped connection on reset Software caused connection abort Connection reset by peer No buffer space available Socket is already connected Socket is not connected Can't send after socket shutdown Too many references: can't splice Operation timed out Connection refused Too many levels of symbolic links File name too long Host is down No route to host Directory not empty Too many processes Too many users Disc quota exceeded Stale NFS file handle Too many levels of remote in path RPC struct is bad RPC version wrong RPC prog. not avail Program version wrong Bad procedure for program No locks available Function not implemented Inappropriate file type or format Authentication error Need authenticator Device power is off Device error, e.g. paper out Value too large to be stored in data type Bad executable Bad CPU type in executable Shared library version mismatch Malformed Macho file Operation canceled Identifier removed No message of desired type Illegal byte sequence Attribute not found Bad message Reserved No message available on STREAM Reserved No STREAM resources Not a STREAM Protocol error STREAM ioctl timeout No such policy registered State not recoverable Previous owner died Interface output queue is full Kernel return values

pub const KernE = enum(u32) {
    SUCCESS = 0,

    INVALID_ADDRESS = 1,

    PROTECTION_FAILURE = 2,

    NO_SPACE = 3,

    INVALID_ARGUMENT = 4,

    FAILURE = 5,

    RESOURCE_SHORTAGE = 6,

    NOT_RECEIVER = 7,

    NO_ACCESS = 8,

    MEMORY_FAILURE = 9,

    MEMORY_ERROR = 10,

    ALREADY_IN_SET = 11,

    NOT_IN_SET = 12,

    NAME_EXISTS = 13,

    ABORTED = 14,

    INVALID_NAME = 15,

    INVALID_TASK = 16,

    INVALID_RIGHT = 17,

    INVALID_VALUE = 18,

    UREFS_OVERFLOW = 19,

    INVALID_CAPABILITY = 20,

    RIGHT_EXISTS = 21,

    INVALID_HOST = 22,

    MEMORY_PRESENT = 23,

    MEMORY_DATA_MOVED = 24,

    MEMORY_RESTART_COPY = 25,

    INVALID_PROCESSOR_SET = 26,

    POLICY_LIMIT = 27,

    INVALID_POLICY = 28,

    INVALID_OBJECT = 29,

    ALREADY_WAITING = 30,

    DEFAULT_SET = 31,

    EXCEPTION_PROTECTED = 32,

    INVALID_LEDGER = 33,

    INVALID_MEMORY_CONTROL = 34,

    INVALID_SECURITY = 35,

    NOT_DEPRESSED = 36,

    TERMINATED = 37,

    LOCK_SET_DESTROYED = 38,

    LOCK_UNSTABLE = 39,

    LOCK_OWNED = 40,

    LOCK_OWNED_SELF = 41,

    SEMAPHORE_DESTROYED = 42,

    RPC_SERVER_TERMINATED = 43,

    RPC_TERMINATE_ORPHAN = 44,

    RPC_CONTINUE_ORPHAN = 45,

    NOT_SUPPORTED = 46,

    NODE_DOWN = 47,

    NOT_WAITING = 48,

    OPERATION_TIMED_OUT = 49,

    CODESIGN_ERROR = 50,

    POLICY_STATIC = 51,

    INSUFFICIENT_BUFFER_SIZE = 52,

    DENIED = 53,

    MISSING_KC = 54,

    INVALID_KC = 55,

    NOT_FOUND = 56,

    _,
};

mach_msg_return_t

Specified address is not currently valid Specified memory is valid, but does not permit the required forms of access. The address range specified is already in use, or no address range of the size specified could be found. The function requested was not applicable to this type of argument, or an argument is invalid The function could not be performed. A catch-all. A system resource could not be allocated to fulfill this request. This failure may not be permanent. The task in question does not hold receive rights for the port argument. Bogus access restriction. During a page fault, the target address refers to a memory object that has been destroyed. This failure is permanent. During a page fault, the memory object indicated that the data could not be returned. This failure may be temporary; future attempts to access this same data may succeed, as defined by the memory object. The receive right is already a member of the portset. The receive right is not a member of a port set. The name already denotes a right in the task. The operation was aborted. Ipc code will catch this and reflect it as a message error. The name doesn't denote a right in the task. Target task isn't an active task. The name denotes a right, but not an appropriate right. A blatant range error. Operation would overflow limit on user-references. The supplied (port) capability is improper. The task already has send or receive rights for the port under another name. Target host isn't actually a host. An attempt was made to supply "precious" data for memory that is already present in a memory object. A page was requested of a memory manager via memory_object_data_request for an object using a MEMORY_OBJECT_COPY_CALL strategy, with the VM_PROT_WANTS_COPY flag being used to specify that the page desired is for a copy of the object, and the memory manager has detected the page was pushed into a copy of the object while the kernel was walking the shadow chain from the copy to the object. This error code is delivered via memory_object_data_error and is handled by the kernel (it forces the kernel to restart the fault). It will not be seen by users. A strategic copy was attempted of an object upon which a quicker copy is now possible. The caller should retry the copy using vm_object_copy_quickly. This error code is seen only by the kernel. An argument applied to assert processor set privilege was not a processor set control port. The specified scheduling attributes exceed the thread's limits. The specified scheduling policy is not currently enabled for the processor set. The external memory manager failed to initialize the memory object. A thread is attempting to wait for an event for which there is already a waiting thread. An attempt was made to destroy the default processor set. An attempt was made to fetch an exception port that is protected, or to abort a thread while processing a protected exception. A ledger was required but not supplied. The port was not a memory cache control port. An argument supplied to assert security privilege was not a host security port. thread_depress_abort was called on a thread which was not currently depressed. Object has been terminated and is no longer available Lock set has been destroyed and is no longer available. The thread holding the lock terminated before releasing the lock The lock is already owned by another thread The lock is already owned by the calling thread Semaphore has been destroyed and is no longer available. Return from RPC indicating the target server was terminated before it successfully replied Terminate an orphaned activation. Allow an orphaned activation to continue executing. Empty thread activation (No thread linked to it) Remote node down or inaccessible. A signalled thread was not actually waiting. Some thread-oriented operation (semaphore_wait) timed out During a page fault, indicates that the page was rejected as a result of a signature check. The requested property cannot be changed at this time. The provided buffer is of insufficient size for the requested data. Denied by security policy The KC on which the function is operating is missing The KC on which the function is operating is invalid A search or query operation did not return a result

pub const mach_msg_return_t = kern_return_t;

getMachMsgError()

pub fn getMachMsgError(err: mach_msg_return_t) MachMsgE {
    return @as(MachMsgE, @enumFromInt(@as(u32, @truncate(@as(usize, @intCast(err))))));
}

MACH_MSG_MASK

All special error code bits defined below.

pub const MACH_MSG_MASK: u32 = 0x3e00;

MACH_MSG_IPC_SPACE

No room in IPC name space for another capability name.

pub const MACH_MSG_IPC_SPACE: u32 = 0x2000;

MACH_MSG_VM_SPACE

No room in VM address space for out-of-line memory.

pub const MACH_MSG_VM_SPACE: u32 = 0x1000;

MACH_MSG_IPC_KERNEL

Kernel resource shortage handling out-of-line memory.

pub const MACH_MSG_IPC_KERNEL: u32 = 0x800;

MACH_MSG_VM_KERNEL

Kernel resource shortage handling an IPC capability.

pub const MACH_MSG_VM_KERNEL: u32 = 0x400;

MachMsgE

Mach msg return values

pub const MachMsgE = enum(u32) {
    SUCCESS = 0x00000000,

    SEND_IN_PROGRESS = 0x10000001,
    SEND_INVALID_DATA = 0x10000002,
    SEND_INVALID_DEST = 0x10000003,
    SEND_TIMED_OUT = 0x10000004,
    SEND_INVALID_VOUCHER = 0x10000005,
    SEND_INTERRUPTED = 0x10000007,
    SEND_MSG_TOO_SMALL = 0x10000008,
    SEND_INVALID_REPLY = 0x10000009,
    SEND_INVALID_RIGHT = 0x1000000a,
    SEND_INVALID_NOTIFY = 0x1000000b,
    SEND_INVALID_MEMORY = 0x1000000c,
    SEND_NO_BUFFER = 0x1000000d,
    SEND_TOO_LARGE = 0x1000000e,
    SEND_INVALID_TYPE = 0x1000000f,
    SEND_INVALID_HEADER = 0x10000010,
    SEND_INVALID_TRAILER = 0x10000011,
    SEND_INVALID_CONTEXT = 0x10000012,
    SEND_INVALID_RT_OOL_SIZE = 0x10000015,
    SEND_NO_GRANT_DEST = 0x10000016,
    SEND_MSG_FILTERED = 0x10000017,

    RCV_IN_PROGRESS = 0x10004001,
    RCV_INVALID_NAME = 0x10004002,
    RCV_TIMED_OUT = 0x10004003,
    RCV_TOO_LARGE = 0x10004004,
    RCV_INTERRUPTED = 0x10004005,
    RCV_PORT_CHANGED = 0x10004006,
    RCV_INVALID_NOTIFY = 0x10004007,
    RCV_INVALID_DATA = 0x10004008,
    RCV_PORT_DIED = 0x10004009,
    RCV_IN_SET = 0x1000400a,
    RCV_HEADER_ERROR = 0x1000400b,
    RCV_BODY_ERROR = 0x1000400c,
    RCV_INVALID_TYPE = 0x1000400d,
    RCV_SCATTER_SMALL = 0x1000400e,
    RCV_INVALID_TRAILER = 0x1000400f,
    RCV_IN_PROGRESS_TIMED = 0x10004011,
    RCV_INVALID_REPLY = 0x10004012,
};

SIGSTKSZ

Thread is waiting to send. (Internal use only.) Bogus in-line data. Bogus destination port. Message not sent before timeout expired. Bogus voucher port. Software interrupt. Data doesn't contain a complete message. Bogus reply port. Bogus port rights in the message body. Bogus notify port argument. Invalid out-of-line memory pointer. No message buffer is available. Send is too large for port Invalid msg-type specification. A field in the header had a bad value. The trailer to be sent does not match kernel format. The sending thread context did not match the context on the dest port compatibility: no longer a returned error The destination port doesn't accept ports in body Message send was rejected by message filter Thread is waiting for receive. (Internal use only.) Bogus name for receive port/port-set. Didn't get a message within the timeout value. Message buffer is not large enough for inline data. Software interrupt. compatibility: no longer a returned error Bogus notify port argument. Bogus message buffer for inline data. Port/set was sent away/died during receive. compatibility: no longer a returned error Error receiving message header. See special bits. Error receiving message body. See special bits. Invalid msg-type specification in scatter list. Out-of-line overwrite region is not large enough trailer type or number of trailer elements not supported Waiting for receive with timeout. (Internal use only.) invalid reply port used in a STRICT_REPLY message

pub const SIGSTKSZ = 131072;

MINSIGSTKSZ

pub const MINSIGSTKSZ = 32768;

SS_ONSTACK

pub const SS_ONSTACK = 1;

SS_DISABLE

pub const SS_DISABLE = 4;

stack_t

pub const stack_t = extern struct {
    sp: [*]u8,
    size: isize,
    flags: i32,
};

S

pub const S = struct {
    pub const IFMT = 0o170000;

    pub const IFIFO = 0o010000;
    pub const IFCHR = 0o020000;
    pub const IFDIR = 0o040000;
    pub const IFBLK = 0o060000;
    pub const IFREG = 0o100000;
    pub const IFLNK = 0o120000;
    pub const IFSOCK = 0o140000;
    pub const IFWHT = 0o160000;

    pub const ISUID = 0o4000;
    pub const ISGID = 0o2000;
    pub const ISVTX = 0o1000;
    pub const IRWXU = 0o700;
    pub const IRUSR = 0o400;
    pub const IWUSR = 0o200;
    pub const IXUSR = 0o100;
    pub const IRWXG = 0o070;
    pub const IRGRP = 0o040;
    pub const IWGRP = 0o020;
    pub const IXGRP = 0o010;
    pub const IRWXO = 0o007;
    pub const IROTH = 0o004;
    pub const IWOTH = 0o002;
    pub const IXOTH = 0o001;

ISFIFO()

    pub fn ISFIFO(m: u32) bool {
        return m & IFMT == IFIFO;
    }

ISCHR()

    pub fn ISCHR(m: u32) bool {
        return m & IFMT == IFCHR;
    }

ISDIR()

    pub fn ISDIR(m: u32) bool {
        return m & IFMT == IFDIR;
    }

ISBLK()

    pub fn ISBLK(m: u32) bool {
        return m & IFMT == IFBLK;
    }

ISREG()

    pub fn ISREG(m: u32) bool {
        return m & IFMT == IFREG;
    }

ISLNK()

    pub fn ISLNK(m: u32) bool {
        return m & IFMT == IFLNK;
    }

ISSOCK()

    pub fn ISSOCK(m: u32) bool {
        return m & IFMT == IFSOCK;
    }

IWHT()

    pub fn IWHT(m: u32) bool {
        return m & IFMT == IFWHT;
    }
};

HOST_NAME_MAX

pub const HOST_NAME_MAX = 72;

AT

pub const AT = struct {
    pub const FDCWD = -2;
    pub const EACCESS = 0x0010;
    pub const SYMLINK_NOFOLLOW = 0x0020;
    pub const SYMLINK_FOLLOW = 0x0040;
    pub const REMOVEDIR = 0x0080;
};

addrinfo

Use effective ids in access check Act on the symlink itself not the target Act on target of symlink Path refers to directory

pub const addrinfo = extern struct {
    flags: i32,
    family: i32,
    socktype: i32,
    protocol: i32,
    addrlen: socklen_t,
    canonname: ?[*:0]u8,
    addr: ?*sockaddr,
    next: ?*addrinfo,
};

RTLD

pub const RTLD = struct {
    pub const LAZY = 0x1;
    pub const NOW = 0x2;
    pub const LOCAL = 0x4;
    pub const GLOBAL = 0x8;
    pub const NOLOAD = 0x10;
    pub const NODELETE = 0x80;
    pub const FIRST = 0x100;

    pub const NEXT = @as(*anyopaque, @ptrFromInt(@as(usize, @bitCast(@as(isize, -1)))));
    pub const DEFAULT = @as(*anyopaque, @ptrFromInt(@as(usize, @bitCast(@as(isize, -2)))));
    pub const SELF = @as(*anyopaque, @ptrFromInt(@as(usize, @bitCast(@as(isize, -3)))));
    pub const MAIN_ONLY = @as(*anyopaque, @ptrFromInt(@as(usize, @bitCast(@as(isize, -5)))));
};

F

pub const F = struct {
    pub const DUPFD = 0;
    pub const GETFD = 1;
    pub const SETFD = 2;
    pub const GETFL = 3;
    pub const SETFL = 4;
    pub const GETOWN = 5;
    pub const SETOWN = 6;
    pub const GETLK = 7;
    pub const SETLK = 8;
    pub const SETLKW = 9;
    pub const SETLKWTIMEOUT = 10;
    pub const FLUSH_DATA = 40;
    pub const CHKCLEAN = 41;
    pub const PREALLOCATE = 42;
    pub const SETSIZE = 43;
    pub const RDADVISE = 44;
    pub const RDAHEAD = 45;
    pub const NOCACHE = 48;
    pub const LOG2PHYS = 49;
    pub const GETPATH = 50;
    pub const FULLFSYNC = 51;
    pub const PATHPKG_CHECK = 52;
    pub const FREEZE_FS = 53;
    pub const THAW_FS = 54;
    pub const GLOBAL_NOCACHE = 55;
    pub const ADDSIGS = 59;
    pub const ADDFILESIGS = 61;
    pub const NODIRECT = 62;
    pub const GETPROTECTIONCLASS = 63;
    pub const SETPROTECTIONCLASS = 64;
    pub const LOG2PHYS_EXT = 65;
    pub const GETLKPID = 66;
    pub const SETBACKINGSTORE = 70;
    pub const GETPATH_MTMINFO = 71;
    pub const GETCODEDIR = 72;
    pub const SETNOSIGPIPE = 73;
    pub const GETNOSIGPIPE = 74;
    pub const TRANSCODEKEY = 75;
    pub const SINGLE_WRITER = 76;
    pub const GETPROTECTIONLEVEL = 77;
    pub const FINDSIGS = 78;
    pub const ADDFILESIGS_FOR_DYLD_SIM = 83;
    pub const BARRIERFSYNC = 85;
    pub const ADDFILESIGS_RETURN = 97;
    pub const CHECK_LV = 98;
    pub const PUNCHHOLE = 99;
    pub const TRIM_ACTIVE_FILE = 100;
    pub const DUPFD_CLOEXEC = 67;
    pub const RDLCK = 1;
    pub const UNLCK = 2;
    pub const WRLCK = 3;
};

FCNTL_FS_SPECIFIC_BASE

duplicate file descriptor get file descriptor flags set file descriptor flags get file status flags set file status flags get SIGIO/SIGURG proc/pgrp set SIGIO/SIGURG proc/pgrp get record locking information set record locking information F.SETLK; wait if blocked F.SETLK; wait if blocked, return on timeout Used for regression test Preallocate storage Truncate a file without zeroing space Issue an advisory read async with no copy to user turn read ahead off/on for this fd turn data caching off/on for this fd file offset to device offset return the full path of the fd fsync + ask the drive to flush to the media find which component (if any) is a package "freeze" all fs operations "thaw" all fs operations turn data caching off/on (globally) for this file add detached signatures add signature from same file (used by dyld for shared libs) used in conjunction with F.NOCACHE to indicate that DIRECT, synchronous writes should not be used (i.e. its ok to temporaily create cached pages)Get the protection class of a file from the EA, returns intSet the protection class of a file for the EA, requires intfile offset to device offset, extendedget record locking information, per-processMark the file as being the backing store for another filesystemreturn the full path of the FD, but error in specific mtmd circumstancesReturns the code directory, with associated hashes, to the callerNo SIGPIPE generated on EPIPEStatus of SIGPIPE for this fdFor some cases, we need to rewrap the key for AKS/MKBfile being written to a by single writer... if throttling enabled, writesmay be broken into smaller chunks with throttling in betweenGet the protection version number for this filesystemAdd detached code signatures (used by dyld for shared libs)Add signature from same file, only if it is signed by Apple (used by dyld for simulator)fsync + issue barrier to driveAdd signature from same file, return end offset in structure on successCheck if Library Validation allows this Mach-O file to be mapped into the calling processDeallocate a range of the fileTrim an active filemark the dup with FD_CLOEXEC shared or read lock unlock exclusive or write lock

pub const FCNTL_FS_SPECIFIC_BASE = 0x00010000;

FD_CLOEXEC

close-on-exec flag

pub const FD_CLOEXEC = 1;

LOCK

pub const LOCK = struct {
    pub const SH = 1;
    pub const EX = 2;
    pub const UN = 8;
    pub const NB = 4;
};

nfds_t

pub const nfds_t = u32;

pollfd

pub const pollfd = extern struct {
    fd: fd_t,
    events: i16,
    revents: i16,
};

POLL

pub const POLL = struct {
    pub const IN = 0x001;
    pub const PRI = 0x002;
    pub const OUT = 0x004;
    pub const RDNORM = 0x040;
    pub const WRNORM = OUT;
    pub const RDBAND = 0x080;
    pub const WRBAND = 0x100;

    pub const EXTEND = 0x0200;
    pub const ATTRIB = 0x0400;
    pub const NLINK = 0x0800;
    pub const WRITE = 0x1000;

    pub const ERR = 0x008;
    pub const HUP = 0x010;
    pub const NVAL = 0x020;

    pub const STANDARD = IN | PRI | OUT | RDNORM | RDBAND | WRBAND | ERR | HUP | NVAL;
};

CLOCK

pub const CLOCK = struct {
    pub const REALTIME = 0;
    pub const MONOTONIC = 6;
    pub const MONOTONIC_RAW = 4;
    pub const MONOTONIC_RAW_APPROX = 5;
    pub const UPTIME_RAW = 8;
    pub const UPTIME_RAW_APPROX = 9;
    pub const PROCESS_CPUTIME_ID = 12;
    pub const THREAD_CPUTIME_ID = 16;
};

OPEN_MAX

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;

rusage

pub const rusage = extern struct {
    utime: timeval,
    stime: timeval,
    maxrss: isize,
    ixrss: isize,
    idrss: isize,
    isrss: isize,
    minflt: isize,
    majflt: isize,
    nswap: isize,
    inblock: isize,
    oublock: isize,
    msgsnd: isize,
    msgrcv: isize,
    nsignals: isize,
    nvcsw: isize,
    nivcsw: isize,

    pub const SELF = 0;
    pub const CHILDREN = -1;
};

rlimit_resource

pub const rlimit_resource = enum(c_int) {
    CPU = 0,
    FSIZE = 1,
    DATA = 2,
    STACK = 3,
    CORE = 4,
    RSS = 5,
    MEMLOCK = 6,
    NPROC = 7,
    NOFILE = 8,
    _,

    pub const AS: rlimit_resource = .RSS;
};

rlim_t

pub const rlim_t = u64;

RLIM

pub const RLIM = struct {
    pub const INFINITY: rlim_t = (1 << 63) - 1;

    pub const SAVED_MAX = INFINITY;
    pub const SAVED_CUR = INFINITY;
};

rlimit

No limit

pub const rlimit = extern struct {
    cur: rlim_t,
    max: rlim_t,
};

SHUT

Soft limit Hard limit

pub const SHUT = struct {
    pub const RD = 0;
    pub const WR = 1;
    pub const RDWR = 2;
};

// Term

V

pub const V = struct {
    pub const EOF = 0;
    pub const EOL = 1;
    pub const EOL2 = 2;
    pub const ERASE = 3;
    pub const WERASE = 4;
    pub const KILL = 5;
    pub const REPRINT = 6;
    pub const INTR = 8;
    pub const QUIT = 9;
    pub const SUSP = 10;
    pub const DSUSP = 11;
    pub const START = 12;
    pub const STOP = 13;
    pub const LNEXT = 14;
    pub const DISCARD = 15;
    pub const MIN = 16;
    pub const TIME = 17;
    pub const STATUS = 18;
};

NCCS

pub const NCCS = 20; // 2 spares (7, 19)

cc_t

pub const cc_t = u8;

speed_t

pub const speed_t = u64;

tcflag_t

pub const tcflag_t = u64;

IGNBRK

pub const IGNBRK: tcflag_t = 0x00000001; // ignore BREAK condition

BRKINT

pub const BRKINT: tcflag_t = 0x00000002; // map BREAK to SIGINTR

IGNPAR

pub const IGNPAR: tcflag_t = 0x00000004; // ignore (discard) parity errors

PARMRK

pub const PARMRK: tcflag_t = 0x00000008; // mark parity and framing errors

INPCK

pub const INPCK: tcflag_t = 0x00000010; // enable checking of parity errors

ISTRIP

pub const ISTRIP: tcflag_t = 0x00000020; // strip 8th bit off chars

INLCR

pub const INLCR: tcflag_t = 0x00000040; // map NL into CR

IGNCR

pub const IGNCR: tcflag_t = 0x00000080; // ignore CR

ICRNL

pub const ICRNL: tcflag_t = 0x00000100; // map CR to NL (ala CRMOD)

IXON

pub const IXON: tcflag_t = 0x00000200; // enable output flow control

IXOFF

pub const IXOFF: tcflag_t = 0x00000400; // enable input flow control

IXANY

pub const IXANY: tcflag_t = 0x00000800; // any char will restart after stop

IMAXBEL

pub const IMAXBEL: tcflag_t = 0x00002000; // ring bell on input queue full

IUTF8

pub const IUTF8: tcflag_t = 0x00004000; // maintain state for UTF-8 VERASE

OPOST

pub const OPOST: tcflag_t = 0x00000001; //enable following output processing

ONLCR

pub const ONLCR: tcflag_t = 0x00000002; // map NL to CR-NL (ala CRMOD)

OXTABS

pub const OXTABS: tcflag_t = 0x00000004; // expand tabs to spaces

ONOEOT

pub const ONOEOT: tcflag_t = 0x00000008; // discard EOT's (^D) on output)

OCRNL

pub const OCRNL: tcflag_t = 0x00000010; // map CR to NL on output

ONOCR

pub const ONOCR: tcflag_t = 0x00000020; // no CR output at column 0

ONLRET

pub const ONLRET: tcflag_t = 0x00000040; // NL performs CR function

OFILL

pub const OFILL: tcflag_t = 0x00000080; // use fill characters for delay

NLDLY

pub const NLDLY: tcflag_t = 0x00000300; // \n delay

TABDLY

pub const TABDLY: tcflag_t = 0x00000c04; // horizontal tab delay

CRDLY

pub const CRDLY: tcflag_t = 0x00003000; // \r delay

FFDLY

pub const FFDLY: tcflag_t = 0x00004000; // form feed delay

BSDLY

pub const BSDLY: tcflag_t = 0x00008000; // \b delay

VTDLY

pub const VTDLY: tcflag_t = 0x00010000; // vertical tab delay

OFDEL

pub const OFDEL: tcflag_t = 0x00020000; // fill is DEL, else NUL

NL0

pub const NL0: tcflag_t = 0x00000000;

NL1

pub const NL1: tcflag_t = 0x00000100;

NL2

pub const NL2: tcflag_t = 0x00000200;

NL3

pub const NL3: tcflag_t = 0x00000300;

TAB0

pub const TAB0: tcflag_t = 0x00000000;

TAB1

pub const TAB1: tcflag_t = 0x00000400;

TAB2

pub const TAB2: tcflag_t = 0x00000800;

TAB3

pub const TAB3: tcflag_t = 0x00000004;

CR0

pub const CR0: tcflag_t = 0x00000000;

CR1

pub const CR1: tcflag_t = 0x00001000;

CR2

pub const CR2: tcflag_t = 0x00002000;

CR3

pub const CR3: tcflag_t = 0x00003000;

FF0

pub const FF0: tcflag_t = 0x00000000;

FF1

pub const FF1: tcflag_t = 0x00004000;

BS0

pub const BS0: tcflag_t = 0x00000000;

BS1

pub const BS1: tcflag_t = 0x00008000;

VT0

pub const VT0: tcflag_t = 0x00000000;

VT1

pub const VT1: tcflag_t = 0x00010000;

CIGNORE

pub const CIGNORE: tcflag_t = 0x00000001; // ignore control flags

CSIZE

pub const CSIZE: tcflag_t = 0x00000300; // character size mask

CS5

pub const CS5: tcflag_t = 0x00000000; //    5 bits (pseudo)

CS6

pub const CS6: tcflag_t = 0x00000100; //    6 bits

CS7

pub const CS7: tcflag_t = 0x00000200; //    7 bits

CS8

pub const CS8: tcflag_t = 0x00000300; //    8 bits

CSTOPB

pub const CSTOPB: tcflag_t = 0x0000040; // send 2 stop bits

CREAD

pub const CREAD: tcflag_t = 0x00000800; // enable receiver

PARENB

pub const PARENB: tcflag_t = 0x00001000; // parity enable

PARODD

pub const PARODD: tcflag_t = 0x00002000; // odd parity, else even

HUPCL

pub const HUPCL: tcflag_t = 0x00004000; // hang up on last close

CLOCAL

pub const CLOCAL: tcflag_t = 0x00008000; // ignore modem status lines

CCTS_OFLOW

pub const CCTS_OFLOW: tcflag_t = 0x00010000; // CTS flow control of output

CRTSCTS

pub const CRTSCTS: tcflag_t = (CCTS_OFLOW | CRTS_IFLOW);

CRTS_IFLOW

pub const CRTS_IFLOW: tcflag_t = 0x00020000; // RTS flow control of input

CDTR_IFLOW

pub const CDTR_IFLOW: tcflag_t = 0x00040000; // DTR flow control of input

CDSR_OFLOW

pub const CDSR_OFLOW: tcflag_t = 0x00080000; // DSR flow control of output

CCAR_OFLOW

pub const CCAR_OFLOW: tcflag_t = 0x00100000; // DCD flow control of output

MDMBUF

pub const MDMBUF: tcflag_t = 0x00100000; // old name for CCAR_OFLOW

ECHOKE

pub const ECHOKE: tcflag_t = 0x00000001; // visual erase for line kill

ECHOE

pub const ECHOE: tcflag_t = 0x00000002; // visually erase chars

ECHOK

pub const ECHOK: tcflag_t = 0x00000004; // echo NL after line kill

ECHO

pub const ECHO: tcflag_t = 0x00000008; // enable echoing

ECHONL

pub const ECHONL: tcflag_t = 0x00000010; // echo NL even if ECHO is off

ECHOPRT

pub const ECHOPRT: tcflag_t = 0x00000020; // visual erase mode for hardcopy

ECHOCTL

pub const ECHOCTL: tcflag_t = 0x00000040; // echo control chars as ^(Char)

ISIG

pub const ISIG: tcflag_t = 0x00000080; // enable signals INTR, QUIT, [D]SUSP

ICANON

pub const ICANON: tcflag_t = 0x00000100; // canonicalize input lines

ALTWERASE

pub const ALTWERASE: tcflag_t = 0x00000200; // use alternate WERASE algorithm

IEXTEN

pub const IEXTEN: tcflag_t = 0x00000400; // enable DISCARD and LNEXT

EXTPROC

pub const EXTPROC: tcflag_t = 0x00000800; // external processing

TOSTOP

pub const TOSTOP: tcflag_t = 0x00400000; // stop background jobs from output

FLUSHO

pub const FLUSHO: tcflag_t = 0x00800000; // output being flushed (state)

NOKERNINFO

pub const NOKERNINFO: tcflag_t = 0x02000000; // no kernel output from VSTATUS

PENDIN

pub const PENDIN: tcflag_t = 0x20000000; // XXX retype pending input (state)

NOFLSH

pub const NOFLSH: tcflag_t = 0x80000000; // don't flush after interrupt

TCSANOW

pub const TCSANOW: tcflag_t = 0; // make change immediate

TCSADRAIN

pub const TCSADRAIN: tcflag_t = 1; // drain output, then change

TCSAFLUSH

pub const TCSAFLUSH: tcflag_t = 2; // drain output, flush input

TCSASOFT

pub const TCSASOFT: tcflag_t = 0x10; // flag - don't alter h.w. state

TCSA

pub const TCSA = enum(c_uint) {
    NOW,
    DRAIN,
    FLUSH,
    _,
};

B0

pub const B0: tcflag_t = 0;

B50

pub const B50: tcflag_t = 50;

B75

pub const B75: tcflag_t = 75;

B110

pub const B110: tcflag_t = 110;

B134

pub const B134: tcflag_t = 134;

B150

pub const B150: tcflag_t = 150;

B200

pub const B200: tcflag_t = 200;

B300

pub const B300: tcflag_t = 300;

B600

pub const B600: tcflag_t = 600;

B1200

pub const B1200: tcflag_t = 1200;

B1800

pub const B1800: tcflag_t = 1800;

B2400

pub const B2400: tcflag_t = 2400;

B4800

pub const B4800: tcflag_t = 4800;

B9600

pub const B9600: tcflag_t = 9600;

B19200

pub const B19200: tcflag_t = 19200;

B38400

pub const B38400: tcflag_t = 38400;

B7200

pub const B7200: tcflag_t = 7200;

B14400

pub const B14400: tcflag_t = 14400;

B28800

pub const B28800: tcflag_t = 28800;

B57600

pub const B57600: tcflag_t = 57600;

B76800

pub const B76800: tcflag_t = 76800;

B115200

pub const B115200: tcflag_t = 115200;

B230400

pub const B230400: tcflag_t = 230400;

EXTA

pub const EXTA: tcflag_t = 19200;

EXTB

pub const EXTB: tcflag_t = 38400;

TCIFLUSH

pub const TCIFLUSH: tcflag_t = 1;

TCOFLUSH

pub const TCOFLUSH: tcflag_t = 2;

TCIOFLUSH

pub const TCIOFLUSH: tcflag_t = 3;

TCOOFF

pub const TCOOFF: tcflag_t = 1;

TCOON

pub const TCOON: tcflag_t = 2;

TCIOFF

pub const TCIOFF: tcflag_t = 3;

TCION

pub const TCION: tcflag_t = 4;

termios

pub const termios = extern struct {
    iflag: tcflag_t, // input flags
    oflag: tcflag_t, // output flags
    cflag: tcflag_t, // control flags
    lflag: tcflag_t, // local flags
    cc: [NCCS]cc_t, // control chars
    ispeed: speed_t align(8), // input speed
    ospeed: speed_t, // output speed
};

winsize

pub const winsize = extern struct {
    ws_row: u16,
    ws_col: u16,
    ws_xpixel: u16,
    ws_ypixel: u16,
};

T

pub const T = struct {
    pub const IOCGWINSZ = ior(0x40000000, 't', 104, @sizeOf(winsize));
};

IOCPARM_MASK

pub const IOCPARM_MASK = 0x1fff;

fn ior(inout: u32, group: usize, num: usize, len: usize) usize {
    return (inout | ((len & IOCPARM_MASK) << 16) | ((group) << 8) | (num));
}

// CPU families mapping

CPUFAMILY

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,
    _,
};

PT

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

caddr_t

pub const caddr_t = ?[*]u8;

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

POSIX_SPAWN

pub const POSIX_SPAWN = struct {
    pub const RESETIDS = 0x0001;
    pub const SETPGROUP = 0x0002;
    pub const SETSIGDEF = 0x0004;
    pub const SETSIGMASK = 0x0008;
    pub const SETEXEC = 0x0040;
    pub const START_SUSPENDED = 0x0080;
    pub const DISABLE_ASLR = 0x0100;
    pub const SETSID = 0x0400;
    pub const RESLIDE = 0x0800;
    pub const CLOEXEC_DEFAULT = 0x4000;
};

posix_spawnattr_t

pub const posix_spawnattr_t = *opaque {};

posix_spawn_file_actions_t

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: c_short) c_int;
pub extern "c" fn posix_spawnattr_getflags(attr: *const posix_spawnattr_t, flags: *c_short) 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]?[*:0]const u8,
    env: [*:null]?[*: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]?[*:0]const u8,
    env: [*:null]?[*:0]const u8,
) c_int;

PosixSpawn

pub const PosixSpawn = struct {
    const errno = std.os.errno;
    const unexpectedErrno = std.os.unexpectedErrno;

    pub const Error = error{
        SystemResources,
        InvalidFileDescriptor,
        NameTooLong,
        TooBig,
        PermissionDenied,
        InputOutput,
        FileSystem,
        FileNotFound,
        InvalidExe,
        NotDir,
        FileBusy,
        ChildExecFailed,
    } || std.os.UnexpectedError;

    pub const Attr = struct {
        attr: posix_spawnattr_t,

init()

Returned when the child fails to execute either in the pre-exec() initialization step, or when exec(3) is invoked.

        pub fn init() Error!Attr {
            var attr: posix_spawnattr_t = undefined;
            switch (errno(posix_spawnattr_init(&attr))) {
                .SUCCESS => return Attr{ .attr = attr },
                .NOMEM => return error.SystemResources,
                .INVAL => unreachable,
                else => |err| return unexpectedErrno(err),
            }
        }

deinit()

        pub fn deinit(self: *Attr) void {
            defer self.* = undefined;
            switch (errno(posix_spawnattr_destroy(&self.attr))) {
                .SUCCESS => return,
                .INVAL => unreachable, // Invalid parameters.
                else => unreachable,
            }
        }

get()

        pub fn get(self: Attr) Error!u16 {
            var flags: c_short = undefined;
            switch (errno(posix_spawnattr_getflags(&self.attr, &flags))) {
                .SUCCESS => return @as(u16, @bitCast(flags)),
                .INVAL => unreachable,
                else => |err| return unexpectedErrno(err),
            }
        }

set()

        pub fn set(self: *Attr, flags: u16) Error!void {
            switch (errno(posix_spawnattr_setflags(&self.attr, @as(c_short, @bitCast(flags))))) {
                .SUCCESS => return,
                .INVAL => unreachable,
                else => |err| return unexpectedErrno(err),
            }
        }
    };

    pub const Actions = struct {
        actions: posix_spawn_file_actions_t,

init()

        pub fn init() Error!Actions {
            var actions: posix_spawn_file_actions_t = undefined;
            switch (errno(posix_spawn_file_actions_init(&actions))) {
                .SUCCESS => return Actions{ .actions = actions },
                .NOMEM => return error.SystemResources,
                .INVAL => unreachable,
                else => |err| return unexpectedErrno(err),
            }
        }

deinit()

        pub fn deinit(self: *Actions) void {
            defer self.* = undefined;
            switch (errno(posix_spawn_file_actions_destroy(&self.actions))) {
                .SUCCESS => return,
                .INVAL => unreachable, // Invalid parameters.
                else => unreachable,
            }
        }

open()

        pub fn open(self: *Actions, fd: fd_t, path: []const u8, flags: u32, mode: mode_t) Error!void {
            const posix_path = try std.os.toPosixPath(path);
            return self.openZ(fd, &posix_path, flags, mode);
        }

openZ()

        pub fn openZ(self: *Actions, fd: fd_t, path: [*:0]const u8, flags: u32, mode: mode_t) Error!void {
            switch (errno(posix_spawn_file_actions_addopen(&self.actions, fd, path, @as(c_int, @bitCast(flags)), mode))) {
                .SUCCESS => return,
                .BADF => return error.InvalidFileDescriptor,
                .NOMEM => return error.SystemResources,
                .NAMETOOLONG => return error.NameTooLong,
                .INVAL => unreachable, // the value of file actions is invalid
                else => |err| return unexpectedErrno(err),
            }
        }

close()

        pub fn close(self: *Actions, fd: fd_t) Error!void {
            switch (errno(posix_spawn_file_actions_addclose(&self.actions, fd))) {
                .SUCCESS => return,
                .BADF => return error.InvalidFileDescriptor,
                .NOMEM => return error.SystemResources,
                .INVAL => unreachable, // the value of file actions is invalid
                .NAMETOOLONG => unreachable,
                else => |err| return unexpectedErrno(err),
            }
        }

dup2()

        pub fn dup2(self: *Actions, fd: fd_t, newfd: fd_t) Error!void {
            switch (errno(posix_spawn_file_actions_adddup2(&self.actions, fd, newfd))) {
                .SUCCESS => return,
                .BADF => return error.InvalidFileDescriptor,
                .NOMEM => return error.SystemResources,
                .INVAL => unreachable, // the value of file actions is invalid
                .NAMETOOLONG => unreachable,
                else => |err| return unexpectedErrno(err),
            }
        }

inherit()

        pub fn inherit(self: *Actions, fd: fd_t) Error!void {
            switch (errno(posix_spawn_file_actions_addinherit_np(&self.actions, fd))) {
                .SUCCESS => return,
                .BADF => return error.InvalidFileDescriptor,
                .NOMEM => return error.SystemResources,
                .INVAL => unreachable, // the value of file actions is invalid
                .NAMETOOLONG => unreachable,
                else => |err| return unexpectedErrno(err),
            }
        }

chdir()

        pub fn chdir(self: *Actions, path: []const u8) Error!void {
            const posix_path = try std.os.toPosixPath(path);
            return self.chdirZ(&posix_path);
        }

chdirZ()

        pub fn chdirZ(self: *Actions, path: [*:0]const u8) Error!void {
            switch (errno(posix_spawn_file_actions_addchdir_np(&self.actions, path))) {
                .SUCCESS => return,
                .NOMEM => return error.SystemResources,
                .NAMETOOLONG => return error.NameTooLong,
                .BADF => unreachable,
                .INVAL => unreachable, // the value of file actions is invalid
                else => |err| return unexpectedErrno(err),
            }
        }

fchdir()

        pub fn fchdir(self: *Actions, fd: fd_t) Error!void {
            switch (errno(posix_spawn_file_actions_addfchdir_np(&self.actions, fd))) {
                .SUCCESS => return,
                .BADF => return error.InvalidFileDescriptor,
                .NOMEM => return error.SystemResources,
                .INVAL => unreachable, // the value of file actions is invalid
                .NAMETOOLONG => unreachable,
                else => |err| return unexpectedErrno(err),
            }
        }
    };

spawn()

    pub fn spawn(
        path: []const u8,
        actions: ?Actions,
        attr: ?Attr,
        argv: [*:null]?[*:0]const u8,
        envp: [*:null]?[*:0]const u8,
    ) Error!pid_t {
        const posix_path = try std.os.toPosixPath(path);
        return spawnZ(&posix_path, actions, attr, argv, envp);
    }

spawnZ()

    pub fn spawnZ(
        path: [*:0]const u8,
        actions: ?Actions,
        attr: ?Attr,
        argv: [*:null]?[*:0]const u8,
        envp: [*:null]?[*:0]const u8,
    ) Error!pid_t {
        var pid: pid_t = undefined;
        switch (errno(posix_spawn(
            &pid,
            path,
            if (actions) |a| &a.actions else null,
            if (attr) |a| &a.attr else null,
            argv,
            envp,
        ))) {
            .SUCCESS => return pid,
            .@"2BIG" => return error.TooBig,
            .NOMEM => return error.SystemResources,
            .BADF => return error.InvalidFileDescriptor,
            .ACCES => return error.PermissionDenied,
            .IO => return error.InputOutput,
            .LOOP => return error.FileSystem,
            .NAMETOOLONG => return error.NameTooLong,
            .NOENT => return error.FileNotFound,
            .NOEXEC => return error.InvalidExe,
            .NOTDIR => return error.NotDir,
            .TXTBSY => return error.FileBusy,
            .BADARCH => return error.InvalidExe,
            .BADEXEC => return error.InvalidExe,
            .FAULT => unreachable,
            .INVAL => unreachable,
            else => |err| return unexpectedErrno(err),
        }
    }

waitpid()

    pub fn waitpid(pid: pid_t, flags: u32) Error!std.os.WaitPidResult {
        var status: c_int = undefined;
        while (true) {
            const rc = waitpid(pid, &status, @as(c_int, @intCast(flags)));
            switch (errno(rc)) {
                .SUCCESS => return std.os.WaitPidResult{
                    .pid = @as(pid_t, @intCast(rc)),
                    .status = @as(u32, @bitCast(status)),
                },
                .INTR => continue,
                .CHILD => return error.ChildExecFailed,
                .INVAL => unreachable, // Invalid flags.
                else => unreachable,
            }
        }
    }
};

getKernError()

pub fn getKernError(err: kern_return_t) KernE {
    return @as(KernE, @enumFromInt(@as(u32, @truncate(@as(usize, @intCast(err))))));
}

unexpectedKernError()

pub fn unexpectedKernError(err: KernE) std.os.UnexpectedError {
    if (std.os.unexpected_error_tracing) {
        std.debug.print("unexpected error: {d}\n", .{@intFromEnum(err)});
        std.debug.dumpCurrentStackTrace(null);
    }
    return error.Unexpected;
}

MachError

pub const MachError = error{
    PermissionDenied,
} || std.os.UnexpectedError;

MachTask

Not enough permissions held to perform the requested kernel call.

pub const MachTask = extern struct {
    port: mach_port_name_t,

isValid()

    pub fn isValid(self: MachTask) bool {
        return self.port != TASK_NULL;
    }

pidForTask()

    pub fn pidForTask(self: MachTask) MachError!std.os.pid_t {
        var pid: std.os.pid_t = undefined;
        switch (getKernError(pid_for_task(self.port, &pid))) {
            .SUCCESS => return pid,
            .FAILURE => return error.PermissionDenied,
            else => |err| return unexpectedKernError(err),
        }
    }

allocatePort()

    pub fn allocatePort(self: MachTask, right: MACH_PORT_RIGHT) MachError!MachTask {
        var out_port: mach_port_name_t = undefined;
        switch (getKernError(mach_port_allocate(
            self.port,
            @intFromEnum(right),
            &out_port,
        ))) {
            .SUCCESS => return .{ .port = out_port },
            .FAILURE => return error.PermissionDenied,
            else => |err| return unexpectedKernError(err),
        }
    }

deallocatePort()

    pub fn deallocatePort(self: MachTask, port: MachTask) void {
        _ = getKernError(mach_port_deallocate(self.port, port.port));
    }

insertRight()

    pub fn insertRight(self: MachTask, port: MachTask, msg: MACH_MSG_TYPE) !void {
        switch (getKernError(mach_port_insert_right(
            self.port,
            port.port,
            port.port,
            @intFromEnum(msg),
        ))) {
            .SUCCESS => return,
            .FAILURE => return error.PermissionDenied,
            else => |err| return unexpectedKernError(err),
        }
    }

    pub const PortInfo = struct {
        mask: exception_mask_t,
        masks: [EXC_TYPES_COUNT]exception_mask_t,
        ports: [EXC_TYPES_COUNT]mach_port_t,
        behaviors: [EXC_TYPES_COUNT]exception_behavior_t,
        flavors: [EXC_TYPES_COUNT]thread_state_flavor_t,
        count: mach_msg_type_number_t,
    };

getExceptionPorts()

    pub fn getExceptionPorts(self: MachTask, mask: exception_mask_t) !PortInfo {
        var info = PortInfo{
            .mask = mask,
            .masks = undefined,
            .ports = undefined,
            .behaviors = undefined,
            .flavors = undefined,
            .count = 0,
        };
        info.count = info.ports.len / @sizeOf(mach_port_t);

        switch (getKernError(task_get_exception_ports(
            self.port,
            info.mask,
            &info.masks,
            &info.count,
            &info.ports,
            &info.behaviors,
            &info.flavors,
        ))) {
            .SUCCESS => return info,
            .FAILURE => return error.PermissionDenied,
            else => |err| return unexpectedKernError(err),
        }
    }

setExceptionPorts()

    pub fn setExceptionPorts(
        self: MachTask,
        mask: exception_mask_t,
        new_port: MachTask,
        behavior: exception_behavior_t,
        new_flavor: thread_state_flavor_t,
    ) !void {
        switch (getKernError(task_set_exception_ports(
            self.port,
            mask,
            new_port.port,
            behavior,
            new_flavor,
        ))) {
            .SUCCESS => return,
            .FAILURE => return error.PermissionDenied,
            else => |err| return unexpectedKernError(err),
        }
    }

    pub const RegionInfo = struct {
        pub const Tag = enum {
            basic,
            extended,
            top,
        };

        base_addr: u64,
        tag: Tag,
        info: union {
            basic: vm_region_basic_info_64,
            extended: vm_region_extended_info,
            top: vm_region_top_info,
        },
    };

getRegionInfo()

    pub fn getRegionInfo(
        task: MachTask,
        address: u64,
        len: usize,
        tag: RegionInfo.Tag,
    ) MachError!RegionInfo {
        var info: RegionInfo = .{
            .base_addr = address,
            .tag = tag,
            .info = undefined,
        };
        switch (tag) {
            .basic => info.info = .{ .basic = undefined },
            .extended => info.info = .{ .extended = undefined },
            .top => info.info = .{ .top = undefined },
        }
        var base_len: mach_vm_size_t = if (len == 1) 2 else len;
        var objname: mach_port_t = undefined;
        var count: mach_msg_type_number_t = switch (tag) {
            .basic => VM_REGION_BASIC_INFO_COUNT,
            .extended => VM_REGION_EXTENDED_INFO_COUNT,
            .top => VM_REGION_TOP_INFO_COUNT,
        };
        switch (getKernError(mach_vm_region(
            task.port,
            &info.base_addr,
            &base_len,
            switch (tag) {
                .basic => VM_REGION_BASIC_INFO_64,
                .extended => VM_REGION_EXTENDED_INFO,
                .top => VM_REGION_TOP_INFO,
            },
            switch (tag) {
                .basic => @as(vm_region_info_t, @ptrCast(&info.info.basic)),
                .extended => @as(vm_region_info_t, @ptrCast(&info.info.extended)),
                .top => @as(vm_region_info_t, @ptrCast(&info.info.top)),
            },
            &count,
            &objname,
        ))) {
            .SUCCESS => return info,
            .FAILURE => return error.PermissionDenied,
            else => |err| return unexpectedKernError(err),
        }
    }

    pub const RegionSubmapInfo = struct {
        pub const Tag = enum {
            short,
            full,
        };

        tag: Tag,
        base_addr: u64,
        info: union {
            short: vm_region_submap_short_info_64,
            full: vm_region_submap_info_64,
        },
    };

getRegionSubmapInfo()

    pub fn getRegionSubmapInfo(
        task: MachTask,
        address: u64,
        len: usize,
        nesting_depth: u32,
        tag: RegionSubmapInfo.Tag,
    ) MachError!RegionSubmapInfo {
        var info: RegionSubmapInfo = .{
            .base_addr = address,
            .tag = tag,
            .info = undefined,
        };
        switch (tag) {
            .short => info.info = .{ .short = undefined },
            .full => info.info = .{ .full = undefined },
        }
        var nesting = nesting_depth;
        var base_len: mach_vm_size_t = if (len == 1) 2 else len;
        var count: mach_msg_type_number_t = switch (tag) {
            .short => VM_REGION_SUBMAP_SHORT_INFO_COUNT_64,
            .full => VM_REGION_SUBMAP_INFO_COUNT_64,
        };
        switch (getKernError(mach_vm_region_recurse(
            task.port,
            &info.base_addr,
            &base_len,
            &nesting,
            switch (tag) {
                .short => @as(vm_region_recurse_info_t, @ptrCast(&info.info.short)),
                .full => @as(vm_region_recurse_info_t, @ptrCast(&info.info.full)),
            },
            &count,
        ))) {
            .SUCCESS => return info,
            .FAILURE => return error.PermissionDenied,
            else => |err| return unexpectedKernError(err),
        }
    }

getCurrProtection()

    pub fn getCurrProtection(task: MachTask, address: u64, len: usize) MachError!vm_prot_t {
        const info = try task.getRegionSubmapInfo(address, len, 0, .short);
        return info.info.short.protection;
    }

setMaxProtection()

    pub fn setMaxProtection(task: MachTask, address: u64, len: usize, prot: vm_prot_t) MachError!void {
        return task.setProtectionImpl(address, len, true, prot);
    }

setCurrProtection()

    pub fn setCurrProtection(task: MachTask, address: u64, len: usize, prot: vm_prot_t) MachError!void {
        return task.setProtectionImpl(address, len, false, prot);
    }

    fn setProtectionImpl(task: MachTask, address: u64, len: usize, set_max: bool, prot: vm_prot_t) MachError!void {
        switch (getKernError(mach_vm_protect(task.port, address, len, @intFromBool(set_max), prot))) {
            .SUCCESS => return,
            .FAILURE => return error.PermissionDenied,
            else => |err| return unexpectedKernError(err),
        }
    }

writeMemProtected()

Will write to VM even if current protection attributes specifically prohibit us from doing so, by temporarily setting protection level to a level with VM_PROT_COPY variant, and resetting after a successful or unsuccessful write.

    pub fn writeMemProtected(task: MachTask, address: u64, buf: []const u8, arch: std.Target.Cpu.Arch) MachError!usize {
        const curr_prot = try task.getCurrProtection(address, buf.len);
        try task.setCurrProtection(
            address,
            buf.len,
            PROT.READ | PROT.WRITE | PROT.COPY,
        );
        defer {
            task.setCurrProtection(address, buf.len, curr_prot) catch {};
        }
        return task.writeMem(address, buf, arch);
    }

writeMem()

    pub fn writeMem(task: MachTask, address: u64, buf: []const u8, arch: std.Target.Cpu.Arch) MachError!usize {
        const count = buf.len;
        var total_written: usize = 0;
        var curr_addr = address;
        const page_size = try getPageSize(task); // TODO we probably can assume value here
        var out_buf = buf[0..];

        while (total_written < count) {
            const curr_size = maxBytesLeftInPage(page_size, curr_addr, count - total_written);
            switch (getKernError(mach_vm_write(
                task.port,
                curr_addr,
                @intFromPtr(out_buf.ptr),
                @as(mach_msg_type_number_t, @intCast(curr_size)),
            ))) {
                .SUCCESS => {},
                .FAILURE => return error.PermissionDenied,
                else => |err| return unexpectedKernError(err),
            }

            switch (arch) {
                .aarch64 => {
                    var mattr_value: vm_machine_attribute_val_t = MATTR_VAL_CACHE_FLUSH;
                    switch (getKernError(vm_machine_attribute(
                        task.port,
                        curr_addr,
                        curr_size,
                        MATTR_CACHE,
                        &mattr_value,
                    ))) {
                        .SUCCESS => {},
                        .FAILURE => return error.PermissionDenied,
                        else => |err| return unexpectedKernError(err),
                    }
                },
                .x86_64 => {},
                else => unreachable,
            }

            out_buf = out_buf[curr_size..];
            total_written += curr_size;
            curr_addr += curr_size;
        }

        return total_written;
    }

readMem()

    pub fn readMem(task: MachTask, address: u64, buf: []u8) MachError!usize {
        const count = buf.len;
        var total_read: usize = 0;
        var curr_addr = address;
        const page_size = try getPageSize(task); // TODO we probably can assume value here
        var out_buf = buf[0..];

        while (total_read < count) {
            const curr_size = maxBytesLeftInPage(page_size, curr_addr, count - total_read);
            var curr_bytes_read: mach_msg_type_number_t = 0;
            var vm_memory: vm_offset_t = undefined;
            switch (getKernError(mach_vm_read(task.port, curr_addr, curr_size, &vm_memory, &curr_bytes_read))) {
                .SUCCESS => {},
                .FAILURE => return error.PermissionDenied,
                else => |err| return unexpectedKernError(err),
            }

            @memcpy(out_buf[0..curr_bytes_read], @as([*]const u8, @ptrFromInt(vm_memory)));
            _ = vm_deallocate(mach_task_self(), vm_memory, curr_bytes_read);

            out_buf = out_buf[curr_bytes_read..];
            curr_addr += curr_bytes_read;
            total_read += curr_bytes_read;
        }

        return total_read;
    }

    fn maxBytesLeftInPage(page_size: usize, address: u64, count: usize) usize {
        var left = count;
        if (page_size > 0) {
            const page_offset = address % page_size;
            const bytes_left_in_page = page_size - page_offset;
            if (count > bytes_left_in_page) {
                left = bytes_left_in_page;
            }
        }
        return left;
    }

    fn getPageSize(task: MachTask) MachError!usize {
        if (task.isValid()) {
            var info_count = TASK_VM_INFO_COUNT;
            var vm_info: task_vm_info_data_t = undefined;
            switch (getKernError(task_info(
                task.port,
                TASK_VM_INFO,
                @as(task_info_t, @ptrCast(&vm_info)),
                &info_count,
            ))) {
                .SUCCESS => return @as(usize, @intCast(vm_info.page_size)),
                else => {},
            }
        }
        var page_size: vm_size_t = undefined;
        switch (getKernError(_host_page_size(mach_host_self(), &page_size))) {
            .SUCCESS => return page_size,
            else => |err| return unexpectedKernError(err),
        }
    }

basicTaskInfo()

    pub fn basicTaskInfo(task: MachTask) MachError!mach_task_basic_info {
        var info: mach_task_basic_info = undefined;
        var count = MACH_TASK_BASIC_INFO_COUNT;
        switch (getKernError(task_info(
            task.port,
            MACH_TASK_BASIC_INFO,
            @as(task_info_t, @ptrCast(&info)),
            &count,
        ))) {
            .SUCCESS => return info,
            else => |err| return unexpectedKernError(err),
        }
    }

    pub fn @"resume"(task: MachTask) MachError!void {
        switch (getKernError(task_resume(task.port))) {
            .SUCCESS => {},
            else => |err| return unexpectedKernError(err),
        }
    }

    pub fn @"suspend"(task: MachTask) MachError!void {
        switch (getKernError(task_suspend(task.port))) {
            .SUCCESS => {},
            else => |err| return unexpectedKernError(err),
        }
    }

    const ThreadList = struct {
        buf: []MachThread,

deinit()

        pub fn deinit(list: ThreadList) void {
            const self_task = machTaskForSelf();
            _ = vm_deallocate(
                self_task.port,
                @intFromPtr(list.buf.ptr),
                @as(vm_size_t, @intCast(list.buf.len * @sizeOf(mach_port_t))),
            );
        }
    };

getThreads()

    pub fn getThreads(task: MachTask) MachError!ThreadList {
        var thread_list: mach_port_array_t = undefined;
        var thread_count: mach_msg_type_number_t = undefined;
        switch (getKernError(task_threads(task.port, &thread_list, &thread_count))) {
            .SUCCESS => return ThreadList{ .buf = @as([*]MachThread, @ptrCast(thread_list))[0..thread_count] },
            else => |err| return unexpectedKernError(err),
        }
    }
};

MachThread

pub const MachThread = extern struct {
    port: mach_port_t,

isValid()

    pub fn isValid(thread: MachThread) bool {
        return thread.port != THREAD_NULL;
    }

getBasicInfo()

    pub fn getBasicInfo(thread: MachThread) MachError!thread_basic_info {
        var info: thread_basic_info = undefined;
        var count = THREAD_BASIC_INFO_COUNT;
        switch (getKernError(thread_info(
            thread.port,
            THREAD_BASIC_INFO,
            @as(thread_info_t, @ptrCast(&info)),
            &count,
        ))) {
            .SUCCESS => return info,
            else => |err| return unexpectedKernError(err),
        }
    }

getIdentifierInfo()

    pub fn getIdentifierInfo(thread: MachThread) MachError!thread_identifier_info {
        var info: thread_identifier_info = undefined;
        var count = THREAD_IDENTIFIER_INFO_COUNT;
        switch (getKernError(thread_info(
            thread.port,
            THREAD_IDENTIFIER_INFO,
            @as(thread_info_t, @ptrCast(&info)),
            &count,
        ))) {
            .SUCCESS => return info,
            else => |err| return unexpectedKernError(err),
        }
    }
};

machTaskForPid()

pub fn machTaskForPid(pid: std.os.pid_t) MachError!MachTask {
    var port: mach_port_name_t = undefined;
    switch (getKernError(task_for_pid(mach_task_self(), pid, &port))) {
        .SUCCESS => {},
        .FAILURE => return error.PermissionDenied,
        else => |err| return unexpectedKernError(err),
    }
    return MachTask{ .port = port };
}

machTaskForSelf()

pub fn machTaskForSelf() MachTask {
    return .{ .port = mach_task_self() };
}

os_signpost_id_t

pub const os_signpost_id_t = u64;

OS_SIGNPOST_ID_NULL

pub const OS_SIGNPOST_ID_NULL: os_signpost_id_t = 0;

OS_SIGNPOST_ID_INVALID

pub const OS_SIGNPOST_ID_INVALID: os_signpost_id_t = !0;

OS_SIGNPOST_ID_EXCLUSIVE

pub const OS_SIGNPOST_ID_EXCLUSIVE: os_signpost_id_t = 0xeeeeb0b5b2b2eeee;

os_log_t

pub const os_log_t = opaque {};

os_log_type_t

pub const os_log_type_t = enum(u8) {
    OS_LOG_TYPE_DEFAULT = 0x00,
    OS_LOG_TYPE_INFO = 0x01,
    OS_LOG_TYPE_DEBUG = 0x02,
    OS_LOG_TYPE_ERROR = 0x10,
    OS_LOG_TYPE_FAULT = 0x11,
};

OS_LOG_CATEGORY_POINTS_OF_INTEREST

default messages always captures messages with additional infos debug messages error messages unexpected conditions messages

pub const OS_LOG_CATEGORY_POINTS_OF_INTEREST: *const u8 = "PointsOfInterest";

OS_LOG_CATEGORY_DYNAMIC_TRACING

pub const OS_LOG_CATEGORY_DYNAMIC_TRACING: *const u8 = "DynamicTracing";

OS_LOG_CATEGORY_DYNAMIC_STACK_TRACING

pub const OS_LOG_CATEGORY_DYNAMIC_STACK_TRACING: *const u8 = "DynamicStackTracing";

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;