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.posix.iovec_const; pub const aarch64 = @import("darwin/aarch64.zig"); pub const x86_64 = @import("darwin/x86_64.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 {}, }; pub const EXC_TYPES_COUNT = arch_bits.EXC_TYPES_COUNT; pub const THREAD_STATE_NONE = arch_bits.THREAD_STATE_NONE; pub const EXC = enum(exception_type_t) { NULL = 0, /// Could not access memory BAD_ACCESS = 1, /// Instruction failed BAD_INSTRUCTION = 2, /// Arithmetic exception ARITHMETIC = 3, /// Emulation instruction EMULATION = 4, /// Software generated exception SOFTWARE = 5, /// Trace, breakpoint, etc. BREAKPOINT = 6, /// System calls. SYSCALL = 7, /// Mach system calls. MACH_SYSCALL = 8, /// RPC alert RPC_ALERT = 9, /// Abnormal process exit CRASH = 10, /// Hit resource consumption limit RESOURCE = 11, /// Violated guarded resource protections GUARD = 12, /// Abnormal process exited to corpse state CORPSE_NOTIFY = 13, }; pub const EXC_SOFT_SIGNAL = 0x10003; pub const EXC_MASK_BAD_ACCESS = 1 << @intFromEnum(EXC.BAD_ACCESS); pub const EXC_MASK_BAD_INSTRUCTION = 1 << @intFromEnum(EXC.BAD_INSTRUCTION); pub const EXC_MASK_ARITHMETIC = 1 << @intFromEnum(EXC.ARITHMETIC); pub const EXC_MASK_EMULATION = 1 << @intFromEnum(EXC.EMULATION); pub const EXC_MASK_SOFTWARE = 1 << @intFromEnum(EXC.SOFTWARE); pub const EXC_MASK_BREAKPOINT = 1 << @intFromEnum(EXC.BREAKPOINT); pub const EXC_MASK_SYSCALL = 1 << @intFromEnum(EXC.SYSCALL); pub const EXC_MASK_MACH_SYSCALL = 1 << @intFromEnum(EXC.MACH_SYSCALL); pub const EXC_MASK_RPC_ALERT = 1 << @intFromEnum(EXC.RPC_ALERT); pub const EXC_MASK_CRASH = 1 << @intFromEnum(EXC.CRASH); pub const EXC_MASK_RESOURCE = 1 << @intFromEnum(EXC.RESOURCE); pub const EXC_MASK_GUARD = 1 << @intFromEnum(EXC.GUARD); pub const EXC_MASK_CORPSE_NOTIFY = 1 << @intFromEnum(EXC.CORPSE_NOTIFY); pub const EXC_MASK_MACHINE = arch_bits.EXC_MASK_MACHINE; 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; /// Send a catch_exception_raise message including the identity. pub const EXCEPTION_DEFAULT = 1; /// Send a catch_exception_raise_state message including the /// thread state. pub const EXCEPTION_STATE = 2; /// Send a catch_exception_raise_state_identity message including /// the thread identity and state. pub const EXCEPTION_STATE_IDENTITY = 3; /// Send a catch_exception_raise_identity_protected message including protected task /// and thread identity. pub const EXCEPTION_IDENTITY_PROTECTED = 4; /// Prefer sending a catch_exception_raice_backtrace message, if applicable. pub const MACH_EXCEPTION_BACKTRACE_PREFERRED = 0x20000000; /// include additional exception specific errors, not used yet. pub const MACH_EXCEPTION_ERRORS = 0x40000000; /// Send 64-bit code and subcode in the exception header */ pub const MACH_EXCEPTION_CODES = 0x80000000; pub const MACH_EXCEPTION_MASK = MACH_EXCEPTION_CODES | MACH_EXCEPTION_ERRORS | MACH_EXCEPTION_BACKTRACE_PREFERRED; pub const TASK_NULL: task_t = 0; pub const THREAD_NULL: thread_t = 0; pub const MACH_PORT_NULL: mach_port_t = 0; pub const MACH_MSG_TIMEOUT_NONE: mach_msg_timeout_t = 0; pub const MACH_MSG_OPTION_NONE = 0x00000000; pub const MACH_SEND_MSG = 0x00000001; pub const MACH_RCV_MSG = 0x00000002; pub const MACH_RCV_LARGE = 0x00000004; pub const MACH_RCV_LARGE_IDENTITY = 0x00000008; pub const MACH_SEND_TIMEOUT = 0x00000010; pub const MACH_SEND_OVERRIDE = 0x00000020; pub const MACH_SEND_INTERRUPT = 0x00000040; pub const MACH_SEND_NOTIFY = 0x00000080; pub const MACH_SEND_ALWAYS = 0x00010000; pub const MACH_SEND_FILTER_NONFATAL = 0x00010000; pub const MACH_SEND_TRAILER = 0x00020000; pub const MACH_SEND_NOIMPORTANCE = 0x00040000; pub const MACH_SEND_NODENAP = MACH_SEND_NOIMPORTANCE; pub const MACH_SEND_IMPORTANCE = 0x00080000; pub const MACH_SEND_SYNC_OVERRIDE = 0x00100000; pub const MACH_SEND_PROPAGATE_QOS = 0x00200000; pub const MACH_SEND_SYNC_USE_THRPRI = MACH_SEND_PROPAGATE_QOS; pub const MACH_SEND_KERNEL = 0x00400000; pub const MACH_SEND_SYNC_BOOTSTRAP_CHECKIN = 0x00800000; pub const MACH_RCV_TIMEOUT = 0x00000100; pub const MACH_RCV_NOTIFY = 0x00000000; pub const MACH_RCV_INTERRUPT = 0x00000400; pub const MACH_RCV_VOUCHER = 0x00000800; pub const MACH_RCV_OVERWRITE = 0x00000000; pub const MACH_RCV_GUARDED_DESC = 0x00001000; pub const MACH_RCV_SYNC_WAIT = 0x00004000; pub const MACH_RCV_SYNC_PEEK = 0x00008000; pub const MACH_MSG_STRICT_REPLY = 0x00000200; 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, }; 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; pub const COPYFILE_ACL = 1 << 0; pub const COPYFILE_STAT = 1 << 1; pub const COPYFILE_XATTR = 1 << 2; pub const COPYFILE_DATA = 1 << 3; 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 __getdirentries64(fd: c_int, buf_ptr: [*]u8, buf_len: usize, basep: *i64) isize; 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; /// 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. 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 }); } } pub const mach_header_64 = macho.mach_header_64; pub const mach_header = macho.mach_header; 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; pub const exception_type_t = c_int; pub const exception_data_type_t = integer_t; pub const exception_data_t = ?*mach_exception_data_type_t; pub const mach_exception_data_type_t = i64; pub const mach_exception_data_t = ?*mach_exception_data_type_t; pub const vm_map_t = mach_port_t; pub const vm_map_read_t = mach_port_t; pub const vm_region_flavor_t = c_int; pub const vm_region_info_t = *c_int; pub const vm_region_recurse_info_t = *c_int; pub const mach_vm_address_t = usize; pub const vm_offset_t = usize; pub const mach_vm_size_t = u64; pub const mach_msg_bits_t = c_uint; pub const mach_msg_id_t = integer_t; pub const mach_msg_type_number_t = natural_t; pub const mach_msg_type_name_t = c_uint; pub const mach_msg_option_t = integer_t; pub const mach_msg_size_t = natural_t; pub const mach_msg_timeout_t = natural_t; pub const mach_port_right_t = natural_t; pub const task_t = mach_port_t; pub const thread_port_t = task_t; pub const thread_t = thread_port_t; pub const exception_mask_t = c_uint; pub const exception_mask_array_t = [*]exception_mask_t; pub const exception_handler_t = mach_port_t; pub const exception_handler_array_t = [*]exception_handler_t; pub const exception_port_t = exception_handler_t; pub const exception_port_array_t = exception_handler_array_t; pub const exception_flavor_array_t = [*]thread_state_flavor_t; pub const exception_behavior_t = c_uint; pub const exception_behavior_array_t = [*]exception_behavior_t; pub const thread_state_flavor_t = c_int; pub const ipc_space_t = mach_port_t; pub const ipc_space_port_t = ipc_space_t; pub const MACH_PORT_RIGHT = enum(mach_port_right_t) { SEND = 0, RECEIVE = 1, SEND_ONCE = 2, PORT_SET = 3, DEAD_NAME = 4, /// Obsolete right LABELH = 5, /// Right not implemented NUMBER = 6, }; pub const MACH_MSG_TYPE = enum(mach_msg_type_name_t) { /// Must hold receive right MOVE_RECEIVE = 16, /// Must hold send right(s) MOVE_SEND = 17, /// Must hold sendonce right MOVE_SEND_ONCE = 18, /// Must hold send right(s) COPY_SEND = 19, /// Must hold receive right MAKE_SEND = 20, /// Must hold receive right MAKE_SEND_ONCE = 21, /// NOT VALID COPY_RECEIVE = 22, /// Must hold receive right DISPOSE_RECEIVE = 24, /// Must hold send right(s) DISPOSE_SEND = 25, /// Must hold sendonce right DISPOSE_SEND_ONCE = 26, }; extern "c" var mach_task_self_: mach_port_t; pub fn mach_task_self() callconv(.C) mach_port_t { return mach_task_self_; } pub extern "c" fn mach_msg( msg: ?*mach_msg_header_t, option: mach_msg_option_t, send_size: mach_msg_size_t, rcv_size: mach_msg_size_t, rcv_name: mach_port_name_t, timeout: mach_msg_timeout_t, notify: mach_port_name_t, ) kern_return_t; pub const mach_msg_header_t = extern struct { msgh_bits: mach_msg_bits_t, msgh_size: mach_msg_size_t, msgh_remote_port: mach_port_t, msgh_local_port: mach_port_t, msgh_voucher_port: mach_port_name_t, msgh_id: mach_msg_id_t, }; pub extern "c" fn task_get_exception_ports( task: task_t, exception_mask: exception_mask_t, masks: exception_mask_array_t, masks_cnt: *mach_msg_type_number_t, old_handlers: exception_handler_array_t, old_behaviors: exception_behavior_array_t, old_flavors: exception_flavor_array_t, ) kern_return_t; pub extern "c" fn task_set_exception_ports( task: task_t, exception_mask: exception_mask_t, new_port: mach_port_t, behavior: exception_behavior_t, new_flavor: thread_state_flavor_t, ) kern_return_t; pub const task_read_t = mach_port_t; pub extern "c" fn task_resume(target_task: task_read_t) kern_return_t; pub extern "c" fn task_suspend(target_task: task_read_t) kern_return_t; pub extern "c" fn task_for_pid(target_tport: mach_port_name_t, pid: pid_t, t: *mach_port_name_t) kern_return_t; pub extern "c" fn pid_for_task(target_tport: mach_port_name_t, pid: *pid_t) kern_return_t; pub extern "c" fn mach_vm_read( target_task: vm_map_read_t, address: mach_vm_address_t, size: mach_vm_size_t, data: *vm_offset_t, data_cnt: *mach_msg_type_number_t, ) kern_return_t; pub extern "c" fn mach_vm_write( target_task: vm_map_t, address: mach_vm_address_t, data: vm_offset_t, data_cnt: mach_msg_type_number_t, ) kern_return_t; pub extern "c" fn mach_vm_region( target_task: vm_map_t, address: *mach_vm_address_t, size: *mach_vm_size_t, flavor: vm_region_flavor_t, info: vm_region_info_t, info_cnt: *mach_msg_type_number_t, object_name: *mach_port_t, ) kern_return_t; pub extern "c" fn mach_vm_region_recurse( target_task: vm_map_t, address: *mach_vm_address_t, size: *mach_vm_size_t, nesting_depth: *natural_t, info: vm_region_recurse_info_t, info_cnt: *mach_msg_type_number_t, ) kern_return_t; pub const vm_inherit_t = u32; pub const memory_object_offset_t = u64; pub const vm_behavior_t = i32; pub const vm32_object_id_t = u32; pub const vm_object_id_t = u64; pub const VM_INHERIT_SHARE: vm_inherit_t = 0; pub const VM_INHERIT_COPY: vm_inherit_t = 1; pub const VM_INHERIT_NONE: vm_inherit_t = 2; pub const VM_INHERIT_DONATE_COPY: vm_inherit_t = 3; pub const VM_INHERIT_DEFAULT = VM_INHERIT_COPY; pub const VM_BEHAVIOR_DEFAULT: vm_behavior_t = 0; pub const VM_BEHAVIOR_RANDOM: vm_behavior_t = 1; pub const VM_BEHAVIOR_SEQUENTIAL: vm_behavior_t = 2; pub const VM_BEHAVIOR_RSEQNTL: vm_behavior_t = 3; pub const VM_BEHAVIOR_WILLNEED: vm_behavior_t = 4; pub const VM_BEHAVIOR_DONTNEED: vm_behavior_t = 5; pub const VM_BEHAVIOR_FREE: vm_behavior_t = 6; pub const VM_BEHAVIOR_ZERO_WIRED_PAGES: vm_behavior_t = 7; pub const VM_BEHAVIOR_REUSABLE: vm_behavior_t = 8; pub const VM_BEHAVIOR_REUSE: vm_behavior_t = 9; pub const VM_BEHAVIOR_CAN_REUSE: vm_behavior_t = 10; pub const VM_BEHAVIOR_PAGEOUT: vm_behavior_t = 11; pub const VM_REGION_BASIC_INFO_64 = 9; pub const VM_REGION_EXTENDED_INFO = 13; pub const VM_REGION_TOP_INFO = 12; pub const VM_REGION_SUBMAP_INFO_COUNT_64: mach_msg_type_number_t = @sizeOf(vm_region_submap_info_64) / @sizeOf(natural_t); pub const VM_REGION_SUBMAP_SHORT_INFO_COUNT_64: mach_msg_type_number_t = @sizeOf(vm_region_submap_short_info_64) / @sizeOf(natural_t); pub const VM_REGION_BASIC_INFO_COUNT: mach_msg_type_number_t = @sizeOf(vm_region_basic_info_64) / @sizeOf(c_int); pub const VM_REGION_EXTENDED_INFO_COUNT: mach_msg_type_number_t = @sizeOf(vm_region_extended_info) / @sizeOf(natural_t); pub const VM_REGION_TOP_INFO_COUNT: mach_msg_type_number_t = @sizeOf(vm_region_top_info) / @sizeOf(natural_t); pub fn VM_MAKE_TAG(tag: u8) u32 { return @as(u32, tag) << 24; } pub const vm_region_basic_info_64 = extern struct { protection: vm_prot_t, max_protection: vm_prot_t, inheritance: vm_inherit_t, shared: boolean_t, reserved: boolean_t, offset: memory_object_offset_t, behavior: vm_behavior_t, user_wired_count: u16, }; pub const vm_region_extended_info = extern struct { protection: vm_prot_t, user_tag: u32, pages_resident: u32, pages_shared_now_private: u32, pages_swapped_out: u32, pages_dirtied: u32, ref_count: u32, shadow_depth: u16, external_pager: u8, share_mode: u8, pages_reusable: u32, }; pub const vm_region_top_info = extern struct { obj_id: u32, ref_count: u32, private_pages_resident: u32, shared_pages_resident: u32, share_mode: u8, }; pub const vm_region_submap_info_64 = extern struct { // present across protection protection: vm_prot_t, // max avail through vm_prot max_protection: vm_prot_t, // behavior of map/obj on fork inheritance: vm_inherit_t, // offset into object/map offset: memory_object_offset_t, // user tag on map entry user_tag: u32, // only valid for objects pages_resident: u32, // only for objects pages_shared_now_private: u32, // only for objects pages_swapped_out: u32, // only for objects pages_dirtied: u32, // obj/map mappers, etc. ref_count: u32, // only for obj shadow_depth: u16, // only for obj external_pager: u8, // see enumeration share_mode: u8, // submap vs obj is_submap: boolean_t, // access behavior hint behavior: vm_behavior_t, // obj/map name, not a handle object_id: vm32_object_id_t, user_wired_count: u16, pages_reusable: u32, object_id_full: vm_object_id_t, }; pub const vm_region_submap_short_info_64 = extern struct { // present access protection protection: vm_prot_t, // max avail through vm_prot max_protection: vm_prot_t, // behavior of map/obj on fork inheritance: vm_inherit_t, // offset into object/map offset: memory_object_offset_t, // user tag on map entry user_tag: u32, // obj/map mappers, etc ref_count: u32, // only for obj shadow_depth: u16, // only for obj external_pager: u8, // see enumeration share_mode: u8, // submap vs obj is_submap: boolean_t, // access behavior hint behavior: vm_behavior_t, // obj/map name, not a handle object_id: vm32_object_id_t, user_wired_count: u16, }; pub const thread_act_t = mach_port_t; pub const thread_state_t = *natural_t; pub const mach_port_array_t = [*]mach_port_t; pub extern "c" fn task_threads( target_task: mach_port_t, init_port_set: *mach_port_array_t, init_port_count: *mach_msg_type_number_t, ) kern_return_t; pub extern "c" fn thread_get_state( thread: thread_act_t, flavor: thread_flavor_t, state: thread_state_t, count: *mach_msg_type_number_t, ) kern_return_t; pub extern "c" fn thread_set_state( thread: thread_act_t, flavor: thread_flavor_t, new_state: thread_state_t, count: mach_msg_type_number_t, ) kern_return_t; pub extern "c" fn thread_info( thread: thread_act_t, flavor: thread_flavor_t, info: thread_info_t, count: *mach_msg_type_number_t, ) kern_return_t; pub extern "c" fn thread_resume(thread: thread_act_t) kern_return_t; pub const THREAD_BASIC_INFO = 3; pub const THREAD_BASIC_INFO_COUNT: mach_msg_type_number_t = @sizeOf(thread_basic_info) / @sizeOf(natural_t); pub const THREAD_IDENTIFIER_INFO = 4; pub const THREAD_IDENTIFIER_INFO_COUNT: mach_msg_type_number_t = @sizeOf(thread_identifier_info) / @sizeOf(natural_t); pub const thread_flavor_t = natural_t; pub const thread_info_t = *integer_t; pub const time_value_t = time_value; pub const task_policy_flavor_t = natural_t; pub const task_policy_t = *integer_t; pub const policy_t = c_int; pub const time_value = extern struct { seconds: integer_t, microseconds: integer_t, }; pub const thread_basic_info = extern struct { // user run time user_time: time_value_t, // system run time system_time: time_value_t, // scaled cpu usage percentage cpu_usage: integer_t, // scheduling policy in effect policy: policy_t, // run state run_state: integer_t, // various flags flags: integer_t, // suspend count for thread suspend_count: integer_t, // number of seconds that thread has been sleeping sleep_time: integer_t, }; pub const thread_identifier_info = extern struct { /// System-wide unique 64-bit thread id thread_id: u64, /// Handle to be used by libproc thread_handle: u64, /// libdispatch queue address dispatch_qaddr: u64, }; /// Cachability pub const MATTR_CACHE = 1; /// Migrability pub const MATTR_MIGRATE = 2; /// Replicability pub const MATTR_REPLICATE = 4; /// (Generic) turn attribute off pub const MATTR_VAL_OFF = 0; /// (Generic) turn attribute on pub const MATTR_VAL_ON = 1; /// (Generic) return current value pub const MATTR_VAL_GET = 2; /// Flush from all caches pub const MATTR_VAL_CACHE_FLUSH = 6; /// Flush from data caches pub const MATTR_VAL_DCACHE_FLUSH = 7; /// Flush from instruction caches pub const MATTR_VAL_ICACHE_FLUSH = 8; /// Sync I+D caches pub const MATTR_VAL_CACHE_SYNC = 9; /// Get page info (stats) pub const MATTR_VAL_GET_INFO = 10; pub const TASK_VM_INFO = 22; pub const TASK_VM_INFO_COUNT: mach_msg_type_number_t = @sizeOf(task_vm_info_data_t) / @sizeOf(natural_t); pub const task_vm_info = extern struct { // virtual memory size (bytes) virtual_size: mach_vm_size_t, // number of memory regions region_count: integer_t, page_size: integer_t, // resident memory size (bytes) resident_size: mach_vm_size_t, // peak resident size (bytes) resident_size_peak: mach_vm_size_t, device: mach_vm_size_t, device_peak: mach_vm_size_t, internal: mach_vm_size_t, internal_peak: mach_vm_size_t, external: mach_vm_size_t, external_peak: mach_vm_size_t, reusable: mach_vm_size_t, reusable_peak: mach_vm_size_t, purgeable_volatile_pmap: mach_vm_size_t, purgeable_volatile_resident: mach_vm_size_t, purgeable_volatile_virtual: mach_vm_size_t, compressed: mach_vm_size_t, compressed_peak: mach_vm_size_t, compressed_lifetime: mach_vm_size_t, // added for rev1 phys_footprint: mach_vm_size_t, // added for rev2 min_address: mach_vm_address_t, max_address: mach_vm_address_t, // added for rev3 ledger_phys_footprint_peak: i64, ledger_purgeable_nonvolatile: i64, ledger_purgeable_novolatile_compressed: i64, ledger_purgeable_volatile: i64, ledger_purgeable_volatile_compressed: i64, ledger_tag_network_nonvolatile: i64, ledger_tag_network_nonvolatile_compressed: i64, ledger_tag_network_volatile: i64, ledger_tag_network_volatile_compressed: i64, ledger_tag_media_footprint: i64, ledger_tag_media_footprint_compressed: i64, ledger_tag_media_nofootprint: i64, ledger_tag_media_nofootprint_compressed: i64, ledger_tag_graphics_footprint: i64, ledger_tag_graphics_footprint_compressed: i64, ledger_tag_graphics_nofootprint: i64, ledger_tag_graphics_nofootprint_compressed: i64, ledger_tag_neural_footprint: i64, ledger_tag_neural_footprint_compressed: i64, ledger_tag_neural_nofootprint: i64, ledger_tag_neural_nofootprint_compressed: i64, // added for rev4 limit_bytes_remaining: u64, // added for rev5 decompressions: integer_t, }; pub const task_vm_info_data_t = task_vm_info; pub const vm_prot_t = c_int; 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; pub const mach_task_basic_info = extern struct { /// Virtual memory size (bytes) virtual_size: mach_vm_size_t, /// Resident memory size (bytes) resident_size: mach_vm_size_t, /// Total user run time for terminated threads user_time: time_value_t, /// Total system run time for terminated threads system_time: time_value_t, /// Default policy for new threads policy: policy_t, /// Suspend count for task suspend_count: mach_vm_size_t, }; pub const MACH_TASK_BASIC_INFO = 20; 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; 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; 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; pub const IFNAMESIZE = 16; pub const AI = struct { /// get address to use bind() pub const PASSIVE = 0x00000001; /// fill ai_canonname pub const CANONNAME = 0x00000002; /// prevent host name resolution pub const NUMERICHOST = 0x00000004; /// prevent service name resolution pub const NUMERICSERV = 0x00001000; }; pub const EAI = enum(c_int) { /// address family for hostname not supported ADDRFAMILY = 1, /// temporary failure in name resolution AGAIN = 2, /// invalid value for ai_flags BADFLAGS = 3, /// non-recoverable failure in name resolution FAIL = 4, /// ai_family not supported FAMILY = 5, /// memory allocation failure MEMORY = 6, /// no address associated with hostname NODATA = 7, /// hostname nor servname provided, or not known NONAME = 8, /// servname not supported for ai_socktype SERVICE = 9, /// ai_socktype not supported SOCKTYPE = 10, /// system error returned in errno SYSTEM = 11, /// invalid value for hints BADHINTS = 12, /// resolved protocol is unknown PROTOCOL = 13, /// argument buffer overflow OVERFLOW = 14, _, }; pub const EAI_MAX = 15; pub const qos_class_t = enum(c_uint) { /// highest priority QOS class for critical tasks QOS_CLASS_USER_INTERACTIVE = 0x21, /// slightly more moderate priority QOS class QOS_CLASS_USER_INITIATED = 0x19, /// default QOS class when none is set QOS_CLASS_DEFAULT = 0x15, /// more energy efficient QOS class than default QOS_CLASS_UTILITY = 0x11, /// QOS class more appropriate for background tasks QOS_CLASS_BACKGROUND = 0x09, /// QOS class as a return value QOS_CLASS_UNSPECIFIED = 0x00, }; pub const sem_t = c_int; 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) c_int; pub extern "c" fn pthread_getname_np(thread: std.c.pthread_t, name: [*:0]u8, len: usize) c_int; pub extern "c" fn pthread_attr_set_qos_class_np(attr: *pthread_attr_t, qos_class: qos_class_t, relative_priority: c_int) c_int; pub extern "c" fn pthread_attr_get_qos_class_np(attr: *pthread_attr_t, qos_class: *qos_class_t, relative_priority: *c_int) c_int; pub extern "c" fn pthread_set_qos_class_self_np(qos_class: qos_class_t, relative_priority: c_int) c_int; pub extern "c" fn pthread_get_qos_class_np(pthread: std.c.pthread_t, qos_class: *qos_class_t, relative_priority: *c_int) c_int; pub 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; 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; pub const dispatch_time_t = u64; pub const DISPATCH_TIME_NOW = @as(dispatch_time_t, 0); 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 pub const UL_COMPARE_AND_WAIT = 1; pub const UL_UNFAIR_LOCK = 2; // Obsolete/deprecated pub const UL_OSSPINLOCK = UL_COMPARE_AND_WAIT; pub const UL_HANDOFFLOCK = UL_UNFAIR_LOCK; pub const ULF_WAKE_ALL = 0x100; pub const ULF_WAKE_THREAD = 0x200; pub const ULF_WAIT_WORKQ_DATA_CONTENTION = 0x10000; pub const ULF_WAIT_CANCEL_POINT = 0x20000; pub const ULF_NO_ERRNO = 0x1000000; // The following are only supported on darwin 19+ // (macOS 10.15+, iOS 13.0+) pub const UL_COMPARE_AND_WAIT_SHARED = 3; pub const UL_UNFAIR_LOCK64_SHARED = 4; pub const UL_COMPARE_AND_WAIT64 = 5; pub const UL_COMPARE_AND_WAIT64_SHARED = 6; 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; pub const OS_UNFAIR_LOCK_INIT = os_unfair_lock{}; pub const os_unfair_lock_t = *os_unfair_lock; pub const os_unfair_lock = extern struct { _os_unfair_lock_opaque: u32 = 0, }; pub extern "c" fn os_unfair_lock_lock(o: os_unfair_lock_t) void; pub extern "c" fn os_unfair_lock_unlock(o: os_unfair_lock_t) void; pub extern "c" fn os_unfair_lock_trylock(o: os_unfair_lock_t) bool; pub extern "c" fn os_unfair_lock_assert_owner(o: os_unfair_lock_t) void; pub extern "c" fn os_unfair_lock_assert_not_owner(o: os_unfair_lock_t) void; // 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 pub const blkcnt_t = i64; pub const blksize_t = i32; pub const dev_t = i32; pub const fd_t = c_int; pub const pid_t = c_int; pub const mode_t = c_uint; pub const uid_t = u32; pub const gid_t = u32; // machine/_types.h pub const clock_t = c_ulong; pub const time_t = c_long; pub const in_port_t = u16; pub const sa_family_t = u8; pub const socklen_t = u32; 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, }; /// UNIX domain socket pub const un = extern struct { len: u8 = @sizeOf(un), family: sa_family_t = AF.UNIX, path: [104]u8, }; }; pub const timeval = extern struct { tv_sec: c_long, tv_usec: i32, }; pub const timezone = extern struct { tz_minuteswest: i32, tz_dsttime: i32, }; pub const mach_timebase_info_data = extern struct { numer: u32, denom: u32, }; pub const off_t = i64; pub const ino_t = u64; pub const Flock = extern struct { start: off_t, len: off_t, pid: pid_t, type: i16, whence: i16, }; 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, pub fn atime(self: @This()) timespec { return self.atimespec; } pub fn mtime(self: @This()) timespec { return self.mtimespec; } pub fn ctime(self: @This()) timespec { return self.ctimespec; } pub fn birthtime(self: @This()) timespec { return self.birthtimespec; } }; pub const timespec = extern struct { tv_sec: isize, tv_nsec: isize, }; pub const sigset_t = u32; pub const empty_sigset: sigset_t = 0; pub const SIG = struct { pub const ERR: ?Sigaction.handler_fn = @ptrFromInt(maxInt(usize)); pub const DFL: ?Sigaction.handler_fn = @ptrFromInt(0); pub const IGN: ?Sigaction.handler_fn = @ptrFromInt(1); pub const HOLD: ?Sigaction.handler_fn = @ptrFromInt(5); /// block specified signal set pub const BLOCK = 1; /// unblock specified signal set pub const UNBLOCK = 2; /// set specified signal set pub const SETMASK = 3; /// hangup pub const HUP = 1; /// interrupt pub const INT = 2; /// quit pub const QUIT = 3; /// illegal instruction (not reset when caught) pub const ILL = 4; /// trace trap (not reset when caught) pub const TRAP = 5; /// abort() pub const ABRT = 6; /// pollable event ([XSR] generated, not supported) pub const POLL = 7; /// compatibility pub const IOT = ABRT; /// EMT instruction pub const EMT = 7; /// floating point exception pub const FPE = 8; /// kill (cannot be caught or ignored) pub const KILL = 9; /// bus error pub const BUS = 10; /// segmentation violation pub const SEGV = 11; /// bad argument to system call pub const SYS = 12; /// write on a pipe with no one to read it pub const PIPE = 13; /// alarm clock pub const ALRM = 14; /// software termination signal from kill pub const TERM = 15; /// urgent condition on IO channel pub const URG = 16; /// sendable stop signal not from tty pub const STOP = 17; /// stop signal from tty pub const TSTP = 18; /// continue a stopped process pub const CONT = 19; /// to parent on child stop or exit pub const CHLD = 20; /// to readers pgrp upon background tty read pub const TTIN = 21; /// like TTIN for output if (tp->t_local<OSTOP) pub const TTOU = 22; /// input/output possible signal pub const IO = 23; /// exceeded CPU time limit pub const XCPU = 24; /// exceeded file size limit pub const XFSZ = 25; /// virtual time alarm pub const VTALRM = 26; /// profiling time alarm pub const PROF = 27; /// window size changes pub const WINCH = 28; /// information request pub const INFO = 29; /// user defined signal 1 pub const USR1 = 30; /// user defined signal 2 pub const USR2 = 31; }; 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: *allowzero anyopaque, value: extern union { int: c_int, ptr: *anyopaque, }, si_band: c_long, _pad: [7]c_ulong, }; /// Renamed from `sigaction` to `Sigaction` to avoid conflict with function name. pub const Sigaction = extern struct { pub const handler_fn = *align(1) const fn (i32) callconv(.C) void; pub const sigaction_fn = *const fn (i32, *const siginfo_t, ?*anyopaque) callconv(.C) void; handler: extern union { handler: ?handler_fn, sigaction: ?sigaction_fn, }, mask: sigset_t, flags: c_uint, }; pub const dirent = extern struct { ino: u64, seekoff: u64, reclen: u16, namlen: u16, type: u8, name: [1024]u8, }; /// 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); } } 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); } } pub const mach_port_t = c_uint; pub const clock_serv_t = mach_port_t; pub const clock_res_t = c_int; pub const mach_port_name_t = natural_t; pub const natural_t = c_uint; pub const mach_timespec_t = extern struct { tv_sec: c_uint, tv_nsec: clock_res_t, }; pub const kern_return_t = c_int; pub const host_t = mach_port_t; pub const integer_t = c_int; pub const task_flavor_t = natural_t; pub const task_info_t = *integer_t; pub const task_name_t = mach_port_name_t; pub const vm_address_t = vm_offset_t; pub const vm_size_t = mach_vm_size_t; pub const vm_machine_attribute_t = usize; pub const vm_machine_attribute_val_t = isize; pub const CALENDAR_CLOCK = 1; pub const PATH_MAX = 1024; pub const NAME_MAX = 255; pub const IOV_MAX = 16; pub const STDIN_FILENO = 0; pub const STDOUT_FILENO = 1; pub const STDERR_FILENO = 2; pub const PROT = struct { /// [MC2] no permissions pub const NONE: vm_prot_t = 0x00; /// [MC2] pages can be read pub const READ: vm_prot_t = 0x01; /// [MC2] pages can be written pub const WRITE: vm_prot_t = 0x02; /// [MC2] pages can be executed pub const EXEC: vm_prot_t = 0x04; /// 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 COPY: vm_prot_t = 0x10; }; 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; }; pub const SA = struct { /// take signal on signal stack pub const ONSTACK = 0x0001; /// restart system on signal return pub const RESTART = 0x0002; /// reset to SIG.DFL when taking signal pub const RESETHAND = 0x0004; /// do not generate SIG.CHLD on child stop pub const NOCLDSTOP = 0x0008; /// don't mask the signal we're delivering pub const NODEFER = 0x0010; /// don't keep zombies around pub const NOCLDWAIT = 0x0020; /// signal handler with SIGINFO args pub const SIGINFO = 0x0040; /// do not bounce off kernel's sigtramp pub const USERTRAMP = 0x0100; /// signal handler with SIGINFO args with 64bit regs information pub const @"64REGSET" = 0x0200; }; pub const F_OK = 0; pub const X_OK = 1; pub const W_OK = 2; pub const R_OK = 4; pub const SEEK = struct { pub const SET = 0x0; pub const CUR = 0x1; pub const END = 0x2; }; 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; }; /// no flag value pub const KEVENT_FLAG_NONE = 0x000; /// immediate timeout pub const KEVENT_FLAG_IMMEDIATE = 0x001; /// output events only include change pub const KEVENT_FLAG_ERROR_EVENTS = 0x002; /// add event to kq (implies enable) pub const EV_ADD = 0x0001; /// delete event from kq pub const EV_DELETE = 0x0002; /// enable event pub const EV_ENABLE = 0x0004; /// disable event (not reported) pub const EV_DISABLE = 0x0008; /// only report one occurrence pub const EV_ONESHOT = 0x0010; /// clear event state after reporting pub const EV_CLEAR = 0x0020; /// force immediate event output /// ... with or without EV_ERROR /// ... use KEVENT_FLAG_ERROR_EVENTS /// on syscalls supporting flags pub const EV_RECEIPT = 0x0040; /// disable event after reporting pub const EV_DISPATCH = 0x0080; /// unique kevent per udata value pub const EV_UDATA_SPECIFIC = 0x0100; /// ... 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; /// report that source has vanished /// ... only valid with EV_DISPATCH2 pub const EV_VANISHED = 0x0200; /// reserved by system pub const EV_SYSFLAGS = 0xF000; /// filter-specific flag pub const EV_FLAG0 = 0x1000; /// filter-specific flag pub const EV_FLAG1 = 0x2000; /// EOF detected pub const EV_EOF = 0x8000; /// error, data contains errno pub const EV_ERROR = 0x4000; pub const EV_POLL = EV_FLAG0; pub const EV_OOBAND = EV_FLAG1; pub const EVFILT_READ = -1; pub const EVFILT_WRITE = -2; /// attached to aio requests pub const EVFILT_AIO = -3; /// attached to vnodes pub const EVFILT_VNODE = -4; /// attached to struct proc pub const EVFILT_PROC = -5; /// attached to struct proc pub const EVFILT_SIGNAL = -6; /// timers pub const EVFILT_TIMER = -7; /// Mach portsets pub const EVFILT_MACHPORT = -8; /// Filesystem events pub const EVFILT_FS = -9; /// User events pub const EVFILT_USER = -10; /// Virtual memory events pub const EVFILT_VM = -12; /// Exception events pub const EVFILT_EXCEPT = -15; pub const EVFILT_SYSCOUNT = 17; /// On input, NOTE_TRIGGER causes the event to be triggered for output. pub const NOTE_TRIGGER = 0x01000000; /// ignore input fflags pub const NOTE_FFNOP = 0x00000000; /// and fflags pub const NOTE_FFAND = 0x40000000; /// or fflags pub const NOTE_FFOR = 0x80000000; /// copy fflags pub const NOTE_FFCOPY = 0xc0000000; /// mask for operations pub const NOTE_FFCTRLMASK = 0xc0000000; pub const NOTE_FFLAGSMASK = 0x00ffffff; /// low water mark pub const NOTE_LOWAT = 0x00000001; /// OOB data pub const NOTE_OOB = 0x00000002; /// vnode was removed pub const NOTE_DELETE = 0x00000001; /// data contents changed pub const NOTE_WRITE = 0x00000002; /// size increased pub const NOTE_EXTEND = 0x00000004; /// attributes changed pub const NOTE_ATTRIB = 0x00000008; /// link count changed pub const NOTE_LINK = 0x00000010; /// vnode was renamed pub const NOTE_RENAME = 0x00000020; /// vnode access was revoked pub const NOTE_REVOKE = 0x00000040; /// No specific vnode event: to test for EVFILT_READ activation pub const NOTE_NONE = 0x00000080; /// vnode was unlocked by flock(2) pub const NOTE_FUNLOCK = 0x00000100; /// process exited pub const NOTE_EXIT = 0x80000000; /// process forked pub const NOTE_FORK = 0x40000000; /// process exec'd pub const NOTE_EXEC = 0x20000000; /// shared with EVFILT_SIGNAL pub const NOTE_SIGNAL = 0x08000000; /// exit status to be returned, valid for child process only pub const NOTE_EXITSTATUS = 0x04000000; /// provide details on reasons for exit pub const NOTE_EXIT_DETAIL = 0x02000000; /// mask for signal & exit status pub const NOTE_PDATAMASK = 0x000fffff; pub const NOTE_PCTRLMASK = (~NOTE_PDATAMASK); pub const NOTE_EXIT_DETAIL_MASK = 0x00070000; pub const NOTE_EXIT_DECRYPTFAIL = 0x00010000; pub const NOTE_EXIT_MEMORY = 0x00020000; pub const NOTE_EXIT_CSERROR = 0x00040000; /// will react on memory pressure pub const NOTE_VM_PRESSURE = 0x80000000; /// will quit on memory pressure, possibly after cleaning up dirty state pub const NOTE_VM_PRESSURE_TERMINATE = 0x40000000; /// will quit immediately on memory pressure pub const NOTE_VM_PRESSURE_SUDDEN_TERMINATE = 0x20000000; /// there was an error pub const NOTE_VM_ERROR = 0x10000000; /// data is seconds pub const NOTE_SECONDS = 0x00000001; /// data is microseconds pub const NOTE_USECONDS = 0x00000002; /// data is nanoseconds pub const NOTE_NSECONDS = 0x00000004; /// absolute timeout pub const NOTE_ABSOLUTE = 0x00000008; /// ext[1] holds leeway for power aware timers pub const NOTE_LEEWAY = 0x00000010; /// system does minimal timer coalescing pub const NOTE_CRITICAL = 0x00000020; /// system does maximum timer coalescing pub const NOTE_BACKGROUND = 0x00000040; pub const NOTE_MACH_CONTINUOUS_TIME = 0x00000080; /// data is mach absolute time units pub const NOTE_MACHTIME = 0x00000100; 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; }; 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; }; pub const SYSPROTO_EVENT = 1; pub const SYSPROTO_CONTROL = 2; 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; /// 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 CLOEXEC = 1 << 15; /// 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 NONBLOCK = 1 << 16; }; 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; }; pub const SOL = struct { pub const SOCKET = 0xffff; }; 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; }; pub const W = struct { /// [XSI] no hang in wait/no child to reap pub const NOHANG = 0x00000001; /// [XSI] notify on stop, untraced child pub const UNTRACED = 0x00000002; pub fn EXITSTATUS(x: u32) u8 { return @as(u8, @intCast(x >> 8)); } pub fn TERMSIG(x: u32) u32 { return status(x); } pub fn STOPSIG(x: u32) u32 { return x >> 8; } pub fn IFEXITED(x: u32) bool { return status(x) == 0; } pub fn IFSTOPPED(x: u32) bool { return status(x) == stopped and STOPSIG(x) != 0x13; } 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; }; pub const E = enum(u16) { /// No error occurred. SUCCESS = 0, /// Operation not permitted PERM = 1, /// No such file or directory NOENT = 2, /// No such process SRCH = 3, /// Interrupted system call INTR = 4, /// Input/output error IO = 5, /// Device not configured NXIO = 6, /// Argument list too long @"2BIG" = 7, /// Exec format error NOEXEC = 8, /// Bad file descriptor BADF = 9, /// No child processes CHILD = 10, /// Resource deadlock avoided DEADLK = 11, /// Cannot allocate memory NOMEM = 12, /// Permission denied ACCES = 13, /// Bad address FAULT = 14, /// Block device required NOTBLK = 15, /// Device / Resource busy BUSY = 16, /// File exists EXIST = 17, /// Cross-device link XDEV = 18, /// Operation not supported by device NODEV = 19, /// Not a directory NOTDIR = 20, /// Is a directory ISDIR = 21, /// Invalid argument INVAL = 22, /// Too many open files in system NFILE = 23, /// Too many open files MFILE = 24, /// Inappropriate ioctl for device NOTTY = 25, /// Text file busy TXTBSY = 26, /// File too large FBIG = 27, /// No space left on device NOSPC = 28, /// Illegal seek SPIPE = 29, /// Read-only file system ROFS = 30, /// Too many links MLINK = 31, /// Broken pipe PIPE = 32, // math software /// Numerical argument out of domain DOM = 33, /// Result too large RANGE = 34, // non-blocking and interrupt i/o /// Resource temporarily unavailable /// This is the same code used for `WOULDBLOCK`. AGAIN = 35, /// Operation now in progress INPROGRESS = 36, /// Operation already in progress ALREADY = 37, // ipc/network software -- argument errors /// Socket operation on non-socket NOTSOCK = 38, /// Destination address required DESTADDRREQ = 39, /// Message too long MSGSIZE = 40, /// Protocol wrong type for socket PROTOTYPE = 41, /// Protocol not available NOPROTOOPT = 42, /// Protocol not supported PROTONOSUPPORT = 43, /// Socket type not supported SOCKTNOSUPPORT = 44, /// Operation not supported /// The same code is used for `NOTSUP`. OPNOTSUPP = 45, /// Protocol family not supported PFNOSUPPORT = 46, /// Address family not supported by protocol family AFNOSUPPORT = 47, /// Address already in use ADDRINUSE = 48, /// Can't assign requested address // ipc/network software -- operational errors ADDRNOTAVAIL = 49, /// Network is down NETDOWN = 50, /// Network is unreachable NETUNREACH = 51, /// Network dropped connection on reset NETRESET = 52, /// Software caused connection abort CONNABORTED = 53, /// Connection reset by peer CONNRESET = 54, /// No buffer space available NOBUFS = 55, /// Socket is already connected ISCONN = 56, /// Socket is not connected NOTCONN = 57, /// Can't send after socket shutdown SHUTDOWN = 58, /// Too many references: can't splice TOOMANYREFS = 59, /// Operation timed out TIMEDOUT = 60, /// Connection refused CONNREFUSED = 61, /// Too many levels of symbolic links LOOP = 62, /// File name too long NAMETOOLONG = 63, /// Host is down HOSTDOWN = 64, /// No route to host HOSTUNREACH = 65, /// Directory not empty // quotas & mush NOTEMPTY = 66, /// Too many processes PROCLIM = 67, /// Too many users USERS = 68, /// Disc quota exceeded // Network File System DQUOT = 69, /// Stale NFS file handle STALE = 70, /// Too many levels of remote in path REMOTE = 71, /// RPC struct is bad BADRPC = 72, /// RPC version wrong RPCMISMATCH = 73, /// RPC prog. not avail PROGUNAVAIL = 74, /// Program version wrong PROGMISMATCH = 75, /// Bad procedure for program PROCUNAVAIL = 76, /// No locks available NOLCK = 77, /// Function not implemented NOSYS = 78, /// Inappropriate file type or format FTYPE = 79, /// Authentication error AUTH = 80, /// Need authenticator NEEDAUTH = 81, // Intelligent device errors /// Device power is off PWROFF = 82, /// Device error, e.g. paper out DEVERR = 83, /// Value too large to be stored in data type OVERFLOW = 84, // Program loading errors /// Bad executable BADEXEC = 85, /// Bad CPU type in executable BADARCH = 86, /// Shared library version mismatch SHLIBVERS = 87, /// Malformed Macho file BADMACHO = 88, /// Operation canceled CANCELED = 89, /// Identifier removed IDRM = 90, /// No message of desired type NOMSG = 91, /// Illegal byte sequence ILSEQ = 92, /// Attribute not found NOATTR = 93, /// Bad message BADMSG = 94, /// Reserved MULTIHOP = 95, /// No message available on STREAM NODATA = 96, /// Reserved NOLINK = 97, /// No STREAM resources NOSR = 98, /// Not a STREAM NOSTR = 99, /// Protocol error PROTO = 100, /// STREAM ioctl timeout TIME = 101, /// No such policy registered NOPOLICY = 103, /// State not recoverable NOTRECOVERABLE = 104, /// Previous owner died OWNERDEAD = 105, /// Interface output queue is full QFULL = 106, _, }; /// Kernel return values pub const KernE = enum(u32) { SUCCESS = 0, /// Specified address is not currently valid INVALID_ADDRESS = 1, /// Specified memory is valid, but does not permit the /// required forms of access. PROTECTION_FAILURE = 2, /// The address range specified is already in use, or /// no address range of the size specified could be /// found. NO_SPACE = 3, /// The function requested was not applicable to this /// type of argument, or an argument is invalid INVALID_ARGUMENT = 4, /// The function could not be performed. A catch-all. FAILURE = 5, /// A system resource could not be allocated to fulfill /// this request. This failure may not be permanent. RESOURCE_SHORTAGE = 6, /// The task in question does not hold receive rights /// for the port argument. NOT_RECEIVER = 7, /// Bogus access restriction. NO_ACCESS = 8, /// During a page fault, the target address refers to a /// memory object that has been destroyed. This /// failure is permanent. MEMORY_FAILURE = 9, /// 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. MEMORY_ERROR = 10, /// The receive right is already a member of the portset. ALREADY_IN_SET = 11, /// The receive right is not a member of a port set. NOT_IN_SET = 12, /// The name already denotes a right in the task. NAME_EXISTS = 13, /// The operation was aborted. Ipc code will /// catch this and reflect it as a message error. ABORTED = 14, /// The name doesn't denote a right in the task. INVALID_NAME = 15, /// Target task isn't an active task. INVALID_TASK = 16, /// The name denotes a right, but not an appropriate right. INVALID_RIGHT = 17, /// A blatant range error. INVALID_VALUE = 18, /// Operation would overflow limit on user-references. UREFS_OVERFLOW = 19, /// The supplied (port) capability is improper. INVALID_CAPABILITY = 20, /// The task already has send or receive rights /// for the port under another name. RIGHT_EXISTS = 21, /// Target host isn't actually a host. INVALID_HOST = 22, /// An attempt was made to supply "precious" data /// for memory that is already present in a /// memory object. MEMORY_PRESENT = 23, /// 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. MEMORY_DATA_MOVED = 24, /// 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. MEMORY_RESTART_COPY = 25, /// An argument applied to assert processor set privilege /// was not a processor set control port. INVALID_PROCESSOR_SET = 26, /// The specified scheduling attributes exceed the thread's /// limits. POLICY_LIMIT = 27, /// The specified scheduling policy is not currently /// enabled for the processor set. INVALID_POLICY = 28, /// The external memory manager failed to initialize the /// memory object. INVALID_OBJECT = 29, /// A thread is attempting to wait for an event for which /// there is already a waiting thread. ALREADY_WAITING = 30, /// An attempt was made to destroy the default processor /// set. DEFAULT_SET = 31, /// An attempt was made to fetch an exception port that is /// protected, or to abort a thread while processing a /// protected exception. EXCEPTION_PROTECTED = 32, /// A ledger was required but not supplied. INVALID_LEDGER = 33, /// The port was not a memory cache control port. INVALID_MEMORY_CONTROL = 34, /// An argument supplied to assert security privilege /// was not a host security port. INVALID_SECURITY = 35, /// thread_depress_abort was called on a thread which /// was not currently depressed. NOT_DEPRESSED = 36, /// Object has been terminated and is no longer available TERMINATED = 37, /// Lock set has been destroyed and is no longer available. LOCK_SET_DESTROYED = 38, /// The thread holding the lock terminated before releasing /// the lock LOCK_UNSTABLE = 39, /// The lock is already owned by another thread LOCK_OWNED = 40, /// The lock is already owned by the calling thread LOCK_OWNED_SELF = 41, /// Semaphore has been destroyed and is no longer available. SEMAPHORE_DESTROYED = 42, /// Return from RPC indicating the target server was /// terminated before it successfully replied RPC_SERVER_TERMINATED = 43, /// Terminate an orphaned activation. RPC_TERMINATE_ORPHAN = 44, /// Allow an orphaned activation to continue executing. RPC_CONTINUE_ORPHAN = 45, /// Empty thread activation (No thread linked to it) NOT_SUPPORTED = 46, /// Remote node down or inaccessible. NODE_DOWN = 47, /// A signalled thread was not actually waiting. NOT_WAITING = 48, /// Some thread-oriented operation (semaphore_wait) timed out OPERATION_TIMED_OUT = 49, /// During a page fault, indicates that the page was rejected /// as a result of a signature check. CODESIGN_ERROR = 50, /// The requested property cannot be changed at this time. POLICY_STATIC = 51, /// The provided buffer is of insufficient size for the requested data. INSUFFICIENT_BUFFER_SIZE = 52, /// Denied by security policy DENIED = 53, /// The KC on which the function is operating is missing MISSING_KC = 54, /// The KC on which the function is operating is invalid INVALID_KC = 55, /// A search or query operation did not return a result NOT_FOUND = 56, _, }; pub const mach_msg_return_t = kern_return_t; pub fn getMachMsgError(err: mach_msg_return_t) MachMsgE { return @as(MachMsgE, @enumFromInt(@as(u32, @truncate(@as(usize, @intCast(err)))))); } /// All special error code bits defined below. pub const MACH_MSG_MASK: u32 = 0x3e00; /// No room in IPC name space for another capability name. pub const MACH_MSG_IPC_SPACE: u32 = 0x2000; /// No room in VM address space for out-of-line memory. pub const MACH_MSG_VM_SPACE: u32 = 0x1000; /// Kernel resource shortage handling out-of-line memory. pub const MACH_MSG_IPC_KERNEL: u32 = 0x800; /// Kernel resource shortage handling an IPC capability. pub const MACH_MSG_VM_KERNEL: u32 = 0x400; /// Mach msg return values pub const MachMsgE = enum(u32) { SUCCESS = 0x00000000, /// Thread is waiting to send. (Internal use only.) SEND_IN_PROGRESS = 0x10000001, /// Bogus in-line data. SEND_INVALID_DATA = 0x10000002, /// Bogus destination port. SEND_INVALID_DEST = 0x10000003, /// Message not sent before timeout expired. SEND_TIMED_OUT = 0x10000004, /// Bogus voucher port. SEND_INVALID_VOUCHER = 0x10000005, /// Software interrupt. SEND_INTERRUPTED = 0x10000007, /// Data doesn't contain a complete message. SEND_MSG_TOO_SMALL = 0x10000008, /// Bogus reply port. SEND_INVALID_REPLY = 0x10000009, /// Bogus port rights in the message body. SEND_INVALID_RIGHT = 0x1000000a, /// Bogus notify port argument. SEND_INVALID_NOTIFY = 0x1000000b, /// Invalid out-of-line memory pointer. SEND_INVALID_MEMORY = 0x1000000c, /// No message buffer is available. SEND_NO_BUFFER = 0x1000000d, /// Send is too large for port SEND_TOO_LARGE = 0x1000000e, /// Invalid msg-type specification. SEND_INVALID_TYPE = 0x1000000f, /// A field in the header had a bad value. SEND_INVALID_HEADER = 0x10000010, /// The trailer to be sent does not match kernel format. SEND_INVALID_TRAILER = 0x10000011, /// The sending thread context did not match the context on the dest port SEND_INVALID_CONTEXT = 0x10000012, /// compatibility: no longer a returned error SEND_INVALID_RT_OOL_SIZE = 0x10000015, /// The destination port doesn't accept ports in body SEND_NO_GRANT_DEST = 0x10000016, /// Message send was rejected by message filter SEND_MSG_FILTERED = 0x10000017, /// Thread is waiting for receive. (Internal use only.) RCV_IN_PROGRESS = 0x10004001, /// Bogus name for receive port/port-set. RCV_INVALID_NAME = 0x10004002, /// Didn't get a message within the timeout value. RCV_TIMED_OUT = 0x10004003, /// Message buffer is not large enough for inline data. RCV_TOO_LARGE = 0x10004004, /// Software interrupt. RCV_INTERRUPTED = 0x10004005, /// compatibility: no longer a returned error RCV_PORT_CHANGED = 0x10004006, /// Bogus notify port argument. RCV_INVALID_NOTIFY = 0x10004007, /// Bogus message buffer for inline data. RCV_INVALID_DATA = 0x10004008, /// Port/set was sent away/died during receive. RCV_PORT_DIED = 0x10004009, /// compatibility: no longer a returned error RCV_IN_SET = 0x1000400a, /// Error receiving message header. See special bits. RCV_HEADER_ERROR = 0x1000400b, /// Error receiving message body. See special bits. RCV_BODY_ERROR = 0x1000400c, /// Invalid msg-type specification in scatter list. RCV_INVALID_TYPE = 0x1000400d, /// Out-of-line overwrite region is not large enough RCV_SCATTER_SMALL = 0x1000400e, /// trailer type or number of trailer elements not supported RCV_INVALID_TRAILER = 0x1000400f, /// Waiting for receive with timeout. (Internal use only.) RCV_IN_PROGRESS_TIMED = 0x10004011, /// invalid reply port used in a STRICT_REPLY message RCV_INVALID_REPLY = 0x10004012, }; pub const SIGSTKSZ = 131072; pub const MINSIGSTKSZ = 32768; pub const SS_ONSTACK = 1; pub const SS_DISABLE = 4; pub const stack_t = extern struct { sp: [*]u8, size: isize, flags: i32, }; 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; pub fn ISFIFO(m: u32) bool { return m & IFMT == IFIFO; } pub fn ISCHR(m: u32) bool { return m & IFMT == IFCHR; } pub fn ISDIR(m: u32) bool { return m & IFMT == IFDIR; } pub fn ISBLK(m: u32) bool { return m & IFMT == IFBLK; } pub fn ISREG(m: u32) bool { return m & IFMT == IFREG; } pub fn ISLNK(m: u32) bool { return m & IFMT == IFLNK; } pub fn ISSOCK(m: u32) bool { return m & IFMT == IFSOCK; } pub fn IWHT(m: u32) bool { return m & IFMT == IFWHT; } }; pub const HOST_NAME_MAX = 72; pub const addrinfo = extern struct { flags: i32, family: i32, socktype: i32, protocol: i32, addrlen: socklen_t, canonname: ?[*:0]u8, addr: ?*sockaddr, next: ?*addrinfo, }; 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))))); }; pub const F = struct { /// duplicate file descriptor pub const DUPFD = 0; /// get file descriptor flags pub const GETFD = 1; /// set file descriptor flags pub const SETFD = 2; /// get file status flags pub const GETFL = 3; /// set file status flags pub const SETFL = 4; /// get SIGIO/SIGURG proc/pgrp pub const GETOWN = 5; /// set SIGIO/SIGURG proc/pgrp pub const SETOWN = 6; /// get record locking information pub const GETLK = 7; /// set record locking information pub const SETLK = 8; /// F.SETLK; wait if blocked pub const SETLKW = 9; /// F.SETLK; wait if blocked, return on timeout pub const SETLKWTIMEOUT = 10; pub const FLUSH_DATA = 40; /// Used for regression test pub const CHKCLEAN = 41; /// Preallocate storage pub const PREALLOCATE = 42; /// Truncate a file without zeroing space pub const SETSIZE = 43; /// Issue an advisory read async with no copy to user pub const RDADVISE = 44; /// turn read ahead off/on for this fd pub const RDAHEAD = 45; /// turn data caching off/on for this fd pub const NOCACHE = 48; /// file offset to device offset pub const LOG2PHYS = 49; /// return the full path of the fd pub const GETPATH = 50; /// fsync + ask the drive to flush to the media pub const FULLFSYNC = 51; /// find which component (if any) is a package pub const PATHPKG_CHECK = 52; /// "freeze" all fs operations pub const FREEZE_FS = 53; /// "thaw" all fs operations pub const THAW_FS = 54; /// turn data caching off/on (globally) for this file pub const GLOBAL_NOCACHE = 55; /// add detached signatures pub const ADDSIGS = 59; /// add signature from same file (used by dyld for shared libs) pub const ADDFILESIGS = 61; /// 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) pub const NODIRECT = 62; ///Get the protection class of a file from the EA, returns int pub const GETPROTECTIONCLASS = 63; ///Set the protection class of a file for the EA, requires int pub const SETPROTECTIONCLASS = 64; ///file offset to device offset, extended pub const LOG2PHYS_EXT = 65; ///get record locking information, per-process pub const GETLKPID = 66; ///Mark the file as being the backing store for another filesystem pub const SETBACKINGSTORE = 70; ///return the full path of the FD, but error in specific mtmd circumstances pub const GETPATH_MTMINFO = 71; ///Returns the code directory, with associated hashes, to the caller pub const GETCODEDIR = 72; ///No SIGPIPE generated on EPIPE pub const SETNOSIGPIPE = 73; ///Status of SIGPIPE for this fd pub const GETNOSIGPIPE = 74; ///For some cases, we need to rewrap the key for AKS/MKB pub const TRANSCODEKEY = 75; ///file being written to a by single writer... if throttling enabled, writes ///may be broken into smaller chunks with throttling in between pub const SINGLE_WRITER = 76; ///Get the protection version number for this filesystem pub const GETPROTECTIONLEVEL = 77; ///Add detached code signatures (used by dyld for shared libs) pub const FINDSIGS = 78; ///Add signature from same file, only if it is signed by Apple (used by dyld for simulator) pub const ADDFILESIGS_FOR_DYLD_SIM = 83; ///fsync + issue barrier to drive pub const BARRIERFSYNC = 85; ///Add signature from same file, return end offset in structure on success pub const ADDFILESIGS_RETURN = 97; ///Check if Library Validation allows this Mach-O file to be mapped into the calling process pub const CHECK_LV = 98; ///Deallocate a range of the file pub const PUNCHHOLE = 99; ///Trim an active file pub const TRIM_ACTIVE_FILE = 100; ///mark the dup with FD_CLOEXEC pub const DUPFD_CLOEXEC = 67; /// shared or read lock pub const RDLCK = 1; /// unlock pub const UNLCK = 2; /// exclusive or write lock pub const WRLCK = 3; }; pub const FCNTL_FS_SPECIFIC_BASE = 0x00010000; ///close-on-exec flag pub const FD_CLOEXEC = 1; pub const LOCK = struct { pub const SH = 1; pub const EX = 2; pub const UN = 8; pub const NB = 4; }; pub const nfds_t = u32; pub const pollfd = extern struct { fd: fd_t, events: i16, revents: i16, }; 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; }; 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; }; /// 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; 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; }; 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; }; pub const rlim_t = u64; pub const RLIM = struct { /// No limit pub const INFINITY: rlim_t = (1 << 63) - 1; pub const SAVED_MAX = INFINITY; pub const SAVED_CUR = INFINITY; }; pub const rlimit = extern struct { /// Soft limit cur: rlim_t, /// Hard limit max: rlim_t, }; pub const SHUT = struct { pub const RD = 0; pub const WR = 1; pub const RDWR = 2; }; pub const TCSA = enum(c_uint) { NOW, DRAIN, FLUSH, _, }; pub const winsize = extern struct { ws_row: u16, ws_col: u16, ws_xpixel: u16, ws_ypixel: u16, }; pub const T = struct { pub const IOCGWINSZ = ior(0x40000000, 't', 104, @sizeOf(winsize)); }; 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 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, _, }; 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; }; pub const caddr_t = ?[*]u8; pub extern "c" fn ptrace(request: c_int, pid: pid_t, addr: caddr_t, data: c_int) c_int; 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; }; pub const posix_spawnattr_t = *opaque {}; pub const posix_spawn_file_actions_t = *opaque {}; pub extern "c" fn posix_spawnattr_init(attr: *posix_spawnattr_t) c_int; pub extern "c" fn posix_spawnattr_destroy(attr: *posix_spawnattr_t) c_int; pub extern "c" fn posix_spawnattr_setflags(attr: *posix_spawnattr_t, flags: 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; pub fn getKernError(err: kern_return_t) KernE { return @as(KernE, @enumFromInt(@as(u32, @truncate(@as(usize, @intCast(err)))))); } pub fn unexpectedKernError(err: KernE) std.posix.UnexpectedError { if (std.posix.unexpected_error_tracing) { std.debug.print("unexpected error: {d}\n", .{@intFromEnum(err)}); std.debug.dumpCurrentStackTrace(null); } return error.Unexpected; } pub const MachError = error{ /// Not enough permissions held to perform the requested kernel /// call. PermissionDenied, } || std.posix.UnexpectedError; pub const MachTask = extern struct { port: mach_port_name_t, pub fn isValid(self: MachTask) bool { return self.port != TASK_NULL; } pub fn pidForTask(self: MachTask) MachError!std.c.pid_t { var pid: std.c.pid_t = undefined; switch (getKernError(pid_for_task(self.port, &pid))) { .SUCCESS => return pid, .FAILURE => return error.PermissionDenied, else => |err| return unexpectedKernError(err), } } 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), } } pub fn deallocatePort(self: MachTask, port: MachTask) void { _ = getKernError(mach_port_deallocate(self.port, port.port)); } 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, }; 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), } } 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, }, }; 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, }, }; 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), } } 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; } pub fn setMaxProtection(task: MachTask, address: u64, len: usize, prot: vm_prot_t) MachError!void { return task.setProtectionImpl(address, len, true, prot); } 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), } } /// 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); } 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; } 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), } } 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, 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))), ); } }; 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), } } }; pub const MachThread = extern struct { port: mach_port_t, pub fn isValid(thread: MachThread) bool { return thread.port != THREAD_NULL; } 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), } } 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), } } }; pub fn machTaskForPid(pid: std.c.pid_t) MachError!MachTask { var port: mach_port_name_t = undefined; switch (getKernError(task_for_pid(mach_task_self(), pid, &port))) { .SUCCESS => {}, .FAILURE => return error.PermissionDenied, else => |err| return unexpectedKernError(err), } return MachTask{ .port = port }; } pub fn machTaskForSelf() MachTask { return .{ .port = mach_task_self() }; } pub const os_signpost_id_t = u64; pub const OS_SIGNPOST_ID_NULL: os_signpost_id_t = 0; pub const OS_SIGNPOST_ID_INVALID: os_signpost_id_t = !0; pub const OS_SIGNPOST_ID_EXCLUSIVE: os_signpost_id_t = 0xeeeeb0b5b2b2eeee; pub const os_log_t = opaque {}; pub const os_log_type_t = enum(u8) { /// default messages always captures OS_LOG_TYPE_DEFAULT = 0x00, /// messages with additional infos OS_LOG_TYPE_INFO = 0x01, /// debug messages OS_LOG_TYPE_DEBUG = 0x02, /// error messages OS_LOG_TYPE_ERROR = 0x10, /// unexpected conditions messages OS_LOG_TYPE_FAULT = 0x11, }; pub const OS_LOG_CATEGORY_POINTS_OF_INTEREST: *const u8 = "PointsOfInterest"; pub const OS_LOG_CATEGORY_DYNAMIC_TRACING: *const u8 = "DynamicTracing"; 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;