Commit 0c83fa2fd0

Jacob Young <jacobly0@users.noreply.github.com>
2024-04-06 23:47:54
haiku: fix directory iteration
1 parent 23ee391
Changed files (2)
lib
lib/std/c/haiku.zig
@@ -5,28 +5,18 @@ const maxInt = std.math.maxInt;
 const iovec = std.posix.iovec;
 const iovec_const = std.posix.iovec_const;
 
-extern "c" fn _errnop() *c_int;
+pub extern "root" fn find_directory(which: directory_which, volume: i32, createIt: bool, path_ptr: [*]u8, length: i32) u64;
 
-pub const _errno = _errnop;
-
-pub extern "c" fn find_directory(which: directory_which, volume: i32, createIt: bool, path_ptr: [*]u8, length: i32) u64;
+pub extern "root" fn find_thread(thread_name: ?*anyopaque) i32;
 
-pub extern "c" fn find_thread(thread_name: ?*anyopaque) i32;
+pub extern "root" fn get_system_info(system_info: *system_info) usize;
 
-pub extern "c" fn get_system_info(system_info: *system_info) usize;
+pub extern "root" fn _get_team_info(team: i32, team_info: *team_info, size: usize) i32;
 
-pub extern "c" fn _get_team_info(team: c_int, team_info: *team_info, size: usize) i32;
-
-pub extern "c" fn _get_next_area_info(team: c_int, cookie: *i64, area_info: *area_info, size: usize) i32;
+pub extern "root" fn _get_next_area_info(team: i32, cookie: *i64, area_info: *area_info, size: usize) i32;
 
 // TODO revisit if abi changes or better option becomes apparent
