const std = #import("std"); const stdin: FileDescriptor = 0; const stdout: FileDescriptor = 1; const stderr: FileDescriptor = 2; const cpu = #import("builtin").cpu; const Syscall = switch (cpu) { .x86_64 => Syscall_x86_64, .aarch64 => Syscall_aarch64, else => #error("Architecture not supported"), }; const current_working_directory_file_descriptor: ssize = -100; const ProcessId = s32; const Syscall_aarch64 = enum(usize) { io_setup = 0, io_destroy = 1, io_submit = 2, io_cancel = 3, io_getevents = 4, setxattr = 5, lsetxattr = 6, fsetxattr = 7, getxattr = 8, lgetxattr = 9, fgetxattr = 10, listxattr = 11, llistxattr = 12, flistxattr = 13, removexattr = 14, lremovexattr = 15, fremovexattr = 16, getcwd = 17, lookup_dcookie = 18, eventfd2 = 19, epoll_create1 = 20, epoll_ctl = 21, epoll_pwait = 22, dup = 23, dup3 = 24, fcntl = 25, inotify_init1 = 26, inotify_add_watch = 27, inotify_rm_watch = 28, ioctl = 29, ioprio_set = 30, ioprio_get = 31, flock = 32, mknodat = 33, mkdirat = 34, unlinkat = 35, symlinkat = 36, linkat = 37, renameat = 38, umount2 = 39, mount = 40, pivot_root = 41, nfsservctl = 42, statfs = 43, fstatfs = 44, truncate = 45, ftruncate = 46, fallocate = 47, faccessat = 48, chdir = 49, fchdir = 50, chroot = 51, fchmod = 52, fchmodat = 53, fchownat = 54, fchown = 55, openat = 56, close = 57, vhangup = 58, pipe2 = 59, quotactl = 60, getdents64 = 61, lseek = 62, read = 63, write = 64, readv = 65, writev = 66, pread64 = 67, pwrite64 = 68, preadv = 69, pwritev = 70, sendfile = 71, pselect6 = 72, ppoll = 73, signalfd4 = 74, vmsplice = 75, splice = 76, tee = 77, readlinkat = 78, fstatat = 79, fstat = 80, sync = 81, fsync = 82, fdatasync = 83, sync_file_range = 84, timerfd_create = 85, timerfd_settime = 86, timerfd_gettime = 87, utimensat = 88, acct = 89, capget = 90, capset = 91, personality = 92, exit = 93, exit_group = 94, waitid = 95, set_tid_address = 96, unshare = 97, futex = 98, set_robust_list = 99, get_robust_list = 100, nanosleep = 101, getitimer = 102, setitimer = 103, kexec_load = 104, init_module = 105, delete_module = 106, timer_create = 107, timer_gettime = 108, timer_getoverrun = 109, timer_settime = 110, timer_delete = 111, clock_settime = 112, clock_gettime = 113, clock_getres = 114, clock_nanosleep = 115, syslog = 116, ptrace = 117, sched_setparam = 118, sched_setscheduler = 119, sched_getscheduler = 120, sched_getparam = 121, sched_setaffinity = 122, sched_getaffinity = 123, sched_yield = 124, sched_get_priority_max = 125, sched_get_priority_min = 126, sched_rr_get_interval = 127, restart_syscall = 128, kill = 129, tkill = 130, tgkill = 131, sigaltstack = 132, rt_sigsuspend = 133, rt_sigaction = 134, rt_sigprocmask = 135, rt_sigpending = 136, rt_sigtimedwait = 137, rt_sigqueueinfo = 138, rt_sigreturn = 139, setpriority = 140, getpriority = 141, reboot = 142, setregid = 143, setgid = 144, setreuid = 145, setuid = 146, setresuid = 147, getresuid = 148, setresgid = 149, getresgid = 150, setfsuid = 151, setfsgid = 152, times = 153, setpgid = 154, getpgid = 155, getsid = 156, setsid = 157, getgroups = 158, setgroups = 159, uname = 160, sethostname = 161, setdomainname = 162, getrlimit = 163, setrlimit = 164, getrusage = 165, umask = 166, prctl = 167, getcpu = 168, gettimeofday = 169, settimeofday = 170, adjtimex = 171, getpid = 172, getppid = 173, getuid = 174, geteuid = 175, getgid = 176, getegid = 177, gettid = 178, sysinfo = 179, mq_open = 180, mq_unlink = 181, mq_timedsend = 182, mq_timedreceive = 183, mq_notify = 184, mq_getsetattr = 185, msgget = 186, msgctl = 187, msgrcv = 188, msgsnd = 189, semget = 190, semctl = 191, semtimedop = 192, semop = 193, shmget = 194, shmctl = 195, shmat = 196, shmdt = 197, socket = 198, socketpair = 199, bind = 200, listen = 201, accept = 202, connect = 203, getsockname = 204, getpeername = 205, sendto = 206, recvfrom = 207, setsockopt = 208, getsockopt = 209, shutdown = 210, sendmsg = 211, recvmsg = 212, readahead = 213, brk = 214, munmap = 215, mremap = 216, add_key = 217, request_key = 218, keyctl = 219, clone = 220, execve = 221, mmap = 222, fadvise64 = 223, swapon = 224, swapoff = 225, mprotect = 226, msync = 227, mlock = 228, munlock = 229, mlockall = 230, munlockall = 231, mincore = 232, madvise = 233, remap_file_pages = 234, mbind = 235, get_mempolicy = 236, set_mempolicy = 237, migrate_pages = 238, move_pages = 239, rt_tgsigqueueinfo = 240, perf_event_open = 241, accept4 = 242, recvmmsg = 243, wait4 = 260, prlimit64 = 261, fanotify_init = 262, fanotify_mark = 263, name_to_handle_at = 264, open_by_handle_at = 265, clock_adjtime = 266, syncfs = 267, setns = 268, sendmmsg = 269, process_vm_readv = 270, process_vm_writev = 271, kcmp = 272, finit_module = 273, sched_setattr = 274, sched_getattr = 275, renameat2 = 276, seccomp = 277, getrandom = 278, memfd_create = 279, bpf = 280, execveat = 281, userfaultfd = 282, membarrier = 283, mlock2 = 284, copy_file_range = 285, preadv2 = 286, pwritev2 = 287, pkey_mprotect = 288, pkey_alloc = 289, pkey_free = 290, statx = 291, io_pgetevents = 292, rseq = 293, kexec_file_load = 294, pidfd_send_signal = 424, io_uring_setup = 425, io_uring_enter = 426, io_uring_register = 427, open_tree = 428, move_mount = 429, fsopen = 430, fsconfig = 431, fsmount = 432, fspick = 433, pidfd_open = 434, clone3 = 435, close_range = 436, openat2 = 437, pidfd_getfd = 438, faccessat2 = 439, process_madvise = 440, epoll_pwait2 = 441, mount_setattr = 442, quotactl_fd = 443, landlock_create_ruleset = 444, landlock_add_rule = 445, landlock_restrict_self = 446, memfd_secret = 447, process_mrelease = 448, futex_waitv = 449, set_mempolicy_home_node = 450, cachestat = 451, fchmodat2 = 452, map_shadow_stack = 453, futex_wake = 454, futex_wait = 455, futex_requeue = 456, }; const Syscall_x86_64 = enum(usize) { read = 0, write = 1, open = 2, close = 3, stat = 4, fstat = 5, lstat = 6, poll = 7, lseek = 8, mmap = 9, mprotect = 10, munmap = 11, brk = 12, rt_sigaction = 13, rt_sigprocmask = 14, rt_sigreturn = 15, ioctl = 16, pread64 = 17, pwrite64 = 18, readv = 19, writev = 20, access = 21, pipe = 22, select = 23, sched_yield = 24, mremap = 25, msync = 26, mincore = 27, madvise = 28, shmget = 29, shmat = 30, shmctl = 31, dup = 32, dup2 = 33, pause = 34, nanosleep = 35, getitimer = 36, alarm = 37, setitimer = 38, getpid = 39, sendfile = 40, socket = 41, connect = 42, accept = 43, sendto = 44, recvfrom = 45, sendmsg = 46, recvmsg = 47, shutdown = 48, bind = 49, listen = 50, getsockname = 51, getpeername = 52, socketpair = 53, setsockopt = 54, getsockopt = 55, clone = 56, fork = 57, vfork = 58, execve = 59, exit = 60, wait4 = 61, kill = 62, uname = 63, semget = 64, semop = 65, semctl = 66, shmdt = 67, msgget = 68, msgsnd = 69, msgrcv = 70, msgctl = 71, fcntl = 72, flock = 73, fsync = 74, fdatasync = 75, truncate = 76, ftruncate = 77, getdents = 78, getcwd = 79, chdir = 80, fchdir = 81, rename = 82, mkdir = 83, rmdir = 84, creat = 85, link = 86, unlink = 87, symlink = 88, readlink = 89, chmod = 90, fchmod = 91, chown = 92, fchown = 93, lchown = 94, umask = 95, gettimeofday = 96, getrlimit = 97, getrusage = 98, sysinfo = 99, times = 100, ptrace = 101, getuid = 102, syslog = 103, getgid = 104, setuid = 105, setgid = 106, geteuid = 107, getegid = 108, setpgid = 109, getppid = 110, getpgrp = 111, setsid = 112, setreuid = 113, setregid = 114, getgroups = 115, setgroups = 116, setresuid = 117, getresuid = 118, setresgid = 119, getresgid = 120, getpgid = 121, setfsuid = 122, setfsgid = 123, getsid = 124, capget = 125, capset = 126, rt_sigpending = 127, rt_sigtimedwait = 128, rt_sigqueueinfo = 129, rt_sigsuspend = 130, sigaltstack = 131, utime = 132, mknod = 133, uselib = 134, personality = 135, ustat = 136, statfs = 137, fstatfs = 138, sysfs = 139, getpriority = 140, setpriority = 141, sched_setparam = 142, sched_getparam = 143, sched_setscheduler = 144, sched_getscheduler = 145, sched_get_priority_max = 146, sched_get_priority_min = 147, sched_rr_get_interval = 148, mlock = 149, munlock = 150, mlockall = 151, munlockall = 152, vhangup = 153, modify_ldt = 154, pivot_root = 155, _sysctl = 156, prctl = 157, arch_prctl = 158, adjtimex = 159, setrlimit = 160, chroot = 161, sync = 162, acct = 163, settimeofday = 164, mount = 165, umount2 = 166, swapon = 167, swapoff = 168, reboot = 169, sethostname = 170, setdomainname = 171, iopl = 172, ioperm = 173, create_module = 174, init_module = 175, delete_module = 176, get_kernel_syms = 177, query_module = 178, quotactl = 179, nfsservctl = 180, getpmsg = 181, putpmsg = 182, afs_syscall = 183, tuxcall = 184, security = 185, gettid = 186, readahead = 187, setxattr = 188, lsetxattr = 189, fsetxattr = 190, getxattr = 191, lgetxattr = 192, fgetxattr = 193, listxattr = 194, llistxattr = 195, flistxattr = 196, removexattr = 197, lremovexattr = 198, fremovexattr = 199, tkill = 200, time = 201, futex = 202, sched_setaffinity = 203, sched_getaffinity = 204, set_thread_area = 205, io_setup = 206, io_destroy = 207, io_getevents = 208, io_submit = 209, io_cancel = 210, get_thread_area = 211, lookup_dcookie = 212, epoll_create = 213, epoll_ctl_old = 214, epoll_wait_old = 215, remap_file_pages = 216, getdents64 = 217, set_tid_address = 218, restart_syscall = 219, semtimedop = 220, fadvise64 = 221, timer_create = 222, timer_settime = 223, timer_gettime = 224, timer_getoverrun = 225, timer_delete = 226, clock_settime = 227, clock_gettime = 228, clock_getres = 229, clock_nanosleep = 230, exit_group = 231, epoll_wait = 232, epoll_ctl = 233, tgkill = 234, utimes = 235, vserver = 236, mbind = 237, set_mempolicy = 238, get_mempolicy = 239, mq_open = 240, mq_unlink = 241, mq_timedsend = 242, mq_timedreceive = 243, mq_notify = 244, mq_getsetattr = 245, kexec_load = 246, waitid = 247, add_key = 248, request_key = 249, keyctl = 250, ioprio_set = 251, ioprio_get = 252, inotify_init = 253, inotify_add_watch = 254, inotify_rm_watch = 255, migrate_pages = 256, openat = 257, mkdirat = 258, mknodat = 259, fchownat = 260, futimesat = 261, fstatat64 = 262, unlinkat = 263, renameat = 264, linkat = 265, symlinkat = 266, readlinkat = 267, fchmodat = 268, faccessat = 269, pselect6 = 270, ppoll = 271, unshare = 272, set_robust_list = 273, get_robust_list = 274, splice = 275, tee = 276, sync_file_range = 277, vmsplice = 278, move_pages = 279, utimensat = 280, epoll_pwait = 281, signalfd = 282, timerfd_create = 283, eventfd = 284, fallocate = 285, timerfd_settime = 286, timerfd_gettime = 287, accept4 = 288, signalfd4 = 289, eventfd2 = 290, epoll_create1 = 291, dup3 = 292, pipe2 = 293, inotify_init1 = 294, preadv = 295, pwritev = 296, rt_tgsigqueueinfo = 297, perf_event_open = 298, recvmmsg = 299, fanotify_init = 300, fanotify_mark = 301, prlimit64 = 302, name_to_handle_at = 303, open_by_handle_at = 304, clock_adjtime = 305, syncfs = 306, sendmmsg = 307, setns = 308, getcpu = 309, process_vm_readv = 310, process_vm_writev = 311, kcmp = 312, finit_module = 313, sched_setattr = 314, sched_getattr = 315, renameat2 = 316, seccomp = 317, getrandom = 318, memfd_create = 319, kexec_file_load = 320, bpf = 321, execveat = 322, userfaultfd = 323, membarrier = 324, mlock2 = 325, copy_file_range = 326, preadv2 = 327, pwritev2 = 328, pkey_mprotect = 329, pkey_alloc = 330, pkey_free = 331, statx = 332, io_pgetevents = 333, rseq = 334, pidfd_send_signal = 424, io_uring_setup = 425, io_uring_enter = 426, io_uring_register = 427, open_tree = 428, move_mount = 429, fsopen = 430, fsconfig = 431, fsmount = 432, fspick = 433, pidfd_open = 434, clone3 = 435, close_range = 436, openat2 = 437, pidfd_getfd = 438, faccessat2 = 439, process_madvise = 440, epoll_pwait2 = 441, mount_setattr = 442, quotactl_fd = 443, landlock_create_ruleset = 444, landlock_add_rule = 445, landlock_restrict_self = 446, memfd_secret = 447, process_mrelease = 448, futex_waitv = 449, set_mempolicy_home_node = 450, cachestat = 451, }; const Error = error{ /// Operation not permitted PERM = 1, /// No such file or directory NOENT = 2, /// No such process SRCH = 3, /// Interrupted system call INTR = 4, /// I/O error IO = 5, /// No such device or address NXIO = 6, /// Arg list too long TOO_BIG = 7, /// Exec format error NOEXEC = 8, /// Bad file number BADF = 9, /// No child processes CHILD = 10, /// Try again /// Also means: WOULDBLOCK: operation would block AGAIN = 11, /// Out of memory NOMEM = 12, /// Permission denied ACCES = 13, /// Bad address FAULT = 14, /// Block device required NOTBLK = 15, /// Device or resource busy BUSY = 16, /// File exists EXIST = 17, /// Cross-device link XDEV = 18, /// No such device NODEV = 19, /// Not a directory NOTDIR = 20, /// Is a directory ISDIR = 21, /// Invalid argument INVAL = 22, /// File table overflow NFILE = 23, /// Too many open files MFILE = 24, /// Not a typewriter 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 argument out of domain of func DOM = 33, /// Math result not representable RANGE = 34, /// Resource deadlock would occur DEADLK = 35, /// File name too long NAMETOOLONG = 36, /// No record locks available NOLCK = 37, /// Function not implemented NOSYS = 38, /// Directory not empty NOTEMPTY = 39, /// Too many symbolic links encountered LOOP = 40, /// No message of desired type NOMSG = 42, /// Identifier removed IDRM = 43, /// Channel number out of range CHRNG = 44, /// Level 2 not synchronized L2NSYNC = 45, /// Level 3 halted L3HLT = 46, /// Level 3 reset L3RST = 47, /// Link number out of range LNRNG = 48, /// Protocol driver not attached UNATCH = 49, /// No CSI structure available NOCSI = 50, /// Level 2 halted L2HLT = 51, /// Invalid exchange BADE = 52, /// Invalid request descriptor BADR = 53, /// Exchange full XFULL = 54, /// No anode NOANO = 55, /// Invalid request code BADRQC = 56, /// Invalid slot BADSLT = 57, /// Bad font file format BFONT = 59, /// Device not a stream NOSTR = 60, /// No data available NODATA = 61, /// Timer expired TIME = 62, /// Out of streams resources NOSR = 63, /// Machine is not on the network NONET = 64, /// Package not installed NOPKG = 65, /// Object is remote REMOTE = 66, /// Link has been severed NOLINK = 67, /// Advertise error ADV = 68, /// Srmount error SRMNT = 69, /// Communication error on send COMM = 70, /// Protocol error PROTO = 71, /// Multihop attempted MULTIHOP = 72, /// RFS specific error DOTDOT = 73, /// Not a data message BADMSG = 74, /// Value too large for defined data type OVERFLOW = 75, /// Name not unique on network NOTUNIQ = 76, /// File descriptor in bad state BADFD = 77, /// Remote address changed REMCHG = 78, /// Can not access a needed shared library LIBACC = 79, /// Accessing a corrupted shared library LIBBAD = 80, /// .lib section in a.out corrupted LIBSCN = 81, /// Attempting to link in too many shared libraries LIBMAX = 82, /// Cannot exec a shared library directly LIBEXEC = 83, /// Illegal byte sequence ILSEQ = 84, /// Interrupted system call should be restarted RESTART = 85, /// Streams pipe error STRPIPE = 86, /// Too many users USERS = 87, /// Socket operation on non-socket NOTSOCK = 88, /// Destination address required DESTADDRREQ = 89, /// Message too long MSGSIZE = 90, /// Protocol wrong type for socket PROTOTYPE = 91, /// Protocol not available NOPROTOOPT = 92, /// Protocol not supported PROTONOSUPPORT = 93, /// Socket type not supported SOCKTNOSUPPORT = 94, /// Operation not supported on transport endpoint /// This code also means `NOTSUP`. OPNOTSUPP = 95, /// Protocol family not supported PFNOSUPPORT = 96, /// Address family not supported by protocol AFNOSUPPORT = 97, /// Address already in use ADDRINUSE = 98, /// Cannot assign requested address ADDRNOTAVAIL = 99, /// Network is down NETDOWN = 100, /// Network is unreachable NETUNREACH = 101, /// Network dropped connection because of reset NETRESET = 102, /// Software caused connection abort CONNABORTED = 103, /// Connection reset by peer CONNRESET = 104, /// No buffer space available NOBUFS = 105, /// Transport endpoint is already connected ISCONN = 106, /// Transport endpoint is not connected NOTCONN = 107, /// Cannot send after transport endpoint shutdown SHUTDOWN = 108, /// Too many references: cannot splice TOOMANYREFS = 109, /// Connection timed out TIMEDOUT = 110, /// Connection refused CONNREFUSED = 111, /// Host is down HOSTDOWN = 112, /// No route to host HOSTUNREACH = 113, /// Operation already in progress ALREADY = 114, /// Operation now in progress INPROGRESS = 115, /// Stale NFS file handle STALE = 116, /// Structure needs cleaning UCLEAN = 117, /// Not a XENIX named type file NOTNAM = 118, /// No XENIX semaphores available NAVAIL = 119, /// Is a named type file ISNAM = 120, /// Remote I/O error REMOTEIO = 121, /// Quota exceeded DQUOT = 122, /// No medium found NOMEDIUM = 123, /// Wrong medium type MEDIUMTYPE = 124, /// Operation canceled CANCELED = 125, /// Required key not available NOKEY = 126, /// Key has expired KEYEXPIRED = 127, /// Key has been revoked KEYREVOKED = 128, /// Key was rejected by service KEYREJECTED = 129, // for robust mutexes /// Owner died OWNERDEAD = 130, /// State not recoverable NOTRECOVERABLE = 131, /// Operation not possible due to RF-kill RFKILL = 132, /// Memory page has hardware error HWPOISON = 133, // nameserver query return codes /// DNS server returned answer with no data NSRNODATA = 160, /// DNS server claims query was misformatted NSRFORMERR = 161, /// DNS server returned general failure NSRSERVFAIL = 162, /// Domain name not found NSRNOTFOUND = 163, /// DNS server does not implement requested operation NSRNOTIMP = 164, /// DNS server refused query NSRREFUSED = 165, /// Misformatted DNS query NSRBADQUERY = 166, /// Misformatted domain name NSRBADNAME = 167, /// Unsupported address family NSRBADFAMILY = 168, /// Misformatted DNS reply NSRBADRESP = 169, /// Could not contact DNS servers NSRCONNREFUSED = 170, /// Timeout while contacting DNS servers NSRTIMEOUT = 171, /// End of file NSROF = 172, /// Error reading file NSRFILE = 173, /// Out of memory NSRNOMEM = 174, /// Application terminated lookup NSRDESTRUCTION = 175, /// Domain name is too long NSRQUERYDOMAINTOOLONG = 176, /// Domain name is too long NSRCNAMELOOP = 177, }; const FileDescriptor = s32; const ProtectionFlags = bitfield(u32) { read: bool, write: bool, execute: bool, }; const MapFlags = bitfield(u32){ shared: bool, private: bool, reserved: u2 = 0, fixed: bool, anonymous: 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, .anonymous = true, }; } const exit = fn (exit_code: s32) noreturn { _ = #syscall(#cast(Syscall.exit), #cast(exit_code)); unreachable; } const mmap = fn(address: ?[&]u8, length: usize, protection_flags: ProtectionFlags, map_flags: MapFlags, fd: FileDescriptor, offset: u64) usize { const flat_protection_flags: u32 = #cast(protection_flags); const flat_map_flags: u32 = #cast(map_flags); const result = #syscall(#cast(Syscall.mmap), #cast(address), length, flat_protection_flags, flat_map_flags, #cast(fd), offset); return result; } const mprotect = fn(address: &any, length: usize, protection_flags: ProtectionFlags) usize { const flat_protection_flags: u32 = #cast(protection_flags); const result = #syscall(#cast(Syscall.mprotect), #cast(address), length, flat_protection_flags); return result; } const munmap = fn(bytes: []const u8) usize { const result = #syscall(#cast(Syscall.munmap), #cast(bytes.pointer), bytes.length); return result; } const readlink = fn(file_path: [&:0]const u8, bytes: []u8) usize { switch (cpu) { .x86_64 => { const result = #syscall(#cast(Syscall.readlink), #cast(file_path), #cast(bytes.pointer), bytes.length); return result; }, .aarch64 => { const result = #syscall(#cast(Syscall.readlinkat), #cast(current_working_directory_file_descriptor), #cast(file_path), #cast(bytes.pointer), bytes.length); return result; }, } } const SIG = struct { const BLOCK = 0; const UNBLOCK = 1; const SETMASK = 2; const HUP = 1; const INT = 2; const QUIT = 3; const ILL = 4; const TRAP = 5; const ABRT = 6; const IOT = ABRT; const BUS = 7; const FPE = 8; const KILL = 9; const USR1 = 10; const SEGV = 11; const USR2 = 12; const PIPE = 13; const ALRM = 14; const TERM = 15; const STKFLT = 16; const CHLD = 17; const CONT = 18; const STOP = 19; const TSTP = 20; const TTIN = 21; const TTOU = 22; const URG = 23; const XCPU = 24; const XFSZ = 25; const VTALRM = 26; const PROF = 27; const WINCH = 28; const IO = 29; const POLL = 29; const PWR = 30; const SYS = 31; }; const fork = fn() usize { switch (cpu) { .x86_64 => { const result = #syscall(#cast(Syscall.fork)); return result; }, .aarch64 => { const result = #syscall(#cast(Syscall.clone), SIG.CHLD, 0); return result; }, } } const execve = fn(path: [&:0]const u8, argv: [&:null]const ?[&:0]const u8, env: [&:null]const ?[&:null]const u8) usize { const result = #syscall(#cast(Syscall.execve), #cast(path), #cast(argv), #cast(env)); return result; } const event_file_descriptor = fn(count: u32, flags: u32) usize { const result = #syscall(#cast(Syscall.eventfd2), #cast(count), #cast(flags)); return result; } const dup2 = fn(old: FileDescriptor, new: FileDescriptor) usize { const result = #syscall(#cast(Syscall.dup2), #cast(old), #cast(new)); return result; } const open = fn(path: [&:0]const u8, flags: OpenFlags, permissions: u32) usize { const flattened_flags: u32 = #cast(flags); switch (cpu) { .x86_64 => { const result = #syscall(#cast(Syscall.open), #cast(path), flattened_flags, permissions); return result; }, .aarch64 => { const result = #syscall(#cast(Syscall.openat), #cast(current_working_directory_file_descriptor), #cast(path), flattened_flags, permissions); return result; }, } } const openat = fn(directory_file_descriptor: FileDescriptor, path: [&:0]const u8, flags: u32, permissions: u32) usize { const result = #syscall(#cast(Syscall.openat), #cast(directory_file_descriptor), #cast(path), flags, permissions); return result; } const read = fn(file_descriptor: FileDescriptor, byte_pointer: [&]u8, byte_count: usize) usize { const result = #syscall(#cast(Syscall.read), #cast(file_descriptor), #cast(byte_pointer), byte_count); return result; } const write = fn(file_descriptor: FileDescriptor, bytes: []const u8) usize { const result = #syscall(#cast(Syscall.write), #cast(file_descriptor), #cast(bytes.pointer), bytes.length); return result; } const close = fn(file_descriptor: FileDescriptor) usize { const result = #syscall(#cast(Syscall.close), #cast(file_descriptor)); return result; } const pipe2 = fn (pipe_pointer: &[2]FileDescriptor, flags: u32) usize { const result = #syscall(#cast(Syscall.pipe2), #cast(pipe_pointer), flags); return result; } const waitpid = fn(pid: ProcessId, status: &u32, flags: u32, resource_usage: usize) usize { const pid_unsigned: u32 = #cast(pid); const result = #syscall(#cast(Syscall.wait4), pid_unsigned, #cast(status), flags, resource_usage); return result; } const poll = fn(file_descriptors: [&]PollFileDescriptor, file_descriptor_count: usize, timeout: s32) usize { const result = #syscall(#cast(Syscall.poll), #cast(file_descriptors), file_descriptor_count, #cast(timeout)); return result; } const memfd_create = fn(name: [&:0]const u8, flags: u32) usize { const result = #syscall(#cast(Syscall.memfd_create), flags); return result; } const TimeSpec = struct{ seconds: s64, nanoseconds: s64, }; const Stat = struct{ dev: u64, inode: u64, nlink: u64, mode: u32, uid: u32, gid: u32, _: u32, rdev: u64, size: s64, block_size: s64, blocks: s64, atime: TimeSpec, mtime: TimeSpec, ctime: TimeSpec, _: [3]u64, }; const fstat = fn(file_descriptor: FileDescriptor, stat_buffer: &Stat) usize { const file_descriptor_u: u32 = #cast(file_descriptor); const result = #syscall(#cast(Syscall.fstat), file_descriptor_u, #cast(stat_buffer)); return result; } const unwrap_syscall = fn(syscall_result: usize) Error!usize { const signed_syscall_result: ssize = #cast(syscall_result); if (signed_syscall_result > -4096 and signed_syscall_result < 0) { const absolute_error: u64 = #cast(-signed_syscall_result); const error_int: u32 = #cast(absolute_error); const err: Error = #cast(error_int); return err; } else { return syscall_result; } } const EventFileDescriptorFlags = enum(u32) { semaphore = 1, cloexec = 0o2000000, nonblock = 0o4000, }; const PollFileDescriptor = struct{ file_descriptor: FileDescriptor, events: Poll, revents: Poll, const Poll = bitfield(u16) { in: bool = false, pri: bool = false, out: bool = false, err: bool = false, hup: bool = false, nval: bool = false, rdnorm: bool = false, rdband: bool = false, }; }; const AccessMode = enum(u2) { read_only = 0, write_only = 1, read_write = 2, }; const OpenFlags = bitfield(u32) { access_mode: AccessMode, _: u4 = 0, creat: bool = false, excl: bool = false, noctty: bool = false, truncate: bool = false, append: bool = false, non_block: bool = false, dsync: bool = false, async: bool = false, direct: bool = false, _: u1 = 0, directory: bool = false, no_follow: bool = false, noatime: bool = false, cloexec: bool = false, sync: bool = false, path: bool = false, tmpfile: bool = false, _: u9 = 0, };