const std = #import("std"); const linux = std.os.linux; const macos = std.os.macos; const builtin = #import("builtin"); const os = builtin.os; const Error = switch (os) { .linux => linux.Error, .macos => macos.Error, else => #error("OS not supported"), }; const unwrap_syscall = fn(syscall_result: ssize) Error!usize { if (syscall_result == -1) { const absolute_error: u64 = #cast(-syscall_result); const error_int: u32 = #cast(absolute_error); const err: Error = #cast(error_int); return err; } else { const result: usize = #cast(syscall_result); return result; } } const MapFlags = switch (os) { .macos => bitfield(u32){ shared: bool, private: bool, reserved: u2 = 0, fixed: bool, reserved0: bool = 0, noreserve: bool, reserved1: u2 = 0, has_semaphore: bool, no_cache: bool, reserved2: u1 = 0, anonymous: bool, reserved3: u19 = 0, }, .linux => linux.MapFlags, else => #error("OS not supported"), }; const FileDescriptor = s32; const ProcessId = s32; const MAP_FAILED = 0xffffffffffffffff; const ProtectionFlags = bitfield(u32) { read: bool, write: bool, execute: bool, }; const get_protection_flags = fn(flags: std.os.ProtectionFlags) ProtectionFlags { return ProtectionFlags{ .read = flags.read, .write = flags.write, .execute = flags.execute, }; } const get_map_flags = fn(flags: std.os.MapFlags) MapFlags{ return MapFlags{ .shared = false, .private = true, .fixed = false, .noreserve = false, .has_semaphore = false, .no_cache = false, .anonymous = true, }; } const write :: extern = fn cc(.c) (file_descriptor: FileDescriptor, bytes_ptr: [&]const u8, bytes_len: usize) ssize; const exit :: extern = fn cc(.c) (exit_code: s32) noreturn; const fork :: extern = fn cc(.c) () ProcessId; const mmap :: extern = fn cc(.c) (address: ?[&]const u8, length: usize, protection_flags: ProtectionFlags, map_flags: MapFlags, file_descriptor: FileDescriptor, offset: u64) usize; const munmap :: extern = fn cc(.c) (address: [&]const u8, length: usize) s32; const execve :: extern = fn cc(.c) (path: [&:0]const u8, argv: [&:null]const ?[&:0]const u8, env: [&:null]const ?[&:null]const u8) s32; const realpath :: extern = fn cc(.c) (path: [&:0]const u8, resolved_path: [&:0]u8) ?[&:0]u8; const waitpid :: extern = fn cc(.c) (pid: ProcessId, status: &s32, flags: s32) s32; const _NSGetExecutablePath :: extern = fn cc(.c) (buffer: [&:0]u8, buffer_size: &u32) s32;