-pub extern "c" fn _get_next_image_info(team: c_int, cookie: *i32, image_info: *image_info, size: usize) i32;
-
-pub extern "c" fn _kern_read_dir(fd: c_int, buf_ptr: [*]u8, nbytes: usize, maxcount: u32) usize;
-
-pub extern "c" fn _kern_read_stat(fd: c_int, path_ptr: [*]u8, traverse_link: bool, st: *Stat, stat_size: i32) usize;
-
-pub extern "c" fn _kern_get_current_team() i32;
+pub extern "root" fn _get_next_image_info(team: i32, cookie: *i32, image_info: *image_info, size: usize) i32;
 
 pub const sem_t = extern struct {
     type: i32,
@@ -45,7 +35,7 @@ pub const pthread_attr_t = extern struct {
     __stack_address: ?*anyopaque,
 };
 
-pub const EAI = enum(c_int) {
+pub const EAI = enum(i32) {
     /// address family for hostname not supported
     ADDRFAMILY = 1,
 
@@ -99,11 +89,7 @@ pub const AI = struct {
 
 pub const AI_NUMERICSERV = AI.NUMERICSERV;
 
-pub const fd_t = c_int;
-pub const pid_t = c_int;
-pub const uid_t = u32;
-pub const gid_t = u32;
-pub const mode_t = c_uint;
+pub const fd_t = i32;
 
 pub const socklen_t = u32;
 
@@ -129,8 +115,8 @@ pub const dl_phdr_info = extern struct {
 };
 
 pub const Flock = extern struct {
-    type: c_short,
-    whence: c_short,
+    type: i16,
+    whence: i16,
     start: off_t,
     len: off_t,
     pid: pid_t,
@@ -159,54 +145,6 @@ pub const msghdr = extern struct {
     msg_flags: i32,
 };
 
-pub const off_t = i64;
-pub const ino_t = u64;
-
-pub const Stat = extern struct {
-    dev: i32,
-    ino: u64,
-    mode: u32,
-    nlink: i32,
-    uid: i32,
-    gid: i32,
-    size: i64,
-    rdev: i32,
-    blksize: i32,
-    atim: timespec,
-    mtim: timespec,
-    ctim: timespec,
-    crtim: timespec,
-    st_type: u32,
-    blocks: i64,
-
-    pub fn atime(self: @This()) timespec {
-        return self.atim;
-    }
-    pub fn mtime(self: @This()) timespec {
-        return self.mtim;
-    }
-    pub fn ctime(self: @This()) timespec {
-        return self.ctim;
-    }
-    pub fn birthtime(self: @This()) timespec {
-        return self.crtim;
-    }
-};
-
-pub const timespec = extern struct {
-    tv_sec: isize,
-    tv_nsec: isize,
-};
-
-pub const dirent = extern struct {
-    dev: i32,
-    pdev: i32,
-    ino: i64,
-    pino: i64,
-    reclen: u16,
-    name: [256]u8,
-};
-
 pub const B_OS_NAME_LENGTH = 32; // OS.h
 
 pub const area_info = extern struct {
@@ -354,17 +292,6 @@ pub const PROT = struct {
     pub const NONE = 0x00;
 };
 
-pub const CLOCK = struct {
-    /// system-wide monotonic clock (aka system time)
-    pub const MONOTONIC = 0;
-    /// system-wide real time clock
-    pub const REALTIME = -1;
-    /// clock measuring the used CPU time of the current process
-    pub const PROCESS_CPUTIME_ID = -2;
-    /// clock measuring the used CPU time of the current thread
-    pub const THREAD_CPUTIME_ID = -3;
-};
-
 pub const MSF = struct {
     pub const ASYNC = 1;
     pub const INVALIDATE = 2;
@@ -404,159 +331,526 @@ pub const W = struct {
     }
 };
 
-// /system/develop/headers/posix/poll.h
-
-pub const nfds_t = usize;
+// access function
+pub const F_OK = 0; // test for existence of file
+pub const X_OK = 1; // test for execute or search permission
+pub const W_OK = 2; // test for write permission
+pub const R_OK = 4; // test for read permission
 
-pub const pollfd = extern struct {
-    fd: i32,
-    events: i16,
-    revents: i16,
-};
+pub const F = struct {
+    pub const DUPFD = 0x0001;
+    pub const GETFD = 0x0002;
+    pub const SETFD = 0x0004;
+    pub const GETFL = 0x0008;
+    pub const SETFL = 0x0010;
 
-pub const POLL = struct {
-    /// any readable data available
-    pub const IN = 0x0001;
-    /// file descriptor is writeable
-    pub const OUT = 0x0002;
-    pub const RDNORM = IN;
-    pub const WRNORM = OUT;
-    /// priority readable data
-    pub const RDBAND = 0x0008;
-    /// priority data can be written
-    pub const WRBAND = 0x0010;
-    /// high priority readable data
-    pub const PRI = 0x0020;
+    pub const GETLK = 0x0020;
+    pub const SETLK = 0x0080;
+    pub const SETLKW = 0x0100;
+    pub const DUPFD_CLOEXEC = 0x0200;
 
-    /// errors pending
-    pub const ERR = 0x0004;
-    /// disconnected
-    pub const HUP = 0x0080;
-    /// invalid file descriptor
-    pub const NVAL = 0x1000;
+    pub const RDLCK = 0x0040;
+    pub const UNLCK = 0x0200;
+    pub const WRLCK = 0x0400;
 };
 
-// /system/develop/headers/posix/signal.h
-
-pub const sigset_t = u64;
-pub const empty_sigset: sigset_t = 0;
-pub const filled_sigset = ~@as(sigset_t, 0);
-
-pub const SIG = struct {
-    pub const DFL: ?Sigaction.handler_fn = @ptrFromInt(0);
-    pub const IGN: ?Sigaction.handler_fn = @ptrFromInt(1);
-    pub const ERR: ?Sigaction.handler_fn = @ptrFromInt(maxInt(usize));
-
-    pub const HOLD: ?Sigaction.handler_fn = @ptrFromInt(3);
-
-    pub const HUP = 1;
-    pub const INT = 2;
-    pub const QUIT = 3;
-    pub const ILL = 4;
-    pub const CHLD = 5;
-    pub const ABRT = 6;
-    pub const IOT = ABRT;
-    pub const PIPE = 7;
-    pub const FPE = 8;
-    pub const KILL = 9;
-    pub const STOP = 10;
-    pub const SEGV = 11;
-    pub const CONT = 12;
-    pub const TSTP = 13;
-    pub const ALRM = 14;
-    pub const TERM = 15;
-    pub const TTIN = 16;
-    pub const TTOU = 17;
-    pub const USR1 = 18;
-    pub const USR2 = 19;
-    pub const WINCH = 20;
-    pub const KILLTHR = 21;
-    pub const TRAP = 22;
-    pub const POLL = 23;
-    pub const PROF = 24;
-    pub const SYS = 25;
-    pub const URG = 26;
-    pub const VTALRM = 27;
-    pub const XCPU = 28;
-    pub const XFSZ = 29;
-    pub const BUS = 30;
-    pub const RESERVED1 = 31;
-    pub const RESERVED2 = 32;
-
-    pub const BLOCK = 1;
-    pub const UNBLOCK = 2;
-    pub const SETMASK = 3;
+pub const LOCK = struct {
+    pub const SH = 0x01;
+    pub const EX = 0x02;
+    pub const NB = 0x04;
+    pub const UN = 0x08;
 };
 
-pub const siginfo_t = extern struct {
-    signo: c_int,
-    code: c_int,
-    errno: c_int,
+pub const FD_CLOEXEC = 1;
 
-    pid: pid_t,
-    uid: uid_t,
-    addr: *allowzero anyopaque,
+pub const SEEK = struct {
+    pub const SET = 0;
+    pub const CUR = 1;
+    pub const END = 2;
 };
 
-/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
-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;
-
-    /// signal handler
-    handler: extern union {
-        handler: handler_fn,
-        sigaction: sigaction_fn,
-    },
+pub const SOCK = struct {
+    pub const STREAM = 1;
+    pub const DGRAM = 2;
+    pub const RAW = 3;
+    pub const SEQPACKET = 5;
 
-    /// signal mask to apply
-    mask: sigset_t,
+    /// WARNING: this flag is not supported by windows socket functions directly,
+    ///          it is only supported by std.os.socket. Be sure that this value does
+    ///          not share any bits with any of the `SOCK` values.
+    pub const CLOEXEC = 0x10000;
+    /// WARNING: this flag is not supported by windows socket functions directly,
+    ///          it is only supported by std.os.socket. Be sure that this value does
+    ///          not share any bits with any of the `SOCK` values.
+    pub const NONBLOCK = 0x20000;
+};
 
-    /// see signal options
-    flags: c_int,
+pub const SO = struct {
+    pub const ACCEPTCONN = 0x00000001;
+    pub const BROADCAST = 0x00000002;
+    pub const DEBUG = 0x00000004;
+    pub const DONTROUTE = 0x00000008;
+    pub const KEEPALIVE = 0x00000010;
+    pub const OOBINLINE = 0x00000020;
+    pub const REUSEADDR = 0x00000040;
+    pub const REUSEPORT = 0x00000080;
+    pub const USELOOPBACK = 0x00000100;
+    pub const LINGER = 0x00000200;
 
-    /// will be passed to the signal handler, BeOS extension
-    userdata: *allowzero anyopaque = undefined,
+    pub const SNDBUF = 0x40000001;
+    pub const SNDLOWAT = 0x40000002;
+    pub const SNDTIMEO = 0x40000003;
+    pub const RCVBUF = 0x40000004;
+    pub const RCVLOWAT = 0x40000005;
+    pub const RCVTIMEO = 0x40000006;
+    pub const ERROR = 0x40000007;
+    pub const TYPE = 0x40000008;
+    pub const NONBLOCK = 0x40000009;
+    pub const BINDTODEVICE = 0x4000000a;
+    pub const PEERCRED = 0x4000000b;
 };
 
-pub const SA = struct {
-    pub const NOCLDSTOP = 0x01;
-    pub const NOCLDWAIT = 0x02;
-    pub const RESETHAND = 0x04;
-    pub const NODEFER = 0x08;
-    pub const RESTART = 0x10;
-    pub const ONSTACK = 0x20;
-    pub const SIGINFO = 0x40;
-    pub const NOMASK = NODEFER;
-    pub const STACK = ONSTACK;
-    pub const ONESHOT = RESETHAND;
+pub const SOL = struct {
+    pub const SOCKET = -1;
 };
 
-pub const SS = struct {
-    pub const ONSTACK = 0x1;
-    pub const DISABLE = 0x2;
+pub const PF = struct {
+    pub const UNSPEC = AF.UNSPEC;
+    pub const INET = AF.INET;
+    pub const ROUTE = AF.ROUTE;
+    pub const LINK = AF.LINK;
+    pub const INET6 = AF.INET6;
+    pub const LOCAL = AF.LOCAL;
+    pub const UNIX = AF.UNIX;
+    pub const BLUETOOTH = AF.BLUETOOTH;
 };
 
-pub const MINSIGSTKSZ = 8192;
-pub const SIGSTKSZ = 16384;
-
-pub const stack_t = extern struct {
-    sp: [*]u8,
-    size: isize,
-    flags: i32,
+pub const AF = struct {
+    pub const UNSPEC = 0;
+    pub const INET = 1;
+    pub const APPLETALK = 2;
+    pub const ROUTE = 3;
+    pub const LINK = 4;
+    pub const INET6 = 5;
+    pub const DLI = 6;
+    pub const IPX = 7;
+    pub const NOTIFY = 8;
+    pub const LOCAL = 9;
+    pub const UNIX = LOCAL;
+    pub const BLUETOOTH = 10;
+    pub const MAX = 11;
 };
 
-pub const NSIG = 65;
+pub const DT = struct {};
 
-pub const mcontext_t = vregs;
+/// add event to kq (implies enable)
+pub const EV_ADD = 0x0001;
 
-pub const ucontext_t = extern struct {
-    link: ?*ucontext_t,
-    sigmask: sigset_t,
-    stack: stack_t,
-    mcontext: mcontext_t,
+/// 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;
+
+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;
+
+/// Process descriptors
+pub const EVFILT_PROCDESC = -8;
+
+/// Filesystem events
+pub const EVFILT_FS = -9;
+
+pub const EVFILT_LIO = -10;
+
+/// User events
+pub const EVFILT_USER = -11;
+
+/// Sendfile events
+pub const EVFILT_SENDFILE = -12;
+
+pub const EVFILT_EMPTY = -13;
+
+pub const T = struct {
+    pub const CGETA = 0x8000;
+    pub const CSETA = 0x8001;
+    pub const CSETAF = 0x8002;
+    pub const CSETAW = 0x8003;
+    pub const CWAITEVENT = 0x8004;
+    pub const CSBRK = 0x8005;
+    pub const CFLSH = 0x8006;
+    pub const CXONC = 0x8007;
+    pub const CQUERYCONNECTED = 0x8008;
+    pub const CGETBITS = 0x8009;
+    pub const CSETDTR = 0x8010;
+    pub const CSETRTS = 0x8011;
+    pub const IOCGWINSZ = 0x8012;
+    pub const IOCSWINSZ = 0x8013;
+    pub const CVTIME = 0x8014;
+    pub const IOCGPGRP = 0x8015;
+    pub const IOCSPGRP = 0x8016;
+    pub const IOCSCTTY = 0x8017;
+    pub const IOCMGET = 0x8018;
+    pub const IOCMSET = 0x8019;
+    pub const IOCSBRK = 0x8020;
+    pub const IOCCBRK = 0x8021;
+    pub const IOCMBIS = 0x8022;
+    pub const IOCMBIC = 0x8023;
+    pub const IOCGSID = 0x8024;
+
+    pub const FIONREAD = 0xbe000001;
+    pub const FIONBIO = 0xbe000000;
+};
+
+pub const winsize = extern struct {
+    ws_row: u16,
+    ws_col: u16,
+    ws_xpixel: u16,
+    ws_ypixel: u16,
+};
+
+pub const S = struct {
+    pub const IFMT = 0o170000;
+    pub const IFSOCK = 0o140000;
+    pub const IFLNK = 0o120000;
+    pub const IFREG = 0o100000;
+    pub const IFBLK = 0o060000;
+    pub const IFDIR = 0o040000;
+    pub const IFCHR = 0o020000;
+    pub const IFIFO = 0o010000;
+    pub const INDEX_DIR = 0o4000000000;
+
+    pub const IUMSK = 0o7777;
+    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 ISREG(m: u32) bool {
+        return m & IFMT == IFREG;
+    }
+
+    pub fn ISLNK(m: u32) bool {
+        return m & IFMT == IFLNK;
+    }
+
+    pub fn ISBLK(m: u32) bool {
+        return m & IFMT == IFBLK;
+    }
+
+    pub fn ISDIR(m: u32) bool {
+        return m & IFMT == IFDIR;
+    }
+
+    pub fn ISCHR(m: u32) bool {
+        return m & IFMT == IFCHR;
+    }
+
+    pub fn ISFIFO(m: u32) bool {
+        return m & IFMT == IFIFO;
+    }
+
+    pub fn ISSOCK(m: u32) bool {
+        return m & IFMT == IFSOCK;
+    }
+
+    pub fn ISINDEX(m: u32) bool {
+        return m & INDEX_DIR == INDEX_DIR;
+    }
+};
+
+pub const HOST_NAME_MAX = 255;
+
+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 IPPROTO = struct {
+    pub const IP = 0;
+    pub const HOPOPTS = 0;
+    pub const ICMP = 1;
+    pub const IGMP = 2;
+    pub const TCP = 6;
+    pub const UDP = 17;
+    pub const IPV6 = 41;
+    pub const ROUTING = 43;
+    pub const FRAGMENT = 44;
+    pub const ESP = 50;
+    pub const AH = 51;
+    pub const ICMPV6 = 58;
+    pub const NONE = 59;
+    pub const DSTOPTS = 60;
+    pub const ETHERIP = 97;
+    pub const RAW = 255;
+    pub const MAX = 256;
+};
+
+pub const rlimit_resource = enum(i32) {
+    CORE = 0,
+    CPU = 1,
+    DATA = 2,
+    FSIZE = 3,
+    NOFILE = 4,
+    STACK = 5,
+    AS = 6,
+    NOVMON = 7,
+    _,
+};
+
+pub const rlim_t = i64;
+
+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;
+};
+
+// TODO fill out if needed
+pub const directory_which = enum(i32) {
+    B_USER_SETTINGS_DIRECTORY = 0xbbe,
+
+    _,
+};
+
+pub const MSG_NOSIGNAL = 0x0800;
+
+// /system/develop/headers/os/kernel/OS.h
+
+pub const area_id = i32;
+pub const port_id = i32;
+pub const sem_id = i32;
+pub const team_id = i32;
+pub const thread_id = i32;
+
+// /system/develop/headers/os/support/Errors.h
+
+pub const E = enum(i32) {
+    pub const B_GENERAL_ERROR_BASE: i32 = std.math.minInt(i32);
+    pub const B_OS_ERROR_BASE = B_GENERAL_ERROR_BASE + 0x1000;
+    pub const B_APP_ERROR_BASE = B_GENERAL_ERROR_BASE + 0x2000;
+    pub const B_INTERFACE_ERROR_BASE = B_GENERAL_ERROR_BASE + 0x3000;
+    pub const B_MEDIA_ERROR_BASE = B_GENERAL_ERROR_BASE + 0x4000;
+    pub const B_TRANSLATION_ERROR_BASE = B_GENERAL_ERROR_BASE + 0x4800;
+    pub const B_MIDI_ERROR_BASE = B_GENERAL_ERROR_BASE + 0x5000;
+    pub const B_STORAGE_ERROR_BASE = B_GENERAL_ERROR_BASE + 0x6000;
+    pub const B_POSIX_ERROR_BASE = B_GENERAL_ERROR_BASE + 0x7000;
+    pub const B_MAIL_ERROR_BASE = B_GENERAL_ERROR_BASE + 0x8000;
+    pub const B_PRINT_ERROR_BASE = B_GENERAL_ERROR_BASE + 0x9000;
+    pub const B_DEVICE_ERROR_BASE = B_GENERAL_ERROR_BASE + 0xa000;
+
+    pub const B_ERRORS_END = B_GENERAL_ERROR_BASE + 0xffff;
+
+    pub const B_NO_MEMORY = B_GENERAL_ERROR_BASE + 0;
+    pub const B_IO_ERROR = B_GENERAL_ERROR_BASE + 1;
+    pub const B_PERMISSION_DENIED = B_GENERAL_ERROR_BASE + 2;
+    pub const B_BAD_INDEX = B_GENERAL_ERROR_BASE + 3;
+    pub const B_BAD_TYPE = B_GENERAL_ERROR_BASE + 4;
+    pub const B_BAD_VALUE = B_GENERAL_ERROR_BASE + 5;
+    pub const B_MISMATCHED_VALUES = B_GENERAL_ERROR_BASE + 6;
+    pub const B_NAME_NOT_FOUND = B_GENERAL_ERROR_BASE + 7;
+    pub const B_NAME_IN_USE = B_GENERAL_ERROR_BASE + 8;
+    pub const B_TIMED_OUT = B_GENERAL_ERROR_BASE + 9;
+    pub const B_INTERRUPTED = B_GENERAL_ERROR_BASE + 10;
+    pub const B_WOULD_BLOCK = B_GENERAL_ERROR_BASE + 11;
+    pub const B_CANCELED = B_GENERAL_ERROR_BASE + 12;
+    pub const B_NO_INIT = B_GENERAL_ERROR_BASE + 13;
+    pub const B_NOT_INITIALIZED = B_GENERAL_ERROR_BASE + 13;
+    pub const B_BUSY = B_GENERAL_ERROR_BASE + 14;
+    pub const B_NOT_ALLOWED = B_GENERAL_ERROR_BASE + 15;
+    pub const B_BAD_DATA = B_GENERAL_ERROR_BASE + 16;
+    pub const B_DONT_DO_THAT = B_GENERAL_ERROR_BASE + 17;
+
+    pub const B_BAD_IMAGE_ID = B_OS_ERROR_BASE + 0x300;
+    pub const B_BAD_ADDRESS = B_OS_ERROR_BASE + 0x301;
+    pub const B_NOT_AN_EXECUTABLE = B_OS_ERROR_BASE + 0x302;
+    pub const B_MISSING_LIBRARY = B_OS_ERROR_BASE + 0x303;
+    pub const B_MISSING_SYMBOL = B_OS_ERROR_BASE + 0x304;
+    pub const B_UNKNOWN_EXECUTABLE = B_OS_ERROR_BASE + 0x305;
+    pub const B_LEGACY_EXECUTABLE = B_OS_ERROR_BASE + 0x306;
+
+    pub const B_FILE_ERROR = B_STORAGE_ERROR_BASE + 0;
+    pub const B_FILE_EXISTS = B_STORAGE_ERROR_BASE + 2;
+    pub const B_ENTRY_NOT_FOUND = B_STORAGE_ERROR_BASE + 3;
+    pub const B_NAME_TOO_LONG = B_STORAGE_ERROR_BASE + 4;
+    pub const B_NOT_A_DIRECTORY = B_STORAGE_ERROR_BASE + 5;
+    pub const B_DIRECTORY_NOT_EMPTY = B_STORAGE_ERROR_BASE + 6;
+    pub const B_DEVICE_FULL = B_STORAGE_ERROR_BASE + 7;
+    pub const B_READ_ONLY_DEVICE = B_STORAGE_ERROR_BASE + 8;
+    pub const B_IS_A_DIRECTORY = B_STORAGE_ERROR_BASE + 9;
+    pub const B_NO_MORE_FDS = B_STORAGE_ERROR_BASE + 10;
+    pub const B_CROSS_DEVICE_LINK = B_STORAGE_ERROR_BASE + 11;
+    pub const B_LINK_LIMIT = B_STORAGE_ERROR_BASE + 12;
+    pub const B_BUSTED_PIPE = B_STORAGE_ERROR_BASE + 13;
+    pub const B_UNSUPPORTED = B_STORAGE_ERROR_BASE + 14;
+    pub const B_PARTITION_TOO_SMALL = B_STORAGE_ERROR_BASE + 15;
+    pub const B_PARTIAL_READ = B_STORAGE_ERROR_BASE + 16;
+    pub const B_PARTIAL_WRITE = B_STORAGE_ERROR_BASE + 17;
+
+    SUCCESS = 0,
+
+    @"2BIG" = B_POSIX_ERROR_BASE + 1,
+    CHILD = B_POSIX_ERROR_BASE + 2,
+    DEADLK = B_POSIX_ERROR_BASE + 3,
+    FBIG = B_POSIX_ERROR_BASE + 4,
+    MLINK = B_POSIX_ERROR_BASE + 5,
+    NFILE = B_POSIX_ERROR_BASE + 6,
+    NODEV = B_POSIX_ERROR_BASE + 7,
+    NOLCK = B_POSIX_ERROR_BASE + 8,
+    NOSYS = B_POSIX_ERROR_BASE + 9,
+    NOTTY = B_POSIX_ERROR_BASE + 10,
+    NXIO = B_POSIX_ERROR_BASE + 11,
+    SPIPE = B_POSIX_ERROR_BASE + 12,
+    SRCH = B_POSIX_ERROR_BASE + 13,
+    FPOS = B_POSIX_ERROR_BASE + 14,
+    SIGPARM = B_POSIX_ERROR_BASE + 15,
+    DOM = B_POSIX_ERROR_BASE + 16,
+    RANGE = B_POSIX_ERROR_BASE + 17,
+    PROTOTYPE = B_POSIX_ERROR_BASE + 18,
+    PROTONOSUPPORT = B_POSIX_ERROR_BASE + 19,
+    PFNOSUPPORT = B_POSIX_ERROR_BASE + 20,
+    AFNOSUPPORT = B_POSIX_ERROR_BASE + 21,
+    ADDRINUSE = B_POSIX_ERROR_BASE + 22,
+    ADDRNOTAVAIL = B_POSIX_ERROR_BASE + 23,
+    NETDOWN = B_POSIX_ERROR_BASE + 24,
+    NETUNREACH = B_POSIX_ERROR_BASE + 25,
+    NETRESET = B_POSIX_ERROR_BASE + 26,
+    CONNABORTED = B_POSIX_ERROR_BASE + 27,
+    CONNRESET = B_POSIX_ERROR_BASE + 28,
+    ISCONN = B_POSIX_ERROR_BASE + 29,
+    NOTCONN = B_POSIX_ERROR_BASE + 30,
+    SHUTDOWN = B_POSIX_ERROR_BASE + 31,
+    CONNREFUSED = B_POSIX_ERROR_BASE + 32,
+    HOSTUNREACH = B_POSIX_ERROR_BASE + 33,
+    NOPROTOOPT = B_POSIX_ERROR_BASE + 34,
+    NOBUFS = B_POSIX_ERROR_BASE + 35,
+    INPROGRESS = B_POSIX_ERROR_BASE + 36,
+    ALREADY = B_POSIX_ERROR_BASE + 37,
+    ILSEQ = B_POSIX_ERROR_BASE + 38,
+    NOMSG = B_POSIX_ERROR_BASE + 39,
+    STALE = B_POSIX_ERROR_BASE + 40,
+    OVERFLOW = B_POSIX_ERROR_BASE + 41,
+    MSGSIZE = B_POSIX_ERROR_BASE + 42,
+    OPNOTSUPP = B_POSIX_ERROR_BASE + 43,
+    NOTSOCK = B_POSIX_ERROR_BASE + 44,
+    HOSTDOWN = B_POSIX_ERROR_BASE + 45,
+    BADMSG = B_POSIX_ERROR_BASE + 46,
+    CANCELED = B_POSIX_ERROR_BASE + 47,
+    DESTADDRREQ = B_POSIX_ERROR_BASE + 48,
+    DQUOT = B_POSIX_ERROR_BASE + 49,
+    IDRM = B_POSIX_ERROR_BASE + 50,
+    MULTIHOP = B_POSIX_ERROR_BASE + 51,
+    NODATA = B_POSIX_ERROR_BASE + 52,
+    NOLINK = B_POSIX_ERROR_BASE + 53,
+    NOSR = B_POSIX_ERROR_BASE + 54,
+    NOSTR = B_POSIX_ERROR_BASE + 55,
+    NOTSUP = B_POSIX_ERROR_BASE + 56,
+    PROTO = B_POSIX_ERROR_BASE + 57,
+    TIME = B_POSIX_ERROR_BASE + 58,
+    TXTBSY = B_POSIX_ERROR_BASE + 59,
+    NOATTR = B_POSIX_ERROR_BASE + 60,
+    NOTRECOVERABLE = B_POSIX_ERROR_BASE + 61,
+    OWNERDEAD = B_POSIX_ERROR_BASE + 62,
+
+    NOMEM = B_NO_MEMORY,
+
+    ACCES = B_PERMISSION_DENIED,
+    INTR = B_INTERRUPTED,
+    IO = B_IO_ERROR,
+    BUSY = B_BUSY,
+    FAULT = B_BAD_ADDRESS,
+    TIMEDOUT = B_TIMED_OUT,
+    /// Also used for WOULDBLOCK
+    AGAIN = B_WOULD_BLOCK,
+    BADF = B_FILE_ERROR,
+    EXIST = B_FILE_EXISTS,
+    INVAL = B_BAD_VALUE,
+    NAMETOOLONG = B_NAME_TOO_LONG,
+    NOENT = B_ENTRY_NOT_FOUND,
+    PERM = B_NOT_ALLOWED,
+    NOTDIR = B_NOT_A_DIRECTORY,
+    ISDIR = B_IS_A_DIRECTORY,
+    NOTEMPTY = B_DIRECTORY_NOT_EMPTY,
+    NOSPC = B_DEVICE_FULL,
+    ROFS = B_READ_ONLY_DEVICE,
+    MFILE = B_NO_MORE_FDS,
+    XDEV = B_CROSS_DEVICE_LINK,
+    LOOP = B_LINK_LIMIT,
+    NOEXEC = B_NOT_AN_EXECUTABLE,
+    PIPE = B_BUSTED_PIPE,
+
+    _,
 };
 
+// /system/develop/headers/os/support/SupportDefs.h
+
+pub const status_t = i32;
+
 // /system/develop/headers/posix/arch/*/signal.h
 
 pub const vregs = switch (builtin.cpu.arch) {
@@ -736,531 +1030,364 @@ pub const vregs = switch (builtin.cpu.arch) {
             reserved2: u16,
             mxcsr: u32,
             reserved3: u32,
-            fp_mmx: [8]fp_register,
-            xmmx: [8]xmm_register,
-            reserved4: [224]u8,
-        };
-
-        pub const extended_regs = extern struct {
-            state: extern union {
-                old_format: old_extended_regs,
-                new_format: new_extended_regs,
-            },
-            format: u32,
-        };
-
-        eip: u32,
-        eflags: u32,
-        eax: u32,
-        ecx: u32,
-        edx: u32,
-        esp: u32,
-        ebp: u32,
-        reserved: u32,
-        xregs: extended_regs,
-        edi: u32,
-        esi: u32,
-        ebx: u32,
-    },
-    .x86_64 => extern struct {
-        pub const fp_register = extern struct {
-            value: [10]u8,
-            reserved: [6]u8,
-        };
-
-        pub const xmm_register = extern struct {
-            value: [16]u8,
-        };
-
-        pub const fpu_state = extern struct {
-            control: u16,
-            status: u16,
-            tag: u16,
-            opcode: u16,
-            rip: u64,
-            rdp: u64,
-            mxcsr: u32,
-            mscsr_mask: u32,
-
-            fp_mmx: [8]fp_register,
-            xmm: [16]xmm_register,
-            reserved: [96]u8,
-        };
-
-        pub const xstate_hdr = extern struct {
-            bv: u64,
-            xcomp_bv: u64,
-            reserved: [48]u8,
-        };
-
-        pub const savefpu = extern struct {
-            fxsave: fpu_state,
-            xstate: xstate_hdr,
-            ymm: [16]xmm_register,
-        };
-
-        rax: u64,
-        rbx: u64,
-        rcx: u64,
-        rdx: u64,
-        rdi: u64,
-        rsi: u64,
-        rbp: u64,
-        r8: u64,
-        r9: u64,
-        r10: u64,
-        r11: u64,
-        r12: u64,
-        r13: u64,
-        r14: u64,
-        r15: u64,
-        rsp: u64,
-        rip: u64,
-        rflags: u64,
-        fpu: savefpu,
-    },
-    else => void,
-};
-
-// access function
-pub const F_OK = 0; // test for existence of file
-pub const X_OK = 1; // test for execute or search permission
-pub const W_OK = 2; // test for write permission
-pub const R_OK = 4; // test for read permission
-
-pub const F = struct {
-    pub const DUPFD = 0x0001;
-    pub const GETFD = 0x0002;
-    pub const SETFD = 0x0004;
-    pub const GETFL = 0x0008;
-    pub const SETFL = 0x0010;
-
-    pub const GETLK = 0x0020;
-    pub const SETLK = 0x0080;
-    pub const SETLKW = 0x0100;
-    pub const DUPFD_CLOEXEC = 0x0200;
-
-    pub const RDLCK = 0x0040;
-    pub const UNLCK = 0x0200;
-    pub const WRLCK = 0x0400;
-};
-
-pub const LOCK = struct {
-    pub const SH = 0x01;
-    pub const EX = 0x02;
-    pub const NB = 0x04;
-    pub const UN = 0x08;
-};
-
-pub const FD_CLOEXEC = 1;
-
-pub const SEEK = struct {
-    pub const SET = 0;
-    pub const CUR = 1;
-    pub const END = 2;
-};
-
-pub const SOCK = struct {
-    pub const STREAM = 1;
-    pub const DGRAM = 2;
-    pub const RAW = 3;
-    pub const SEQPACKET = 5;
-
-    /// WARNING: this flag is not supported by windows socket functions directly,
-    ///          it is only supported by std.os.socket. Be sure that this value does
-    ///          not share any bits with any of the `SOCK` values.
-    pub const CLOEXEC = 0x10000;
-    /// WARNING: this flag is not supported by windows socket functions directly,
-    ///          it is only supported by std.os.socket. Be sure that this value does
-    ///          not share any bits with any of the `SOCK` values.
-    pub const NONBLOCK = 0x20000;
-};
-
-pub const SO = struct {
-    pub const ACCEPTCONN = 0x00000001;
-    pub const BROADCAST = 0x00000002;
-    pub const DEBUG = 0x00000004;
-    pub const DONTROUTE = 0x00000008;
-    pub const KEEPALIVE = 0x00000010;
-    pub const OOBINLINE = 0x00000020;
-    pub const REUSEADDR = 0x00000040;
-    pub const REUSEPORT = 0x00000080;
-    pub const USELOOPBACK = 0x00000100;
-    pub const LINGER = 0x00000200;
-
-    pub const SNDBUF = 0x40000001;
-    pub const SNDLOWAT = 0x40000002;
-    pub const SNDTIMEO = 0x40000003;
-    pub const RCVBUF = 0x40000004;
-    pub const RCVLOWAT = 0x40000005;
-    pub const RCVTIMEO = 0x40000006;
-    pub const ERROR = 0x40000007;
-    pub const TYPE = 0x40000008;
-    pub const NONBLOCK = 0x40000009;
-    pub const BINDTODEVICE = 0x4000000a;
-    pub const PEERCRED = 0x4000000b;
-};
+            fp_mmx: [8]fp_register,
+            xmmx: [8]xmm_register,
+            reserved4: [224]u8,
+        };
 
-pub const SOL = struct {
-    pub const SOCKET = -1;
-};
+        pub const extended_regs = extern struct {
+            state: extern union {
+                old_format: old_extended_regs,
+                new_format: new_extended_regs,
+            },
+            format: u32,
+        };
 
-pub const PF = struct {
-    pub const UNSPEC = AF.UNSPEC;
-    pub const INET = AF.INET;
-    pub const ROUTE = AF.ROUTE;
-    pub const LINK = AF.LINK;
-    pub const INET6 = AF.INET6;
-    pub const LOCAL = AF.LOCAL;
-    pub const UNIX = AF.UNIX;
-    pub const BLUETOOTH = AF.BLUETOOTH;
-};
+        eip: u32,
+        eflags: u32,
+        eax: u32,
+        ecx: u32,
+        edx: u32,
+        esp: u32,
+        ebp: u32,
+        reserved: u32,
+        xregs: extended_regs,
+        edi: u32,
+        esi: u32,
+        ebx: u32,
+    },
+    .x86_64 => extern struct {
+        pub const fp_register = extern struct {
+            value: [10]u8,
+            reserved: [6]u8,
+        };
 
-pub const AF = struct {
-    pub const UNSPEC = 0;
-    pub const INET = 1;
-    pub const APPLETALK = 2;
-    pub const ROUTE = 3;
-    pub const LINK = 4;
-    pub const INET6 = 5;
-    pub const DLI = 6;
-    pub const IPX = 7;
-    pub const NOTIFY = 8;
-    pub const LOCAL = 9;
-    pub const UNIX = LOCAL;
-    pub const BLUETOOTH = 10;
-    pub const MAX = 11;
-};
+        pub const xmm_register = extern struct {
+            value: [16]u8,
+        };
 
-pub const DT = struct {};
+        pub const fpu_state = extern struct {
+            control: u16,
+            status: u16,
+            tag: u16,
+            opcode: u16,
+            rip: u64,
+            rdp: u64,
+            mxcsr: u32,
+            mscsr_mask: u32,
 
-/// add event to kq (implies enable)
-pub const EV_ADD = 0x0001;
+            fp_mmx: [8]fp_register,
+            xmm: [16]xmm_register,
+            reserved: [96]u8,
+        };
 
-/// delete event from kq
-pub const EV_DELETE = 0x0002;
+        pub const xstate_hdr = extern struct {
+            bv: u64,
+            xcomp_bv: u64,
+            reserved: [48]u8,
+        };
 
-/// enable event
-pub const EV_ENABLE = 0x0004;
+        pub const savefpu = extern struct {
+            fxsave: fpu_state,
+            xstate: xstate_hdr,
+            ymm: [16]xmm_register,
+        };
 
-/// disable event (not reported)
-pub const EV_DISABLE = 0x0008;
+        rax: u64,
+        rbx: u64,
+        rcx: u64,
+        rdx: u64,
+        rdi: u64,
+        rsi: u64,
+        rbp: u64,
+        r8: u64,
+        r9: u64,
+        r10: u64,
+        r11: u64,
+        r12: u64,
+        r13: u64,
+        r14: u64,
+        r15: u64,
+        rsp: u64,
+        rip: u64,
+        rflags: u64,
+        fpu: savefpu,
+    },
+    else => void,
+};
 
-/// only report one occurrence
-pub const EV_ONESHOT = 0x0010;
+// /system/develop/headers/posix/dirent.h
+
+pub const DirEnt = extern struct {
+    /// device
+    dev: dev_t,
+    /// parent device (only for queries)
+    pdev: dev_t,
+    /// inode number
+    ino: ino_t,
+    /// parent inode (only for queries)
+    pino: ino_t,
+    /// length of this record, not the name
+    reclen: u16,
+    /// name of the entry (null byte terminated)
+    name: [0]u8,
+    pub fn getName(dirent: *const DirEnt) [*:0]const u8 {
+        return @ptrCast(&dirent.name);
+    }
+};
 
-/// clear event state after reporting
-pub const EV_CLEAR = 0x0020;
+// /system/develop/headers/posix/errno.h
 
-/// force immediate event output
-/// ... with or without EV_ERROR
-/// ... use KEVENT_FLAG_ERROR_EVENTS
-///     on syscalls supporting flags
-pub const EV_RECEIPT = 0x0040;
+extern "root" fn _errnop() *i32;
+pub const _errno = _errnop;
 
-/// disable event after reporting
-pub const EV_DISPATCH = 0x0080;
+// /system/develop/headers/posix/poll.h
 
-pub const EVFILT_READ = -1;
-pub const EVFILT_WRITE = -2;
+pub const nfds_t = usize;
 
-/// attached to aio requests
-pub const EVFILT_AIO = -3;
+pub const pollfd = extern struct {
+    fd: i32,
+    events: i16,
+    revents: i16,
+};
 
-/// attached to vnodes
-pub const EVFILT_VNODE = -4;
+pub const POLL = struct {
+    /// any readable data available
+    pub const IN = 0x0001;
+    /// file descriptor is writeable
+    pub const OUT = 0x0002;
+    pub const RDNORM = IN;
+    pub const WRNORM = OUT;
+    /// priority readable data
+    pub const RDBAND = 0x0008;
+    /// priority data can be written
+    pub const WRBAND = 0x0010;
+    /// high priority readable data
+    pub const PRI = 0x0020;
 
-/// attached to struct proc
-pub const EVFILT_PROC = -5;
+    /// errors pending
+    pub const ERR = 0x0004;
+    /// disconnected
+    pub const HUP = 0x0080;
+    /// invalid file descriptor
+    pub const NVAL = 0x1000;
+};
 
-/// attached to struct proc
-pub const EVFILT_SIGNAL = -6;
+// /system/develop/headers/posix/signal.h
 
-/// timers
-pub const EVFILT_TIMER = -7;
+pub const sigset_t = u64;
+pub const empty_sigset: sigset_t = 0;
+pub const filled_sigset = ~@as(sigset_t, 0);
 
-/// Process descriptors
-pub const EVFILT_PROCDESC = -8;
+pub const SIG = struct {
+    pub const DFL: ?Sigaction.handler_fn = @ptrFromInt(0);
+    pub const IGN: ?Sigaction.handler_fn = @ptrFromInt(1);
+    pub const ERR: ?Sigaction.handler_fn = @ptrFromInt(maxInt(usize));
 
-/// Filesystem events
-pub const EVFILT_FS = -9;
+    pub const HOLD: ?Sigaction.handler_fn = @ptrFromInt(3);
 
-pub const EVFILT_LIO = -10;
+    pub const HUP = 1;
+    pub const INT = 2;
+    pub const QUIT = 3;
+    pub const ILL = 4;
+    pub const CHLD = 5;
+    pub const ABRT = 6;
+    pub const IOT = ABRT;
+    pub const PIPE = 7;
+    pub const FPE = 8;
+    pub const KILL = 9;
+    pub const STOP = 10;
+    pub const SEGV = 11;
+    pub const CONT = 12;
+    pub const TSTP = 13;
+    pub const ALRM = 14;
+    pub const TERM = 15;
+    pub const TTIN = 16;
+    pub const TTOU = 17;
+    pub const USR1 = 18;
+    pub const USR2 = 19;
+    pub const WINCH = 20;
+    pub const KILLTHR = 21;
+    pub const TRAP = 22;
+    pub const POLL = 23;
+    pub const PROF = 24;
+    pub const SYS = 25;
+    pub const URG = 26;
+    pub const VTALRM = 27;
+    pub const XCPU = 28;
+    pub const XFSZ = 29;
+    pub const BUS = 30;
+    pub const RESERVED1 = 31;
+    pub const RESERVED2 = 32;
 
-/// User events
-pub const EVFILT_USER = -11;
+    pub const BLOCK = 1;
+    pub const UNBLOCK = 2;
+    pub const SETMASK = 3;
+};
 
-/// Sendfile events
-pub const EVFILT_SENDFILE = -12;
+pub const siginfo_t = extern struct {
+    signo: i32,
+    code: i32,
+    errno: i32,
 
-pub const EVFILT_EMPTY = -13;
+    pid: pid_t,
+    uid: uid_t,
+    addr: *allowzero anyopaque,
+};
 
-pub const T = struct {
-    pub const CGETA = 0x8000;
-    pub const CSETA = 0x8001;
-    pub const CSETAF = 0x8002;
-    pub const CSETAW = 0x8003;
-    pub const CWAITEVENT = 0x8004;
-    pub const CSBRK = 0x8005;
-    pub const CFLSH = 0x8006;
-    pub const CXONC = 0x8007;
-    pub const CQUERYCONNECTED = 0x8008;
-    pub const CGETBITS = 0x8009;
-    pub const CSETDTR = 0x8010;
-    pub const CSETRTS = 0x8011;
-    pub const IOCGWINSZ = 0x8012;
-    pub const IOCSWINSZ = 0x8013;
-    pub const CVTIME = 0x8014;
-    pub const IOCGPGRP = 0x8015;
-    pub const IOCSPGRP = 0x8016;
-    pub const IOCSCTTY = 0x8017;
-    pub const IOCMGET = 0x8018;
-    pub const IOCMSET = 0x8019;
-    pub const IOCSBRK = 0x8020;
-    pub const IOCCBRK = 0x8021;
-    pub const IOCMBIS = 0x8022;
-    pub const IOCMBIC = 0x8023;
-    pub const IOCGSID = 0x8024;
+/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
+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;
 
-    pub const FIONREAD = 0xbe000001;
-    pub const FIONBIO = 0xbe000000;
+    /// signal handler
+    handler: extern union {
+        handler: handler_fn,
+        sigaction: sigaction_fn,
+    },
+
+    /// signal mask to apply
+    mask: sigset_t,
+
+    /// see signal options
+    flags: i32,
+
+    /// will be passed to the signal handler, BeOS extension
+    userdata: *allowzero anyopaque = undefined,
 };
 
-pub const winsize = extern struct {
-    ws_row: u16,
-    ws_col: u16,
-    ws_xpixel: u16,
-    ws_ypixel: u16,
+pub const SA = struct {
+    pub const NOCLDSTOP = 0x01;
+    pub const NOCLDWAIT = 0x02;
+    pub const RESETHAND = 0x04;
+    pub const NODEFER = 0x08;
+    pub const RESTART = 0x10;
+    pub const ONSTACK = 0x20;
+    pub const SIGINFO = 0x40;
+    pub const NOMASK = NODEFER;
+    pub const STACK = ONSTACK;
+    pub const ONESHOT = RESETHAND;
 };
 
-const B_POSIX_ERROR_BASE = -2147454976;
+pub const SS = struct {
+    pub const ONSTACK = 0x1;
+    pub const DISABLE = 0x2;
+};
 
-pub const E = enum(i32) {
-    @"2BIG" = B_POSIX_ERROR_BASE + 1,
-    CHILD = B_POSIX_ERROR_BASE + 2,
-    DEADLK = B_POSIX_ERROR_BASE + 3,
-    FBIG = B_POSIX_ERROR_BASE + 4,
-    MLINK = B_POSIX_ERROR_BASE + 5,
-    NFILE = B_POSIX_ERROR_BASE + 6,
-    NODEV = B_POSIX_ERROR_BASE + 7,
-    NOLCK = B_POSIX_ERROR_BASE + 8,
-    NOSYS = B_POSIX_ERROR_BASE + 9,
-    NOTTY = B_POSIX_ERROR_BASE + 10,
-    NXIO = B_POSIX_ERROR_BASE + 11,
-    SPIPE = B_POSIX_ERROR_BASE + 12,
-    SRCH = B_POSIX_ERROR_BASE + 13,
-    FPOS = B_POSIX_ERROR_BASE + 14,
-    SIGPARM = B_POSIX_ERROR_BASE + 15,
-    DOM = B_POSIX_ERROR_BASE + 16,
-    RANGE = B_POSIX_ERROR_BASE + 17,
-    PROTOTYPE = B_POSIX_ERROR_BASE + 18,
-    PROTONOSUPPORT = B_POSIX_ERROR_BASE + 19,
-    PFNOSUPPORT = B_POSIX_ERROR_BASE + 20,
-    AFNOSUPPORT = B_POSIX_ERROR_BASE + 21,
-    ADDRINUSE = B_POSIX_ERROR_BASE + 22,
-    ADDRNOTAVAIL = B_POSIX_ERROR_BASE + 23,
-    NETDOWN = B_POSIX_ERROR_BASE + 24,
-    NETUNREACH = B_POSIX_ERROR_BASE + 25,
-    NETRESET = B_POSIX_ERROR_BASE + 26,
-    CONNABORTED = B_POSIX_ERROR_BASE + 27,
-    CONNRESET = B_POSIX_ERROR_BASE + 28,
-    ISCONN = B_POSIX_ERROR_BASE + 29,
-    NOTCONN = B_POSIX_ERROR_BASE + 30,
-    SHUTDOWN = B_POSIX_ERROR_BASE + 31,
-    CONNREFUSED = B_POSIX_ERROR_BASE + 32,
-    HOSTUNREACH = B_POSIX_ERROR_BASE + 33,
-    NOPROTOOPT = B_POSIX_ERROR_BASE + 34,
-    NOBUFS = B_POSIX_ERROR_BASE + 35,
-    INPROGRESS = B_POSIX_ERROR_BASE + 36,
-    ALREADY = B_POSIX_ERROR_BASE + 37,
-    ILSEQ = B_POSIX_ERROR_BASE + 38,
-    NOMSG = B_POSIX_ERROR_BASE + 39,
-    STALE = B_POSIX_ERROR_BASE + 40,
-    OVERFLOW = B_POSIX_ERROR_BASE + 41,
-    MSGSIZE = B_POSIX_ERROR_BASE + 42,
-    OPNOTSUPP = B_POSIX_ERROR_BASE + 43,
-    NOTSOCK = B_POSIX_ERROR_BASE + 44,
-    HOSTDOWN = B_POSIX_ERROR_BASE + 45,
-    BADMSG = B_POSIX_ERROR_BASE + 46,
-    CANCELED = B_POSIX_ERROR_BASE + 47,
-    DESTADDRREQ = B_POSIX_ERROR_BASE + 48,
-    DQUOT = B_POSIX_ERROR_BASE + 49,
-    IDRM = B_POSIX_ERROR_BASE + 50,
-    MULTIHOP = B_POSIX_ERROR_BASE + 51,
-    NODATA = B_POSIX_ERROR_BASE + 52,
-    NOLINK = B_POSIX_ERROR_BASE + 53,
-    NOSR = B_POSIX_ERROR_BASE + 54,
-    NOSTR = B_POSIX_ERROR_BASE + 55,
-    NOTSUP = B_POSIX_ERROR_BASE + 56,
-    PROTO = B_POSIX_ERROR_BASE + 57,
-    TIME = B_POSIX_ERROR_BASE + 58,
-    TXTBSY = B_POSIX_ERROR_BASE + 59,
-    NOATTR = B_POSIX_ERROR_BASE + 60,
-    NOTRECOVERABLE = B_POSIX_ERROR_BASE + 61,
-    OWNERDEAD = B_POSIX_ERROR_BASE + 62,
+pub const MINSIGSTKSZ = 8192;
+pub const SIGSTKSZ = 16384;
 
-    ACCES = -0x7ffffffe, // Permission denied
-    INTR = -0x7ffffff6, // Interrupted system call
-    IO = -0x7fffffff, // Input/output error
-    BUSY = -0x7ffffff2, // Device busy
-    FAULT = -0x7fffecff, // Bad address
-    TIMEDOUT = -2147483639, // Operation timed out
-    AGAIN = -0x7ffffff5,
-    BADF = -0x7fffa000, // Bad file descriptor
-    EXIST = -0x7fff9ffe, // File exists
-    INVAL = -0x7ffffffb, // Invalid argument
-    NAMETOOLONG = -2147459068, // File name too long
-    NOENT = -0x7fff9ffd, // No such file or directory
-    PERM = -0x7ffffff1, // Operation not permitted
-    NOTDIR = -0x7fff9ffb, // Not a directory
-    ISDIR = -0x7fff9ff7, // Is a directory
-    NOTEMPTY = -2147459066, // Directory not empty
-    NOSPC = -0x7fff9ff9, // No space left on device
-    ROFS = -0x7fff9ff8, // Read-only filesystem
-    MFILE = -0x7fff9ff6, // Too many open files
-    XDEV = -0x7fff9ff5, // Cross-device link
-    NOEXEC = -0x7fffecfe, // Exec format error
-    PIPE = -0x7fff9ff3, // Broken pipe
-    NOMEM = -0x80000000, // Cannot allocate memory
-    LOOP = -2147459060, // Too many levels of symbolic links
-    SUCCESS = 0,
-    _,
+pub const stack_t = extern struct {
+    sp: [*]u8,
+    size: isize,
+    flags: i32,
 };
 
-pub const S = struct {
-    pub const IFMT = 0o170000;
-    pub const IFSOCK = 0o140000;
-    pub const IFLNK = 0o120000;
-    pub const IFREG = 0o100000;
-    pub const IFBLK = 0o060000;
-    pub const IFDIR = 0o040000;
-    pub const IFCHR = 0o020000;
-    pub const IFIFO = 0o010000;
-    pub const INDEX_DIR = 0o4000000000;
-
-    pub const IUMSK = 0o7777;
-    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 const NSIG = 65;
 
-    pub fn ISREG(m: u32) bool {
-        return m & IFMT == IFREG;
-    }
+pub const mcontext_t = vregs;
 
-    pub fn ISLNK(m: u32) bool {
-        return m & IFMT == IFLNK;
-    }
+pub const ucontext_t = extern struct {
+    link: ?*ucontext_t,
+    sigmask: sigset_t,
+    stack: stack_t,
+    mcontext: mcontext_t,
+};
 
-    pub fn ISBLK(m: u32) bool {
-        return m & IFMT == IFBLK;
-    }
+// /system/develop/headers/posix/sys/stat.h
 
-    pub fn ISDIR(m: u32) bool {
-        return m & IFMT == IFDIR;
-    }
+pub const Stat = extern struct {
+    dev: dev_t,
+    ino: ino_t,
+    mode: mode_t,
+    nlink: nlink_t,
+    uid: uid_t,
+    gid: gid_t,
+    size: off_t,
+    rdev: dev_t,
+    blksize: blksize_t,
+    atim: timespec,
+    mtim: timespec,
+    ctim: timespec,
+    crtim: timespec,
+    type: u32,
+    blocks: blkcnt_t,
 
-    pub fn ISCHR(m: u32) bool {
-        return m & IFMT == IFCHR;
+    pub fn atime(self: @This()) timespec {
+        return self.atim;
     }
-
-    pub fn ISFIFO(m: u32) bool {
-        return m & IFMT == IFIFO;
+    pub fn mtime(self: @This()) timespec {
+        return self.mtim;
     }
-
-    pub fn ISSOCK(m: u32) bool {
-        return m & IFMT == IFSOCK;
+    pub fn ctime(self: @This()) timespec {
+        return self.ctim;
     }
-
-    pub fn ISINDEX(m: u32) bool {
-        return m & INDEX_DIR == INDEX_DIR;
+    pub fn birthtime(self: @This()) timespec {
+        return self.crtim;
     }
 };
 
-pub const HOST_NAME_MAX = 255;
+// /system/develop/headers/posix/sys/types.h
 
-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 blkcnt_t = i64;
+pub const blksize_t = i32;
+pub const fsblkcnt_t = i64;
+pub const fsfilcnt_t = i64;
+pub const off_t = i64;
+pub const ino_t = i64;
+pub const cnt_t = i32;
+pub const dev_t = i32;
+pub const pid_t = i32;
+pub const id_t = i32;
 
-pub const IPPROTO = struct {
-    pub const IP = 0;
-    pub const HOPOPTS = 0;
-    pub const ICMP = 1;
-    pub const IGMP = 2;
-    pub const TCP = 6;
-    pub const UDP = 17;
-    pub const IPV6 = 41;
-    pub const ROUTING = 43;
-    pub const FRAGMENT = 44;
-    pub const ESP = 50;
-    pub const AH = 51;
-    pub const ICMPV6 = 58;
-    pub const NONE = 59;
-    pub const DSTOPTS = 60;
-    pub const ETHERIP = 97;
-    pub const RAW = 255;
-    pub const MAX = 256;
-};
+pub const uid_t = u32;
+pub const gid_t = u32;
+pub const mode_t = u32;
+pub const umode_t = u32;
+pub const nlink_t = i32;
 
-pub const rlimit_resource = enum(c_int) {
-    CORE = 0,
-    CPU = 1,
-    DATA = 2,
-    FSIZE = 3,
-    NOFILE = 4,
-    STACK = 5,
-    AS = 6,
-    NOVMON = 7,
-    _,
-};
+pub const clockid_t = i32;
+pub const timer_t = *opaque {};
 
-pub const rlim_t = i64;
+// /system/develop/headers/posix/time.h
 
-pub const RLIM = struct {
-    /// No limit
-    pub const INFINITY: rlim_t = (1 << 63) - 1;
+pub const clock_t = i32;
+pub const suseconds_t = i32;
+pub const useconds_t = u32;
 
-    pub const SAVED_MAX = INFINITY;
-    pub const SAVED_CUR = INFINITY;
-};
+pub const time_t = isize;
 
-pub const rlimit = extern struct {
-    /// Soft limit
-    cur: rlim_t,
-    /// Hard limit
-    max: rlim_t,
-};
+pub const CLOCKS_PER_SEC = 1_000_000;
+pub const CLK_TCK = CLOCKS_PER_SEC;
+pub const TIME_UTC = 1;
 
-pub const SHUT = struct {
-    pub const RD = 0;
-    pub const WR = 1;
-    pub const RDWR = 2;
+pub const CLOCK = struct {
+    /// system-wide monotonic clock (aka system time)
+    pub const MONOTONIC: clockid_t = 0;
+    /// system-wide real time clock
+    pub const REALTIME: clockid_t = -1;
+    /// clock measuring the used CPU time of the current process
+    pub const PROCESS_CPUTIME_ID: clockid_t = -2;
+    /// clock measuring the used CPU time of the current thread
+    pub const THREAD_CPUTIME_ID: clockid_t = -3;
 };
 
-// TODO fill out if needed
-pub const directory_which = enum(c_int) {
-    B_USER_SETTINGS_DIRECTORY = 0xbbe,
+pub const timespec = extern struct {
+    /// seconds
+    tv_sec: time_t,
+    /// and nanoseconds
+    tv_nsec: isize,
+};
 
-    _,
+pub const itimerspec = extern struct {
+    interval: timespec,
+    value: timespec,
 };
 
-pub const MSG_NOSIGNAL = 0x0800;
+// /system/develop/headers/private/system/syscalls.h
+
+pub extern "root" fn _kern_get_current_team() team_id;
+pub extern "root" fn _kern_open_dir(fd: fd_t, path: [*:0]const u8) fd_t;
+pub extern "root" fn _kern_read_dir(fd: fd_t, buffer: [*]u8, bufferSize: usize, maxCount: u32) isize;
+pub extern "root" fn _kern_rewind_dir(fd: fd_t) status_t;
+pub extern "root" fn _kern_read_stat(fd: fd_t, path: [*:0]const u8, traverseLink: bool, stat: *Stat, statSize: usize) status_t;
lib/std/fs/Dir.zig
@@ -220,71 +220,83 @@ pub const Iterator = switch (native_os) {
     },
     .haiku => struct {
         dir: Dir,
-        buf: [1024]u8, // TODO align(@alignOf(posix.dirent64)),
+        buf: [@sizeOf(DirEnt) + posix.PATH_MAX]u8 align(@alignOf(DirEnt)),
+        offset: usize,
         index: usize,
         end_index: usize,
         first_iter: bool,
 
         const Self = @This();
+        const DirEnt = posix.system.DirEnt;
 
         pub const Error = IteratorError;
 
         /// Memory such as file names referenced in this returned entry becomes invalid
         /// with subsequent calls to `next`, as well as when this `Dir` is deinitialized.
         pub fn next(self: *Self) Error!?Entry {
-            start_over: while (true) {
-                // TODO: find a better max
-                const HAIKU_MAX_COUNT = 10000;
+            while (true) {
                 if (self.index >= self.end_index) {
                     if (self.first_iter) {
-                        posix.lseek_SET(self.dir.fd, 0) catch unreachable; // EBADF here likely means that the Dir was not opened with iteration permissions
+                        switch (@as(posix.E, @enumFromInt(posix.system._kern_rewind_dir(self.dir.fd)))) {
+                            .SUCCESS => {},
+                            .BADF => unreachable, // Dir is invalid
+                            .FAULT => unreachable,
+                            .NOTDIR => unreachable,
+                            .INVAL => unreachable,
+                            .ACCES => return error.AccessDenied,
+                            .PERM => return error.AccessDenied,
+                            else => |err| return posix.unexpectedErrno(err),
+                        }
                         self.first_iter = false;
                     }
                     const rc = posix.system._kern_read_dir(
                         self.dir.fd,
                         &self.buf,
                         self.buf.len,
-                        HAIKU_MAX_COUNT,
+                        self.buf.len / @sizeOf(DirEnt),
                     );
                     if (rc == 0) return null;
                     if (rc < 0) {
-                        switch (posix.errno(rc)) {
-                            .BADF => unreachable, // Dir is invalid or was opened without iteration ability
+                        switch (@as(posix.E, @enumFromInt(rc))) {
+                            .BADF => unreachable, // Dir is invalid
                             .FAULT => unreachable,
                             .NOTDIR => unreachable,
                             .INVAL => unreachable,
+                            .OVERFLOW => unreachable,
+                            .ACCES => return error.AccessDenied,
+                            .PERM => return error.AccessDenied,
                             else => |err| return posix.unexpectedErrno(err),
                         }
                     }
+                    self.offset = 0;
                     self.index = 0;
-                    self.end_index = @as(usize, @intCast(rc));
-                }
-                const haiku_entry = @as(*align(1) posix.system.dirent, @ptrCast(&self.buf[self.index]));
-                const next_index = self.index + haiku_entry.reclen;
-                self.index = next_index;
-                const name = mem.sliceTo(@as([*:0]u8, @ptrCast(&haiku_entry.name)), 0);
-
-                if (mem.eql(u8, name, ".") or mem.eql(u8, name, "..") or (haiku_entry.ino == 0)) {
-                    continue :start_over;
+                    self.end_index = @intCast(rc);
                 }
+                const dirent: *DirEnt = @ptrCast(@alignCast(&self.buf[self.offset]));
+                self.offset += dirent.reclen;
+                self.index += 1;
+                const name = mem.span(dirent.getName());
+                if (mem.eql(u8, name, ".") or mem.eql(u8, name, "..") or dirent.ino == 0) continue;
 
                 var stat_info: posix.Stat = undefined;
-                const rc = posix.system._kern_read_stat(
+                switch (@as(posix.E, @enumFromInt(posix.system._kern_read_stat(
                     self.dir.fd,
-                    &haiku_entry.name,
+                    name,
                     false,
                     &stat_info,
                     0,
-                );
-                if (rc != 0) {
-                    switch (posix.errno(rc)) {
-                        .SUCCESS => {},
-                        .BADF => unreachable, // Dir is invalid or was opened without iteration ability
-                        .FAULT => unreachable,
-                        .NOTDIR => unreachable,
-                        .INVAL => unreachable,
-                        else => |err| return posix.unexpectedErrno(err),
-                    }
+                )))) {
+                    .SUCCESS => {},
+                    .INVAL => unreachable,
+                    .BADF => unreachable, // Dir is invalid
+                    .NOMEM => return error.SystemResources,
+                    .ACCES => return error.AccessDenied,
+                    .PERM => return error.AccessDenied,
+                    .FAULT => unreachable,
+                    .NAMETOOLONG => unreachable,
+                    .LOOP => unreachable,
+                    .NOENT => continue,
+                    else => |err| return posix.unexpectedErrno(err),
                 }
                 const statmode = stat_info.mode & posix.S.IFMT;
 
@@ -315,7 +327,7 @@ pub const Iterator = switch (native_os) {
         dir: Dir,
         // The if guard is solely there to prevent compile errors from missing `linux.dirent64`
         // definition when compiling for other OSes. It doesn't do anything when compiling for Linux.
-        buf: [1024]u8 align(if (native_os != .linux) 1 else @alignOf(linux.dirent64)),
+        buf: [1024]u8 align(@alignOf(linux.dirent64)),
         index: usize,
         end_index: usize,
         first_iter: bool,
@@ -599,13 +611,21 @@ fn iterateImpl(self: Dir, first_iter_start_value: bool) Iterator {
             .buf = undefined,
             .first_iter = first_iter_start_value,
         },
-        .linux, .haiku => return Iterator{
+        .linux => return Iterator{
             .dir = self,
             .index = 0,
             .end_index = 0,
             .buf = undefined,
             .first_iter = first_iter_start_value,
         },
+        .haiku => return Iterator{
+            .dir = self,
+            .offset = 0,
+            .index = 0,
+            .end_index = 0,
+            .buf = undefined,
+            .first_iter = first_iter_start_value,
+        },
         .windows => return Iterator{
             .dir = self,
             .index = 0,
@@ -1429,6 +1449,27 @@ pub fn openDirZ(self: Dir, sub_path_c: [*:0]const u8, args: OpenDirOptions) Open
         .wasi => {
             return openDir(self, mem.sliceTo(sub_path_c, 0), args);
         },
+        .haiku => {
+            const rc = posix.system._kern_open_dir(self.fd, sub_path_c);
+            if (rc >= 0) return .{ .fd = rc };
+            switch (@as(posix.E, @enumFromInt(rc))) {
+                .FAULT => unreachable,
+                .INVAL => unreachable,
+                .BADF => unreachable,
+                .ACCES => return error.AccessDenied,
+                .LOOP => return error.SymLinkLoop,
+                .MFILE => return error.ProcessFdQuotaExceeded,
+                .NAMETOOLONG => return error.NameTooLong,
+                .NFILE => return error.SystemFdQuotaExceeded,
+                .NODEV => return error.NoDevice,
+                .NOENT => return error.FileNotFound,
+                .NOMEM => return error.SystemResources,
+                .NOTDIR => return error.NotDir,
+                .PERM => return error.AccessDenied,
+                .BUSY => return error.DeviceBusy,
+                else => |err| return posix.unexpectedErrno(err),
+            }
+        },
         else => {
             var symlink_flags: posix.O = .{
                 .ACCMODE = .RDONLY,