haiku: fix directory iteration

This commit is contained in:
Jacob Young
2024-04-06 17:47:54 -04:00
parent 23ee39116c
commit 0c83fa2fd0
2 changed files with 830 additions and 662 deletions
+758 -631
View File
@@ -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 "root" fn find_thread(thread_name: ?*anyopaque) i32;
pub extern "c" fn find_directory(which: directory_which, volume: i32, createIt: bool, path_ptr: [*]u8, length: i32) u64;
pub extern "root" fn get_system_info(system_info: *system_info) usize;
pub extern "c" fn find_thread(thread_name: ?*anyopaque) i32;
pub extern "root" fn _get_team_info(team: i32, team_info: *team_info, size: usize) i32;
pub extern "c" fn get_system_info(system_info: *system_info) usize;
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
// 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 nfds_t = usize;
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 pollfd = extern struct {
fd: i32,
events: i16,
revents: i16,
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 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;
/// errors pending
pub const ERR = 0x0004;
/// disconnected
pub const HUP = 0x0080;
/// invalid file descriptor
pub const NVAL = 0x1000;
pub const LOCK = struct {
pub const SH = 0x01;
pub const EX = 0x02;
pub const NB = 0x04;
pub const UN = 0x08;
};
// /system/develop/headers/posix/signal.h
pub const FD_CLOEXEC = 1;
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 SEEK = struct {
pub const SET = 0;
pub const CUR = 1;
pub const END = 2;
};
pub const siginfo_t = extern struct {
signo: c_int,
code: c_int,
errno: c_int,
pub const SOCK = struct {
pub const STREAM = 1;
pub const DGRAM = 2;
pub const RAW = 3;
pub const SEQPACKET = 5;
pid: pid_t,
uid: uid_t,
addr: *allowzero anyopaque,
/// 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;
};
/// 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 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;
/// signal handler
handler: extern union {
handler: handler_fn,
sigaction: sigaction_fn,
},
/// signal mask to apply
mask: sigset_t,
/// see signal options
flags: c_int,
/// 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 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 stack_t = extern struct {
sp: [*]u8,
size: isize,
pub const DT = struct {};
/// 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;
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 NSIG = 65;
pub const mcontext_t = vregs;
pub const ucontext_t = extern struct {
link: ?*ucontext_t,
sigmask: sigset_t,
stack: stack_t,
mcontext: mcontext_t,
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) {
@@ -822,445 +1116,278 @@ pub const vregs = switch (builtin.cpu.arch) {
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
// /system/develop/headers/posix/dirent.h
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;
};
pub const SOL = struct {
pub const SOCKET = -1;
};
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 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 DT = struct {};
/// 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;
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,
};
const B_POSIX_ERROR_BASE = -2147454976;
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,
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 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 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);
}
};
pub const HOST_NAME_MAX = 255;
// /system/develop/headers/posix/errno.h
pub const addrinfo = extern struct {
extern "root" fn _errnop() *i32;
pub const _errno = _errnop;
// /system/develop/headers/posix/poll.h
pub const nfds_t = usize;
pub const pollfd = extern struct {
fd: i32,
events: i16,
revents: i16,
};
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;
/// errors pending
pub const ERR = 0x0004;
/// disconnected
pub const HUP = 0x0080;
/// invalid file descriptor
pub const NVAL = 0x1000;
};
// /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 siginfo_t = extern struct {
signo: i32,
code: i32,
errno: i32,
pid: pid_t,
uid: uid_t,
addr: *allowzero anyopaque,
};
/// 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,
},
/// signal mask to apply
mask: sigset_t,
/// see signal options
flags: i32,
family: i32,
socktype: i32,
protocol: i32,
addrlen: socklen_t,
canonname: ?[*:0]u8,
addr: ?*sockaddr,
next: ?*addrinfo,
/// will be passed to the signal handler, BeOS extension
userdata: *allowzero anyopaque = undefined,
};
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 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 rlimit_resource = enum(c_int) {
CORE = 0,
CPU = 1,
DATA = 2,
FSIZE = 3,
NOFILE = 4,
STACK = 5,
AS = 6,
NOVMON = 7,
_,
pub const SS = struct {
pub const ONSTACK = 0x1;
pub const DISABLE = 0x2;
};
pub const rlim_t = i64;
pub const MINSIGSTKSZ = 8192;
pub const SIGSTKSZ = 16384;
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 stack_t = extern struct {
sp: [*]u8,
size: isize,
flags: i32,
};
pub const rlimit = extern struct {
/// Soft limit
cur: rlim_t,
/// Hard limit
max: rlim_t,
pub const NSIG = 65;
pub const mcontext_t = vregs;
pub const ucontext_t = extern struct {
link: ?*ucontext_t,
sigmask: sigset_t,
stack: stack_t,
mcontext: mcontext_t,
};
pub const SHUT = struct {
pub const RD = 0;
pub const WR = 1;
pub const RDWR = 2;
// /system/develop/headers/posix/sys/stat.h
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 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;
}
};
// TODO fill out if needed
pub const directory_which = enum(c_int) {
B_USER_SETTINGS_DIRECTORY = 0xbbe,
// /system/develop/headers/posix/sys/types.h
_,
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 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 clockid_t = i32;
pub const timer_t = *opaque {};
// /system/develop/headers/posix/time.h
pub const clock_t = i32;
pub const suseconds_t = i32;
pub const useconds_t = u32;
pub const time_t = isize;
pub const CLOCKS_PER_SEC = 1_000_000;
pub const CLK_TCK = CLOCKS_PER_SEC;
pub const TIME_UTC = 1;
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;
};
pub const MSG_NOSIGNAL = 0x0800;
pub const timespec = extern struct {
/// seconds
tv_sec: time_t,
/// and nanoseconds
tv_nsec: isize,
};
pub const itimerspec = extern struct {
interval: timespec,
value: timespec,
};
// /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;
+72 -31
View File
@@ -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,