hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 71a460aebe99b38eea5923a6aed9aea8e1eda10b
parent e5c234e3ff6bba4530951d4dcc2efc525a6961f2
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sun, 24 Oct 2021 13:29:16 +0200

rt: initial +freebsd support

Signed-off-by: Drew DeVault <sir@cmpwn.com>

Diffstat:
MMakefile | 8++++----
Mcmd/hare/main.ha | 1+
Acrypto/random/+freebsd.ha | 33+++++++++++++++++++++++++++++++++
Aformat/elf/+freebsd.ha | 2++
Mhare/module/scan.ha | 1+
Aio/+freebsd/file.ha | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aio/println+freebsd.ha | 35+++++++++++++++++++++++++++++++++++
Anet/+freebsd.ha | 41+++++++++++++++++++++++++++++++++++++++++
Anet/ip/+freebsd.ha | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Anet/tcp/+freebsd.ha | 143+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anet/udp/+freebsd.ha | 139+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anet/unix/+freebsd.ha | 104+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aos/+freebsd/dirfdfs.ha | 459+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aos/+freebsd/environ.ha | 121+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aos/+freebsd/exit.ha | 4++++
Aos/+freebsd/fs.ha | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aos/+freebsd/stdfd.ha | 43+++++++++++++++++++++++++++++++++++++++++++
Aos/exec/exec+freebsd.ha | 101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aos/exec/process+freebsd.ha | 134+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apath/+freebsd.ha | 2++
Art/+freebsd/abort.ha | 9+++++++++
Art/+freebsd/env.ha | 3+++
Art/+freebsd/errno.ha | 134+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Art/+freebsd/platformstart.ha | 7+++++++
Art/+freebsd/segmalloc.ha | 20++++++++++++++++++++
Art/+freebsd/signal.ha | 45+++++++++++++++++++++++++++++++++++++++++++++
Art/+freebsd/socket.ha | 306+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Art/+freebsd/start+aarch64.s | 8++++++++
Art/+freebsd/start+riscv64.s | 6++++++
Art/+freebsd/start+x86_64.s | 5+++++
Art/+freebsd/syscall+aarch64.s | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Art/+freebsd/syscall+riscv64.s | 146+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Art/+freebsd/syscall+x86_64.s | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Art/+freebsd/syscallno.ha | 419+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Art/+freebsd/syscalls.ha | 472+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Art/+freebsd/types.ha | 290+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mrt/+linux/errno.ha | 532++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mrt/+linux/segmalloc.ha | 6------
Mrt/+linux/syscalls.ha | 1-
Art/+test/+freebsd.ha | 13+++++++++++++
Mscripts/gen-stdlib | 190+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
Mscripts/gen-stdlib.sh | 26+++++++++++++++++---------
Mscripts/platform | 3+++
Mstdlib.mk | 1612++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
Atemp/+freebsd.ha | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atime/+freebsd/functions.ha | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtime/+linux/functions.ha | 8++++----
Aunix/+freebsd/nice.ha | 24++++++++++++++++++++++++
Aunix/+freebsd/pipe.ha | 29+++++++++++++++++++++++++++++
Aunix/+freebsd/umask.ha | 7+++++++
Aunix/poll/+freebsd.ha | 48++++++++++++++++++++++++++++++++++++++++++++++++
Aunix/tty/+freebsd/isatty.ha | 14++++++++++++++
Aunix/tty/+freebsd/open.ha | 15+++++++++++++++
Aunix/tty/+freebsd/winsize.ha | 25+++++++++++++++++++++++++
54 files changed, 5546 insertions(+), 745 deletions(-)

diff --git a/Makefile b/Makefile @@ -41,7 +41,7 @@ haredoc_srcs=\ ./cmd/haredoc/sort.ha \ ./cmd/haredoc/resolver.ha -$(HARECACHE)/hare.ssa: $(hare_srcs) $(hare_stdlib_deps) +$(HARECACHE)/hare.ssa: $(hare_srcs) $(stdlib_deps_any) $(stdlib_deps_$(PLATFORM)) @printf 'HAREC\t$@\n' @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) \ -D PLATFORM:str='"'"$$(./scripts/platform)"'"' \ @@ -49,7 +49,7 @@ $(HARECACHE)/hare.ssa: $(hare_srcs) $(hare_stdlib_deps) -D HAREPATH:str='"'"$(HAREPATH)"'"' \ -o $@ $(hare_srcs) -$(TESTCACHE)/hare.ssa: $(hare_srcs) $(hare_testlib_deps) +$(TESTCACHE)/hare.ssa: $(hare_srcs) $(testlib_deps_any) $(testlib_deps_$(PLATFORM)) @printf 'HAREC\t$@\n' @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) \ -D PLATFORM:str='"'"$$(./scripts/platform)"'"' \ @@ -61,13 +61,13 @@ $(TESTCACHE)/hare.ssa: $(hare_srcs) $(hare_testlib_deps) @mkdir -p .bin @printf 'LD\t$@\n' @$(LD) --gc-sections -T $(rtscript) -o $@ \ - $(HARECACHE)/hare.o $(hare_stdlib_deps) + $(HARECACHE)/hare.o $(stdlib_deps_any) $(stdlib_deps_$(PLATFORM)) .bin/hare-tests: $(TESTCACHE)/hare.o @mkdir -p .bin @printf 'LD\t$@\n' @$(LD) -T $(rtscript) -o $@ \ - $(TESTCACHE)/hare.o $(hare_testlib_deps) + $(TESTCACHE)/hare.o $(testlib_deps_any) $(testlib_deps_$(PLATFORM)) .bin/harec: .bin/hare $(harec_srcs) @mkdir -p .bin diff --git a/cmd/hare/main.ha b/cmd/hare/main.ha @@ -1,5 +1,6 @@ use getopt; use os; +use fmt; def VERSION: str = "unknown"; def PLATFORM: str = "unknown"; diff --git a/crypto/random/+freebsd.ha b/crypto/random/+freebsd.ha @@ -0,0 +1,33 @@ +use errors; +use rt; +use io; + +// Fills the given buffer with cryptographically random data. If the system is +// unable to provide random data, abort. If you need to handle errors or want to +// use whatever random data the system can provide, even if less than the +// requested amont, use [[stream]] instead. +export fn buffer(buf: []u8) void = { + let n = 0z; + for (n < len(buf)) { + match (rt::getrandom(buf[n..]: *[*]u8, len(buf), 0)) { + case err: rt::errno => + switch (err) { + case rt::EINTR => void; + case => + abort(); + }; + case z: size => + n += z; + }; + }; +}; + +fn rand_reader(s: *io::stream, buf: []u8) (size | io::EOF | io::error) = { + assert(s == stream); + match (rt::getrandom(buf: *[*]u8, len(buf), 0)) { + case err: rt::errno => + return errors::errno(err); + case n: size => + return n; + }; +}; diff --git a/format/elf/+freebsd.ha b/format/elf/+freebsd.ha @@ -0,0 +1,2 @@ +// The ABI of the target. +export def TARGET_ABI: ident_abi = ident_abi::SYSV; diff --git a/hare/module/scan.ha b/hare/module/scan.ha @@ -164,6 +164,7 @@ fn scan_directory( append(dirs, strings::dup(ent.name)); case fs::mode::REG => append(files, strings::dup(ent.name)); + case => abort(); }; }; diff --git a/io/+freebsd/file.ha b/io/+freebsd/file.ha @@ -0,0 +1,59 @@ +use errors; +use rt; +use strings; + +// This is an opaque type which encloses an OS-level file handle resource (on +// Unix, a file descriptor, or "fd") within a stream. It can be used as an +// [[stream]] in most situations, but there are some APIs which require an +// [[file]] with some OS-level handle backing it - this type is used for such +// APIs. +export type file = int; + +// Opens a Unix file descriptor as a file. This is a low-level interface, to +// open files most programs will use something like [[os::open]]. This function +// is not portable. +export fn fdopen(fd: int) file = fd; + +fn fd_read(fd: file, buf: []u8) (size | EOF | error) = { + match (rt::read(fd, buf: *[*]u8, len(buf))) { + case err: rt::errno => + return errors::errno(err); + case n: size => + switch (n) { + case 0 => + return EOF; + case => + return n; + }; + }; +}; + +fn fd_write(fd: file, buf: const []u8) (size | error) = { + match (rt::write(fd, buf: *const [*]u8, len(buf))) { + case err: rt::errno => + return errors::errno(err); + case n: size => + return n; + }; +}; + +fn fd_close(fd: file) void = rt::close(fd)!; + +fn fd_seek( + fd: file, + off: off, + whence: whence, +) (off | error) = { + match (rt::lseek(fd, off: i64, whence: uint)) { + case err: rt::errno => + return errors::errno(err); + case n: i64 => + return n: off; + }; +}; + +def SENDFILE_MAX: size = 2147479552z; + +fn fd_copy(to: file, from: file) (size | error) = { + abort(); // TODO: FreeBSD +}; diff --git a/io/println+freebsd.ha b/io/println+freebsd.ha @@ -0,0 +1,35 @@ +use rt; + +// Prints strings to stdout, separated by spaces, and followed by a newline. +// +// The output is unbuffered, and may not have good performance. This is only +// recommended for debugging purposes. See [[fmt::println]] instead. +export fn println(msgs: str...) void = { + for (let i = 0z; i < len(msgs); i += 1) { + let msg = msgs[i]; + rt::write(1, *(&msg: **void): *const char, len(msg)): void; + if (i + 1 < len(msgs)) { + const sp = " "; + rt::write(1, *(&sp: **void): *const char, 1): void; + }; + }; + const linefeed = "\n"; + rt::write(1, *(&linefeed: **void): *const char, 1): void; +}; + +// Prints strings to stderr, separated by spaces, and followed by a newline. +// +// The output is unbuffered, and may not have good performance. This is only +// recommended for debugging purposes. See [[fmt::errorln]] instead. +export fn errorln(msgs: str...) void = { + for (let i = 0z; i < len(msgs); i += 1) { + let msg = msgs[i]; + rt::write(2, *(&msg: **void): *const char, len(msg)): void; + if (i + 1 < len(msgs)) { + const sp = " "; + rt::write(2, *(&sp: **void): *const char, 1): void; + }; + }; + const linefeed = "\n"; + rt::write(2, *(&linefeed: **void): *const char, 1): void; +}; diff --git a/net/+freebsd.ha b/net/+freebsd.ha @@ -0,0 +1,41 @@ +// Some common code for handling sockets on +freebsd +use errors; +use fmt; +use io; +use net::ip; +use os; +use rt; +use strings; + +export type stream_listener = struct { + l: listener, + fd: int, +}; + +// Gets the fd of the listener's socket. This function is not portable. +export fn listenerfd(l: *listener) (io::file | void) = { + if (l.accept == &stream_accept) { + return (l: *stream_listener).fd; + }; +}; + +export fn stream_accept(l: *listener) (io::file | error) = { + assert(l.accept == &stream_accept); + let l = l: *stream_listener; + let sn = rt::sockaddr {...}; + const sz = size(rt::sockaddr): u32; + const fd = match (rt::accept(l.fd, &sn, &sz)) { + case err: rt::errno => + return errors::errno(err); + case fd: int => + yield fd; + }; + return io::fdopen(fd); +}; + +export fn stream_shutdown(l: *listener) void = { + assert(l.shutdown == &stream_shutdown); + let l = l: *stream_listener; + rt::close(l.fd)!; + free(l); +}; diff --git a/net/ip/+freebsd.ha b/net/ip/+freebsd.ha @@ -0,0 +1,50 @@ +use rt; +use endian; + +export fn to_native(a: addr, port: u16) rt::sockaddr = { + match (a) { + case v4: addr4 => + return rt::sockaddr { in = rt::sockaddr_in { + sin_len = size(rt::in_addr): u8, + sin_family = rt::AF_INET, + sin_port = endian::htonu16(port), + sin_addr = rt::in_addr { s_addr = *(&v4[0]: *void: *u32) }, + } }; + case v6: addr6 => + return rt::sockaddr { in6 = rt::sockaddr_in6 { + sin6_len = size(rt::in6_addr): u8, + sin6_family = rt::AF_INET6, + sin6_port = endian::htonu16(port), + sin6_addr = rt::in6_addr { s6_addr = v6 }, + } }; + }; +}; + +export fn from_native(a: rt::sockaddr) (addr, u16) = { + let family = a.in.sin_family; + switch (family) { + case rt::AF_INET => + let addr = a.in.sin_addr.s_addr; + return ( + [addr: u8, (addr >> 8): u8, (addr >> 16): u8, + (addr >> 24): u8]: addr4, + endian::ntohu16(a.in.sin_port) + ); + case rt::AF_INET6 => + return ( + a.in6.sin6_addr.s6_addr: addr6, + endian::ntohu16(a.in6.sin6_port) + ); + case => + abort("Wrong address family!"); + }; +}; + +export fn native_addrlen(a: addr) u32 = { + match (a) { + case addr4 => + return size(rt::sockaddr_in): u32; + case addr6 => + return size(rt::sockaddr_in6): u32; + }; +}; diff --git a/net/tcp/+freebsd.ha b/net/tcp/+freebsd.ha @@ -0,0 +1,143 @@ +use errors; +use io; +use net::ip; +use net; +use os; +use rt; + +// Opens a TCP connection to the given host and port. Blocks until the +// connection is established. +export fn connect( + addr: ip::addr, + port: u16, + options: connect_option... +) (io::file | net::error) = { + const sockaddr = ip::to_native(addr, port); + const family = match (addr) { + case ip::addr4 => + yield rt::AF_INET: int; + case ip::addr6 => + yield rt::AF_INET6: int; + }; + const sockfd = match (rt::socket(family, rt::SOCK_STREAM, 0)) { + case err: rt::errno => + return errors::errno(err); + case fd: int => + yield fd; + }; + let flags = rt::fcntl(sockfd, rt::F_GETFL, 0)!; + rt::fcntl(sockfd, rt::F_SETFL, flags | rt::O_CLOEXEC)!; + + for (let i = 0z; i < len(options); i += 1) { + // The only option is keepalive right now + setsockopt(sockfd, rt::SO_KEEPALIVE, true)?; + }; + const sz = ip::native_addrlen(addr); + match (rt::connect(sockfd, &sockaddr, sz)) { + case err: rt::errno => + return errors::errno(err); + case int => void; + }; + return io::fdopen(sockfd); +}; + +// Binds a TCP listener to the given address. +export fn listen( + addr: ip::addr, + port: u16, + options: listen_option... +) (*net::listener | net::error) = { + const sockaddr = ip::to_native(addr, port); + const family = match (addr) { + case ip::addr4 => + yield rt::AF_INET: int; + case ip::addr6 => + yield rt::AF_INET6: int; + }; + const sockfd = match (rt::socket(family, rt::SOCK_STREAM, 0)) { + case err: rt::errno => + return errors::errno(err); + case fd: int => + yield fd; + }; + let flags = rt::fcntl(sockfd, rt::F_GETFL, 0)!; + rt::fcntl(sockfd, rt::F_SETFL, flags | rt::O_CLOEXEC)!; + + let bk: u32 = 10; + for (let i = 0z; i < len(options); i += 1) { + match (options[i]) { + case reuseaddr => + setsockopt(sockfd, rt::SO_REUSEADDR, true)?; + case reuseport => + setsockopt(sockfd, rt::SO_REUSEPORT, true)?; + case keepalive => + setsockopt(sockfd, rt::SO_KEEPALIVE, true)?; + case b: backlog => + bk = b; + case p: portassignment => void; + }; + }; + + const sz = ip::native_addrlen(addr); + match (rt::bind(sockfd, &sockaddr, sz)) { + case err: rt::errno => + return errors::errno(err); + case int => void; + }; + match (rt::listen(sockfd, bk)) { + case err: rt::errno => + return errors::errno(err); + case int => void; + }; + + for (let i = 0z; i < len(options); i += 1) { + let portout = match (options[i]) { + case p: portassignment => + yield p; + case => + continue; + }; + let sn = rt::sockaddr {...}; + let al = size(rt::sockaddr): u32; + match (rt::getsockname(sockfd, &sn, &al)) { + case err: rt::errno => + return errors::errno(err); + case int => void; + }; + const addr = ip::from_native(sn); + *portout = addr.1; + }; + + return alloc(net::stream_listener { + l = net::listener { + accept = &net::stream_accept, + shutdown = &net::stream_shutdown, + }, + fd = sockfd, + }): *net::listener; +}; + +// Returns the remote address for a given connection, or void if none is +// available. +export fn peeraddr(peer: io::file) ((ip::addr, u16) | void) = { + let sn = rt::sockaddr {...}; + let sz = size(rt::sockaddr): u32; + if (rt::getpeername(peer, &sn, &sz) is rt::errno) { + return; + }; + return ip::from_native(sn); +}; + +fn setsockopt( + sockfd: int, + option: int, + value: bool, +) (void | net::error) = { + let val: int = if (value) 1 else 0; + match (rt::setsockopt(sockfd, rt::SOL_SOCKET, option, + &val: *void, size(int): u32)) { + case err: rt::errno => + return errors::errno(err); + case int => void; + }; +}; diff --git a/net/udp/+freebsd.ha b/net/udp/+freebsd.ha @@ -0,0 +1,139 @@ +use errors; +use io; +use net::ip; +use net; +use os; +use rt; + +// Creates a UDP socket and sets the default destination to the given address. +export fn connect( + dest: ip::addr, + port: u16, +) (io::file | net::error) = { + const family = match (dest) { + case ip::addr4 => + yield rt::AF_INET: int; + case ip::addr6 => + yield rt::AF_INET6: int; + }; + const sockfd = match (rt::socket(family, rt::SOCK_DGRAM, 0)) { + case err: rt::errno => + return errors::errno(err); + case fd: int => + yield fd; + }; + + const sockaddr = ip::to_native(dest, port); + const sz = ip::native_addrlen(dest); + match (rt::connect(sockfd, &sockaddr, sz)) { + case int => + return io::fdopen(sockfd); + case err: rt::errno => + return errors::errno(err); + }; +}; + +// Creates a UDP socket bound to an interface. +export fn listen( + addr: ip::addr, + port: u16, + options: listen_option... +) (io::file | net::error) = { + const family = match (addr) { + case ip::addr4 => + yield rt::AF_INET: int; + case ip::addr6 => + yield rt::AF_INET6: int; + }; + const sockfd = match (rt::socket(family, rt::SOCK_DGRAM, 0)) { + case err: rt::errno => + return errors::errno(err); + case fd: int => + yield fd; + }; + let flags = rt::fcntl(sockfd, rt::F_GETFL, 0)!; + rt::fcntl(sockfd, rt::F_SETFL, flags | rt::O_CLOEXEC)!; + + const sockaddr = ip::to_native(addr, port); + const sz = ip::native_addrlen(addr); + match (rt::bind(sockfd, &sockaddr, sz)) { + case int => void; + case err: rt::errno => + return errors::errno(err); + }; + + for (let i = 0z; i < len(options); i += 1) { + // The only option is portassignment right now + let sn = rt::sockaddr {...}; + let al = size(rt::sockaddr): u32; + match (rt::getsockname(sockfd, &sn, &al)) { + case err: rt::errno => + return errors::errno(err); + case int => void; + }; + const addr = ip::from_native(sn); + *options[i] = addr.1; + }; + + return io::fdopen(sockfd); +}; + +// Sends a UDP packet to the destination previously specified by [[connect]]. +export fn send(sock: io::file, buf: []u8) (size | net::error) = { + match (rt::send(sock, buf: *[*]u8, len(buf), 0)) { + case sz: size => + return sz; + case err: rt::errno => + return errors::errno(err); + }; +}; + +// Sends a UDP packet using this socket. +export fn sendto( + sock: io::file, + buf: []u8, + dest: ip::addr, + port: u16, +) (size | net::error) = { + const sockaddr = ip::to_native(dest, port); + const sz = ip::native_addrlen(dest); + match (rt::sendto(sock, buf: *[*]u8, len(buf), 0, &sockaddr, sz)) { + case sz: size => + return sz; + case err: rt::errno => + return errors::errno(err); + }; +}; + +// Receives a UDP packet from a bound socket. +export fn recvfrom( + sock: io::file, + buf: []u8, + src: nullable *ip::addr, + port: nullable *u16, +) (size | net::error) = { + let addrsz = size(rt::sockaddr): u32; + const sockaddr = rt::sockaddr { ... }; + const sz = match (rt::recvfrom(sock, buf: *[*]u8, len(buf), 0, + &sockaddr, &addrsz)) { + case sz: size => + yield sz; + case err: rt::errno => + return errors::errno(err); + }; + + assert(addrsz <= size(rt::sockaddr)); + const peer = ip::from_native(sockaddr); + match (src) { + case null => void; + case src: *ip::addr => + *src = peer.0; + }; + match (port) { + case null => void; + case port: *u16 => + *port = peer.1; + }; + + return sz; +}; diff --git a/net/unix/+freebsd.ha b/net/unix/+freebsd.ha @@ -0,0 +1,104 @@ +use errors; +use fmt; +use io; +use net; +use os; +use rt; +use strings; +use types; + +// Opens a UNIX socket connection to the path. Blocks until the connection is +// established. +export fn connect(addr: addr) (io::file | net::error) = { + let sockaddr = match (to_native(addr)) { + case a: rt::sockaddr => + yield a; + case invalid => + return errors::unsupported; // path too long + }; + const sockfd = match (rt::socket(rt::AF_UNIX: int, rt::SOCK_STREAM, 0)) { + case err: rt::errno => + return errors::errno(err); + case fd: int => + yield fd; + }; + let flags = rt::fcntl(sockfd, rt::F_GETFL, 0)!; + rt::fcntl(sockfd, rt::F_SETFL, flags | rt::O_CLOEXEC)!; + + const sz = size(rt::sockaddr_un): u32; + match (rt::connect(sockfd, &sockaddr, sz)) { + case err: rt::errno => + return errors::errno(err); + case int => void; + }; + static let buf: [rt::UNIX_PATH_MAX + 32]u8 = [0...]; + return io::fdopen(sockfd); +}; + +// Binds a UNIX socket listener to the given path. +export fn listen( + addr: addr, + options: listen_option... +) (*net::listener | net::error) = { + let sockaddr = match (to_native(addr)) { + case a: rt::sockaddr => + yield a; + case invalid => + return errors::unsupported; // path too long + }; + const sockfd = match (rt::socket(rt::AF_UNIX: int, rt::SOCK_STREAM, 0)) { + case err: rt::errno => + return errors::errno(err); + case fd: int => + yield fd; + }; + let flags = rt::fcntl(sockfd, rt::F_GETFL, 0)!; + rt::fcntl(sockfd, rt::F_SETFL, flags | rt::O_CLOEXEC)!; + + let bk: u32 = 10; + for (let i = 0z; i < len(options); i += 1) { + // Only option is backlog right now + bk = options[i]; + }; + + match (rt::bind(sockfd, &sockaddr, size(rt::sockaddr_un): u32)) { + case err: rt::errno => + return errors::errno(err); + case int => void; + }; + match (rt::listen(sockfd, bk)) { + case err: rt::errno => + return errors::errno(err); + case int => void; + }; + + return alloc(net::stream_listener { + l = net::listener { + accept = &net::stream_accept, + shutdown = &net::stream_shutdown, + }, + fd = sockfd, + }): *net::listener; +}; + +// Converts a UNIX socket address to a native sockaddr. +fn to_native(addr: addr) (rt::sockaddr | invalid) = { + // sun_path should be null-terminated and fit into rt::UNIX_PATH_MAX + if (len(addr) > rt::UNIX_PATH_MAX - 1) { + return invalid; + }; + let ret = rt::sockaddr { + un = rt::sockaddr_un { + sun_len = size(rt::sockaddr_un): u8, + sun_family = rt::AF_UNIX, + ... + } + }; + match ((&addr: *types::string).data) { + case null => void; + case data: *[*]u8 => + rt::memcpy(&ret.un.sun_path, data, len(addr)); + }; + ret.un.sun_path[len(addr)] = 0; + return ret; +}; diff --git a/os/+freebsd/dirfdfs.ha b/os/+freebsd/dirfdfs.ha @@ -0,0 +1,459 @@ +use bytes; +use errors; +use encoding::utf8; +use fs; +use io; +use path; +use rt; +use strings; +use time; + +type os_filesystem = struct { + fs: fs::fs, + dirfd: int, + getdents_bufsz: size, +}; + +// Opens a file descriptor as an [[fs::fs]]. This file descriptor must be a +// directory file. The file will be closed when the fs is closed. +// +// If no other flags are provided to [[fs::open]] and [[fs::create]] when used with +// a dirfdfs, [[fs::flags::NOCTTY]] and [[fs::flags::CLOEXEC]] are used when opening +// the file. If you pass your own flags, it is recommended that you add these +// unless you know that you do not want them. +export fn dirfdopen(fd: io::file) *fs::fs = { + let ofs = alloc(os_filesystem { ... }); + let fs = static_dirfdopen(fd, ofs); + fs.close = &fs_close; + return fs; +}; + +fn static_dirfdopen(fd: io::file, filesystem: *os_filesystem) *fs::fs = { + *filesystem = os_filesystem { + fs = fs::fs { + open = &fs_open, + openfile = &fs_open_file, + create = &fs_create, + createfile = &fs_create_file, + remove = &fs_remove, + rename = &fs_rename, + iter = &fs_iter, + stat = &fs_stat, + readlink = &fs_readlink, + subdir = &fs_subdir, + mkdir = &fs_mkdir, + rmdir = &fs_rmdir, + chmod = &fs_chmod, + chown = &fs_chown, + resolve = &fs_resolve, + ... + }, + dirfd = fd, + getdents_bufsz = 32768, // 32 KiB + }; + return &filesystem.fs; +}; + +// Sets the buffer size to use with the getdents(2) system call, for use with +// [[fs::iter]]. A larger buffer requires a larger runtime allocation, but can +// scan large directories faster. The default buffer size is 32 KiB. +// +// This function is not portable. +export fn dirfdfs_set_getdents_bufsz(fs: *fs::fs, sz: size) void = { + assert(fs.open == &fs_open); + let fs = fs: *os_filesystem; + fs.getdents_bufsz = sz; +}; + +// Returns an [[io::file]] for this filesystem. This function is not portable. +export fn dirfile(fs: *fs::fs) io::file = { + assert(fs.open == &fs_open); + let fs = fs: *os_filesystem; + return fs.dirfd; +}; + +fn errno_to_fs(err: rt::errno) fs::error = switch (err) { +case rt::ENOENT => + yield errors::noentry; +case rt::EEXIST => + yield errors::exists; +case rt::EACCES => + yield errors::noaccess; +case rt::EBUSY => + yield errors::busy; +case rt::ENOTDIR => + yield fs::wrongtype; +case rt::EOPNOTSUPP, rt::ENOSYS => + yield errors::unsupported; +case rt::EXDEV => + yield fs::cannotrename; +case => + yield errors::errno(err); +}; + +fn _fs_open( + fs: *fs::fs, + path: str, + flags: int, + mode: uint, +) (io::file | fs::error) = { + let fs = fs: *os_filesystem; + + let fd = match (rt::openat(fs.dirfd, path, flags, mode)) { + case err: rt::errno => + return errno_to_fs(err); + case fd: int => + yield fd; + }; + + return io::fdopen(fd); +}; + +fn fsflags_to_bsd(flags: fs::flags) int = { + let out = 0; + if (flags & fs::flags::WRONLY > 0) { + out |= rt::O_WRONLY; + }; + if (flags & fs::flags::RDWR > 0) { + out |= rt::O_RDWR; + }; + if (flags & fs::flags::CREATE > 0) { + out |= rt::O_CREAT; + }; + if (flags & fs::flags::EXCL > 0) { + out |= rt::O_EXCL; + }; + if (flags & fs::flags::NOCTTY > 0) { + out |= rt::O_NOCTTY; + }; + if (flags & fs::flags::TRUNC > 0) { + out |= rt::O_TRUNC; + }; + if (flags & fs::flags::APPEND > 0) { + out |= rt::O_APPEND; + }; + if (flags & fs::flags::NONBLOCK > 0) { + out |= rt::O_NONBLOCK; + }; + if (flags & fs::flags::DSYNC > 0) { + out |= rt::O_DSYNC; + }; + if (flags & fs::flags::SYNC > 0) { + out |= rt::O_SYNC; + }; + if (flags & fs::flags::RSYNC > 0) { + out |= rt::O_SYNC; + }; + if (flags & fs::flags::DIRECTORY > 0) { + out |= rt::O_DIRECTORY; + }; + if (flags & fs::flags::NOFOLLOW > 0) { + out |= rt::O_NOFOLLOW; + }; + if (flags & fs::flags::CLOEXEC > 0) { + out |= rt::O_CLOEXEC; + }; + if (flags & fs::flags::PATH > 0) { + abort("fs::flags::PATH is not supported on FreeBSD"); + }; + if (flags & fs::flags::NOATIME > 0) { + abort("fs::flags::NOATIME is not supported on FreeBSD"); + }; + if (flags & fs::flags::TMPFILE > 0) { + abort("fs::flags::TMPFILE is not supported on FreeBSD"); + }; + return out; +}; + +fn fs_open_file( + fs: *fs::fs, + path: str, + flags: fs::flags... +) (io::file | fs::error) = { + let oflags = fs::flags::RDONLY; + if (len(flags) == 0z) { + oflags |= fs::flags::NOCTTY | fs::flags::CLOEXEC; + }; + for (let i = 0z; i < len(flags); i += 1z) { + oflags |= flags[i]; + }; + return _fs_open(fs, path, fsflags_to_bsd(oflags), 0); +}; + +fn fs_open( + fs: *fs::fs, + path: str, + flags: fs::flags... +) (io::handle | fs::error) = fs_open_file(fs, path, flags...)?; + +fn fs_create_file( + fs: *fs::fs, + path: str, + mode: fs::mode, + flags: fs::flags... +) (io::file | fs::error) = { + let oflags = fs::flags::RDONLY; + if (len(flags) == 0z) { + oflags |= fs::flags::NOCTTY | fs::flags::CLOEXEC; + }; + for (let i = 0z; i < len(flags); i += 1z) { + oflags |= flags[i]; + }; + oflags |= fs::flags::CREATE; + return _fs_open(fs, path, fsflags_to_bsd(oflags), mode)?; +}; + +fn fs_create( + fs: *fs::fs, + path: str, + mode: fs::mode, + flags: fs::flags... +) (io::handle | fs::error) = { + return fs_create_file(fs, path, mode, flags...)?; +}; + +fn fs_remove(fs: *fs::fs, path: str) (void | fs::error) = { + let fs = fs: *os_filesystem; + match (rt::unlinkat(fs.dirfd, path, 0)) { + case err: rt::errno => + return errno_to_fs(err); + case void => void; + }; +}; + +fn fs_rename(fs: *fs::fs, oldpath: str, newpath: str) (void | fs::error) = { + let fs = fs: *os_filesystem; + match (rt::renameat(fs.dirfd, oldpath, fs.dirfd, newpath)) { + case err: rt::errno => + return errno_to_fs(err); + case void => void; + }; +}; + +fn fs_stat(fs: *fs::fs, path: str) (fs::filestat | fs::error) = { + let fs = fs: *os_filesystem; + let st = rt::st { ... }; + match (rt::fstatat(fs.dirfd, path, &st, rt::AT_SYMLINK_NOFOLLOW)) { + case err: rt::errno => + return errno_to_fs(err); + case void => void; + }; + return fs::filestat { + mask = fs::stat_mask::UID + | fs::stat_mask::GID + | fs::stat_mask::SIZE + | fs::stat_mask::INODE + | fs::stat_mask::ATIME + | fs::stat_mask::MTIME + | fs::stat_mask::CTIME, + mode = st.mode: fs::mode, + uid = st.uid, + uid = st.gid, + sz = st.sz: size, + inode = st.ino, + atime = time::instant { + sec = st.atime.tv_sec, + nsec = st.atime.tv_nsec, + }, + mtime = time::instant { + sec = st.mtime.tv_sec, + nsec = st.mtime.tv_nsec, + }, + ctime = time::instant { + sec = st.ctime.tv_sec, + nsec = st.ctime.tv_nsec, + }, + }; +}; + +fn fs_readlink(fs: *fs::fs, path: str) (str | fs::error) = { + let fs = fs: *os_filesystem; + static let buf: [rt::PATH_MAX]u8 = [0...]; + let z = match (rt::readlinkat(fs.dirfd, path, buf[..])) { + case err: rt::errno => + return errno_to_fs(err); + case z: size => + yield z; + }; + return strings::dup(strings::fromutf8(buf[..z])); +}; + +fn fs_subdir(fs: *fs::fs, path: str) (*fs::fs | fs::error) = { + let fs = fs: *os_filesystem; + let flags = rt::O_RDONLY | rt::O_CLOEXEC | rt::O_DIRECTORY; + + let fd: int = match (rt::openat(fs.dirfd, path, flags, 0)) { + case err: rt::errno => + return errno_to_fs(err); + case fd: int => + yield fd; + }; + + return dirfdopen(fd); +}; + +fn fs_rmdir(fs: *fs::fs, path: str) (void | fs::error) = { + let fs = fs: *os_filesystem; + match (rt::unlinkat(fs.dirfd, path, rt::AT_REMOVEDIR)) { + case err: rt::errno => + return errno_to_fs(err); + case void => void; + }; +}; + +fn fs_mkdir(fs: *fs::fs, path: str) (void | fs::error) = { + let fs = fs: *os_filesystem; + match (rt::mkdirat(fs.dirfd, path, 0o755)) { + case err: rt::errno => + switch (err) { + case rt::EISDIR => + return errors::exists; + case => + return errno_to_fs(err); + }; + case void => void; + }; +}; + +fn fs_chmod(fs: *fs::fs, path: str, mode: fs::mode) (void | fs::error) = { + let fs = fs: *os_filesystem; + match (rt::fchmodat(fs.dirfd, path, mode: uint, 0)) { + case err: rt::errno => + return errno_to_fs(err); + case void => void; + }; +}; + +fn fs_chown(fs: *fs::fs, path: str, uid: uint, gid: uint) (void | fs::error) = { + let fs = fs: *os_filesystem; + match (rt::fchownat(fs.dirfd, path, uid, gid, 0)) { + case err: rt::errno => + return errno_to_fs(err); + case void => void; + }; +}; + +fn resolve_part(parts: *[]str, part: str) void = { + if (part == ".") { + // no-op + void; + } else if (part == "..") { + if (len(parts) != 0) { + delete(parts[len(parts) - 1]); + }; + } else { + append(parts, part); + }; +}; + +fn fs_resolve(fs: *fs::fs, path: str) str = { + let parts: []str = []; + if (!path::abs(path)) { + let iter = path::iter(getcwd()); + for (true) { + match (path::next(&iter)) { + case void => + break; + case p: str => + resolve_part(&parts, p); + }; + }; + }; + let iter = path::iter(path); + for (true) { + match (path::next(&iter)) { + case void => + break; + case p: str => + resolve_part(&parts, p); + }; + }; + return path::join(parts...); +}; + +fn fs_close(fs: *fs::fs) void = { + let fs = fs: *os_filesystem; + rt::close(fs.dirfd)!; +}; + +def BUFSIZ: size = 2048; + +// Based on musl's readdir +type os_iterator = struct { + iter: fs::iterator, + fd: int, + buf_pos: size, + buf_end: size, + buf: []u8, +}; + +fn fs_iter(fs: *fs::fs, path: str) (*fs::iterator | fs::error) = { + let fs = fs: *os_filesystem; + let flags = rt::O_RDONLY | rt::O_CLOEXEC | rt::O_DIRECTORY; + let fd: int = match (rt::openat(fs.dirfd, path, flags, 0)) { + case err: rt::errno => + return errno_to_fs(err); + case fd: int => + yield fd; + }; + + let buf = match (rt::malloc(fs.getdents_bufsz)) { + case v: *void => + yield v: *[*]u8; + case null => + return errors::nomem; + }; + let iter = alloc(os_iterator { + iter = fs::iterator { + next = &iter_next, + }, + fd = fd, + buf = buf[..fs.getdents_bufsz], + ... + }); + return &iter.iter; +}; + +fn iter_next(iter: *fs::iterator) (fs::dirent | void) = { + let iter = iter: *os_iterator; + if (iter.buf_pos >= iter.buf_end) { + let n = rt::getdents(iter.fd, + iter.buf: *[*]u8, len(iter.buf)) as size; + if (n == 0) { + rt::close(iter.fd)!; + free(iter.buf); + free(iter); + return; + }; + iter.buf_end = n; + iter.buf_pos = 0; + }; + let de = &iter.buf[iter.buf_pos]: *rt::freebsd11_dirent; + iter.buf_pos += de.d_reclen; + let name = strings::fromc(&de.d_name: *const char); + + let ftype: fs::mode = switch (de.d_type) { + case rt::DT_UNKNOWN => + yield fs::mode::UNKNOWN; + case rt::DT_FIFO => + yield fs::mode::FIFO; + case rt::DT_CHR => + yield fs::mode::CHR; + case rt::DT_DIR => + yield fs::mode::DIR; + case rt::DT_BLK => + yield fs::mode::BLK; + case rt::DT_REG => + yield fs::mode::REG; + case rt::DT_LNK => + yield fs::mode::LINK; + case rt::DT_SOCK => + yield fs::mode::SOCK; + case => + yield fs::mode::UNKNOWN; + }; + return fs::dirent { + name = name, + ftype = ftype, + }; +}; diff --git a/os/+freebsd/environ.ha b/os/+freebsd/environ.ha @@ -0,0 +1,121 @@ +use bytes; +use rt; +use strings; +use types; + +// The command line arguments provided to the program. By convention, the first +// member is usually the name of the program. +export let args: []str = []; + +// Statically allocate arg strings if there are few enough arguments, saves a +// syscall if we don't need it. +let args_static: [32]str = [""...]; + +@init fn init_environ() void = { + if (rt::argc < len(args_static)) { + args = args_static[..rt::argc]; + for (let i = 0z; i < rt::argc; i += 1) { + args[i] = strings::fromc(rt::argv[i]); + }; + } else { + args = alloc([], rt::argc); + for (let i = 0z; i < rt::argc; i += 1) { + append(args, strings::fromc(rt::argv[i])); + }; + }; + +}; + +@fini fn fini_environ() void = { + if (rt::argc >= len(args_static)) { + free(args); + }; +}; + +// Looks up an environment variable and returns its value, or void if unset. +export fn getenv(name: const str) (str | void) = { + const name_b = strings::toutf8(name); + for (let i = 0z; rt::envp[i] != null; i += 1) { + const item = rt::envp[i]: *[*]u8; + const ln = strings::cstrlen(item: *char); + const eq: size = match (bytes::index(item[..ln], '=': u8)) { + case void => + abort("Environment violates System-V invariants"); + case i: size => + yield i; + }; + if (bytes::equal(name_b, item[..eq])) { + const ln = strings::cstrlen(item: *const char); + return strings::fromutf8(item[eq+1..ln]); + }; + }; +}; + +// Looks up an environment variable and returns its value, or a default value if +// unset. +export fn tryenv(name: const str, default: str) str = match (getenv(name)) { +case s: str => + yield s; +case void => + yield default; +}; + +let envp: []str = []; + +// Returns a slice of the environment strings in the form KEY=VALUE. +export fn getenvs() []str = { + if (len(envp) != 0) { + return envp; + }; + for (let i = 0z; rt::envp[i] != null; i += 1) { + append(envp, strings::fromc(rt::envp[i]: *const char)); + }; + return envp; +}; + +// Returns the host kernel name +export fn sysname() const str = { + static let buf: [512]u8 = [0...]; + let sz: size = len(buf); + rt::sysctlbyname("kern.ostype", &buf, &sz, null, 0)!; + return strings::fromutf8(buf[..(sz - 1)]); +}; + +// Returns the host system hostname +export fn hostname() const str = { + static let buf: [512]u8 = [0...]; + let sz: size = len(buf); + rt::sysctlbyname("kern.hostname", &buf, &sz, null, 0)!; + return strings::fromutf8(buf[..(sz - 1)]); +}; + +// Returns the host kernel version +export fn release() const str = { + static let buf: [512]u8 = [0...]; + let sz: size = len(buf); + rt::sysctlbyname("kern.osrelease", &buf, &sz, null, 0)!; + return strings::fromutf8(buf[..(sz - 1)]); +}; + +// Returns the host operating system version +export fn version() const str = { + static let buf: [512]u8 = [0...]; + let sz: size = len(buf); + rt::sysctlbyname("kern.version", &buf, &sz, null, 0)!; + return strings::fromutf8(buf[..(sz - 1)]); +}; + +// Returns the host CPU architecture +export fn machine() const str = { + static let buf: [512]u8 = [0...]; + let sz: size = len(buf); + rt::sysctlbyname("hw.machine", &buf, &sz, null, 0)!; + const mach = strings::fromutf8(buf[..(sz - 1)]); + // Translate to Hare names + switch (mach) { + case "amd64" => + return "x86_64"; + case => + return mach; + }; +}; diff --git a/os/+freebsd/exit.ha b/os/+freebsd/exit.ha @@ -0,0 +1,4 @@ +use rt; + +// Exit the program with the provided status code. +export @noreturn fn exit(status: int) void = rt::exit(status); diff --git a/os/+freebsd/fs.ha b/os/+freebsd/fs.ha @@ -0,0 +1,54 @@ +use errors; +use fs; +use path; +use rt; +use strings; + +@init fn init() void = { + static let cwd_fs = os_filesystem { ... }; + cwd = static_dirfdopen(rt::AT_FDCWD, &cwd_fs); +}; + +// Returns the current working directory. The return value is statically +// allocated and must be duplicated (see [[strings::dup]]) before calling getcwd +// again. +export fn getcwd() str = strings::fromc(rt::getcwd() as *const char); + +// Change the current working directory. +export fn chdir(target: (*fs::fs | str)) (void | fs::error) = { + const path: str = match (target) { + case fs: *fs::fs => + assert(fs.open == &fs_open); + let fs = fs: *os_filesystem; + match (rt::fchdir(fs.dirfd)) { + case err: rt::errno => + return errors::errno(err); + case void => + return; + }; + case s: str => + yield s; + }; + match (rt::chdir(path)) { + case err: rt::errno => + return errors::errno(err); + case void => void; + }; +}; + +// Changes the root directory of the process. Generally requires the caller to +// have root or otherwise elevated permissions. +// +// This function is not appropriate for sandboxing. +export fn chroot(target: str) (void | fs::error) = { + match (rt::chroot(target)) { + case err: rt::errno => + return errors::errno(err); + case void => void; + }; +}; + +// TODO: FreeBSD +// export fn mkfifo(path: str, mode: fs::mode) (void | fs::error) = { +// export fn mkblk( +// export fn mkchr( diff --git a/os/+freebsd/stdfd.ha b/os/+freebsd/stdfd.ha @@ -0,0 +1,43 @@ +use bufio; +use io; + +let static_stdin_bufio: bufio::bufstream = bufio::bufstream { + source = 0, + ... +}; + +let static_stdout_bufio: bufio::bufstream = bufio::bufstream { + source = 1, + ... +}; + +// The standard input. This handle is buffered. +export let stdin: io::handle = 0; + +// The standard input, as an [[io::file]]. This handle is unbuffered. +export let stdin_file: io::file = 0; + +// The standard output. This handle is buffered. +export let stdout: io::handle = 1; + +// The standard output, as an [[io::file]]. This handle is unbuffered. +export let stdout_file: io::file = 1; + +// The standard error. +export let stderr: io::file = 2; + +// The recommended buffer size for reading from disk. +export def BUFSIZ: size = 4096; // 4 KiB + +@init fn init_stdfd() void = { + static let stdinbuf: [BUFSIZ]u8 = [0...]; + stdin = bufio::static_buffered(0, stdinbuf, [], &static_stdin_bufio); + + static let stdoutbuf: [BUFSIZ]u8 = [0...]; + stdout = bufio::static_buffered(1, [], stdoutbuf, &static_stdout_bufio); +}; + +@fini fn fini_stdfd() void = { + // Flush any pending writes + io::close(stdout); +}; diff --git a/os/exec/exec+freebsd.ha b/os/exec/exec+freebsd.ha @@ -0,0 +1,101 @@ +use errors; +use rt; +use strings; +use os; + +export type platform_cmd = int; + +// Forks the current process, returning the pid of the child (to the parent) and +// void (to the child), or an error. +export fn fork() (int | void | error) = { + match (rt::fork()) { + case err: rt::errno => + return errors::errno(err); + case i: (int | void) => + return i; + }; +}; + +fn open(path: str) (platform_cmd | error) = { + match (rt::access(path, rt::X_OK)) { + case err: rt::errno => + return errors::errno(err); + case b: bool => + if (!b) { + return errors::noaccess; + }; + }; + // XXX: FreeBSD does not support O_PATH + match (rt::open(path, rt::O_RDONLY, 0u)) { + case fd: int => + return fd; + case err: rt::errno => + return errors::errno(err); + }; +}; + +fn platform_finish(cmd: *command) void = rt::close(cmd.platform)!; + +fn platform_exec(cmd: *command) error = { + // We don't worry about freeing the return values from strings::to_c + // because once we exec(2) our heap is fried anyway + let argv: []nullable *const char = alloc([], len(cmd.argv) + 1z); + for (let i = 0z; i < len(cmd.argv); i += 1z) { + append(argv, strings::to_c(cmd.argv[i])); + }; + append(argv, null); + + let envp: nullable *[*]nullable *const char = null; + if (len(cmd.env) != 0) { + let env: []nullable *const char = alloc([], len(cmd.env) + 1); + for (let i = 0z; i < len(cmd.env); i += 1) { + append(env, strings::to_c(cmd.env[i])); + }; + append(env, null); + envp = env: *[*]nullable *const char; + }; + + return errors::errno(rt::fexecve(cmd.platform, + argv: *[*]nullable *const char, envp)); +}; + +fn platform_start(cmd: *command) (process | errors::error) = { + // TODO: Let the user configure clone more to their taste (e.g. SIGCHLD) + let pipe: [2]int = [0...]; + match (rt::pipe2(&pipe, rt::O_CLOEXEC)) { + case err: rt::errno => + return errors::errno(err); + case void => void; + }; + + match (rt::fork()) { + case err: rt::errno => + return errors::errno(err); + case pid: int => + rt::close(pipe[1])!; + let errno: int = 0; + match (rt::read(pipe[0], &errno, size(int))) { + case err: rt::errno => + return errors::errno(err); + case n: size => + switch (n) { + case size(int) => + return errors::errno(errno); + case 0 => + return pid; + case => + abort("Unexpected rt::read result"); + }; + }; + case void => + rt::close(pipe[0])!; + let err = platform_exec(cmd); + if (!(err is errors::opaque)) { + rt::exit(1); + }; + let err = err as errors::opaque; + let err = &err.data: *rt::errno; + rt::write(pipe[1], &err, size(int))!; + rt::exit(1); + }; +}; diff --git a/os/exec/process+freebsd.ha b/os/exec/process+freebsd.ha @@ -0,0 +1,134 @@ +use errors; +use rt; +use fmt; +// TODO: Add function to wait on all/any children + +// Stores information about a child process. +export type process = int; + +// Stores information about an exited process. +export type status = struct { + status: int, + // Not all of these members are supported on all operating systems. + // Only utime and stime are guaranteed to be available. + rusage: struct { + // TODO: utime, stime + maxrss: i64, + ixrss: i64, + idrss: i64, + isrss: i64, + minflt: i64, + majflt: i64, + nswap: i64, + inblock: i64, + oublock: i64, + msgsnd: i64, + msgrcv: i64, + nsignals: i64, + nvcsw: i64, + nivcsw: i64, + }, +}; + +fn rusage(st: *status, ru: *rt::rusage) void = { + st.rusage.maxrss = ru.ru_maxrss; + st.rusage.ixrss = ru.ru_ixrss; + st.rusage.idrss = ru.ru_idrss; + st.rusage.isrss = ru.ru_isrss; + st.rusage.minflt = ru.ru_minflt; + st.rusage.majflt = ru.ru_majflt; + st.rusage.nswap = ru.ru_nswap; + st.rusage.inblock = ru.ru_inblock; + st.rusage.oublock = ru.ru_oublock; + st.rusage.msgsnd = ru.ru_msgsnd; + st.rusage.msgrcv = ru.ru_msgrcv; + st.rusage.nsignals = ru.ru_nsignals; + st.rusage.nvcsw = ru.ru_nvcsw; + st.rusage.nivcsw = ru.ru_nivcsw; +}; + +// Waits for a process to complete, then returns its status information. +export fn wait(proc: *process) (status | error) = { + let ru: rt::rusage = rt::rusage { ... }; + let st: status = status { ... }; + match (rt::wait4(*proc, &st.status, 0, &ru)) { + case err: rt::errno => + return errors::errno(err); + case pid: int => + assert(pid == *proc); + }; + rusage(&st, &ru); + return st; +}; + +// Checks for process completion, returning its status information on +// completion, or void if it is still running. +export fn peek(proc: *process) (status | void | error) = { + let ru: rt::rusage = rt::rusage { ... }; + let st: status = status { ... }; + match (rt::wait4(*proc, &st.status, 0, &ru)) { + case err: rt::errno => + return errors::errno(err); + case pid: int => + switch (pid) { + case 0 => + return; + case => + assert(pid == *proc); + }; + }; + rusage(&st, &ru); + return st; +}; + +// The exit status code of a process. +export type exited = int; + +// The signal number which caused a process to terminate. +export type signaled = int; + +// The exit status of a process. +export type exit_status = (exited | signaled); + +// Returns a human friendly string describing the exit status. +export fn exitstr(status: exit_status) const str = { + static let buf: [1024]u8 = [0...]; + match (status) { + case i: exited => + switch (i) { + case 0 => + return "exited normally"; + case => + return fmt::bsprintf(buf, "exited with status {}", + i: int); + }; + case s: signaled => + // TODO: Add signal name + return fmt::bsprintf(buf, "exited with signal {}", s: int); + }; +}; + +// Returns the exit status of a completed process. +export fn exit(stat: *status) exit_status = { + if (rt::wifexited(stat.status)) { + return rt::wexitstatus(stat.status): exited; + }; + if (rt::wifsignaled(stat.status)) { + return rt::wtermsig(stat.status): signaled; + }; + abort("Unexpected exit status"); +}; + +// Checks the exit status of a completed process, returning void if successful, +// or its status code as an error type if not. +export fn check(stat: *status) (void | !exit_status) = { + if (rt::wifexited(stat.status)) { + switch (rt::wexitstatus(stat.status)) { + case 0 => + return void; + case => + return exit(stat); + }; + }; + return exit(stat); +}; diff --git a/path/+freebsd.ha b/path/+freebsd.ha @@ -0,0 +1,2 @@ +// Path separator, platform-specific. +export def PATHSEP: u8 = '/': u32: u8; diff --git a/rt/+freebsd/abort.ha b/rt/+freebsd/abort.ha @@ -0,0 +1,9 @@ +fn platform_abort(msg: str) void = { + const prefix = "Abort: "; + const linefeed = "\n"; + write(2, *(&prefix: **void): *const char, len(prefix)): void; + write(2, *(&msg: **void): *const char, len(msg)): void; + write(2, *(&linefeed: **void): *const char, 1): void; + kill(getpid(), SIGABRT): void; + for (true) void; +}; diff --git a/rt/+freebsd/env.ha b/rt/+freebsd/env.ha @@ -0,0 +1,3 @@ +export let argc: size = 0; +export let argv: *[*]*char = null: *[*]*char; +export let envp: *[*]nullable *char = null: *[*]nullable *char; diff --git a/rt/+freebsd/errno.ha b/rt/+freebsd/errno.ha @@ -0,0 +1,134 @@ +// Represents an error returned from the FreeBSD kernel. +export type errno = !int; + +// Given an integer error number, wraps it in an error type. +export fn wrap_errno(err: int) errno = err: errno; + +// Checks the return value from a FreeBSD syscall and, if found to be in error, +// returns the appropriate error. Otherwise, returns the original value. +fn wrap_return(r: u64) (errno | u64) = { + if (r > -4096: u64) { + return (-(r: i64)): int: errno; + }; + return r; +}; + +// Obtains a human-friendly reading of an [[errno]] (e.g. "Operation not +// permitted"). +export fn strerror(err: errno) str = { + // TODO + switch (err: int) { + case => + return "[unknown errno]"; // TODO: snprintf to add errno? + }; +}; + +// Gets the programmer-friendly name for an [[errno]] (e.g. EPERM). +export fn errname(err: errno) str = { + // TODO + switch (err: int) { + case => + return "[unknown errno]"; // TODO: snprintf to add errno? + }; +}; + +export def EPERM: int = 1; +export def ENOENT: int = 2; +export def ESRCH: int = 3; +export def EINTR: int = 4; +export def EIO: int = 5; +export def ENXIO: int = 6; +export def E2BIG: int = 7; +export def ENOEXEC: int = 8; +export def EBADF: int = 9; +export def ECHILD: int = 10; +export def EDEADLK: int = 11; +export def ENOMEM: int = 12; +export def EACCES: int = 13; +export def EFAULT: int = 14; +export def ENOTBLK: int = 15; +export def EBUSY: int = 16; +export def EEXIST: int = 17; +export def EXDEV: int = 18; +export def ENODEV: int = 19; +export def ENOTDIR: int = 20; +export def EISDIR: int = 21; +export def EINVAL: int = 22; +export def ENFILE: int = 23; +export def EMFILE: int = 24; +export def ENOTTY: int = 25; +export def ETXTBSY: int = 26; +export def EFBIG: int = 27; +export def ENOSPC: int = 28; +export def ESPIPE: int = 29; +export def EROFS: int = 30; +export def EMLINK: int = 31; +export def EPIPE: int = 32; +export def EDOM: int = 33; +export def ERANGE: int = 34; +export def EAGAIN: int = 35; +export def EWOULDBLOCK: int = EAGAIN; +export def EINPROGRESS: int = 36; +export def EALREADY: int = 37; +export def ENOTSOCK: int = 38; +export def EDESTADDRREQ: int = 39; +export def EMSGSIZE: int = 40; +export def EPROTOTYPE: int = 41; +export def ENOPROTOOPT: int = 42; +export def EPROTONOSUPPORT: int = 43; +export def ESOCKTNOSUPPORT: int = 44; +export def EOPNOTSUPP: int = 45; +export def ENOTSUP: int = EOPNOTSUPP; +export def EPFNOSUPPORT: int = 46; +export def EAFNOSUPPORT: int = 47; +export def EADDRINUSE: int = 48; +export def EADDRNOTAVAIL: int = 49; +export def ENETDOWN: int = 50; +export def ENETUNREACH: int = 51; +export def ENETRESET: int = 52; +export def ECONNABORTED: int = 53; +export def ECONNRESET: int = 54; +export def ENOBUFS: int = 55; +export def EISCONN: int = 56; +export def ENOTCONN: int = 57; +export def ESHUTDOWN: int = 58; +export def ETOOMANYREFS: int = 59; +export def ETIMEDOUT: int = 60; +export def ETIME: int = ETIMEDOUT; +export def ECONNREFUSED: int = 61; +export def ELOOP: int = 62; +export def ENAMETOOLONG: int = 63; +export def EHOSTDOWN: int = 64; +export def EHOSTUNREACH: int = 65; +export def ENOTEMPTY: int = 66; +export def EPROCLIM: int = 67; +export def EUSERS: int = 68; +export def EDQUOT: int = 69; +export def ESTALE: int = 70; +export def EREMOTE: int = 71; +export def EBADRPC: int = 72; +export def ERPCMISMATCH: int = 73; +export def EPROGUNAVAIL: int = 74; +export def EPROGMISMATCH: int = 75; +export def EPROCUNAVAIL: int = 76; +export def ENOLCK: int = 77; +export def ENOSYS: int = 78; +export def EFTYPE: int = 79; +export def EAUTH: int = 80; +export def ENEEDAUTH: int = 81; +export def EIDRM: int = 82; +export def ENOMSG: int = 83; +export def EOVERFLOW: int = 84; +export def ECANCELED: int = 85; +export def EILSEQ: int = 86; +export def ENOATTR: int = 87; +export def EDOOFUS: int = 88; +export def EBADMSG: int = 89; +export def EMULTIHOP: int = 90; +export def ENOLINK: int = 91; +export def EPROTO: int = 92; +export def ENOTCAPABLE: int = 93; +export def ECAPMODE: int = 94; +export def ENOTRECOVERABLE: int = 95; +export def EOWNERDEAD: int = 96; +export def EINTEGRITY: int = 97; diff --git a/rt/+freebsd/platformstart.ha b/rt/+freebsd/platformstart.ha @@ -0,0 +1,7 @@ +export @noreturn fn start_freebsd(iv: *[*]uintptr) void = { + // TODO: Find & parse auxv + argc = iv[0]: size; + argv = &iv[1]: *[*]*char; + envp = &argv[argc + 1]: *[*]nullable *char; + start_ha(); +}; diff --git a/rt/+freebsd/segmalloc.ha b/rt/+freebsd/segmalloc.ha @@ -0,0 +1,20 @@ +// Allocates a segment. +fn segmalloc(n: size) nullable *void = { + return match (mmap(null, n, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0)) { + case err: errno => + assert(err == ENOMEM: errno); + yield null; + case p: *void => + yield p; + }; +}; + +// Frees a segment allocated with segmalloc. +fn segfree(p: *void, s: size) void = { + match (munmap(p, s)) { + case err: errno => + abort("munmap failed"); + case void => void; + }; +}; diff --git a/rt/+freebsd/signal.ha b/rt/+freebsd/signal.ha @@ -0,0 +1,45 @@ +// TODO: work when _NSIG != 32 + +export fn sigemptyset(set: *sigset) int = { + for (let i = 0z; i < len(set.__bits); i += 1) { + set.__bits[i] = 0; + }; + return 0; +}; + +export fn sigaddset(set: *sigset, signum: int) (int | errno) = { + if (signum > NSIG) { + return EINVAL; + }; + signum -= 1; + set.__bits[signum >> 5] |= (1 << signum): u32; + return 0; +}; + +export fn sigdelset(set: *sigset, signum: int) (int | errno) = { + if (signum > NSIG) { + return EINVAL; + }; + signum -= 1; + set.__bits[signum >> 5] &= ~(1 << signum: u32); + return 0; +}; + +export fn sigismember(set: *sigset, signum: int) (int | errno) = { + if (signum > NSIG) { + return EINVAL; + }; + signum -= 1; + if ((set.__bits[signum >> 5] & (1 << signum: u32)) != 0) { + return 1; + } else { + return 0; + }; +}; + +export fn sigfillset(set: *sigset) (int | errno) = { + for (let i = 0z; i < len(set.__bits); i += 1) { + set.__bits[i] = ~0u32; + }; + return 0; +}; diff --git a/rt/+freebsd/socket.ha b/rt/+freebsd/socket.ha @@ -0,0 +1,306 @@ +export type sa_family_t = u8; + +export type in_addr = struct { + s_addr: u32 +}; + +export type sockaddr_in = struct { + sin_len: u8, + sin_family: sa_family_t, + sin_port: u16, + sin_addr: in_addr, + __pad: [8]char, +}; + +export type in6_addr = struct { + union { + s6_addr: [16]u8, + s6_addr16: [8]u16, + s6_addr32: [4]u32, + } +}; + +export type sockaddr_in6 = struct { + sin6_len: u8, + sin6_family: sa_family_t, + sin6_port: u16, + sin6_flowinfo: u32, + sin6_addr: in6_addr, + sin6_scope_id: u32, +}; + +export def UNIX_PATH_MAX: size = 104; + +export type sockaddr_un = struct { + sun_len: u8, + sun_family: sa_family_t, + sun_path: [UNIX_PATH_MAX]char, +}; + +export type sockaddr = struct { + union { + in: sockaddr_in, + in6: sockaddr_in6, + un: sockaddr_un, + }, +}; + +export def AF_UNSPEC: sa_family_t = 0; +export def AF_UNIX: sa_family_t = 1; +export def AF_LOCAL: sa_family_t = AF_UNIX; +export def AF_INET: sa_family_t = 2; +export def AF_IMPLINK: sa_family_t = 3; +export def AF_PUP: sa_family_t = 4; +export def AF_CHAOS: sa_family_t = 5; +export def AF_NETBIOS: sa_family_t = 6; +export def AF_ISO: sa_family_t = 7; +export def AF_OSI: sa_family_t = AF_ISO; +export def AF_ECMA: sa_family_t = 8; +export def AF_DATAKIT: sa_family_t = 9; +export def AF_CCITT: sa_family_t = 10; +export def AF_SNA: sa_family_t = 11; +export def AF_DECnet: sa_family_t = 12; +export def AF_DLI: sa_family_t = 13; +export def AF_LAT: sa_family_t = 14; +export def AF_HYLINK: sa_family_t = 15; +export def AF_APPLETALK: sa_family_t = 16; +export def AF_ROUTE: sa_family_t = 17; +export def AF_LINK: sa_family_t = 18; +export def pseudo_AF_XTP: sa_family_t = 19; +export def AF_COIP: sa_family_t = 20; +export def AF_CNT: sa_family_t = 21; +export def pseudo_AF_RTIP: sa_family_t = 22; +export def AF_IPX: sa_family_t = 23; +export def AF_SIP: sa_family_t = 24; +export def pseudo_AF_PIP: sa_family_t = 25; +export def AF_ISDN: sa_family_t = 26; +export def AF_E164: sa_family_t = AF_ISDN; +export def AF_INET6: sa_family_t = 28; +export def AF_NATM: sa_family_t = 29; +export def AF_ATM: sa_family_t = 30; +export def AF_NETGRAPH: sa_family_t = 32; +export def AF_SLOW: sa_family_t = 33; +export def AF_SCLUSTER: sa_family_t = 34; +export def AF_ARP: sa_family_t = 35; +export def AF_BLUETOOTH: sa_family_t = 36; +export def AF_IEEE80211: sa_family_t = 37; +export def AF_INET_SDP: sa_family_t = 40; +export def AF_INET6_SDP: sa_family_t = 42; +export def AF_HYPERV: sa_family_t = 43; +export def AF_MAX: sa_family_t = 43; +export def AF_VENDOR00: sa_family_t = 39; +export def AF_VENDOR01: sa_family_t = 41; +export def AF_VENDOR03: sa_family_t = 45; +export def AF_VENDOR04: sa_family_t = 47; +export def AF_VENDOR05: sa_family_t = 49; +export def AF_VENDOR06: sa_family_t = 51; +export def AF_VENDOR07: sa_family_t = 53; +export def AF_VENDOR08: sa_family_t = 55; +export def AF_VENDOR09: sa_family_t = 57; +export def AF_VENDOR10: sa_family_t = 59; +export def AF_VENDOR11: sa_family_t = 61; +export def AF_VENDOR12: sa_family_t = 63; +export def AF_VENDOR13: sa_family_t = 65; +export def AF_VENDOR14: sa_family_t = 67; +export def AF_VENDOR15: sa_family_t = 69; +export def AF_VENDOR16: sa_family_t = 71; +export def AF_VENDOR17: sa_family_t = 73; +export def AF_VENDOR18: sa_family_t = 75; +export def AF_VENDOR19: sa_family_t = 77; +export def AF_VENDOR20: sa_family_t = 79; +export def AF_VENDOR21: sa_family_t = 81; +export def AF_VENDOR22: sa_family_t = 83; +export def AF_VENDOR23: sa_family_t = 85; +export def AF_VENDOR24: sa_family_t = 87; +export def AF_VENDOR25: sa_family_t = 89; +export def AF_VENDOR26: sa_family_t = 91; +export def AF_VENDOR27: sa_family_t = 93; +export def AF_VENDOR28: sa_family_t = 95; +export def AF_VENDOR29: sa_family_t = 97; +export def AF_VENDOR30: sa_family_t = 99; +export def AF_VENDOR31: sa_family_t = 101; +export def AF_VENDOR32: sa_family_t = 103; +export def AF_VENDOR33: sa_family_t = 105; +export def AF_VENDOR34: sa_family_t = 107; +export def AF_VENDOR35: sa_family_t = 109; +export def AF_VENDOR36: sa_family_t = 111; +export def AF_VENDOR37: sa_family_t = 113; +export def AF_VENDOR38: sa_family_t = 115; +export def AF_VENDOR39: sa_family_t = 117; +export def AF_VENDOR40: sa_family_t = 119; +export def AF_VENDOR41: sa_family_t = 121; +export def AF_VENDOR42: sa_family_t = 123; +export def AF_VENDOR43: sa_family_t = 125; +export def AF_VENDOR44: sa_family_t = 127; +export def AF_VENDOR45: sa_family_t = 129; +export def AF_VENDOR46: sa_family_t = 131; +export def AF_VENDOR47: sa_family_t = 133; + +export def SOCK_STREAM: int = 1; +export def SOCK_DGRAM: int = 2; +export def SOCK_RAW: int = 3; +export def SOCK_RDM: int = 4; +export def SOCK_SEQPACKET: int = 5; +export def SOCK_CLOEXEC: int = 0x10000000; +export def SOCK_NONBLOCK: int = 0x20000000; + +export def IPPROTO_HOPOPTS: int = 0; +export def IPPROTO_IGMP: int = 2; +export def IPPROTO_GGP: int = 3; +export def IPPROTO_IPV4: int = 4; +export def IPPROTO_IPIP: int = IPPROTO_IPV4; +export def IPPROTO_ST: int = 7; +export def IPPROTO_EGP: int = 8; +export def IPPROTO_PIGP: int = 9; +export def IPPROTO_RCCMON: int = 10; +export def IPPROTO_NVPII: int = 11; +export def IPPROTO_PUP: int = 12; +export def IPPROTO_ARGUS: int = 13; +export def IPPROTO_EMCON: int = 14; +export def IPPROTO_XNET: int = 15; +export def IPPROTO_CHAOS: int = 16; +export def IPPROTO_MUX: int = 18; +export def IPPROTO_MEAS: int = 19; +export def IPPROTO_HMP: int = 20; +export def IPPROTO_PRM: int = 21; +export def IPPROTO_IDP: int = 22; +export def IPPROTO_TRUNK1: int = 23; +export def IPPROTO_TRUNK2: int = 24; +export def IPPROTO_LEAF1: int = 25; +export def IPPROTO_LEAF2: int = 26; +export def IPPROTO_RDP: int = 27; +export def IPPROTO_IRTP: int = 28; +export def IPPROTO_TP: int = 29; +export def IPPROTO_BLT: int = 30; +export def IPPROTO_NSP: int = 31; +export def IPPROTO_INP: int = 32; +export def IPPROTO_DCCP: int = 33; +export def IPPROTO_3PC: int = 34; +export def IPPROTO_IDPR: int = 35; +export def IPPROTO_XTP: int = 36; +export def IPPROTO_DDP: int = 37; +export def IPPROTO_CMTP: int = 38; +export def IPPROTO_TPXX: int = 39; +export def IPPROTO_IL: int = 40; +export def IPPROTO_SDRP: int = 42; +export def IPPROTO_ROUTING: int = 43; +export def IPPROTO_FRAGMENT: int = 44; +export def IPPROTO_IDRP: int = 45; +export def IPPROTO_RSVP: int = 46; +export def IPPROTO_GRE: int = 47; +export def IPPROTO_MHRP: int = 48; +export def IPPROTO_BHA: int = 49; +export def IPPROTO_ESP: int = 50; +export def IPPROTO_AH: int = 51; +export def IPPROTO_INLSP: int = 52; +export def IPPROTO_SWIPE: int = 53; +export def IPPROTO_NHRP: int = 54; +export def IPPROTO_MOBILE: int = 55; +export def IPPROTO_TLSP: int = 56; +export def IPPROTO_SKIP: int = 57; +export def IPPROTO_ICMPV6: int = 58; +export def IPPROTO_NONE: int = 59; +export def IPPROTO_DSTOPTS: int = 60; +export def IPPROTO_AHIP: int = 61; +export def IPPROTO_CFTP: int = 62; +export def IPPROTO_HELLO: int = 63; +export def IPPROTO_SATEXPAK: int = 64; +export def IPPROTO_KRYPTOLAN: int = 65; +export def IPPROTO_RVD: int = 66; +export def IPPROTO_IPPC: int = 67; +export def IPPROTO_ADFS: int = 68; +export def IPPROTO_SATMON: int = 69; +export def IPPROTO_VISA: int = 70; +export def IPPROTO_IPCV: int = 71; +export def IPPROTO_CPNX: int = 72; +export def IPPROTO_CPHB: int = 73; +export def IPPROTO_WSN: int = 74; +export def IPPROTO_PVP: int = 75; +export def IPPROTO_BRSATMON: int = 76; +export def IPPROTO_ND: int = 77; +export def IPPROTO_WBMON: int = 78; +export def IPPROTO_WBEXPAK: int = 79; +export def IPPROTO_EON: int = 80; +export def IPPROTO_VMTP: int = 81; +export def IPPROTO_SVMTP: int = 82; +export def IPPROTO_VINES: int = 83; +export def IPPROTO_TTP: int = 84; +export def IPPROTO_IGP: int = 85; +export def IPPROTO_DGP: int = 86; +export def IPPROTO_TCF: int = 87; +export def IPPROTO_IGRP: int = 88; +export def IPPROTO_OSPFIGP: int = 89; +export def IPPROTO_SRPC: int = 90; +export def IPPROTO_LARP: int = 91; +export def IPPROTO_MTP: int = 92; +export def IPPROTO_AX25: int = 93; +export def IPPROTO_IPEIP: int = 94; +export def IPPROTO_MICP: int = 95; +export def IPPROTO_SCCSP: int = 96; +export def IPPROTO_ETHERIP: int = 97; +export def IPPROTO_ENCAP: int = 98; +export def IPPROTO_APES: int = 99; +// TODO: There are more but honestly I'm runing out of patience and I've never +// seen anyone use these constants anyway + +export def MSG_OOB: int = 0x00000001; +export def MSG_PEEK: int = 0x00000002; +export def MSG_DONTROUTE: int = 0x00000004; +export def MSG_EOR: int = 0x00000008; +export def MSG_TRUNC: int = 0x00000010; +export def MSG_CTRUNC: int = 0x00000020; +export def MSG_WAITALL: int = 0x00000040; +export def MSG_DONTWAIT: int = 0x00000080; +export def MSG_EOF: int = 0x00000100; +export def MSG_NOTIFICATION: int = 0x00002000; +export def MSG_NBIO: int = 0x00004000; +export def MSG_COMPAT: int = 0x00008000; +export def MSG_NOSIGNAL: int = 0x00020000; +export def MSG_CMSG_CLOEXEC: int = 0x00040000; +export def MSG_WAITFORONE: int = 0x00080000; + +export def SO_DEBUG: int = 0x00000001; +export def SO_ACCEPTCONN: int = 0x00000002; +export def SO_REUSEADDR: int = 0x00000004; +export def SO_KEEPALIVE: int = 0x00000008; +export def SO_DONTROUTE: int = 0x00000010; +export def SO_BROADCAST: int = 0x00000020; +export def SO_USELOOPBACK: int = 0x00000040; +export def SO_LINGER: int = 0x00000080; +export def SO_OOBINLINE: int = 0x00000100; +export def SO_REUSEPORT: int = 0x00000200; +export def SO_TIMESTAMP: int = 0x00000400; +export def SO_NOSIGPIPE: int = 0x00000800; +export def SO_ACCEPTFILTER: int = 0x00001000; +export def SO_BINTIME: int = 0x00002000; +export def SO_NO_OFFLOAD: int = 0x00004000; +export def SO_NO_DDP: int = 0x00008000; +export def SO_REUSEPORT_LB: int = 0x00010000; +export def SO_SNDBUF: int = 0x1001; +export def SO_RCVBUF: int = 0x1002; +export def SO_SNDLOWAT: int = 0x1003; +export def SO_RCVLOWAT: int = 0x1004; +export def SO_SNDTIMEO: int = 0x1005; +export def SO_RCVTIMEO: int = 0x1006; +export def SO_ERROR: int = 0x1007; +export def SO_TYPE: int = 0x1008; +export def SO_LABEL: int = 0x1009; +export def SO_PEERLABEL: int = 0x1010; +export def SO_LISTENQLIMIT: int = 0x1011; +export def SO_LISTENQLEN: int = 0x1012; +export def SO_LISTENINCQLEN: int = 0x1013; +export def SO_SETFIB: int = 0x1014; +export def SO_USER_COOKIE: int = 0x1015; +export def SO_PROTOCOL: int = 0x1016; +export def SO_PROTOTYPE: int = SO_PROTOCOL; +export def SO_TS_CLOCK: int = 0x1017; +export def SO_MAX_PACING_RATE: int = 0x1018; +export def SO_DOMAIN: int = 0x1019; +export def SO_TS_REALTIME_MICRO: int = 0; +export def SO_TS_BINTIME: int = 1; +export def SO_TS_REALTIME: int = 2; +export def SO_TS_MONOTONIC: int = 3; +export def SO_TS_DEFAULT: int = SO_TS_REALTIME_MICRO; +export def SO_TS_CLOCK_MAX: int = SO_TS_MONOTONIC; + +export def SOL_SOCKET: int = 0xffff; diff --git a/rt/+freebsd/start+aarch64.s b/rt/+freebsd/start+aarch64.s @@ -0,0 +1,8 @@ +.text +.global _start +_start: + mov x29, #0 + mov x30, #0 + mov x0, sp + add sp, x0, #-16 + b rt.start_freebsd diff --git a/rt/+freebsd/start+riscv64.s b/rt/+freebsd/start+riscv64.s @@ -0,0 +1,6 @@ +.text +.global _start +_start: + mv a0, sp + andi sp, sp, -16 + tail rt.start_freebsd diff --git a/rt/+freebsd/start+x86_64.s b/rt/+freebsd/start+x86_64.s @@ -0,0 +1,5 @@ +.text +.global _start +_start: + xor %rbp, %rbp + call rt.start_freebsd diff --git a/rt/+freebsd/syscall+aarch64.s b/rt/+freebsd/syscall+aarch64.s @@ -0,0 +1,69 @@ +.section .text.rt.syscall0 +.global rt.syscall0 +rt.syscall0: + mov x8, x0 + svc 0 + ret + +.section .text.rt.syscall1 +.global rt.syscall1 +rt.syscall1: + mov x8, x0 + mov x0, x1 + svc 0 + ret + +.section .text.rt.syscall2 +.global rt.syscall2 +rt.syscall2: + mov x8, x0 + mov x0, x1 + mov x1, x2 + svc 0 + ret + +.section .text.rt.syscall3 +.global rt.syscall3 +rt.syscall3: + mov x8, x0 + mov x0, x1 + mov x1, x2 + mov x2, x3 + svc 0 + ret + +.section .text.rt.syscall4 +.global rt.syscall4 +rt.syscall4: + mov x8, x0 + mov x0, x1 + mov x1, x2 + mov x2, x3 + mov x3, x4 + svc 0 + ret + +.section .text.rt.syscall5 +.global rt.syscall5 +rt.syscall5: + mov x8, x0 + mov x0, x1 + mov x1, x2 + mov x2, x3 + mov x3, x4 + mov x4, x5 + svc 0 + ret + +.section .text.rt.syscall6 +.global rt.syscall6 +rt.syscall6: + mov x8, x0 + mov x0, x1 + mov x1, x2 + mov x2, x3 + mov x3, x4 + mov x4, x5 + mov x5, x6 + svc 0 + ret diff --git a/rt/+freebsd/syscall+riscv64.s b/rt/+freebsd/syscall+riscv64.s @@ -0,0 +1,146 @@ +.section .text.rt.syscall0 +.global rt.syscall0 +rt.syscall0: + addi sp, sp, -32 + sd s0, 24(sp) + addi s0, sp, 32 + sd a0, -24(s0) + ld a7, -24(s0) + ecall + mv a5, a0 + mv a0, a5 + ld s0, 24(sp) + addi sp, sp, 32 + jr ra + +.section .text.rt.syscall1 +.global rt.syscall1 +rt.syscall1: + addi sp, sp, -32 + sd s0, 24(sp) + addi s0, sp, 32 + sd a0, -24(s0) + sd a1, -32(s0) + ld a7, -24(s0) + ld a0, -32(s0) + ecall + mv a5, a0 + mv a0, a5 + ld s0, 24(sp) + addi sp, sp, 32 + jr ra + +.section .text.rt.syscall2 +.global rt.syscall2 +rt.syscall2: + addi sp, sp, -48 + sd s0, 40(sp) + addi s0, sp, 48 + sd a0, -24(s0) + sd a1, -32(s0) + sd a2, -40(s0) + ld a7, -24(s0) + ld a0, -32(s0) + ld a1, -40(s0) + ecall + mv a5, a0 + mv a0, a5 + ld s0, 40(sp) + addi sp, sp, 48 + jr ra + +.section .text.rt.syscall3 +.global rt.syscall3 +rt.syscall3: + addi sp, sp, -48 + sd s0, 40(sp) + addi s0, sp, 48 + sd a0, -24(s0) + sd a1, -32(s0) + sd a2, -40(s0) + sd a3, -48(s0) + ld a7, -24(s0) + ld a0, -32(s0) + ld a1, -40(s0) + ld a2, -48(s0) + ecall + mv a5, a0 + mv a0, a5 + ld s0, 40(sp) + addi sp, sp, 48 + jr ra + +.section .text.rt.syscall4 +.global rt.syscall4 +rt.syscall4: + addi sp, sp, -64 + sd s0, 56(sp) + addi s0, sp, 64 + sd a0, -24(s0) + sd a1, -32(s0) + sd a2, -40(s0) + sd a3, -48(s0) + sd a4, -56(s0) + ld a7, -24(s0) + ld a0, -32(s0) + ld a1, -40(s0) + ld a2, -48(s0) + ld a3, -56(s0) + ecall + mv a5, a0 + mv a0, a5 + ld s0, 56(sp) + addi sp, sp, 64 + jr ra + +.section .text.rt.syscall5 +.global rt.syscall5 +rt.syscall5: + addi sp, sp, -64 + sd s0, 56(sp) + addi s0, sp, 64 + sd a0, -24(s0) + sd a1, -32(s0) + sd a2, -40(s0) + sd a3, -48(s0) + sd a4, -56(s0) + sd a5, -64(s0) + ld a7, -24(s0) + ld a0, -32(s0) + ld a1, -40(s0) + ld a2, -48(s0) + ld a3, -56(s0) + ld a4, -64(s0) + ecall + mv a5, a0 + mv a0, a5 + ld s0, 56(sp) + addi sp, sp, 64 + jr ra + +.section .text.rt.syscall6 +.global rt.syscall6 +rt.syscall6: + addi sp, sp, -80 + sd s0, 72(sp) + addi s0, sp, 80 + sd a0, -24(s0) + sd a1, -32(s0) + sd a2, -40(s0) + sd a3, -48(s0) + sd a4, -56(s0) + sd a5, -64(s0) + sd a6, -72(s0) + ld a7, -24(s0) + ld a0, -32(s0) + ld a1, -40(s0) + ld a2, -48(s0) + ld a3, -56(s0) + ld a4, -64(s0) + ld a5, -72(s0) + ecall + mv a5, a0 + mv a0, a5 + ld s0, 72(sp) + addi sp, sp, 80 + jr ra diff --git a/rt/+freebsd/syscall+x86_64.s b/rt/+freebsd/syscall+x86_64.s @@ -0,0 +1,81 @@ +.section .text +error: + neg %rax + ret + +.section .text.rt.syscall0 +.global rt.syscall0 +rt.syscall0: + movq %rdi, %rax + syscall + jc error + ret + +.section .text.rt.syscall1 +.global rt.syscall1 +rt.syscall1: + movq %rdi, %rax + movq %rsi, %rdi + syscall + jc error + ret + +.section .text.rt.syscall2 +.global rt.syscall2 +rt.syscall2: + movq %rdi, %rax + movq %rsi, %rdi + movq %rdx, %rsi + syscall + jc error + ret + +.section .text.rt.syscall3 +.global rt.syscall3 +rt.syscall3: + movq %rdi, %rax + movq %rsi, %rdi + movq %rdx, %rsi + movq %rcx, %rdx + syscall + jc error + ret + +.section .text.rt.syscall4 +.global rt.syscall4 +rt.syscall4: + movq %rdi, %rax + movq %r8, %r10 + movq %rsi, %rdi + movq %rdx, %rsi + movq %rcx, %rdx + syscall + jc error + ret + +.section .text.rt.syscall5 +.global rt.syscall5 +rt.syscall5: + movq %rdi, %rax + movq %r8, %r10 + movq %rsi, %rdi + movq %r9, %r8 + movq %rdx, %rsi + movq %rcx, %rdx + syscall + jc error + ret + +.section .text.rt.syscall6 +.global rt.syscall6 +rt.syscall6: + movq %rdi, %rax + movq %r8, %r10 + movq %rsi, %rdi + movq %r9, %r8 + movq %rdx, %rsi + movq 8(%rsp), %r9 + movq %rcx, %rdx + syscall + jc error + ret diff --git a/rt/+freebsd/syscallno.ha b/rt/+freebsd/syscallno.ha @@ -0,0 +1,419 @@ +export def SYS_syscall: u64 = 0; +export def SYS_exit: u64 = 1; +export def SYS_fork: u64 = 2; +export def SYS_read: u64 = 3; +export def SYS_write: u64 = 4; +export def SYS_open: u64 = 5; +export def SYS_close: u64 = 6; +export def SYS_wait4: u64 = 7; +export def SYS_link: u64 = 9; +export def SYS_unlink: u64 = 10; +export def SYS_chdir: u64 = 12; +export def SYS_fchdir: u64 = 13; +export def SYS_freebsd11_mknod: u64 = 14; +export def SYS_chmod: u64 = 15; +export def SYS_chown: u64 = 16; +export def SYS_break: u64 = 17; +export def SYS_getpid: u64 = 20; +export def SYS_mount: u64 = 21; +export def SYS_unmount: u64 = 22; +export def SYS_setuid: u64 = 23; +export def SYS_getuid: u64 = 24; +export def SYS_geteuid: u64 = 25; +export def SYS_ptrace: u64 = 26; +export def SYS_recvmsg: u64 = 27; +export def SYS_sendmsg: u64 = 28; +export def SYS_recvfrom: u64 = 29; +export def SYS_accept: u64 = 30; +export def SYS_getpeername: u64 = 31; +export def SYS_getsockname: u64 = 32; +export def SYS_access: u64 = 33; +export def SYS_chflags: u64 = 34; +export def SYS_fchflags: u64 = 35; +export def SYS_sync: u64 = 36; +export def SYS_kill: u64 = 37; +export def SYS_getppid: u64 = 39; +export def SYS_dup: u64 = 41; +export def SYS_freebsd10_pipe: u64 = 42; +export def SYS_getegid: u64 = 43; +export def SYS_profil: u64 = 44; +export def SYS_ktrace: u64 = 45; +export def SYS_getgid: u64 = 47; +export def SYS_getlogin: u64 = 49; +export def SYS_setlogin: u64 = 50; +export def SYS_acct: u64 = 51; +export def SYS_sigaltstack: u64 = 53; +export def SYS_ioctl: u64 = 54; +export def SYS_reboot: u64 = 55; +export def SYS_revoke: u64 = 56; +export def SYS_symlink: u64 = 57; +export def SYS_readlink: u64 = 58; +export def SYS_execve: u64 = 59; +export def SYS_umask: u64 = 60; +export def SYS_chroot: u64 = 61; +export def SYS_msync: u64 = 65; +export def SYS_vfork: u64 = 66; +export def SYS_sbrk: u64 = 69; +export def SYS_sstk: u64 = 70; +export def SYS_freebsd11_vadvise: u64 = 72; +export def SYS_munmap: u64 = 73; +export def SYS_mprotect: u64 = 74; +export def SYS_madvise: u64 = 75; +export def SYS_mincore: u64 = 78; +export def SYS_getgroups: u64 = 79; +export def SYS_setgroups: u64 = 80; +export def SYS_getpgrp: u64 = 81; +export def SYS_setpgid: u64 = 82; +export def SYS_setitimer: u64 = 83; +export def SYS_swapon: u64 = 85; +export def SYS_getitimer: u64 = 86; +export def SYS_getdtablesize: u64 = 89; +export def SYS_dup2: u64 = 90; +export def SYS_fcntl: u64 = 92; +export def SYS_select: u64 = 93; +export def SYS_fsync: u64 = 95; +export def SYS_setpriority: u64 = 96; +export def SYS_socket: u64 = 97; +export def SYS_connect: u64 = 98; +export def SYS_getpriority: u64 = 100; +export def SYS_bind: u64 = 104; +export def SYS_setsockopt: u64 = 105; +export def SYS_listen: u64 = 106; +export def SYS_gettimeofday: u64 = 116; +export def SYS_getrusage: u64 = 117; +export def SYS_getsockopt: u64 = 118; +export def SYS_readv: u64 = 120; +export def SYS_writev: u64 = 121; +export def SYS_settimeofday: u64 = 122; +export def SYS_fchown: u64 = 123; +export def SYS_fchmod: u64 = 124; +export def SYS_setreuid: u64 = 126; +export def SYS_setregid: u64 = 127; +export def SYS_rename: u64 = 128; +export def SYS_flock: u64 = 131; +export def SYS_mkfifo: u64 = 132; +export def SYS_sendto: u64 = 133; +export def SYS_shutdown: u64 = 134; +export def SYS_socketpair: u64 = 135; +export def SYS_mkdir: u64 = 136; +export def SYS_rmdir: u64 = 137; +export def SYS_utimes: u64 = 138; +export def SYS_adjtime: u64 = 140; +export def SYS_setsid: u64 = 147; +export def SYS_quotactl: u64 = 148; +export def SYS_nlm_syscall: u64 = 154; +export def SYS_nfssvc: u64 = 155; +export def SYS_lgetfh: u64 = 160; +export def SYS_getfh: u64 = 161; +export def SYS_sysarch: u64 = 165; +export def SYS_rtprio: u64 = 166; +export def SYS_semsys: u64 = 169; +export def SYS_msgsys: u64 = 170; +export def SYS_shmsys: u64 = 171; +export def SYS_setfib: u64 = 175; +export def SYS_ntp_adjtime: u64 = 176; +export def SYS_setgid: u64 = 181; +export def SYS_setegid: u64 = 182; +export def SYS_seteuid: u64 = 183; +export def SYS_freebsd11_stat: u64 = 188; +export def SYS_freebsd11_fstat: u64 = 189; +export def SYS_freebsd11_lstat: u64 = 190; +export def SYS_pathconf: u64 = 191; +export def SYS_fpathconf: u64 = 192; +export def SYS_getrlimit: u64 = 194; +export def SYS_setrlimit: u64 = 195; +export def SYS_freebsd11_getdirentries: u64 = 196; +export def SYS___syscall: u64 = 198; +export def SYS___sysctl: u64 = 202; +export def SYS_mlock: u64 = 203; +export def SYS_munlock: u64 = 204; +export def SYS_undelete: u64 = 205; +export def SYS_futimes: u64 = 206; +export def SYS_getpgid: u64 = 207; +export def SYS_poll: u64 = 209; +export def SYS_freebsd7___semctl: u64 = 220; +export def SYS_semget: u64 = 221; +export def SYS_semop: u64 = 222; +export def SYS_freebsd7_msgctl: u64 = 224; +export def SYS_msgget: u64 = 225; +export def SYS_msgsnd: u64 = 226; +export def SYS_msgrcv: u64 = 227; +export def SYS_shmat: u64 = 228; +export def SYS_freebsd7_shmctl: u64 = 229; +export def SYS_shmdt: u64 = 230; +export def SYS_shmget: u64 = 231; +export def SYS_clock_gettime: u64 = 232; +export def SYS_clock_settime: u64 = 233; +export def SYS_clock_getres: u64 = 234; +export def SYS_ktimer_create: u64 = 235; +export def SYS_ktimer_delete: u64 = 236; +export def SYS_ktimer_settime: u64 = 237; +export def SYS_ktimer_gettime: u64 = 238; +export def SYS_ktimer_getoverrun: u64 = 239; +export def SYS_nanosleep: u64 = 240; +export def SYS_ffclock_getcounter: u64 = 241; +export def SYS_ffclock_setestimate: u64 = 242; +export def SYS_ffclock_getestimate: u64 = 243; +export def SYS_clock_nanosleep: u64 = 244; +export def SYS_clock_getcpuclockid2: u64 = 247; +export def SYS_ntp_gettime: u64 = 248; +export def SYS_minherit: u64 = 250; +export def SYS_rfork: u64 = 251; +export def SYS_issetugid: u64 = 253; +export def SYS_lchown: u64 = 254; +export def SYS_aio_read: u64 = 255; +export def SYS_aio_write: u64 = 256; +export def SYS_lio_listio: u64 = 257; +export def SYS_freebsd11_getdents: u64 = 272; +export def SYS_lchmod: u64 = 274; +export def SYS_lutimes: u64 = 276; +export def SYS_freebsd11_nstat: u64 = 278; +export def SYS_freebsd11_nfstat: u64 = 279; +export def SYS_freebsd11_nlstat: u64 = 280; +export def SYS_preadv: u64 = 289; +export def SYS_pwritev: u64 = 290; +export def SYS_fhopen: u64 = 298; +export def SYS_freebsd11_fhstat: u64 = 299; +export def SYS_modnext: u64 = 300; +export def SYS_modstat: u64 = 301; +export def SYS_modfnext: u64 = 302; +export def SYS_modfind: u64 = 303; +export def SYS_kldload: u64 = 304; +export def SYS_kldunload: u64 = 305; +export def SYS_kldfind: u64 = 306; +export def SYS_kldnext: u64 = 307; +export def SYS_kldstat: u64 = 308; +export def SYS_kldfirstmod: u64 = 309; +export def SYS_getsid: u64 = 310; +export def SYS_setresuid: u64 = 311; +export def SYS_setresgid: u64 = 312; +export def SYS_aio_return: u64 = 314; +export def SYS_aio_suspend: u64 = 315; +export def SYS_aio_cancel: u64 = 316; +export def SYS_aio_error: u64 = 317; +export def SYS_yield: u64 = 321; +export def SYS_mlockall: u64 = 324; +export def SYS_munlockall: u64 = 325; +export def SYS___getcwd: u64 = 326; +export def SYS_sched_setparam: u64 = 327; +export def SYS_sched_getparam: u64 = 328; +export def SYS_sched_setscheduler: u64 = 329; +export def SYS_sched_getscheduler: u64 = 330; +export def SYS_sched_yield: u64 = 331; +export def SYS_sched_get_priority_max: u64 = 332; +export def SYS_sched_get_priority_min: u64 = 333; +export def SYS_sched_rr_get_u64erval: u64 = 334; +export def SYS_utrace: u64 = 335; +export def SYS_kldsym: u64 = 337; +export def SYS_jail: u64 = 338; +export def SYS_nnpfs_syscall: u64 = 339; +export def SYS_sigprocmask: u64 = 340; +export def SYS_sigsuspend: u64 = 341; +export def SYS_sigpending: u64 = 343; +export def SYS_sigtimedwait: u64 = 345; +export def SYS_sigwaitinfo: u64 = 346; +export def SYS___acl_get_file: u64 = 347; +export def SYS___acl_set_file: u64 = 348; +export def SYS___acl_get_fd: u64 = 349; +export def SYS___acl_set_fd: u64 = 350; +export def SYS___acl_delete_file: u64 = 351; +export def SYS___acl_delete_fd: u64 = 352; +export def SYS___acl_aclcheck_file: u64 = 353; +export def SYS___acl_aclcheck_fd: u64 = 354; +export def SYS_extattrctl: u64 = 355; +export def SYS_extattr_set_file: u64 = 356; +export def SYS_extattr_get_file: u64 = 357; +export def SYS_extattr_delete_file: u64 = 358; +export def SYS_aio_waitcomplete: u64 = 359; +export def SYS_getresuid: u64 = 360; +export def SYS_getresgid: u64 = 361; +export def SYS_kqueue: u64 = 362; +export def SYS_freebsd11_kevent: u64 = 363; +export def SYS_extattr_set_fd: u64 = 371; +export def SYS_extattr_get_fd: u64 = 372; +export def SYS_extattr_delete_fd: u64 = 373; +export def SYS___setugid: u64 = 374; +export def SYS_eaccess: u64 = 376; +export def SYS_afs3_syscall: u64 = 377; +export def SYS_nmount: u64 = 378; +export def SYS___mac_get_proc: u64 = 384; +export def SYS___mac_set_proc: u64 = 385; +export def SYS___mac_get_fd: u64 = 386; +export def SYS___mac_get_file: u64 = 387; +export def SYS___mac_set_fd: u64 = 388; +export def SYS___mac_set_file: u64 = 389; +export def SYS_kenv: u64 = 390; +export def SYS_lchflags: u64 = 391; +export def SYS_uuidgen: u64 = 392; +export def SYS_sendfile: u64 = 393; +export def SYS_mac_syscall: u64 = 394; +export def SYS_freebsd11_getfsstat: u64 = 395; +export def SYS_freebsd11_statfs: u64 = 396; +export def SYS_freebsd11_fstatfs: u64 = 397; +export def SYS_freebsd11_fhstatfs: u64 = 398; +export def SYS_ksem_close: u64 = 400; +export def SYS_ksem_post: u64 = 401; +export def SYS_ksem_wait: u64 = 402; +export def SYS_ksem_trywait: u64 = 403; +export def SYS_ksem_init: u64 = 404; +export def SYS_ksem_open: u64 = 405; +export def SYS_ksem_unlink: u64 = 406; +export def SYS_ksem_getvalue: u64 = 407; +export def SYS_ksem_destroy: u64 = 408; +export def SYS___mac_get_pid: u64 = 409; +export def SYS___mac_get_link: u64 = 410; +export def SYS___mac_set_link: u64 = 411; +export def SYS_extattr_set_link: u64 = 412; +export def SYS_extattr_get_link: u64 = 413; +export def SYS_extattr_delete_link: u64 = 414; +export def SYS___mac_execve: u64 = 415; +export def SYS_sigaction: u64 = 416; +export def SYS_sigreturn: u64 = 417; +export def SYS_getcontext: u64 = 421; +export def SYS_setcontext: u64 = 422; +export def SYS_swapcontext: u64 = 423; +export def SYS_swapoff: u64 = 424; +export def SYS___acl_get_link: u64 = 425; +export def SYS___acl_set_link: u64 = 426; +export def SYS___acl_delete_link: u64 = 427; +export def SYS___acl_aclcheck_link: u64 = 428; +export def SYS_sigwait: u64 = 429; +export def SYS_thr_create: u64 = 430; +export def SYS_thr_exit: u64 = 431; +export def SYS_thr_self: u64 = 432; +export def SYS_thr_kill: u64 = 433; +export def SYS_jail_attach: u64 = 436; +export def SYS_extattr_list_fd: u64 = 437; +export def SYS_extattr_list_file: u64 = 438; +export def SYS_extattr_list_link: u64 = 439; +export def SYS_ksem_timedwait: u64 = 441; +export def SYS_thr_suspend: u64 = 442; +export def SYS_thr_wake: u64 = 443; +export def SYS_kldunloadf: u64 = 444; +export def SYS_audit: u64 = 445; +export def SYS_auditon: u64 = 446; +export def SYS_getauid: u64 = 447; +export def SYS_setauid: u64 = 448; +export def SYS_getaudit: u64 = 449; +export def SYS_setaudit: u64 = 450; +export def SYS_getaudit_addr: u64 = 451; +export def SYS_setaudit_addr: u64 = 452; +export def SYS_auditctl: u64 = 453; +export def SYS__umtx_op: u64 = 454; +export def SYS_thr_new: u64 = 455; +export def SYS_sigqueue: u64 = 456; +export def SYS_kmq_open: u64 = 457; +export def SYS_kmq_setattr: u64 = 458; +export def SYS_kmq_timedreceive: u64 = 459; +export def SYS_kmq_timedsend: u64 = 460; +export def SYS_kmq_notify: u64 = 461; +export def SYS_kmq_unlink: u64 = 462; +export def SYS_abort2: u64 = 463; +export def SYS_thr_set_name: u64 = 464; +export def SYS_aio_fsync: u64 = 465; +export def SYS_rtprio_thread: u64 = 466; +export def SYS_sctp_peeloff: u64 = 471; +export def SYS_sctp_generic_sendmsg: u64 = 472; +export def SYS_sctp_generic_sendmsg_iov: u64 = 473; +export def SYS_sctp_generic_recvmsg: u64 = 474; +export def SYS_pread: u64 = 475; +export def SYS_pwrite: u64 = 476; +export def SYS_mmap: u64 = 477; +export def SYS_lseek: u64 = 478; +export def SYS_truncate: u64 = 479; +export def SYS_ftruncate: u64 = 480; +export def SYS_thr_kill2: u64 = 481; +export def SYS_freebsd12_shm_open: u64 = 482; +export def SYS_shm_unlink: u64 = 483; +export def SYS_cpuset: u64 = 484; +export def SYS_cpuset_setid: u64 = 485; +export def SYS_cpuset_getid: u64 = 486; +export def SYS_cpuset_getaffinity: u64 = 487; +export def SYS_cpuset_setaffinity: u64 = 488; +export def SYS_faccessat: u64 = 489; +export def SYS_fchmodat: u64 = 490; +export def SYS_fchownat: u64 = 491; +export def SYS_fexecve: u64 = 492; +export def SYS_freebsd11_fstatat: u64 = 493; +export def SYS_futimesat: u64 = 494; +export def SYS_linkat: u64 = 495; +export def SYS_mkdirat: u64 = 496; +export def SYS_mkfifoat: u64 = 497; +export def SYS_freebsd11_mknodat: u64 = 498; +export def SYS_openat: u64 = 499; +export def SYS_readlinkat: u64 = 500; +export def SYS_renameat: u64 = 501; +export def SYS_symlinkat: u64 = 502; +export def SYS_unlinkat: u64 = 503; +export def SYS_posix_openpt: u64 = 504; +export def SYS_gssd_syscall: u64 = 505; +export def SYS_jail_get: u64 = 506; +export def SYS_jail_set: u64 = 507; +export def SYS_jail_remove: u64 = 508; +export def SYS_freebsd12_closefrom: u64 = 509; +export def SYS___semctl: u64 = 510; +export def SYS_msgctl: u64 = 511; +export def SYS_shmctl: u64 = 512; +export def SYS_lpathconf: u64 = 513; +export def SYS___cap_rights_get: u64 = 515; +export def SYS_cap_enter: u64 = 516; +export def SYS_cap_getmode: u64 = 517; +export def SYS_pdfork: u64 = 518; +export def SYS_pdkill: u64 = 519; +export def SYS_pdgetpid: u64 = 520; +export def SYS_pselect: u64 = 522; +export def SYS_getloginclass: u64 = 523; +export def SYS_setloginclass: u64 = 524; +export def SYS_rctl_get_racct: u64 = 525; +export def SYS_rctl_get_rules: u64 = 526; +export def SYS_rctl_get_limits: u64 = 527; +export def SYS_rctl_add_rule: u64 = 528; +export def SYS_rctl_remove_rule: u64 = 529; +export def SYS_posix_fallocate: u64 = 530; +export def SYS_posix_fadvise: u64 = 531; +export def SYS_wait6: u64 = 532; +export def SYS_cap_rights_limit: u64 = 533; +export def SYS_cap_ioctls_limit: u64 = 534; +export def SYS_cap_ioctls_get: u64 = 535; +export def SYS_cap_fcntls_limit: u64 = 536; +export def SYS_cap_fcntls_get: u64 = 537; +export def SYS_bindat: u64 = 538; +export def SYS_connectat: u64 = 539; +export def SYS_chflagsat: u64 = 540; +export def SYS_accept4: u64 = 541; +export def SYS_pipe2: u64 = 542; +export def SYS_aio_mlock: u64 = 543; +export def SYS_procctl: u64 = 544; +export def SYS_ppoll: u64 = 545; +export def SYS_futimens: u64 = 546; +export def SYS_utimensat: u64 = 547; +export def SYS_fdatasync: u64 = 550; +export def SYS_fstat: u64 = 551; +export def SYS_fstatat: u64 = 552; +export def SYS_fhstat: u64 = 553; +export def SYS_getdirentries: u64 = 554; +export def SYS_statfs: u64 = 555; +export def SYS_fstatfs: u64 = 556; +export def SYS_getfsstat: u64 = 557; +export def SYS_fhstatfs: u64 = 558; +export def SYS_mknodat: u64 = 559; +export def SYS_kevent: u64 = 560; +export def SYS_cpuset_getdomain: u64 = 561; +export def SYS_cpuset_setdomain: u64 = 562; +export def SYS_getrandom: u64 = 563; +export def SYS_getfhat: u64 = 564; +export def SYS_fhlink: u64 = 565; +export def SYS_fhlinkat: u64 = 566; +export def SYS_fhreadlink: u64 = 567; +export def SYS_funlinkat: u64 = 568; +export def SYS_copy_file_range: u64 = 569; +export def SYS___sysctlbyname: u64 = 570; +export def SYS_shm_open2: u64 = 571; +export def SYS_shm_rename: u64 = 572; +export def SYS_sigfastblock: u64 = 573; +export def SYS___realpathat: u64 = 574; +export def SYS_close_range: u64 = 575; +export def SYS_rpctls_syscall: u64 = 576; +export def SYS___specialfd: u64 = 577; +export def SYS_aio_writev: u64 = 578; +export def SYS_aio_readv: u64 = 579; diff --git a/rt/+freebsd/syscalls.ha b/rt/+freebsd/syscalls.ha @@ -0,0 +1,472 @@ +fn syscall0(_: u64) u64; +fn syscall1(_: u64, _: u64) u64; +fn syscall2(_: u64, _: u64, _: u64) u64; +fn syscall3(_: u64, _: u64, _: u64, _: u64) u64; +fn syscall4(_: u64, _: u64, _: u64, _: u64, _: u64) u64; +fn syscall5(_: u64, _: u64, _: u64, _: u64, _: u64, _: u64) u64; +fn syscall6(_: u64, _: u64, _: u64, _: u64, _: u64, _: u64, _: u64) u64; + +export def PATH_MAX: size = 1024z; +export type path = (str | []u8 | *const char); +let pathbuf: [PATH_MAX + 1]u8 = [0...]; + +fn copy_kpath(path: path, buf: []u8) (*const char | errno) = { + let path = match (path) { + case c: *const char => + return c; + case s: str => + let ptr = &s: *struct { + buf: *[*]u8, + length: size, + capacity: size, + }; + yield ptr.buf[..ptr.length]; + case b: []u8 => + yield b; + }; + if (len(path) + 1 >= len(pathbuf)) { + return ENAMETOOLONG; + }; + memcpy(buf: *[*]u8, path: *[*]u8, len(path)); + buf[len(path)] = 0; + return buf: *[*]u8: *const char; +}; + +// NUL terminates a string and stores it in a static buffer of PATH_MAX+1 bytes +// in length. +fn kpath(path: path) (*const char | errno) = { + return copy_kpath(path, pathbuf); +}; + +export fn read(fd: int, buf: *void, count: size) (size | errno) = { + return wrap_return(syscall3(SYS_read, + fd: u64, buf: uintptr: u64, count: u64))?: size; +}; + +export fn write(fd: int, buf: *const void, count: size) (size | errno) = { + return wrap_return(syscall3(SYS_write, + fd: u64, buf: uintptr: u64, count: u64))?: size; +}; + +export fn close(fd: int) (void | errno) = { + wrap_return(syscall1(SYS_close, fd: u64))?; + return; +}; + +export fn lseek(fd: int, off: i64, whence: uint) (i64 | errno) = { + return wrap_return(syscall3(SYS_lseek, + fd: u64, off: u64, whence: u64))?: i64; +}; + +export fn pipe2(pipefd: *[2]int, flags: int) (void | errno) = { + wrap_return(syscall2(SYS_pipe2, pipefd: uintptr: u64, flags: u64))?; + return; +}; + +export fn ioctl(fd: int, req: u64, arg: nullable *void) (int | errno) = { + return wrap_return(syscall3(SYS_ioctl, fd: u64, + req, arg: uintptr: u64))?: int; +}; + +export fn openat( + dirfd: int, + path: path, + flags: int, + mode: uint, +) (int | errno) = { + let path = kpath(path)?; + return wrap_return(syscall4(SYS_openat, dirfd: u64, + path: uintptr: u64, flags: u64, mode: u64))?: int; +}; + +export fn open(path: str, flags: int, mode: uint) (int | errno) = { + return openat(AT_FDCWD, path, flags, mode); +}; + +export fn unlink(path: path) (void | errno) = { + let path = kpath(path)?; + wrap_return(syscall3(SYS_unlinkat, + AT_FDCWD: u64, path: uintptr: u64, 0u64))?; + return; +}; + +export fn renameat( + olddirfd: int, + oldpath: str, + newdirfd: int, + newpath: str, +) (void | errno) = { + let oldpath = kpath(oldpath)?; + static let newpathbuf: [PATH_MAX + 1]u8 = [0...]; + let newpath = copy_kpath(newpath, newpathbuf)?; + wrap_return(syscall4(SYS_renameat, + olddirfd: u64, oldpath: uintptr: u64, + newdirfd: u64, newpath: uintptr: u64))?; + return; +}; + +export fn unlinkat(dirfd: int, path: path, flags: int) (void | errno) = { + let path = kpath(path)?; + wrap_return(syscall3(SYS_unlinkat, + dirfd: u64, path: uintptr: u64, flags: u64))?; + return; +}; + +export fn fstatat(fd: int, path: path, stat: *st, flag: int) (void | errno) = { + let path = kpath(path)?; + let fbstat = freebsd11_stat { ... }; + wrap_return(syscall4(SYS_freebsd11_fstatat, fd: u64, + path: uintptr: u64, &fbstat: uintptr: u64, flag: u64))?; + stat.dev = fbstat.st_dev; + stat.ino = fbstat.st_ino; + stat.mode = fbstat.st_mode; + stat.nlink = fbstat.st_nlink; + stat.uid = fbstat.st_uid; + stat.gid = fbstat.st_gid; + stat.rdev = fbstat.st_rdev; + stat.atime.tv_sec = fbstat.st_atim.tv_sec; + stat.atime.tv_nsec = fbstat.st_atim.tv_nsec: i64; + stat.mtime.tv_sec = fbstat.st_mtim.tv_sec; + stat.mtime.tv_nsec = fbstat.st_mtim.tv_nsec: i64; + stat.ctime.tv_sec = fbstat.st_ctim.tv_sec; + stat.ctime.tv_nsec = fbstat.st_ctim.tv_nsec: i64; + stat.btime.tv_sec = fbstat.st_birthtim.tv_sec; + stat.btime.tv_nsec = fbstat.st_birthtim.tv_nsec: i64; + stat.sz = fbstat.st_size; + stat.blocks = fbstat.st_blocks; + stat.blksz = fbstat.st_blksize; + stat.flags = fbstat.st_flags; + return; +}; + +export fn readlinkat( + dirfd: int, + path: path, + buf: []u8, +) (size | errno) = { + let path = kpath(path)?; + return wrap_return(syscall4(SYS_readlinkat, + dirfd: u64, path: uintptr: u64, + buf: *[*]u8: uintptr: u64, + len(buf): u64))?: size; +}; + +export fn mkdirat(dirfd: int, path: path, mode: uint) (void | errno) = { + let path = kpath(path)?; + wrap_return(syscall3(SYS_mkdirat, + dirfd: u64, path: uintptr: u64, mode: u64))?; + return; +}; + +export fn fchmodat(dirfd: int, path: path, mode: uint, flags: int) (void | errno) = { + let path = kpath(path)?; + wrap_return(syscall4(SYS_fchmodat, + dirfd: u64, path: uintptr: u64, mode: u64, flags: u64))?; + return; +}; + +export fn fchownat(dirfd: int, path: path, uid: uint, gid: uint, flags: int) (void | errno) = { + let path = kpath(path)?; + wrap_return(syscall5(SYS_fchownat, + dirfd: u64, path: uintptr: u64, uid: u32, gid: u32, flags: u64))?; + return; +}; + +export fn faccessat( + dirfd: int, + path: path, + mode: int, + flags: int, +) (bool | errno) = { + let path = kpath(path)?; + match (wrap_return(syscall4(SYS_faccessat, dirfd: u64, + path: uintptr: u64, mode: u64, flags: u64))) { + case err: errno => + switch (err) { + case EACCES => + return false; + case => + return err; + }; + case n: u64 => + assert(n == 0); + return true; + }; +}; + +// The use of this function is discouraged, as it can create race conditions. +// TOCTOU is preferred: attempt to simply use the resource you need and handle +// any access errors which occur. +export fn access(path: path, mode: int) (bool | errno) = + faccessat(AT_FDCWD, path, mode, 0); + +// TODO: Consider updating this to use SYS_freebsd11_getdirentries +export fn getdents(dirfd: int, buf: *void, nbytes: size) (size | errno) = { + return wrap_return(syscall3(SYS_freebsd11_getdents, dirfd: u64, + buf: uintptr: u64, nbytes: u64))?: size; +}; + +// The return value is statically allocated and must be duplicated before +// calling getcwd again. +export fn getcwd() (*const char | errno) = { + static let pathbuf: [PATH_MAX + 1]u8 = [0...]; + wrap_return(syscall2(SYS___getcwd, + &pathbuf: *[*]u8: uintptr: u64, + PATH_MAX + 1))?; + return &pathbuf: *const char; +}; + +export fn fchdir(fd: int) (void | errno) = { + wrap_return(syscall1(SYS_fchdir, fd: u64))?; + return; +}; + +export fn chdir(path: path) (void | errno) = { + let path = kpath(path)?; + wrap_return(syscall1(SYS_chdir, path: uintptr: u64))?; + return; +}; + +export fn chroot(path: path) (void | errno) = { + let path = kpath(path)?; + wrap_return(syscall1(SYS_chroot, path: uintptr: u64))?; + return; +}; + +export fn mmap( + addr: nullable *void, + length: size, + prot: uint, + flags: uint, + fd: int, + offs: size +) (errno | *void) = { + return wrap_return(syscall6(SYS_mmap, addr: uintptr: u64, + length: u64, prot: u64, flags: u64, + fd: u64, offs: u64))?: uintptr: *void; +}; + +export fn munmap(addr: *void, length: size) (void | errno) = { + wrap_return(syscall2(SYS_munmap, addr: uintptr: u64, length: u64))?; + return; +}; + +export @noreturn fn exit(status: int) void = syscall1(SYS_exit, status: u64); + +export fn kill(pid: int, signal: int) (void | errno) = { + wrap_return(syscall2(SYS_kill, pid: u64, signal: u64))?; + return; +}; + +export fn fork() (int | void | errno) = { + let n = wrap_return(syscall0(SYS_fork))?: int; + switch (n) { + case 0 => + return; + case => + return n; + }; +}; + +export fn fexecve(fd: int, argv: *[*]nullable *const char, + envp: *[*]nullable *const char) errno = { + return match (wrap_return(syscall3(SYS_fexecve, fd: u64, + argv: uintptr: u64, envp: uintptr: u64))) { + case err: errno => + yield err; + case u64 => + abort("unreachable"); + }; +}; + +export fn wait4( + pid: int, + wstatus: *int, + options: int, + rusage: *rusage, +) (int | errno) = { + return wrap_return(syscall4(SYS_wait4, + pid: u64, wstatus: uintptr: u64, + options: u64, rusage: uintptr: u64))?: int; +}; + +export fn wifexited(status: int) bool = wtermsig(status) == 0; +export fn wexitstatus(status: int) int = (status & 0xff00) >> 8; + +export fn wtermsig(status: int) int = status & 0x7f; +export fn wifsignaled(status: int) bool = + wtermsig(status) != 0o177 && wtermsig(status) != 0 && status != 0x13; + +export fn getpid() int = syscall0(SYS_getpid): int; + +export fn getpriority(which: int, who: id_t) (int | errno) = { + return wrap_return(syscall2(SYS_setpriority, + which: u64, who: u64))?: int; +}; + +export fn setpriority(which: int, who: id_t, prio: int) (void | errno) = { + wrap_return(syscall3(SYS_setpriority, which: u64, who: u64, prio: u64))?; + return; +}; + +export fn umask(mode: mode_t) (mode_t | errno) = { + return wrap_return(syscall1(SYS_umask, mode: u64))?: mode_t; +}; + +export fn setresuid(uid: uid_t, euid: uid_t, suid: uid_t) (void | errno) = { + wrap_return(syscall3(SYS_setresuid, uid: u64, euid: u64, suid: u64))?; + return; +}; + +export fn setresgid(gid: gid_t, egid: gid_t, sgid: gid_t) (void | errno) = { + wrap_return(syscall3(SYS_setresgid, gid: u64, egid: u64, sgid: u64))?; + return; +}; + +export fn getresuid(uid: *uid_t, euid: *uid_t, suid: *uid_t) (void | errno) = { + wrap_return(syscall3(SYS_getresuid, + uid: uintptr: u64, + euid: uintptr: u64, + suid: uintptr: u64))?; + return; +}; + +export fn getresgid(gid: *gid_t, egid: *gid_t, sgid: *gid_t) (void | errno) = { + wrap_return(syscall3(SYS_getresgid, + gid: uintptr: u64, + egid: uintptr: u64, + sgid: uintptr: u64))?; + return; +}; + +export fn clock_gettime(clock_id: int, tp: *timespec) (void | errno) = { + wrap_return(syscall2(SYS_clock_gettime, + clock_id: u64, tp: uintptr: u64))?; + return; +}; + +export fn nanosleep(req: *const timespec, rem: *timespec) (void | errno) = { + wrap_return(syscall2(SYS_nanosleep, + req: uintptr: u64, rem: uintptr: u64))?; + return; +}; + +export fn getrandom(buf: *void, bufln: size, flags: uint) (size | errno) = { + return wrap_return(syscall3(SYS_getrandom, + buf: uintptr: u64, bufln: u64, flags: u64))?: size; +}; + +export type fcntl_arg = (void | int | *st_flock | *u64); + +export fn fcntl(fd: int, cmd: int, arg: fcntl_arg) (int | errno) = { + let _fd = fd: u64, _cmd = cmd: u64; + return wrap_return(match (arg) { + case void => + yield syscall2(SYS_fcntl, _fd, _cmd); + case i: int => + yield syscall3(SYS_fcntl, _fd, _cmd, i: u64); + case l: *st_flock => + yield syscall3(SYS_fcntl, _fd, _cmd, l: uintptr: u64); + case u: *u64 => + yield syscall3(SYS_fcntl, _fd, _cmd, u: uintptr: u64); + })?: int; +}; + +export fn ppoll( + fds: *[*]pollfd, + nfds: nfds_t, + timeout: const nullable *timespec, + sigmask: const nullable *sigset, +) (int | errno) = { + return wrap_return(syscall4(SYS_ppoll, fds: uintptr: u64, nfds: u64, + timeout: uintptr: u64, sigmask: uintptr: u64))?: int; +}; + +export fn poll(fds: *[*]pollfd, nfds: nfds_t, timeout: int) (int | errno) = { + const ts = timespec { + tv_sec = timeout % 1000, + tv_nsec = timeout * 1000000, + }; + return ppoll(fds, nfds, (if (timeout != -1) &ts else null), null); +}; + +export fn socket(domain: int, type_: int, protocol: int) (int | errno) = { + return wrap_return(syscall3(SYS_socket, + domain: u64, type_: u64, protocol: u64))?: int; +}; + +export fn connect(sockfd: int, addr: *const sockaddr, addrlen: u32) (int | errno) = { + return wrap_return(syscall3(SYS_connect, + sockfd: u64, addr: uintptr: u64, addrlen: u64))?: int; +}; + +export fn bind(sockfd: int, addr: *const sockaddr, addrlen: u32) (int | errno) = { + return wrap_return(syscall3(SYS_bind, + sockfd: u64, addr: uintptr: u64, addrlen: u64))?: int; +}; + +export fn listen(sockfd: int, backlog: u32) (int | errno) = { + return wrap_return(syscall2(SYS_listen, + sockfd: u64, backlog: u64))?: int; +}; + +export fn accept(sockfd: int, addr: nullable *sockaddr, addrlen: nullable *u32) (int | errno) = { + return wrap_return(syscall3(SYS_accept, + sockfd: u64, addr: uintptr: u64, addrlen: uintptr: u64))?: int; +}; + +export fn recvfrom(sockfd: int, buf: *void, len_: size, flags: int, + src_addr: nullable *sockaddr, addrlen: nullable *u32 +) (size | errno) = { + return wrap_return(syscall6(SYS_recvfrom, + sockfd: u64, buf: uintptr: u64, len_: u64, flags: u64, + src_addr: uintptr: u64, addrlen: uintptr: u64))?: size; +}; + +export fn sendto(sockfd: int, buf: *void, len_: size, flags: int, + dest_addr: nullable *sockaddr, addrlen: u32 +) (size | errno) = { + return wrap_return(syscall6(SYS_sendto, + sockfd: u64, buf: uintptr: u64, len_: u64, flags: u64, + dest_addr: uintptr: u64, addrlen: u64))?: size; +}; + +export fn recv(sockfd: int, buf: *void, len_: size, flags: int) (size | errno) = { + return recvfrom(sockfd, buf, len_, flags, null, null); +}; + +export fn send(sockfd: int, buf: *void, len_: size, flags: int) (size | errno) = { + return sendto(sockfd, buf, len_, flags, null, 0); +}; + +export fn getsockopt(sockfd: int, level: int, optname: int, optval: nullable *void, optlen: nullable *u32) (int | errno) = { + return wrap_return(syscall5(SYS_getsockopt, + sockfd: u64, level: u64, optname: u64, + optval: uintptr: u64, optlen: uintptr: u64))?: int; +}; + +export fn setsockopt(sockfd: int, level: int, optname: int, optval: *void, optlen: u32) (int | errno) = { + return wrap_return(syscall5(SYS_setsockopt, + sockfd: u64, level: u64, optname: u64, + optval: uintptr: u64, optlen: u64))?: int; +}; + +export fn getsockname(sockfd: int, addr: nullable *sockaddr, addrlen: nullable *u32) (int | errno) = { + return wrap_return(syscall3(SYS_getsockname, + sockfd: u64, addr: uintptr: u64, addrlen: uintptr: u64))?: int; +}; + +export fn getpeername(sockfd: int, addr: nullable *sockaddr, addrlen: nullable *u32) (int | errno) = { + return wrap_return(syscall3(SYS_getpeername, + sockfd: u64, addr: uintptr: u64, addrlen: uintptr: u64))?: int; +}; + +export fn sysctlbyname(name: str, oldp: nullable *void, oldlenp: nullable *size, + newp: nullable *const void, newlen: size) (void | errno) = { + let kname = kpath(name)?; + wrap_return(syscall6(SYS___sysctlbyname, + kname: uintptr: u64, len(name): u64, + oldp: uintptr: u64, oldlenp: uintptr: u64, + newp: uintptr: u64, newlen: u64))?; + return; +}; diff --git a/rt/+freebsd/types.ha b/rt/+freebsd/types.ha @@ -0,0 +1,290 @@ +export type time_t = i64; +export type suseconds_t = i64; +export type dev_t = u64; +export type ino_t = u64; +export type nlink_t = u64; +export type id_t = uint; +export type pid_t = uint; +export type uid_t = uint; +export type gid_t = uint; +export type off_t = i64; +export type blkcnt_t = i64; +export type blksize_t = i32; +export type fflags_t = u32; +export type mode_t = u16; +export type nfds_t = uint; + +export def NSIG: int = 32; + +export type sigset = struct { + __bits: [4]u32, +}; + +export type sigact = struct { + union { + sa_handler: *fn (_: int) void, + sa_sigaction: *fn (_: int, _: *siginfo, _: *void) void, + }, + sa_flags: int, + sa_mask: sigset, +}; + +export type siginfo = struct { + // TODO: Fill in more of this + si_signo: int, + si_errno: int, + si_code: int, + si_pid: pid_t, + si_uid: u32, + si_status: int, + si_addr: *void, +}; + +export type pollfd = struct { + fd: int, + events: i16, + revents: i16, +}; + +export type timespec = struct { + tv_sec: time_t, + tv_nsec: i64, +}; + +export type timeval = struct { + tv_sec: time_t, + tv_usec: suseconds_t, +}; + +export type st_flock = struct { + l_start: off_t, + l_len: off_t, + l_pid: pid_t, + l_type: i16, + l_whence: i16, + l_sysid: int, +}; + +export type st = struct { + dev: dev_t, + ino: ino_t, + nlink: nlink_t, + mode: mode_t, + uid: uid_t, + gid: gid_t, + rdev: dev_t, + atime: timespec, + mtime: timespec, + ctime: timespec, + btime: timespec, + sz: off_t, + blocks: blkcnt_t, + blksz: blksize_t, + flags: fflags_t, +}; + +export type freebsd11_stat = struct { + st_dev: u32, + st_ino: u32, + st_mode: mode_t, + st_nlink: u16, + st_uid: uid_t, + st_gid: gid_t, + st_rdev: u32, + st_atim: timespec, + st_mtim: timespec, + st_ctim: timespec, + st_size: off_t, + st_blocks: blkcnt_t, + st_blksize: blksize_t, + st_flags: fflags_t, + st_gen: u32, + st_lspare: u32, + st_birthtim: timespec, +}; + +export type freebsd11_dirent = struct { + d_fileno: u32, + d_reclen: u16, + d_type: u8, + d_namlen: u8, + d_name: [*]char, +}; + +export type winsize = struct { + ws_row: u16, + ws_col: u16, + ws_xpixel: u16, + ws_ypixel: u16, +}; + +export type rusage = struct { + ru_utime: timeval, + ru_stime: timeval, + ru_maxrss: i64, + ru_ixrss: i64, + ru_idrss: i64, + ru_isrss: i64, + ru_minflt: i64, + ru_majflt: i64, + ru_nswap: i64, + ru_inblock: i64, + ru_oublock: i64, + ru_msgsnd: i64, + ru_msgrcv: i64, + ru_nsignals: i64, + ru_nvcsw: i64, + ru_nivcsw: i64, +}; + +export def TIOCGWINSZ: u64 = 0x40087468; + +export def DT_UNKNOWN: u8 = 0; +export def DT_FIFO: u8 = 1; +export def DT_CHR: u8 = 2; +export def DT_DIR: u8 = 4; +export def DT_BLK: u8 = 6; +export def DT_REG: u8 = 8; +export def DT_LNK: u8 = 10; +export def DT_SOCK: u8 = 12; +export def DT_WHT: u8 = 14; + +export def O_RDONLY: int = 0x0000; +export def O_WRONLY: int = 0x0001; +export def O_RDWR: int = 0x0002; +export def O_NONBLOCK: int = 0x0004; +export def O_APPEND: int = 0x0008; +export def O_SHLOCK: int = 0x0010; +export def O_EXLOCK: int = 0x0020; +export def O_ASYNC: int = 0x0040; +export def O_FSYNC: int = 0x0080; +export def O_SYNC: int = 0x0080; +export def O_NOFOLLOW: int = 0x0100; +export def O_CREAT: int = 0x0200; +export def O_TRUNC: int = 0x0400; +export def O_EXCL: int = 0x0800; +export def O_NOCTTY: int = 0x8000; +export def O_DIRECT: int = 0x00010000; +export def O_DIRECTORY: int = 0x00020000; +export def O_EXEC: int = 0x00040000; +export def O_TTY_INIT: int = 0x00080000; +export def O_CLOEXEC: int = 0x00100000; +export def O_DSYNC: int = 0x01000000; + +export def AT_FDCWD: int = -100; +export def AT_EACCESS: int = 0x0100; +export def AT_SYMLINK_NOFOLLOW: int = 0x0200; +export def AT_SYMLINK_FOLLOW: int = 0x0400; +export def AT_REMOVEDIR: int = 0x0800; +export def AT_RESOLVE_BENEATH: int = 0x2000; + +export def MAP_SHARED: uint = 0x0001; +export def MAP_PRIVATE: uint = 0x0002; +export def MAP_FIXED: uint = 0x0010; +export def MAP_HASSEMAPHORE: uint = 0x0200; +export def MAP_STACK: uint = 0x0400; +export def MAP_NOSYNC: uint = 0x0800; +export def MAP_FILE: uint = 0x0000; +export def MAP_ANON: uint = 0x1000; +export def MAP_GUARD: uint = 0x00002000; +export def MAP_EXCL: uint = 0x00004000; +export def MAP_NOCORE: uint = 0x00020000; +export def MAP_PREFAULT_READ: uint = 0x00040000; +export def MAP_32BIT: uint = 0x00080000; + +export def PROT_NONE: uint = 0x00; +export def PROT_READ: uint = 0x01; +export def PROT_WRITE: uint = 0x02; +export def PROT_EXEC: uint = 0x04; + +export def SIGHUP: int = 1; +export def SIGINT: int = 2; +export def SIGQUIT: int = 3; +export def SIGILL: int = 4; +export def SIGTRAP: int = 5; +export def SIGABRT: int = 6; +export def SIGFPE: int = 8; +export def SIGKILL: int = 9; +export def SIGBUS: int = 10; +export def SIGSEGV: int = 11; +export def SIGSYS: int = 12; +export def SIGPIPE: int = 13; +export def SIGALRM: int = 14; +export def SIGTERM: int = 15; +export def SIGSTOP: int = 17; +export def SIGTSTP: int = 18; +export def SIGCONT: int = 19; +export def SIGCHLD: int = 20; +export def SIGTTIN: int = 21; +export def SIGTTOU: int = 22; +export def SIGIO: int = 23; +export def SIGXCPU: int = 24; +export def SIGXFSZ: int = 25; +export def SIGVTALRM: int = 26; +export def SIGPROF: int = 27; +export def SIGWINCH: int = 28; +export def SIGINFO: int = 29; +export def SIGUSR1: int = 30; +export def SIGUSR2: int = 31; +export def SIGTHR: int = 32; +export def SIGLWP: int = SIGTHR; +export def SIGLIBRT: int = 33; + +export def F_DUPFD: int = 0; +export def F_GETFD: int = 1; +export def F_SETFD: int = 2; +export def F_GETFL: int = 3; +export def F_SETFL: int = 4; +export def F_GETOWN: int = 5; +export def F_SETOWN: int = 6; +export def F_OGETLK: int = 7; +export def F_OSETLK: int = 8; +export def F_OSETLKW: int = 9; +export def F_DUP2FD: int = 10; +export def F_GETLK: int = 11; +export def F_SETLK: int = 12; +export def F_SETLKW: int = 13; +export def F_SETLK_REMOTE: int = 14; +export def F_READAHEAD: int = 15; +export def F_RDAHEAD: int = 16; +export def F_DUPFD_CLOEXEC: int = 17; +export def F_DUP2FD_CLOEXEC: int = 18; +export def F_ADD_SEALS: int = 19; +export def F_GET_SEALS: int = 20; +export def F_ISUNIONSTACK: int = 21; + +export def F_SEAL_SEAL: int = 0x0001; +export def F_SEAL_SHRINK: int = 0x0002; +export def F_SEAL_GROW: int = 0x0004; +export def F_SEAL_WRITE: int = 0x0008; + +export def FD_CLOEXEC: int = 1; +export def F_RDLCK: int = 1; +export def F_UNLCK: int = 2; +export def F_WRLCK: int = 3; +export def F_UNLCKSYS: int = 4; +export def F_CANCEL: int = 5; + +export def PRIO_PROCESS: int = 0; +export def PRIO_PGRP: int = 1; +export def PRIO_USER: int = 2; + +export def F_OK: int = 0; +export def X_OK: int = 0x01; +export def W_OK: int = 0x02; +export def R_OK: int = 0x04; + +export def CLOCK_REALTIME: int = 0; +export def CLOCK_MONOTONIC: int = 4; +export def CLOCK_VIRTUAL: int = 1; +export def CLOCK_PROF: int = 2; +export def CLOCK_UPTIME: int = 5; +export def CLOCK_UPTIME_PRECISE: int = 7; +export def CLOCK_UPTIME_FAST: int = 8; +export def CLOCK_REALTIME_PRECISE: int = 9; +export def CLOCK_REALTIME_FAST: int = 10; +export def CLOCK_MONOTONIC_PRECISE: int = 11; +export def CLOCK_MONOTONIC_FAST: int = 12; +export def CLOCK_SECOND: int = 13; +export def CLOCK_THREAD_CPUTIME_ID: int = 14; +export def CLOCK_PROCESS_CPUTIME_ID: int = 15; diff --git a/rt/+linux/errno.ha b/rt/+linux/errno.ha @@ -16,541 +16,541 @@ fn wrap_return(r: u64) (errno | u64) = { // Obtains a human-friendly reading of an [[errno]] (e.g. "Operation not // permitted"). export fn strerror(err: errno) str = { - return switch (err: int) { + switch (err: int) { case EPERM => - yield "Operation not permitted"; + return "Operation not permitted"; case ENOENT => - yield "No such file or directory"; + return "No such file or directory"; case ESRCH => - yield "No such process"; + return "No such process"; case EINTR => - yield "Interrupted system call"; + return "Interrupted system call"; case EIO => - yield "Input/output error"; + return "Input/output error"; case ENXIO => - yield "No such device or address"; + return "No such device or address"; case E2BIG => - yield "Argument list too long"; + return "Argument list too long"; case ENOEXEC => - yield "Exec format error"; + return "Exec format error"; case EBADF => - yield "Bad file descriptor"; + return "Bad file descriptor"; case ECHILD => - yield "No child processes"; + return "No child processes"; case EAGAIN => - yield "Resource temporarily unavailable"; + return "Resource temporarily unavailable"; case ENOMEM => - yield "Cannot allocate memory"; + return "Cannot allocate memory"; case EACCES => - yield "Permission denied"; + return "Permission denied"; case EFAULT => - yield "Bad address"; + return "Bad address"; case ENOTBLK => - yield "Block device required"; + return "Block device required"; case EBUSY => - yield "Device or resource busy"; + return "Device or resource busy"; case EEXIST => - yield "File exists"; + return "File exists"; case EXDEV => - yield "Invalid cross-device link"; + return "Invalid cross-device link"; case ENODEV => - yield "No such device"; + return "No such device"; case ENOTDIR => - yield "Not a directory"; + return "Not a directory"; case EISDIR => - yield "Is a directory"; + return "Is a directory"; case EINVAL => - yield "Invalid argument"; + return "Invalid argument"; case ENFILE => - yield "Too many open files in system"; + return "Too many open files in system"; case EMFILE => - yield "Too many open files"; + return "Too many open files"; case ENOTTY => - yield "Inappropriate ioctl for device"; + return "Inappropriate ioctl for device"; case ETXTBSY => - yield "Text file busy"; + return "Text file busy"; case EFBIG => - yield "File too large"; + return "File too large"; case ENOSPC => - yield "No space left on device"; + return "No space left on device"; case ESPIPE => - yield "Illegal seek"; + return "Illegal seek"; case EROFS => - yield "Read-only file system"; + return "Read-only file system"; case EMLINK => - yield "Too many links"; + return "Too many links"; case EPIPE => - yield "Broken pipe"; + return "Broken pipe"; case EDOM => - yield "Numerical argument out of domain"; + return "Numerical argument out of domain"; case ERANGE => - yield "Numerical result out of range"; + return "Numerical result out of range"; case EDEADLK => - yield "Resource deadlock avoided"; + return "Resource deadlock avoided"; case ENAMETOOLONG => - yield "File name too long"; + return "File name too long"; case ENOLCK => - yield "No locks available"; + return "No locks available"; case ENOSYS => - yield "Function not implemented"; + return "Function not implemented"; case ENOTEMPTY => - yield "Directory not empty"; + return "Directory not empty"; case ELOOP => - yield "Too many levels of symbolic links"; + return "Too many levels of symbolic links"; case ENOMSG => - yield "No message of desired type"; + return "No message of desired type"; case EIDRM => - yield "Identifier removed"; + return "Identifier removed"; case ECHRNG => - yield "Channel number out of range"; + return "Channel number out of range"; case EL2NSYNC => - yield "Level 2 not synchronized"; + return "Level 2 not synchronized"; case EL3HLT => - yield "Level 3 halted"; + return "Level 3 halted"; case EL3RST => - yield "Level 3 reset"; + return "Level 3 reset"; case ELNRNG => - yield "Link number out of range"; + return "Link number out of range"; case EUNATCH => - yield "Protocol driver not attached"; + return "Protocol driver not attached"; case ENOCSI => - yield "No CSI structure available"; + return "No CSI structure available"; case EL2HLT => - yield "Level 2 halted"; + return "Level 2 halted"; case EBADE => - yield "Invalid exchange"; + return "Invalid exchange"; case EBADR => - yield "Invalid request descriptor"; + return "Invalid request descriptor"; case EXFULL => - yield "Exchange full"; + return "Exchange full"; case ENOANO => - yield "No anode"; + return "No anode"; case EBADRQC => - yield "Invalid request code"; + return "Invalid request code"; case EBADSLT => - yield "Invalid slot"; + return "Invalid slot"; case EBFONT => - yield "Bad font file format"; + return "Bad font file format"; case ENOSTR => - yield "Device not a stream"; + return "Device not a stream"; case ENODATA => - yield "No data available"; + return "No data available"; case ETIME => - yield "Timer expired"; + return "Timer expired"; case ENOSR => - yield "Out of streams resources"; + return "Out of streams resources"; case ENONET => - yield "Machine is not on the network"; + return "Machine is not on the network"; case ENOPKG => - yield "Package not installed"; + return "Package not installed"; case EREMOTE => - yield "Object is remote"; + return "Object is remote"; case ENOLINK => - yield "Link has been severed"; + return "Link has been severed"; case EADV => - yield "Advertise error"; + return "Advertise error"; case ESRMNT => - yield "Srmount error"; + return "Srmount error"; case ECOMM => - yield "Communication error on send"; + return "Communication error on send"; case EPROTO => - yield "Protocol error"; + return "Protocol error"; case EMULTIHOP => - yield "Multihop attempted"; + return "Multihop attempted"; case EDOTDOT => - yield "RFS specific error"; + return "RFS specific error"; case EBADMSG => - yield "Bad message"; + return "Bad message"; case EOVERFLOW => - yield "Value too large for defined data type"; + return "Value too large for defined data type"; case ENOTUNIQ => - yield "Name not unique on network"; + return "Name not unique on network"; case EBADFD => - yield "File descriptor in bad state"; + return "File descriptor in bad state"; case EREMCHG => - yield "Remote address changed"; + return "Remote address changed"; case ELIBACC => - yield "Can not access a needed shared library"; + return "Can not access a needed shared library"; case ELIBBAD => - yield "Accessing a corrupted shared library"; + return "Accessing a corrupted shared library"; case ELIBSCN => - yield ".lib section in a.out corrupted"; + return ".lib section in a.out corrupted"; case ELIBMAX => - yield "Attempting to link in too many shared libraries"; + return "Attempting to link in too many shared libraries"; case ELIBEXEC => - yield "Cannot exec a shared library directly"; + return "Cannot exec a shared library directly"; case EILSEQ => - yield "Invalid or incomplete multibyte or wide character"; + return "Invalid or incomplete multibyte or wide character"; case ERESTART => - yield "Interrupted system call should be restarted"; + return "Interrupted system call should be restarted"; case ESTRPIPE => - yield "Streams pipe error"; + return "Streams pipe error"; case EUSERS => - yield "Too many users"; + return "Too many users"; case ENOTSOCK => - yield "Socket operation on non-socket"; + return "Socket operation on non-socket"; case EDESTADDRREQ => - yield "Destination address required"; + return "Destination address required"; case EMSGSIZE => - yield "Message too long"; + return "Message too long"; case EPROTOTYPE => - yield "Protocol wrong type for socket"; + return "Protocol wrong type for socket"; case ENOPROTOOPT => - yield "Protocol not available"; + return "Protocol not available"; case EPROTONOSUPPORT => - yield "Protocol not supported"; + return "Protocol not supported"; case ESOCKTNOSUPPORT => - yield "Socket type not supported"; + return "Socket type not supported"; case EOPNOTSUPP => - yield "Operation not supported"; + return "Operation not supported"; case EPFNOSUPPORT => - yield "Protocol family not supported"; + return "Protocol family not supported"; case EAFNOSUPPORT => - yield "Address family not supported by protocol"; + return "Address family not supported by protocol"; case EADDRINUSE => - yield "Address already in use"; + return "Address already in use"; case EADDRNOTAVAIL => - yield "Cannot assign requested address"; + return "Cannot assign requested address"; case ENETDOWN => - yield "Network is down"; + return "Network is down"; case ENETUNREACH => - yield "Network is unreachable"; + return "Network is unreachable"; case ENETRESET => - yield "Network dropped connection on reset"; + return "Network dropped connection on reset"; case ECONNABORTED => - yield "Software caused connection abort"; + return "Software caused connection abort"; case ECONNRESET => - yield "Connection reset by peer"; + return "Connection reset by peer"; case ENOBUFS => - yield "No buffer space available"; + return "No buffer space available"; case EISCONN => - yield "Transport endpoint is already connected"; + return "Transport endpoint is already connected"; case ENOTCONN => - yield "Transport endpoint is not connected"; + return "Transport endpoint is not connected"; case ESHUTDOWN => - yield "Cannot send after transport endpoint shutdown"; + return "Cannot send after transport endpoint shutdown"; case ETOOMANYREFS => - yield "Too many references: cannot splice"; + return "Too many references: cannot splice"; case ETIMEDOUT => - yield "Connection timed out"; + return "Connection timed out"; case ECONNREFUSED => - yield "Connection refused"; + return "Connection refused"; case EHOSTDOWN => - yield "Host is down"; + return "Host is down"; case EHOSTUNREACH => - yield "No route to host"; + return "No route to host"; case EALREADY => - yield "Operation already in progress"; + return "Operation already in progress"; case EINPROGRESS => - yield "Operation now in progress"; + return "Operation now in progress"; case ESTALE => - yield "Stale file handle"; + return "Stale file handle"; case EUCLEAN => - yield "Structure needs cleaning"; + return "Structure needs cleaning"; case ENOTNAM => - yield "Not a XENIX named type file"; + return "Not a XENIX named type file"; case ENAVAIL => - yield "No XENIX semaphores available"; + return "No XENIX semaphores available"; case EISNAM => - yield "Is a named type file"; + return "Is a named type file"; case EREMOTEIO => - yield "Remote I/O error"; + return "Remote I/O error"; case EDQUOT => - yield "Disk quota exceeded"; + return "Disk quota exceeded"; case ENOMEDIUM => - yield "No medium found"; + return "No medium found"; case EMEDIUMTYPE => - yield "Wrong medium type"; + return "Wrong medium type"; case ECANCELED => - yield "Operation canceled"; + return "Operation canceled"; case ENOKEY => - yield "Required key not available"; + return "Required key not available"; case EKEYEXPIRED => - yield "Key has expired"; + return "Key has expired"; case EKEYREVOKED => - yield "Key has been revoked"; + return "Key has been revoked"; case EKEYREJECTED => - yield "Key was rejected by service"; + return "Key was rejected by service"; case EOWNERDEAD => - yield "Owner died"; + return "Owner died"; case ENOTRECOVERABLE => - yield "State not recoverable"; + return "State not recoverable"; case ERFKILL => - yield "Operation not possible due to RF-kill"; + return "Operation not possible due to RF-kill"; case EHWPOISON => - yield "Memory page has hardware error"; + return "Memory page has hardware error"; case => - yield "Unknown Linux error code"; // TODO: snprintf to add errno? + return "[unknown errno]"; // TODO: snprintf to add errno? }; }; // Gets the programmer-friendly name for an [[errno]] (e.g. EPERM). export fn errname(err: errno) str = { - return switch (err: int) { + switch (err: int) { case EPERM => - yield "EPERM"; + return "EPERM"; case ENOENT => - yield "ENOENT"; + return "ENOENT"; case ESRCH => - yield "ESRCH"; + return "ESRCH"; case EINTR => - yield "EINTR"; + return "EINTR"; case EIO => - yield "EIO"; + return "EIO"; case ENXIO => - yield "ENXIO"; + return "ENXIO"; case E2BIG => - yield "E2BIG"; + return "E2BIG"; case ENOEXEC => - yield "ENOEXEC"; + return "ENOEXEC"; case EBADF => - yield "EBADF"; + return "EBADF"; case ECHILD => - yield "ECHILD"; + return "ECHILD"; case EAGAIN => - yield "EAGAIN"; + return "EAGAIN"; case ENOMEM => - yield "ENOMEM"; + return "ENOMEM"; case EACCES => - yield "EACCES"; + return "EACCES"; case EFAULT => - yield "EFAULT"; + return "EFAULT"; case ENOTBLK => - yield "ENOTBLK"; + return "ENOTBLK"; case EBUSY => - yield "EBUSY"; + return "EBUSY"; case EEXIST => - yield "EEXIST"; + return "EEXIST"; case EXDEV => - yield "EXDEV"; + return "EXDEV"; case ENODEV => - yield "ENODEV"; + return "ENODEV"; case ENOTDIR => - yield "ENOTDIR"; + return "ENOTDIR"; case EISDIR => - yield "EISDIR"; + return "EISDIR"; case EINVAL => - yield "EINVAL"; + return "EINVAL"; case ENFILE => - yield "ENFILE"; + return "ENFILE"; case EMFILE => - yield "EMFILE"; + return "EMFILE"; case ENOTTY => - yield "ENOTTY"; + return "ENOTTY"; case ETXTBSY => - yield "ETXTBSY"; + return "ETXTBSY"; case EFBIG => - yield "EFBIG"; + return "EFBIG"; case ENOSPC => - yield "ENOSPC"; + return "ENOSPC"; case ESPIPE => - yield "ESPIPE"; + return "ESPIPE"; case EROFS => - yield "EROFS"; + return "EROFS"; case EMLINK => - yield "EMLINK"; + return "EMLINK"; case EPIPE => - yield "EPIPE"; + return "EPIPE"; case EDOM => - yield "EDOM"; + return "EDOM"; case ERANGE => - yield "ERANGE"; + return "ERANGE"; case EDEADLK => - yield "EDEADLK"; + return "EDEADLK"; case ENAMETOOLONG => - yield "ENAMETOOLONG"; + return "ENAMETOOLONG"; case ENOLCK => - yield "ENOLCK"; + return "ENOLCK"; case ENOSYS => - yield "ENOSYS"; + return "ENOSYS"; case ENOTEMPTY => - yield "ENOTEMPTY"; + return "ENOTEMPTY"; case ELOOP => - yield "ELOOP"; + return "ELOOP"; case ENOMSG => - yield "ENOMSG"; + return "ENOMSG"; case EIDRM => - yield "EIDRM"; + return "EIDRM"; case ECHRNG => - yield "ECHRNG"; + return "ECHRNG"; case EL2NSYNC => - yield "EL2NSYNC"; + return "EL2NSYNC"; case EL3HLT => - yield "EL3HLT"; + return "EL3HLT"; case EL3RST => - yield "EL3RST"; + return "EL3RST"; case ELNRNG => - yield "ELNRNG"; + return "ELNRNG"; case EUNATCH => - yield "EUNATCH"; + return "EUNATCH"; case ENOCSI => - yield "ENOCSI"; + return "ENOCSI"; case EL2HLT => - yield "EL2HLT"; + return "EL2HLT"; case EBADE => - yield "EBADE"; + return "EBADE"; case EBADR => - yield "EBADR"; + return "EBADR"; case EXFULL => - yield "EXFULL"; + return "EXFULL"; case ENOANO => - yield "ENOANO"; + return "ENOANO"; case EBADRQC => - yield "EBADRQC"; + return "EBADRQC"; case EBADSLT => - yield "EBADSLT"; + return "EBADSLT"; case EBFONT => - yield "EBFONT"; + return "EBFONT"; case ENOSTR => - yield "ENOSTR"; + return "ENOSTR"; case ENODATA => - yield "ENODATA"; + return "ENODATA"; case ETIME => - yield "ETIME"; + return "ETIME"; case ENOSR => - yield "ENOSR"; + return "ENOSR"; case ENONET => - yield "ENONET"; + return "ENONET"; case ENOPKG => - yield "ENOPKG"; + return "ENOPKG"; case EREMOTE => - yield "EREMOTE"; + return "EREMOTE"; case ENOLINK => - yield "ENOLINK"; + return "ENOLINK"; case EADV => - yield "EADV"; + return "EADV"; case ESRMNT => - yield "ESRMNT"; + return "ESRMNT"; case ECOMM => - yield "ECOMM"; + return "ECOMM"; case EPROTO => - yield "EPROTO"; + return "EPROTO"; case EMULTIHOP => - yield "EMULTIHOP"; + return "EMULTIHOP"; case EDOTDOT => - yield "EDOTDOT"; + return "EDOTDOT"; case EBADMSG => - yield "EBADMSG"; + return "EBADMSG"; case EOVERFLOW => - yield "EOVERFLOW"; + return "EOVERFLOW"; case ENOTUNIQ => - yield "ENOTUNIQ"; + return "ENOTUNIQ"; case EBADFD => - yield "EBADFD"; + return "EBADFD"; case EREMCHG => - yield "EREMCHG"; + return "EREMCHG"; case ELIBACC => - yield "ELIBACC"; + return "ELIBACC"; case ELIBBAD => - yield "ELIBBAD"; + return "ELIBBAD"; case ELIBSCN => - yield "ELIBSCN"; + return "ELIBSCN"; case ELIBMAX => - yield "ELIBMAX"; + return "ELIBMAX"; case ELIBEXEC => - yield "ELIBEXEC"; + return "ELIBEXEC"; case EILSEQ => - yield "EILSEQ"; + return "EILSEQ"; case ERESTART => - yield "ERESTART"; + return "ERESTART"; case ESTRPIPE => - yield "ESTRPIPE"; + return "ESTRPIPE"; case EUSERS => - yield "EUSERS"; + return "EUSERS"; case ENOTSOCK => - yield "ENOTSOCK"; + return "ENOTSOCK"; case EDESTADDRREQ => - yield "EDESTADDRREQ"; + return "EDESTADDRREQ"; case EMSGSIZE => - yield "EMSGSIZE"; + return "EMSGSIZE"; case EPROTOTYPE => - yield "EPROTOTYPE"; + return "EPROTOTYPE"; case ENOPROTOOPT => - yield "ENOPROTOOPT"; + return "ENOPROTOOPT"; case EPROTONOSUPPORT => - yield "EPROTONOSUPPORT"; + return "EPROTONOSUPPORT"; case ESOCKTNOSUPPORT => - yield "ESOCKTNOSUPPORT"; + return "ESOCKTNOSUPPORT"; case EOPNOTSUPP => - yield "EOPNOTSUPP"; + return "EOPNOTSUPP"; case EPFNOSUPPORT => - yield "EPFNOSUPPORT"; + return "EPFNOSUPPORT"; case EAFNOSUPPORT => - yield "EAFNOSUPPORT"; + return "EAFNOSUPPORT"; case EADDRINUSE => - yield "EADDRINUSE"; + return "EADDRINUSE"; case EADDRNOTAVAIL => - yield "EADDRNOTAVAIL"; + return "EADDRNOTAVAIL"; case ENETDOWN => - yield "ENETDOWN"; + return "ENETDOWN"; case ENETUNREACH => - yield "ENETUNREACH"; + return "ENETUNREACH"; case ENETRESET => - yield "ENETRESET"; + return "ENETRESET"; case ECONNABORTED => - yield "ECONNABORTED"; + return "ECONNABORTED"; case ECONNRESET => - yield "ECONNRESET"; + return "ECONNRESET"; case ENOBUFS => - yield "ENOBUFS"; + return "ENOBUFS"; case EISCONN => - yield "EISCONN"; + return "EISCONN"; case ENOTCONN => - yield "ENOTCONN"; + return "ENOTCONN"; case ESHUTDOWN => - yield "ESHUTDOWN"; + return "ESHUTDOWN"; case ETOOMANYREFS => - yield "ETOOMANYREFS"; + return "ETOOMANYREFS"; case ETIMEDOUT => - yield "ETIMEDOUT"; + return "ETIMEDOUT"; case ECONNREFUSED => - yield "ECONNREFUSED"; + return "ECONNREFUSED"; case EHOSTDOWN => - yield "EHOSTDOWN"; + return "EHOSTDOWN"; case EHOSTUNREACH => - yield "EHOSTUNREACH"; + return "EHOSTUNREACH"; case EALREADY => - yield "EALREADY"; + return "EALREADY"; case EINPROGRESS => - yield "EINPROGRESS"; + return "EINPROGRESS"; case ESTALE => - yield "ESTALE"; + return "ESTALE"; case EUCLEAN => - yield "EUCLEAN"; + return "EUCLEAN"; case ENOTNAM => - yield "ENOTNAM"; + return "ENOTNAM"; case ENAVAIL => - yield "ENAVAIL"; + return "ENAVAIL"; case EISNAM => - yield "EISNAM"; + return "EISNAM"; case EREMOTEIO => - yield "EREMOTEIO"; + return "EREMOTEIO"; case EDQUOT => - yield "EDQUOT"; + return "EDQUOT"; case ENOMEDIUM => - yield "ENOMEDIUM"; + return "ENOMEDIUM"; case EMEDIUMTYPE => - yield "EMEDIUMTYPE"; + return "EMEDIUMTYPE"; case ECANCELED => - yield "ECANCELED"; + return "ECANCELED"; case ENOKEY => - yield "ENOKEY"; + return "ENOKEY"; case EKEYEXPIRED => - yield "EKEYEXPIRED"; + return "EKEYEXPIRED"; case EKEYREVOKED => - yield "EKEYREVOKED"; + return "EKEYREVOKED"; case EKEYREJECTED => - yield "EKEYREJECTED"; + return "EKEYREJECTED"; case EOWNERDEAD => - yield "EOWNERDEAD"; + return "EOWNERDEAD"; case ENOTRECOVERABLE => - yield "ENOTRECOVERABLE"; + return "ENOTRECOVERABLE"; case ERFKILL => - yield "ERFKILL"; + return "ERFKILL"; case EHWPOISON => - yield "EHWPOISON"; + return "EHWPOISON"; case => - yield "[unknown errno]"; // TODO: snprintf to add errno? + return "[unknown errno]"; // TODO: snprintf to add errno? }; }; diff --git a/rt/+linux/segmalloc.ha b/rt/+linux/segmalloc.ha @@ -18,9 +18,3 @@ fn segfree(p: *void, s: size) void = { case void => void; }; }; - -// Marks a segment as writable and drops the execute bit. -fn segwrite(seg: *void, n: size) void = mprotect(seg, n, PROT_READ | PROT_WRITE)!; - -// Marks a segment as executable and drops the write bit. -fn segexec(seg: *void, n: size) void = mprotect(seg, n, PROT_READ | PROT_EXEC)!; diff --git a/rt/+linux/syscalls.ha b/rt/+linux/syscalls.ha @@ -369,7 +369,6 @@ export fn getrandom(buf: *void, bufln: size, flags: uint) (size | errno) = { buf: uintptr: u64, bufln: u64, flags: u64))?: size; }; -// TODO: Implement me with VDSO export fn clock_gettime(clock_id: int, tp: *timespec) (void | errno) = { wrap_return(syscall2(SYS_clock_gettime, clock_id: u64, tp: uintptr: u64))?; diff --git a/rt/+test/+freebsd.ha b/rt/+test/+freebsd.ha @@ -0,0 +1,13 @@ +let start: timespec = timespec { ... }; + +fn time_start() void = { + clock_gettime(CLOCK_MONOTONIC, &start) as void; +}; + +// Returns elapsed time as (seconds, milliseconds) +fn time_stop() (size, size) = { + let end: timespec = timespec { ... }; + clock_gettime(CLOCK_MONOTONIC, &end) as void; + return ((end.tv_sec - start.tv_sec): size, + (end.tv_nsec - start.tv_nsec): size / 10000z); +}; diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib @@ -14,24 +14,50 @@ srcdir="$(dirname "$0")" eval ". $srcdir/gen-stdlib.sh" +all_platforms="linux +freebsd" + gensrcs_rt() { gen_srcs -plinux rt \ - '+linux/abort.ha' \ - '+linux/env.ha' \ - '+linux/errno.ha' \ - '+linux/types.ha' \ - '+linux/segmalloc.ha' \ - '+linux/platformstart.ha' \ - '+linux/prctl.ha' \ - '+linux/+$(ARCH).ha' \ - '+linux/syscallno+$(ARCH).ha' \ - '+linux/syscalls.ha' \ - '+linux/signal.ha' \ - '+linux/stat.ha' \ - '+linux/socket.ha' \ - '+$(ARCH)/jmp.ha' \ - '+$(ARCH)/backtrace.ha' \ - 'types_arch+$(ARCH).ha' \ + +linux/abort.ha \ + +linux/env.ha \ + +linux/errno.ha \ + +linux/types.ha \ + +linux/segmalloc.ha \ + +linux/platformstart.ha \ + +linux/prctl.ha \ + +linux/'+$(ARCH)'.ha \ + +linux/syscallno+'$(ARCH)'.ha \ + +linux/syscalls.ha \ + +linux/signal.ha \ + +linux/stat.ha \ + +linux/socket.ha \ + '+$(ARCH)'/jmp.ha \ + '+$(ARCH)'/backtrace.ha \ + types_arch+'$(ARCH)'.ha \ + ensure.ha \ + jmp.ha \ + malloc.ha \ + memcpy.ha \ + memmove.ha \ + memset.ha \ + strcmp.ha \ + types.ha \ + $* + gen_srcs -pfreebsd rt \ + +freebsd/abort.ha \ + +freebsd/env.ha \ + +freebsd/errno.ha \ + +freebsd/platformstart.ha \ + +freebsd/segmalloc.ha \ + +freebsd/signal.ha \ + +freebsd/socket.ha \ + +freebsd/syscallno.ha \ + +freebsd/syscalls.ha \ + +freebsd/types.ha \ + +'$(ARCH)'/jmp.ha \ + +'$(ARCH)'/backtrace.ha \ + types_arch+'$(ARCH)'.ha \ ensure.ha \ jmp.ha \ malloc.ha \ @@ -61,6 +87,7 @@ rt() { +test/ztos.ha fi gen_ssa -plinux rt + gen_ssa -pfreebsd rt cat <<EOF \$($cache)/rt/start.o: \$(STDLIB)/rt/+\$(PLATFORM)/start+\$(ARCH).s @printf 'AS \t\$@\n' @@ -103,8 +130,14 @@ ${stdlib}_asm=\$($cache)/rt/syscall.o \\ @printf 'AR\t\$@\n' @\$(AR) -csr \$@ \$($cache)/rt/rt-linux.o \$(${stdlib}_asm) +\$($cache)/rt/rt-freebsd.a: \$($cache)/rt/rt-freebsd.o \$(${stdlib}_asm) + @printf 'AR\t\$@\n' + @\$(AR) -csr \$@ \$($cache)/rt/rt-freebsd.o \$(${stdlib}_asm) + ${stdlib}_rt=\$($cache)/rt/rt-\$(PLATFORM).a -hare_${stdlib}_deps+=\$(${stdlib}_rt) +${stdlib}_deps_linux+=\$(${stdlib}_rt) +${stdlib}_deps_freebsd+=\$(${stdlib}_rt) +${stdlib}_deps_any+=\$(${stdlib}_rt) EOF } @@ -184,6 +217,11 @@ crypto_random() { +linux.ha \ random.ha gen_ssa -plinux crypto::random rt io errors + + gen_srcs -pfreebsd crypto::random \ + +freebsd.ha \ + random.ha + gen_ssa -pfreebsd crypto::random rt io errors } gensrcs_crypto_sha256() { @@ -557,6 +595,20 @@ gensrcs_io() { tee.ha \ types.ha \ $* + gen_srcs -pfreebsd io \ + 'arch+$(ARCH).ha' \ + println+freebsd.ha \ + +freebsd/file.ha \ + copy.ha \ + drain.ha \ + empty.ha \ + filestream.ha \ + handle.ha \ + limit.ha \ + stream.ha \ + tee.ha \ + types.ha \ + $* } io() { @@ -570,6 +622,7 @@ io() { +test/stream.ha fi gen_ssa -plinux io strings errors + gen_ssa -pfreebsd io strings errors } iobus_io_uring() { @@ -633,6 +686,12 @@ net() { errors.ha \ listener.ha gen_ssa -plinux net io os strings net::ip errors rt fmt + + gen_srcs -pfreebsd net \ + +freebsd.ha \ + errors.ha \ + listener.ha + gen_ssa -pfreebsd net io os strings net::ip errors rt fmt } net_dial() { @@ -658,8 +717,12 @@ net_dns() { gensrcs_net_ip() { gen_srcs -plinux net::ip \ - ip.ha \ +linux.ha \ + ip.ha \ + $* + gen_srcs -pfreebsd net::ip \ + +freebsd.ha \ + ip.ha \ $* } @@ -672,6 +735,7 @@ net_ip() { +test.ha fi gen_ssa -plinux net::ip bytes io strconv strings strio fmt + gen_ssa -pfreebsd net::ip bytes io strconv strings strio fmt } net_tcp() { @@ -680,6 +744,12 @@ net_tcp() { listener.ha \ options.ha gen_ssa -plinux net::tcp io net net::ip os rt + + gen_srcs -pfreebsd net::tcp \ + +freebsd.ha \ + listener.ha \ + options.ha + gen_ssa -pfreebsd net::tcp io net net::ip os rt } net_udp() { @@ -687,6 +757,11 @@ net_udp() { +linux.ha \ options.ha gen_ssa -plinux net::udp net net::ip errors rt os io + + gen_srcs -pfreebsd net::udp \ + +freebsd.ha \ + options.ha + gen_ssa -pfreebsd net::udp net net::ip errors rt os io } net_unix() { @@ -697,6 +772,14 @@ net_unix() { listener.ha \ options.ha gen_ssa -plinux net::unix net errors os io strings types fmt net::dial + + gen_srcs -pfreebsd net::unix \ + +freebsd.ha \ + addr.ha \ + dial.ha \ + listener.ha \ + options.ha + gen_ssa -pfreebsd net::unix net errors os io strings types fmt net::dial } math_random() { @@ -714,6 +797,15 @@ os() { +linux/fs.ha \ fs.ha gen_ssa -plinux os io strings types fs encoding::utf8 bytes bufio errors + + gen_srcs -pfreebsd os \ + +freebsd/environ.ha \ + +freebsd/exit.ha \ + +freebsd/dirfdfs.ha \ + +freebsd/stdfd.ha \ + +freebsd/fs.ha \ + fs.ha + gen_ssa -pfreebsd os io strings types fs encoding::utf8 bytes bufio errors } os_exec() { @@ -723,6 +815,13 @@ os_exec() { types.ha \ cmd.ha gen_ssa -plinux os::exec os strings fmt bytes path errors + + gen_srcs -pfreebsd os::exec \ + exec+freebsd.ha \ + process+freebsd.ha \ + types.ha \ + cmd.ha + gen_ssa -pfreebsd os::exec os strings fmt bytes path errors } path() { @@ -814,6 +913,10 @@ temp() { gen_srcs -plinux temp +linux.ha gen_ssa -plinux temp \ crypto::random encoding::hex fs io os path strio fmt strings + + gen_srcs -pfreebsd temp +freebsd.ha + gen_ssa -pfreebsd temp \ + crypto::random encoding::hex fs io os path strio fmt strings } time() { @@ -823,6 +926,11 @@ time() { arithm.ha \ types.ha gen_ssa -plinux time linux::vdso + gen_srcs -pfreebsd time \ + +freebsd/functions.ha \ + arithm.ha \ + types.ha + gen_ssa -pfreebsd time } gensrcs_types() { @@ -854,6 +962,14 @@ unix() { getuid.ha \ setuid.ha gen_ssa -plinux unix errors fs + + gen_srcs -pfreebsd unix \ + +freebsd/nice.ha \ + +freebsd/pipe.ha \ + +freebsd/umask.ha \ + getuid.ha \ + setuid.ha + gen_ssa -pfreebsd unix errors fs } unix_hosts() { @@ -873,6 +989,9 @@ unix_passwd() { unix_poll() { gen_srcs -plinux unix::poll +linux.ha gen_ssa -plinux unix::poll rt errors time + + gen_srcs -pfreebsd unix::poll +freebsd.ha + gen_ssa -pfreebsd unix::poll rt errors time } unix_resolvconf() { @@ -888,6 +1007,13 @@ unix_tty() { +linux/open.ha \ +linux/winsize.ha gen_ssa -plinux unix::tty rt fs io os + + gen_srcs -pfreebsd unix::tty \ + types.ha \ + +freebsd/isatty.ha \ + +freebsd/open.ha \ + +freebsd/winsize.ha + gen_ssa -pfreebsd unix::tty rt fs io os } uuid() { @@ -908,7 +1034,7 @@ compress::flate compress::zlib crypto::blake2b crypto::math -crypto::random linux +crypto::random linux freebsd crypto::md5 crypto::sha1 crypto::sha256 @@ -940,38 +1066,38 @@ hash::crc16 hash::crc32 hash::crc64 hash::fnv -io linux +io linux freebsd iobus::io_uring linux linux linux linux::signalfd linux linux::io_uring linux linux::vdso linux math -net linux +net linux freebsd net::dial net::dns -net::ip linux -net::tcp linux -net::udp linux -net::unix linux +net::ip linux freebsd +net::tcp linux freebsd +net::udp linux freebsd +net::unix linux freebsd math::random -os linux -os::exec linux +os linux freebsd +os::exec linux freebsd path slice sort strconv strings strio -temp linux -time linux +temp linux freebsd +time linux freebsd types -unix linux +unix linux freebsd unix::hosts unix::passwd -unix::poll linux +unix::poll linux freebsd unix::resolvconf -unix::tty linux +unix::tty linux freebsd uuid" stdlib() { rt diff --git a/scripts/gen-stdlib.sh b/scripts/gen-stdlib.sh @@ -5,7 +5,7 @@ mod_file() { printf '%s\n' "$1" | tr -s '::' '_' } mod_var() { - printf '%s_%s\n' "$stdlib" "$1" | tr -s '::' '_' + printf '%s_%s_%s\n' "$stdlib" "$1" "$2" | tr -s '::' '_' } gen_srcs() { @@ -28,10 +28,10 @@ gen_srcs() { shift path="$(mod_path "$mod")" - var="$(mod_var "$mod")" + var="$(mod_var "$mod" "$platform")" printf '# %s (+%s)\n' "$mod" "$platform" - printf '%s_%s_srcs= \\\n' "$var" "$platform" + printf '%s_srcs= \\\n' "$var" while [ $# -ne 0 ] do if [ $# -eq 1 ] @@ -65,12 +65,12 @@ gen_ssa() { path=$(mod_path "$mod") file=$(mod_file "$mod") - var=$(mod_var "$mod") + var=$(mod_var "$mod" "$platform") - printf "\$($cache)/$path/$file-$platform.ssa: \$(${var}_${platform}_srcs) \$(${stdlib}_rt)" + printf "\$($cache)/$path/$file-$platform.ssa: \$(${var}_srcs) \$(${stdlib}_rt)" for dep in $* do - printf ' $(%s)' "$(mod_var "$dep")" + printf ' $(%s)' "$(mod_var "$dep" \$"(PLATFORM)")" done printf '\n' @@ -78,7 +78,7 @@ gen_ssa() { @printf 'HAREC \t\$@\n' @mkdir -p \$($cache)/$path @HARECACHE=\$($cache) \$(HAREC) \$($flags) -o \$@ -N$mod \\ - -t\$($cache)/$path/$file.td \$(${var}_${platform}_srcs) + -t\$($cache)/$path/$file.td \$(${var}_srcs) EOF } @@ -104,9 +104,17 @@ gen_lib() { mod="$1" path=$(mod_path "$mod") file=$(mod_file "$mod") - var=$(mod_var "$mod") + var=$(mod_var "$mod" "$platform") printf "%s=\$(%s)/%s/%s-%s.o\n" "$var" "$cache" "$path" "$file" "$platform" - printf 'hare_%s_deps+=$(%s)\n\n' "$stdlib" "$var" + printf '%s_deps_%s+=$(%s)\n' "$stdlib" "$platform" "$var" + if [ "$platform" = "any" ] + then + for p in $all_platforms + do + printf '%s=$(%s)\n' "$(mod_var "$mod" "$p")" "$var" + done + fi + printf '\n' } genrules() { diff --git a/scripts/platform b/scripts/platform @@ -4,6 +4,9 @@ case $(uname) in Linux) platform="linux" ;; + FreeBSD) + platform="freebsd" + ;; *) printf "Warning: unknown target %s\n" "$(uname)" >&2 platform="unknown" diff --git a/stdlib.mk b/stdlib.mk @@ -30,12 +30,44 @@ stdlib_rt_linux_srcs= \ $(STDLIB)/rt/abort.ha \ $(STDLIB)/rt/start.ha +# rt (+freebsd) +stdlib_rt_freebsd_srcs= \ + $(STDLIB)/rt/+freebsd/abort.ha \ + $(STDLIB)/rt/+freebsd/env.ha \ + $(STDLIB)/rt/+freebsd/errno.ha \ + $(STDLIB)/rt/+freebsd/platformstart.ha \ + $(STDLIB)/rt/+freebsd/segmalloc.ha \ + $(STDLIB)/rt/+freebsd/signal.ha \ + $(STDLIB)/rt/+freebsd/socket.ha \ + $(STDLIB)/rt/+freebsd/syscallno.ha \ + $(STDLIB)/rt/+freebsd/syscalls.ha \ + $(STDLIB)/rt/+freebsd/types.ha \ + $(STDLIB)/rt/+$(ARCH)/jmp.ha \ + $(STDLIB)/rt/+$(ARCH)/backtrace.ha \ + $(STDLIB)/rt/types_arch+$(ARCH).ha \ + $(STDLIB)/rt/ensure.ha \ + $(STDLIB)/rt/jmp.ha \ + $(STDLIB)/rt/malloc.ha \ + $(STDLIB)/rt/memcpy.ha \ + $(STDLIB)/rt/memmove.ha \ + $(STDLIB)/rt/memset.ha \ + $(STDLIB)/rt/strcmp.ha \ + $(STDLIB)/rt/types.ha \ + $(STDLIB)/rt/abort.ha \ + $(STDLIB)/rt/start.ha + $(HARECACHE)/rt/rt-linux.ssa: $(stdlib_rt_linux_srcs) $(stdlib_rt) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/rt @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nrt \ -t$(HARECACHE)/rt/rt.td $(stdlib_rt_linux_srcs) +$(HARECACHE)/rt/rt-freebsd.ssa: $(stdlib_rt_freebsd_srcs) $(stdlib_rt) + @printf 'HAREC \t$@\n' + @mkdir -p $(HARECACHE)/rt + @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nrt \ + -t$(HARECACHE)/rt/rt.td $(stdlib_rt_freebsd_srcs) + $(HARECACHE)/rt/start.o: $(STDLIB)/rt/+$(PLATFORM)/start+$(ARCH).s @printf 'AS \t$@\n' @mkdir -p $(HARECACHE)/rt @@ -77,303 +109,471 @@ $(HARECACHE)/rt/rt-linux.a: $(HARECACHE)/rt/rt-linux.o $(stdlib_asm) @printf 'AR\t$@\n' @$(AR) -csr $@ $(HARECACHE)/rt/rt-linux.o $(stdlib_asm) +$(HARECACHE)/rt/rt-freebsd.a: $(HARECACHE)/rt/rt-freebsd.o $(stdlib_asm) + @printf 'AR\t$@\n' + @$(AR) -csr $@ $(HARECACHE)/rt/rt-freebsd.o $(stdlib_asm) + stdlib_rt=$(HARECACHE)/rt/rt-$(PLATFORM).a -hare_stdlib_deps+=$(stdlib_rt) +stdlib_deps_linux+=$(stdlib_rt) +stdlib_deps_freebsd+=$(stdlib_rt) +stdlib_deps_any+=$(stdlib_rt) # gen_lib ascii (any) -stdlib_ascii=$(HARECACHE)/ascii/ascii-any.o -hare_stdlib_deps+=$(stdlib_ascii) +stdlib_ascii_any=$(HARECACHE)/ascii/ascii-any.o +stdlib_deps_any+=$(stdlib_ascii_any) +stdlib_ascii_linux=$(stdlib_ascii_any) +stdlib_ascii_freebsd=$(stdlib_ascii_any) # gen_lib bufio (any) -stdlib_bufio=$(HARECACHE)/bufio/bufio-any.o -hare_stdlib_deps+=$(stdlib_bufio) +stdlib_bufio_any=$(HARECACHE)/bufio/bufio-any.o +stdlib_deps_any+=$(stdlib_bufio_any) +stdlib_bufio_linux=$(stdlib_bufio_any) +stdlib_bufio_freebsd=$(stdlib_bufio_any) # gen_lib bytes (any) -stdlib_bytes=$(HARECACHE)/bytes/bytes-any.o -hare_stdlib_deps+=$(stdlib_bytes) +stdlib_bytes_any=$(HARECACHE)/bytes/bytes-any.o +stdlib_deps_any+=$(stdlib_bytes_any) +stdlib_bytes_linux=$(stdlib_bytes_any) +stdlib_bytes_freebsd=$(stdlib_bytes_any) # gen_lib compress::flate (any) -stdlib_compress_flate=$(HARECACHE)/compress/flate/compress_flate-any.o -hare_stdlib_deps+=$(stdlib_compress_flate) +stdlib_compress_flate_any=$(HARECACHE)/compress/flate/compress_flate-any.o +stdlib_deps_any+=$(stdlib_compress_flate_any) +stdlib_compress_flate_linux=$(stdlib_compress_flate_any) +stdlib_compress_flate_freebsd=$(stdlib_compress_flate_any) # gen_lib compress::zlib (any) -stdlib_compress_zlib=$(HARECACHE)/compress/zlib/compress_zlib-any.o -hare_stdlib_deps+=$(stdlib_compress_zlib) +stdlib_compress_zlib_any=$(HARECACHE)/compress/zlib/compress_zlib-any.o +stdlib_deps_any+=$(stdlib_compress_zlib_any) +stdlib_compress_zlib_linux=$(stdlib_compress_zlib_any) +stdlib_compress_zlib_freebsd=$(stdlib_compress_zlib_any) # gen_lib crypto::blake2b (any) -stdlib_crypto_blake2b=$(HARECACHE)/crypto/blake2b/crypto_blake2b-any.o -hare_stdlib_deps+=$(stdlib_crypto_blake2b) +stdlib_crypto_blake2b_any=$(HARECACHE)/crypto/blake2b/crypto_blake2b-any.o +stdlib_deps_any+=$(stdlib_crypto_blake2b_any) +stdlib_crypto_blake2b_linux=$(stdlib_crypto_blake2b_any) +stdlib_crypto_blake2b_freebsd=$(stdlib_crypto_blake2b_any) # gen_lib crypto::math (any) -stdlib_crypto_math=$(HARECACHE)/crypto/math/crypto_math-any.o -hare_stdlib_deps+=$(stdlib_crypto_math) +stdlib_crypto_math_any=$(HARECACHE)/crypto/math/crypto_math-any.o +stdlib_deps_any+=$(stdlib_crypto_math_any) +stdlib_crypto_math_linux=$(stdlib_crypto_math_any) +stdlib_crypto_math_freebsd=$(stdlib_crypto_math_any) # gen_lib crypto::random (linux) -stdlib_crypto_random=$(HARECACHE)/crypto/random/crypto_random-linux.o -hare_stdlib_deps+=$(stdlib_crypto_random) +stdlib_crypto_random_linux=$(HARECACHE)/crypto/random/crypto_random-linux.o +stdlib_deps_linux+=$(stdlib_crypto_random_linux) + +# gen_lib crypto::random (freebsd) +stdlib_crypto_random_freebsd=$(HARECACHE)/crypto/random/crypto_random-freebsd.o +stdlib_deps_freebsd+=$(stdlib_crypto_random_freebsd) # gen_lib crypto::md5 (any) -stdlib_crypto_md5=$(HARECACHE)/crypto/md5/crypto_md5-any.o -hare_stdlib_deps+=$(stdlib_crypto_md5) +stdlib_crypto_md5_any=$(HARECACHE)/crypto/md5/crypto_md5-any.o +stdlib_deps_any+=$(stdlib_crypto_md5_any) +stdlib_crypto_md5_linux=$(stdlib_crypto_md5_any) +stdlib_crypto_md5_freebsd=$(stdlib_crypto_md5_any) # gen_lib crypto::sha1 (any) -stdlib_crypto_sha1=$(HARECACHE)/crypto/sha1/crypto_sha1-any.o -hare_stdlib_deps+=$(stdlib_crypto_sha1) +stdlib_crypto_sha1_any=$(HARECACHE)/crypto/sha1/crypto_sha1-any.o +stdlib_deps_any+=$(stdlib_crypto_sha1_any) +stdlib_crypto_sha1_linux=$(stdlib_crypto_sha1_any) +stdlib_crypto_sha1_freebsd=$(stdlib_crypto_sha1_any) # gen_lib crypto::sha256 (any) -stdlib_crypto_sha256=$(HARECACHE)/crypto/sha256/crypto_sha256-any.o -hare_stdlib_deps+=$(stdlib_crypto_sha256) +stdlib_crypto_sha256_any=$(HARECACHE)/crypto/sha256/crypto_sha256-any.o +stdlib_deps_any+=$(stdlib_crypto_sha256_any) +stdlib_crypto_sha256_linux=$(stdlib_crypto_sha256_any) +stdlib_crypto_sha256_freebsd=$(stdlib_crypto_sha256_any) # gen_lib crypto::sha512 (any) -stdlib_crypto_sha512=$(HARECACHE)/crypto/sha512/crypto_sha512-any.o -hare_stdlib_deps+=$(stdlib_crypto_sha512) +stdlib_crypto_sha512_any=$(HARECACHE)/crypto/sha512/crypto_sha512-any.o +stdlib_deps_any+=$(stdlib_crypto_sha512_any) +stdlib_crypto_sha512_linux=$(stdlib_crypto_sha512_any) +stdlib_crypto_sha512_freebsd=$(stdlib_crypto_sha512_any) # gen_lib dirs (any) -stdlib_dirs=$(HARECACHE)/dirs/dirs-any.o -hare_stdlib_deps+=$(stdlib_dirs) +stdlib_dirs_any=$(HARECACHE)/dirs/dirs-any.o +stdlib_deps_any+=$(stdlib_dirs_any) +stdlib_dirs_linux=$(stdlib_dirs_any) +stdlib_dirs_freebsd=$(stdlib_dirs_any) # gen_lib encoding::base64 (any) -stdlib_encoding_base64=$(HARECACHE)/encoding/base64/encoding_base64-any.o -hare_stdlib_deps+=$(stdlib_encoding_base64) +stdlib_encoding_base64_any=$(HARECACHE)/encoding/base64/encoding_base64-any.o +stdlib_deps_any+=$(stdlib_encoding_base64_any) +stdlib_encoding_base64_linux=$(stdlib_encoding_base64_any) +stdlib_encoding_base64_freebsd=$(stdlib_encoding_base64_any) # gen_lib encoding::hex (any) -stdlib_encoding_hex=$(HARECACHE)/encoding/hex/encoding_hex-any.o -hare_stdlib_deps+=$(stdlib_encoding_hex) +stdlib_encoding_hex_any=$(HARECACHE)/encoding/hex/encoding_hex-any.o +stdlib_deps_any+=$(stdlib_encoding_hex_any) +stdlib_encoding_hex_linux=$(stdlib_encoding_hex_any) +stdlib_encoding_hex_freebsd=$(stdlib_encoding_hex_any) # gen_lib encoding::utf8 (any) -stdlib_encoding_utf8=$(HARECACHE)/encoding/utf8/encoding_utf8-any.o -hare_stdlib_deps+=$(stdlib_encoding_utf8) +stdlib_encoding_utf8_any=$(HARECACHE)/encoding/utf8/encoding_utf8-any.o +stdlib_deps_any+=$(stdlib_encoding_utf8_any) +stdlib_encoding_utf8_linux=$(stdlib_encoding_utf8_any) +stdlib_encoding_utf8_freebsd=$(stdlib_encoding_utf8_any) # gen_lib endian (any) -stdlib_endian=$(HARECACHE)/endian/endian-any.o -hare_stdlib_deps+=$(stdlib_endian) +stdlib_endian_any=$(HARECACHE)/endian/endian-any.o +stdlib_deps_any+=$(stdlib_endian_any) +stdlib_endian_linux=$(stdlib_endian_any) +stdlib_endian_freebsd=$(stdlib_endian_any) # gen_lib errors (any) -stdlib_errors=$(HARECACHE)/errors/errors-any.o -hare_stdlib_deps+=$(stdlib_errors) +stdlib_errors_any=$(HARECACHE)/errors/errors-any.o +stdlib_deps_any+=$(stdlib_errors_any) +stdlib_errors_linux=$(stdlib_errors_any) +stdlib_errors_freebsd=$(stdlib_errors_any) # gen_lib fmt (any) -stdlib_fmt=$(HARECACHE)/fmt/fmt-any.o -hare_stdlib_deps+=$(stdlib_fmt) +stdlib_fmt_any=$(HARECACHE)/fmt/fmt-any.o +stdlib_deps_any+=$(stdlib_fmt_any) +stdlib_fmt_linux=$(stdlib_fmt_any) +stdlib_fmt_freebsd=$(stdlib_fmt_any) # gen_lib fnmatch (any) -stdlib_fnmatch=$(HARECACHE)/fnmatch/fnmatch-any.o -hare_stdlib_deps+=$(stdlib_fnmatch) +stdlib_fnmatch_any=$(HARECACHE)/fnmatch/fnmatch-any.o +stdlib_deps_any+=$(stdlib_fnmatch_any) +stdlib_fnmatch_linux=$(stdlib_fnmatch_any) +stdlib_fnmatch_freebsd=$(stdlib_fnmatch_any) # gen_lib format::elf (any) -stdlib_format_elf=$(HARECACHE)/format/elf/format_elf-any.o -hare_stdlib_deps+=$(stdlib_format_elf) +stdlib_format_elf_any=$(HARECACHE)/format/elf/format_elf-any.o +stdlib_deps_any+=$(stdlib_format_elf_any) +stdlib_format_elf_linux=$(stdlib_format_elf_any) +stdlib_format_elf_freebsd=$(stdlib_format_elf_any) # gen_lib format::ini (any) -stdlib_format_ini=$(HARECACHE)/format/ini/format_ini-any.o -hare_stdlib_deps+=$(stdlib_format_ini) +stdlib_format_ini_any=$(HARECACHE)/format/ini/format_ini-any.o +stdlib_deps_any+=$(stdlib_format_ini_any) +stdlib_format_ini_linux=$(stdlib_format_ini_any) +stdlib_format_ini_freebsd=$(stdlib_format_ini_any) # gen_lib format::xml (any) -stdlib_format_xml=$(HARECACHE)/format/xml/format_xml-any.o -hare_stdlib_deps+=$(stdlib_format_xml) +stdlib_format_xml_any=$(HARECACHE)/format/xml/format_xml-any.o +stdlib_deps_any+=$(stdlib_format_xml_any) +stdlib_format_xml_linux=$(stdlib_format_xml_any) +stdlib_format_xml_freebsd=$(stdlib_format_xml_any) # gen_lib fs (any) -stdlib_fs=$(HARECACHE)/fs/fs-any.o -hare_stdlib_deps+=$(stdlib_fs) +stdlib_fs_any=$(HARECACHE)/fs/fs-any.o +stdlib_deps_any+=$(stdlib_fs_any) +stdlib_fs_linux=$(stdlib_fs_any) +stdlib_fs_freebsd=$(stdlib_fs_any) # gen_lib fs::mem (any) -stdlib_fs_mem=$(HARECACHE)/fs/mem/fs_mem-any.o -hare_stdlib_deps+=$(stdlib_fs_mem) +stdlib_fs_mem_any=$(HARECACHE)/fs/mem/fs_mem-any.o +stdlib_deps_any+=$(stdlib_fs_mem_any) +stdlib_fs_mem_linux=$(stdlib_fs_mem_any) +stdlib_fs_mem_freebsd=$(stdlib_fs_mem_any) # gen_lib getopt (any) -stdlib_getopt=$(HARECACHE)/getopt/getopt-any.o -hare_stdlib_deps+=$(stdlib_getopt) +stdlib_getopt_any=$(HARECACHE)/getopt/getopt-any.o +stdlib_deps_any+=$(stdlib_getopt_any) +stdlib_getopt_linux=$(stdlib_getopt_any) +stdlib_getopt_freebsd=$(stdlib_getopt_any) # gen_lib hare::ast (any) -stdlib_hare_ast=$(HARECACHE)/hare/ast/hare_ast-any.o -hare_stdlib_deps+=$(stdlib_hare_ast) +stdlib_hare_ast_any=$(HARECACHE)/hare/ast/hare_ast-any.o +stdlib_deps_any+=$(stdlib_hare_ast_any) +stdlib_hare_ast_linux=$(stdlib_hare_ast_any) +stdlib_hare_ast_freebsd=$(stdlib_hare_ast_any) # gen_lib hare::lex (any) -stdlib_hare_lex=$(HARECACHE)/hare/lex/hare_lex-any.o -hare_stdlib_deps+=$(stdlib_hare_lex) +stdlib_hare_lex_any=$(HARECACHE)/hare/lex/hare_lex-any.o +stdlib_deps_any+=$(stdlib_hare_lex_any) +stdlib_hare_lex_linux=$(stdlib_hare_lex_any) +stdlib_hare_lex_freebsd=$(stdlib_hare_lex_any) # gen_lib hare::module (any) -stdlib_hare_module=$(HARECACHE)/hare/module/hare_module-any.o -hare_stdlib_deps+=$(stdlib_hare_module) +stdlib_hare_module_any=$(HARECACHE)/hare/module/hare_module-any.o +stdlib_deps_any+=$(stdlib_hare_module_any) +stdlib_hare_module_linux=$(stdlib_hare_module_any) +stdlib_hare_module_freebsd=$(stdlib_hare_module_any) # gen_lib hare::parse (any) -stdlib_hare_parse=$(HARECACHE)/hare/parse/hare_parse-any.o -hare_stdlib_deps+=$(stdlib_hare_parse) +stdlib_hare_parse_any=$(HARECACHE)/hare/parse/hare_parse-any.o +stdlib_deps_any+=$(stdlib_hare_parse_any) +stdlib_hare_parse_linux=$(stdlib_hare_parse_any) +stdlib_hare_parse_freebsd=$(stdlib_hare_parse_any) # gen_lib hare::types (any) -stdlib_hare_types=$(HARECACHE)/hare/types/hare_types-any.o -hare_stdlib_deps+=$(stdlib_hare_types) +stdlib_hare_types_any=$(HARECACHE)/hare/types/hare_types-any.o +stdlib_deps_any+=$(stdlib_hare_types_any) +stdlib_hare_types_linux=$(stdlib_hare_types_any) +stdlib_hare_types_freebsd=$(stdlib_hare_types_any) # gen_lib hare::unit (any) -stdlib_hare_unit=$(HARECACHE)/hare/unit/hare_unit-any.o -hare_stdlib_deps+=$(stdlib_hare_unit) +stdlib_hare_unit_any=$(HARECACHE)/hare/unit/hare_unit-any.o +stdlib_deps_any+=$(stdlib_hare_unit_any) +stdlib_hare_unit_linux=$(stdlib_hare_unit_any) +stdlib_hare_unit_freebsd=$(stdlib_hare_unit_any) # gen_lib hare::unparse (any) -stdlib_hare_unparse=$(HARECACHE)/hare/unparse/hare_unparse-any.o -hare_stdlib_deps+=$(stdlib_hare_unparse) +stdlib_hare_unparse_any=$(HARECACHE)/hare/unparse/hare_unparse-any.o +stdlib_deps_any+=$(stdlib_hare_unparse_any) +stdlib_hare_unparse_linux=$(stdlib_hare_unparse_any) +stdlib_hare_unparse_freebsd=$(stdlib_hare_unparse_any) # gen_lib hash (any) -stdlib_hash=$(HARECACHE)/hash/hash-any.o -hare_stdlib_deps+=$(stdlib_hash) +stdlib_hash_any=$(HARECACHE)/hash/hash-any.o +stdlib_deps_any+=$(stdlib_hash_any) +stdlib_hash_linux=$(stdlib_hash_any) +stdlib_hash_freebsd=$(stdlib_hash_any) # gen_lib hash::adler32 (any) -stdlib_hash_adler32=$(HARECACHE)/hash/adler32/hash_adler32-any.o -hare_stdlib_deps+=$(stdlib_hash_adler32) +stdlib_hash_adler32_any=$(HARECACHE)/hash/adler32/hash_adler32-any.o +stdlib_deps_any+=$(stdlib_hash_adler32_any) +stdlib_hash_adler32_linux=$(stdlib_hash_adler32_any) +stdlib_hash_adler32_freebsd=$(stdlib_hash_adler32_any) # gen_lib hash::crc16 (any) -stdlib_hash_crc16=$(HARECACHE)/hash/crc16/hash_crc16-any.o -hare_stdlib_deps+=$(stdlib_hash_crc16) +stdlib_hash_crc16_any=$(HARECACHE)/hash/crc16/hash_crc16-any.o +stdlib_deps_any+=$(stdlib_hash_crc16_any) +stdlib_hash_crc16_linux=$(stdlib_hash_crc16_any) +stdlib_hash_crc16_freebsd=$(stdlib_hash_crc16_any) # gen_lib hash::crc32 (any) -stdlib_hash_crc32=$(HARECACHE)/hash/crc32/hash_crc32-any.o -hare_stdlib_deps+=$(stdlib_hash_crc32) +stdlib_hash_crc32_any=$(HARECACHE)/hash/crc32/hash_crc32-any.o +stdlib_deps_any+=$(stdlib_hash_crc32_any) +stdlib_hash_crc32_linux=$(stdlib_hash_crc32_any) +stdlib_hash_crc32_freebsd=$(stdlib_hash_crc32_any) # gen_lib hash::crc64 (any) -stdlib_hash_crc64=$(HARECACHE)/hash/crc64/hash_crc64-any.o -hare_stdlib_deps+=$(stdlib_hash_crc64) +stdlib_hash_crc64_any=$(HARECACHE)/hash/crc64/hash_crc64-any.o +stdlib_deps_any+=$(stdlib_hash_crc64_any) +stdlib_hash_crc64_linux=$(stdlib_hash_crc64_any) +stdlib_hash_crc64_freebsd=$(stdlib_hash_crc64_any) # gen_lib hash::fnv (any) -stdlib_hash_fnv=$(HARECACHE)/hash/fnv/hash_fnv-any.o -hare_stdlib_deps+=$(stdlib_hash_fnv) +stdlib_hash_fnv_any=$(HARECACHE)/hash/fnv/hash_fnv-any.o +stdlib_deps_any+=$(stdlib_hash_fnv_any) +stdlib_hash_fnv_linux=$(stdlib_hash_fnv_any) +stdlib_hash_fnv_freebsd=$(stdlib_hash_fnv_any) # gen_lib io (linux) -stdlib_io=$(HARECACHE)/io/io-linux.o -hare_stdlib_deps+=$(stdlib_io) +stdlib_io_linux=$(HARECACHE)/io/io-linux.o +stdlib_deps_linux+=$(stdlib_io_linux) + +# gen_lib io (freebsd) +stdlib_io_freebsd=$(HARECACHE)/io/io-freebsd.o +stdlib_deps_freebsd+=$(stdlib_io_freebsd) # gen_lib iobus::io_uring (linux) -stdlib_iobus_io_uring=$(HARECACHE)/iobus/io_uring/iobus_io_uring-linux.o -hare_stdlib_deps+=$(stdlib_iobus_io_uring) +stdlib_iobus_io_uring_linux=$(HARECACHE)/iobus/io_uring/iobus_io_uring-linux.o +stdlib_deps_linux+=$(stdlib_iobus_io_uring_linux) # gen_lib linux (linux) -stdlib_linux=$(HARECACHE)/linux/linux-linux.o -hare_stdlib_deps+=$(stdlib_linux) +stdlib_linux_linux=$(HARECACHE)/linux/linux-linux.o +stdlib_deps_linux+=$(stdlib_linux_linux) # gen_lib linux::signalfd (linux) -stdlib_linux_signalfd=$(HARECACHE)/linux/signalfd/linux_signalfd-linux.o -hare_stdlib_deps+=$(stdlib_linux_signalfd) +stdlib_linux_signalfd_linux=$(HARECACHE)/linux/signalfd/linux_signalfd-linux.o +stdlib_deps_linux+=$(stdlib_linux_signalfd_linux) # gen_lib linux::io_uring (linux) -stdlib_linux_io_uring=$(HARECACHE)/linux/io_uring/linux_io_uring-linux.o -hare_stdlib_deps+=$(stdlib_linux_io_uring) +stdlib_linux_io_uring_linux=$(HARECACHE)/linux/io_uring/linux_io_uring-linux.o +stdlib_deps_linux+=$(stdlib_linux_io_uring_linux) # gen_lib linux::vdso (linux) -stdlib_linux_vdso=$(HARECACHE)/linux/vdso/linux_vdso-linux.o -hare_stdlib_deps+=$(stdlib_linux_vdso) +stdlib_linux_vdso_linux=$(HARECACHE)/linux/vdso/linux_vdso-linux.o +stdlib_deps_linux+=$(stdlib_linux_vdso_linux) # gen_lib math (any) -stdlib_math=$(HARECACHE)/math/math-any.o -hare_stdlib_deps+=$(stdlib_math) +stdlib_math_any=$(HARECACHE)/math/math-any.o +stdlib_deps_any+=$(stdlib_math_any) +stdlib_math_linux=$(stdlib_math_any) +stdlib_math_freebsd=$(stdlib_math_any) # gen_lib net (linux) -stdlib_net=$(HARECACHE)/net/net-linux.o -hare_stdlib_deps+=$(stdlib_net) +stdlib_net_linux=$(HARECACHE)/net/net-linux.o +stdlib_deps_linux+=$(stdlib_net_linux) + +# gen_lib net (freebsd) +stdlib_net_freebsd=$(HARECACHE)/net/net-freebsd.o +stdlib_deps_freebsd+=$(stdlib_net_freebsd) # gen_lib net::dial (any) -stdlib_net_dial=$(HARECACHE)/net/dial/net_dial-any.o -hare_stdlib_deps+=$(stdlib_net_dial) +stdlib_net_dial_any=$(HARECACHE)/net/dial/net_dial-any.o +stdlib_deps_any+=$(stdlib_net_dial_any) +stdlib_net_dial_linux=$(stdlib_net_dial_any) +stdlib_net_dial_freebsd=$(stdlib_net_dial_any) # gen_lib net::dns (any) -stdlib_net_dns=$(HARECACHE)/net/dns/net_dns-any.o -hare_stdlib_deps+=$(stdlib_net_dns) +stdlib_net_dns_any=$(HARECACHE)/net/dns/net_dns-any.o +stdlib_deps_any+=$(stdlib_net_dns_any) +stdlib_net_dns_linux=$(stdlib_net_dns_any) +stdlib_net_dns_freebsd=$(stdlib_net_dns_any) # gen_lib net::ip (linux) -stdlib_net_ip=$(HARECACHE)/net/ip/net_ip-linux.o -hare_stdlib_deps+=$(stdlib_net_ip) +stdlib_net_ip_linux=$(HARECACHE)/net/ip/net_ip-linux.o +stdlib_deps_linux+=$(stdlib_net_ip_linux) + +# gen_lib net::ip (freebsd) +stdlib_net_ip_freebsd=$(HARECACHE)/net/ip/net_ip-freebsd.o +stdlib_deps_freebsd+=$(stdlib_net_ip_freebsd) # gen_lib net::tcp (linux) -stdlib_net_tcp=$(HARECACHE)/net/tcp/net_tcp-linux.o -hare_stdlib_deps+=$(stdlib_net_tcp) +stdlib_net_tcp_linux=$(HARECACHE)/net/tcp/net_tcp-linux.o +stdlib_deps_linux+=$(stdlib_net_tcp_linux) + +# gen_lib net::tcp (freebsd) +stdlib_net_tcp_freebsd=$(HARECACHE)/net/tcp/net_tcp-freebsd.o +stdlib_deps_freebsd+=$(stdlib_net_tcp_freebsd) # gen_lib net::udp (linux) -stdlib_net_udp=$(HARECACHE)/net/udp/net_udp-linux.o -hare_stdlib_deps+=$(stdlib_net_udp) +stdlib_net_udp_linux=$(HARECACHE)/net/udp/net_udp-linux.o +stdlib_deps_linux+=$(stdlib_net_udp_linux) + +# gen_lib net::udp (freebsd) +stdlib_net_udp_freebsd=$(HARECACHE)/net/udp/net_udp-freebsd.o +stdlib_deps_freebsd+=$(stdlib_net_udp_freebsd) # gen_lib net::unix (linux) -stdlib_net_unix=$(HARECACHE)/net/unix/net_unix-linux.o -hare_stdlib_deps+=$(stdlib_net_unix) +stdlib_net_unix_linux=$(HARECACHE)/net/unix/net_unix-linux.o +stdlib_deps_linux+=$(stdlib_net_unix_linux) + +# gen_lib net::unix (freebsd) +stdlib_net_unix_freebsd=$(HARECACHE)/net/unix/net_unix-freebsd.o +stdlib_deps_freebsd+=$(stdlib_net_unix_freebsd) # gen_lib math::random (any) -stdlib_math_random=$(HARECACHE)/math/random/math_random-any.o -hare_stdlib_deps+=$(stdlib_math_random) +stdlib_math_random_any=$(HARECACHE)/math/random/math_random-any.o +stdlib_deps_any+=$(stdlib_math_random_any) +stdlib_math_random_linux=$(stdlib_math_random_any) +stdlib_math_random_freebsd=$(stdlib_math_random_any) # gen_lib os (linux) -stdlib_os=$(HARECACHE)/os/os-linux.o -hare_stdlib_deps+=$(stdlib_os) +stdlib_os_linux=$(HARECACHE)/os/os-linux.o +stdlib_deps_linux+=$(stdlib_os_linux) + +# gen_lib os (freebsd) +stdlib_os_freebsd=$(HARECACHE)/os/os-freebsd.o +stdlib_deps_freebsd+=$(stdlib_os_freebsd) # gen_lib os::exec (linux) -stdlib_os_exec=$(HARECACHE)/os/exec/os_exec-linux.o -hare_stdlib_deps+=$(stdlib_os_exec) +stdlib_os_exec_linux=$(HARECACHE)/os/exec/os_exec-linux.o +stdlib_deps_linux+=$(stdlib_os_exec_linux) + +# gen_lib os::exec (freebsd) +stdlib_os_exec_freebsd=$(HARECACHE)/os/exec/os_exec-freebsd.o +stdlib_deps_freebsd+=$(stdlib_os_exec_freebsd) # gen_lib path (any) -stdlib_path=$(HARECACHE)/path/path-any.o -hare_stdlib_deps+=$(stdlib_path) +stdlib_path_any=$(HARECACHE)/path/path-any.o +stdlib_deps_any+=$(stdlib_path_any) +stdlib_path_linux=$(stdlib_path_any) +stdlib_path_freebsd=$(stdlib_path_any) # gen_lib slice (any) -stdlib_slice=$(HARECACHE)/slice/slice-any.o -hare_stdlib_deps+=$(stdlib_slice) +stdlib_slice_any=$(HARECACHE)/slice/slice-any.o +stdlib_deps_any+=$(stdlib_slice_any) +stdlib_slice_linux=$(stdlib_slice_any) +stdlib_slice_freebsd=$(stdlib_slice_any) # gen_lib sort (any) -stdlib_sort=$(HARECACHE)/sort/sort-any.o -hare_stdlib_deps+=$(stdlib_sort) +stdlib_sort_any=$(HARECACHE)/sort/sort-any.o +stdlib_deps_any+=$(stdlib_sort_any) +stdlib_sort_linux=$(stdlib_sort_any) +stdlib_sort_freebsd=$(stdlib_sort_any) # gen_lib strconv (any) -stdlib_strconv=$(HARECACHE)/strconv/strconv-any.o -hare_stdlib_deps+=$(stdlib_strconv) +stdlib_strconv_any=$(HARECACHE)/strconv/strconv-any.o +stdlib_deps_any+=$(stdlib_strconv_any) +stdlib_strconv_linux=$(stdlib_strconv_any) +stdlib_strconv_freebsd=$(stdlib_strconv_any) # gen_lib strings (any) -stdlib_strings=$(HARECACHE)/strings/strings-any.o -hare_stdlib_deps+=$(stdlib_strings) +stdlib_strings_any=$(HARECACHE)/strings/strings-any.o +stdlib_deps_any+=$(stdlib_strings_any) +stdlib_strings_linux=$(stdlib_strings_any) +stdlib_strings_freebsd=$(stdlib_strings_any) # gen_lib strio (any) -stdlib_strio=$(HARECACHE)/strio/strio-any.o -hare_stdlib_deps+=$(stdlib_strio) +stdlib_strio_any=$(HARECACHE)/strio/strio-any.o +stdlib_deps_any+=$(stdlib_strio_any) +stdlib_strio_linux=$(stdlib_strio_any) +stdlib_strio_freebsd=$(stdlib_strio_any) # gen_lib temp (linux) -stdlib_temp=$(HARECACHE)/temp/temp-linux.o -hare_stdlib_deps+=$(stdlib_temp) +stdlib_temp_linux=$(HARECACHE)/temp/temp-linux.o +stdlib_deps_linux+=$(stdlib_temp_linux) + +# gen_lib temp (freebsd) +stdlib_temp_freebsd=$(HARECACHE)/temp/temp-freebsd.o +stdlib_deps_freebsd+=$(stdlib_temp_freebsd) # gen_lib time (linux) -stdlib_time=$(HARECACHE)/time/time-linux.o -hare_stdlib_deps+=$(stdlib_time) +stdlib_time_linux=$(HARECACHE)/time/time-linux.o +stdlib_deps_linux+=$(stdlib_time_linux) + +# gen_lib time (freebsd) +stdlib_time_freebsd=$(HARECACHE)/time/time-freebsd.o +stdlib_deps_freebsd+=$(stdlib_time_freebsd) # gen_lib types (any) -stdlib_types=$(HARECACHE)/types/types-any.o -hare_stdlib_deps+=$(stdlib_types) +stdlib_types_any=$(HARECACHE)/types/types-any.o +stdlib_deps_any+=$(stdlib_types_any) +stdlib_types_linux=$(stdlib_types_any) +stdlib_types_freebsd=$(stdlib_types_any) # gen_lib unix (linux) -stdlib_unix=$(HARECACHE)/unix/unix-linux.o -hare_stdlib_deps+=$(stdlib_unix) +stdlib_unix_linux=$(HARECACHE)/unix/unix-linux.o +stdlib_deps_linux+=$(stdlib_unix_linux) + +# gen_lib unix (freebsd) +stdlib_unix_freebsd=$(HARECACHE)/unix/unix-freebsd.o +stdlib_deps_freebsd+=$(stdlib_unix_freebsd) # gen_lib unix::hosts (any) -stdlib_unix_hosts=$(HARECACHE)/unix/hosts/unix_hosts-any.o -hare_stdlib_deps+=$(stdlib_unix_hosts) +stdlib_unix_hosts_any=$(HARECACHE)/unix/hosts/unix_hosts-any.o +stdlib_deps_any+=$(stdlib_unix_hosts_any) +stdlib_unix_hosts_linux=$(stdlib_unix_hosts_any) +stdlib_unix_hosts_freebsd=$(stdlib_unix_hosts_any) # gen_lib unix::passwd (any) -stdlib_unix_passwd=$(HARECACHE)/unix/passwd/unix_passwd-any.o -hare_stdlib_deps+=$(stdlib_unix_passwd) +stdlib_unix_passwd_any=$(HARECACHE)/unix/passwd/unix_passwd-any.o +stdlib_deps_any+=$(stdlib_unix_passwd_any) +stdlib_unix_passwd_linux=$(stdlib_unix_passwd_any) +stdlib_unix_passwd_freebsd=$(stdlib_unix_passwd_any) # gen_lib unix::poll (linux) -stdlib_unix_poll=$(HARECACHE)/unix/poll/unix_poll-linux.o -hare_stdlib_deps+=$(stdlib_unix_poll) +stdlib_unix_poll_linux=$(HARECACHE)/unix/poll/unix_poll-linux.o +stdlib_deps_linux+=$(stdlib_unix_poll_linux) + +# gen_lib unix::poll (freebsd) +stdlib_unix_poll_freebsd=$(HARECACHE)/unix/poll/unix_poll-freebsd.o +stdlib_deps_freebsd+=$(stdlib_unix_poll_freebsd) # gen_lib unix::resolvconf (any) -stdlib_unix_resolvconf=$(HARECACHE)/unix/resolvconf/unix_resolvconf-any.o -hare_stdlib_deps+=$(stdlib_unix_resolvconf) +stdlib_unix_resolvconf_any=$(HARECACHE)/unix/resolvconf/unix_resolvconf-any.o +stdlib_deps_any+=$(stdlib_unix_resolvconf_any) +stdlib_unix_resolvconf_linux=$(stdlib_unix_resolvconf_any) +stdlib_unix_resolvconf_freebsd=$(stdlib_unix_resolvconf_any) # gen_lib unix::tty (linux) -stdlib_unix_tty=$(HARECACHE)/unix/tty/unix_tty-linux.o -hare_stdlib_deps+=$(stdlib_unix_tty) +stdlib_unix_tty_linux=$(HARECACHE)/unix/tty/unix_tty-linux.o +stdlib_deps_linux+=$(stdlib_unix_tty_linux) + +# gen_lib unix::tty (freebsd) +stdlib_unix_tty_freebsd=$(HARECACHE)/unix/tty/unix_tty-freebsd.o +stdlib_deps_freebsd+=$(stdlib_unix_tty_freebsd) # gen_lib uuid (any) -stdlib_uuid=$(HARECACHE)/uuid/uuid-any.o -hare_stdlib_deps+=$(stdlib_uuid) +stdlib_uuid_any=$(HARECACHE)/uuid/uuid-any.o +stdlib_deps_any+=$(stdlib_uuid_any) +stdlib_uuid_linux=$(stdlib_uuid_any) +stdlib_uuid_freebsd=$(stdlib_uuid_any) # ascii (+any) stdlib_ascii_any_srcs= \ $(STDLIB)/ascii/ctype.ha \ $(STDLIB)/ascii/strcmp.ha -$(HARECACHE)/ascii/ascii-any.ssa: $(stdlib_ascii_any_srcs) $(stdlib_rt) $(stdlib_strings) +$(HARECACHE)/ascii/ascii-any.ssa: $(stdlib_ascii_any_srcs) $(stdlib_rt) $(stdlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/ascii @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nascii \ @@ -385,7 +585,7 @@ stdlib_bufio_any_srcs= \ $(STDLIB)/bufio/memstream.ha \ $(STDLIB)/bufio/scanner.ha -$(HARECACHE)/bufio/bufio-any.ssa: $(stdlib_bufio_any_srcs) $(stdlib_rt) $(stdlib_io) $(stdlib_bytes) $(stdlib_strings) $(stdlib_encoding_utf8) $(stdlib_errors) $(stdlib_types) +$(HARECACHE)/bufio/bufio-any.ssa: $(stdlib_bufio_any_srcs) $(stdlib_rt) $(stdlib_io_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_encoding_utf8_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_types_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/bufio @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nbufio \ @@ -401,7 +601,7 @@ stdlib_bytes_any_srcs= \ $(STDLIB)/bytes/tokenize.ha \ $(STDLIB)/bytes/two_way.ha -$(HARECACHE)/bytes/bytes-any.ssa: $(stdlib_bytes_any_srcs) $(stdlib_rt) $(stdlib_types) +$(HARECACHE)/bytes/bytes-any.ssa: $(stdlib_bytes_any_srcs) $(stdlib_rt) $(stdlib_types_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/bytes @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nbytes \ @@ -411,7 +611,7 @@ $(HARECACHE)/bytes/bytes-any.ssa: $(stdlib_bytes_any_srcs) $(stdlib_rt) $(stdlib stdlib_compress_flate_any_srcs= \ $(STDLIB)/compress/flate/inflate.ha -$(HARECACHE)/compress/flate/compress_flate-any.ssa: $(stdlib_compress_flate_any_srcs) $(stdlib_rt) $(stdlib_bufio) $(stdlib_bytes) $(stdlib_endian) $(stdlib_errors) $(stdlib_io) $(stdlib_fmt) +$(HARECACHE)/compress/flate/compress_flate-any.ssa: $(stdlib_compress_flate_any_srcs) $(stdlib_rt) $(stdlib_bufio_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_endian_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/compress/flate @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ncompress::flate \ @@ -421,7 +621,7 @@ $(HARECACHE)/compress/flate/compress_flate-any.ssa: $(stdlib_compress_flate_any_ stdlib_compress_zlib_any_srcs= \ $(STDLIB)/compress/zlib/reader.ha -$(HARECACHE)/compress/zlib/compress_zlib-any.ssa: $(stdlib_compress_zlib_any_srcs) $(stdlib_rt) $(stdlib_bufio) $(stdlib_bytes) $(stdlib_compress_flate) $(stdlib_endian) $(stdlib_errors) $(stdlib_hash) $(stdlib_hash_adler32) $(stdlib_io) $(stdlib_fmt) +$(HARECACHE)/compress/zlib/compress_zlib-any.ssa: $(stdlib_compress_zlib_any_srcs) $(stdlib_rt) $(stdlib_bufio_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_compress_flate_$(PLATFORM)) $(stdlib_endian_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_hash_adler32_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/compress/zlib @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ncompress::zlib \ @@ -431,7 +631,7 @@ $(HARECACHE)/compress/zlib/compress_zlib-any.ssa: $(stdlib_compress_zlib_any_src stdlib_crypto_blake2b_any_srcs= \ $(STDLIB)/crypto/blake2b/blake2b.ha -$(HARECACHE)/crypto/blake2b/crypto_blake2b-any.ssa: $(stdlib_crypto_blake2b_any_srcs) $(stdlib_rt) $(stdlib_encoding_hex) $(stdlib_fmt) $(stdlib_hash) $(stdlib_io) $(stdlib_strings) $(stdlib_strio) $(stdlib_crypto_math) $(stdlib_endian) +$(HARECACHE)/crypto/blake2b/crypto_blake2b-any.ssa: $(stdlib_crypto_blake2b_any_srcs) $(stdlib_rt) $(stdlib_encoding_hex_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_strio_$(PLATFORM)) $(stdlib_crypto_math_$(PLATFORM)) $(stdlib_endian_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/crypto/blake2b @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::blake2b \ @@ -452,17 +652,28 @@ stdlib_crypto_random_linux_srcs= \ $(STDLIB)/crypto/random/+linux.ha \ $(STDLIB)/crypto/random/random.ha -$(HARECACHE)/crypto/random/crypto_random-linux.ssa: $(stdlib_crypto_random_linux_srcs) $(stdlib_rt) $(stdlib_rt) $(stdlib_io) $(stdlib_errors) +$(HARECACHE)/crypto/random/crypto_random-linux.ssa: $(stdlib_crypto_random_linux_srcs) $(stdlib_rt) $(stdlib_rt_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/crypto/random @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::random \ -t$(HARECACHE)/crypto/random/crypto_random.td $(stdlib_crypto_random_linux_srcs) +# crypto::random (+freebsd) +stdlib_crypto_random_freebsd_srcs= \ + $(STDLIB)/crypto/random/+freebsd.ha \ + $(STDLIB)/crypto/random/random.ha + +$(HARECACHE)/crypto/random/crypto_random-freebsd.ssa: $(stdlib_crypto_random_freebsd_srcs) $(stdlib_rt) $(stdlib_rt_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(HARECACHE)/crypto/random + @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::random \ + -t$(HARECACHE)/crypto/random/crypto_random.td $(stdlib_crypto_random_freebsd_srcs) + # crypto::md5 (+any) stdlib_crypto_md5_any_srcs= \ $(STDLIB)/crypto/md5/md5.ha -$(HARECACHE)/crypto/md5/crypto_md5-any.ssa: $(stdlib_crypto_md5_any_srcs) $(stdlib_rt) $(stdlib_hash) $(stdlib_io) $(stdlib_endian) +$(HARECACHE)/crypto/md5/crypto_md5-any.ssa: $(stdlib_crypto_md5_any_srcs) $(stdlib_rt) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_endian_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/crypto/md5 @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::md5 \ @@ -472,7 +683,7 @@ $(HARECACHE)/crypto/md5/crypto_md5-any.ssa: $(stdlib_crypto_md5_any_srcs) $(stdl stdlib_crypto_sha1_any_srcs= \ $(STDLIB)/crypto/sha1/sha1.ha -$(HARECACHE)/crypto/sha1/crypto_sha1-any.ssa: $(stdlib_crypto_sha1_any_srcs) $(stdlib_rt) $(stdlib_hash) $(stdlib_io) $(stdlib_endian) +$(HARECACHE)/crypto/sha1/crypto_sha1-any.ssa: $(stdlib_crypto_sha1_any_srcs) $(stdlib_rt) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_endian_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/crypto/sha1 @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::sha1 \ @@ -482,7 +693,7 @@ $(HARECACHE)/crypto/sha1/crypto_sha1-any.ssa: $(stdlib_crypto_sha1_any_srcs) $(s stdlib_crypto_sha256_any_srcs= \ $(STDLIB)/crypto/sha256/sha256.ha -$(HARECACHE)/crypto/sha256/crypto_sha256-any.ssa: $(stdlib_crypto_sha256_any_srcs) $(stdlib_rt) $(stdlib_hash) $(stdlib_io) $(stdlib_endian) +$(HARECACHE)/crypto/sha256/crypto_sha256-any.ssa: $(stdlib_crypto_sha256_any_srcs) $(stdlib_rt) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_endian_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/crypto/sha256 @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::sha256 \ @@ -492,7 +703,7 @@ $(HARECACHE)/crypto/sha256/crypto_sha256-any.ssa: $(stdlib_crypto_sha256_any_src stdlib_crypto_sha512_any_srcs= \ $(STDLIB)/crypto/sha512/sha512.ha -$(HARECACHE)/crypto/sha512/crypto_sha512-any.ssa: $(stdlib_crypto_sha512_any_srcs) $(stdlib_rt) $(stdlib_hash) $(stdlib_io) $(stdlib_endian) +$(HARECACHE)/crypto/sha512/crypto_sha512-any.ssa: $(stdlib_crypto_sha512_any_srcs) $(stdlib_rt) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_endian_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/crypto/sha512 @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::sha512 \ @@ -502,7 +713,7 @@ $(HARECACHE)/crypto/sha512/crypto_sha512-any.ssa: $(stdlib_crypto_sha512_any_src stdlib_dirs_any_srcs= \ $(STDLIB)/dirs/xdg.ha -$(HARECACHE)/dirs/dirs-any.ssa: $(stdlib_dirs_any_srcs) $(stdlib_rt) $(stdlib_fs) $(stdlib_os) $(stdlib_path) +$(HARECACHE)/dirs/dirs-any.ssa: $(stdlib_dirs_any_srcs) $(stdlib_rt) $(stdlib_fs_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_path_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/dirs @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ndirs \ @@ -512,7 +723,7 @@ $(HARECACHE)/dirs/dirs-any.ssa: $(stdlib_dirs_any_srcs) $(stdlib_rt) $(stdlib_fs stdlib_encoding_base64_any_srcs= \ $(STDLIB)/encoding/base64/base64.ha -$(HARECACHE)/encoding/base64/encoding_base64-any.ssa: $(stdlib_encoding_base64_any_srcs) $(stdlib_rt) $(stdlib_bufio) $(stdlib_bytes) $(stdlib_io) $(stdlib_strio) $(stdlib_strings) +$(HARECACHE)/encoding/base64/encoding_base64-any.ssa: $(stdlib_encoding_base64_any_srcs) $(stdlib_rt) $(stdlib_bufio_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strio_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/encoding/base64 @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nencoding::base64 \ @@ -522,7 +733,7 @@ $(HARECACHE)/encoding/base64/encoding_base64-any.ssa: $(stdlib_encoding_base64_a stdlib_encoding_hex_any_srcs= \ $(STDLIB)/encoding/hex/hex.ha -$(HARECACHE)/encoding/hex/encoding_hex-any.ssa: $(stdlib_encoding_hex_any_srcs) $(stdlib_rt) $(stdlib_ascii) $(stdlib_bytes) $(stdlib_fmt) $(stdlib_io) $(stdlib_strconv) $(stdlib_strio) $(stdlib_strings) +$(HARECACHE)/encoding/hex/encoding_hex-any.ssa: $(stdlib_encoding_hex_any_srcs) $(stdlib_rt) $(stdlib_ascii_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strconv_$(PLATFORM)) $(stdlib_strio_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/encoding/hex @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nencoding::hex \ @@ -534,7 +745,7 @@ stdlib_encoding_utf8_any_srcs= \ $(STDLIB)/encoding/utf8/encode.ha \ $(STDLIB)/encoding/utf8/rune.ha -$(HARECACHE)/encoding/utf8/encoding_utf8-any.ssa: $(stdlib_encoding_utf8_any_srcs) $(stdlib_rt) $(stdlib_types) +$(HARECACHE)/encoding/utf8/encoding_utf8-any.ssa: $(stdlib_encoding_utf8_any_srcs) $(stdlib_rt) $(stdlib_types_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/encoding/utf8 @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nencoding::utf8 \ @@ -571,7 +782,7 @@ $(HARECACHE)/errors/errors-any.ssa: $(stdlib_errors_any_srcs) $(stdlib_rt) stdlib_fmt_any_srcs= \ $(STDLIB)/fmt/fmt.ha -$(HARECACHE)/fmt/fmt-any.ssa: $(stdlib_fmt_any_srcs) $(stdlib_rt) $(stdlib_bufio) $(stdlib_io) $(stdlib_os) $(stdlib_strconv) $(stdlib_strings) $(stdlib_types) +$(HARECACHE)/fmt/fmt-any.ssa: $(stdlib_fmt_any_srcs) $(stdlib_rt) $(stdlib_bufio_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_strconv_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_types_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/fmt @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nfmt \ @@ -581,7 +792,7 @@ $(HARECACHE)/fmt/fmt-any.ssa: $(stdlib_fmt_any_srcs) $(stdlib_rt) $(stdlib_bufio stdlib_fnmatch_any_srcs= \ $(STDLIB)/fnmatch/fnmatch.ha -$(HARECACHE)/fnmatch/fnmatch-any.ssa: $(stdlib_fnmatch_any_srcs) $(stdlib_rt) $(stdlib_strings) $(stdlib_bytes) $(stdlib_sort) $(stdlib_ascii) $(stdlib_io) $(stdlib_fmt) +$(HARECACHE)/fnmatch/fnmatch-any.ssa: $(stdlib_fnmatch_any_srcs) $(stdlib_rt) $(stdlib_strings_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_sort_$(PLATFORM)) $(stdlib_ascii_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/fnmatch @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nfnmatch \ @@ -604,7 +815,7 @@ stdlib_format_ini_any_srcs= \ $(STDLIB)/format/ini/scan.ha \ $(STDLIB)/format/ini/types.ha -$(HARECACHE)/format/ini/format_ini-any.ssa: $(stdlib_format_ini_any_srcs) $(stdlib_rt) $(stdlib_bufio) $(stdlib_encoding_utf8) $(stdlib_fmt) $(stdlib_io) $(stdlib_strings) +$(HARECACHE)/format/ini/format_ini-any.ssa: $(stdlib_format_ini_any_srcs) $(stdlib_rt) $(stdlib_bufio_$(PLATFORM)) $(stdlib_encoding_utf8_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/format/ini @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nformat::ini \ @@ -616,7 +827,7 @@ stdlib_format_xml_any_srcs= \ $(STDLIB)/format/xml/parser.ha \ $(STDLIB)/format/xml/chars.ha -$(HARECACHE)/format/xml/format_xml-any.ssa: $(stdlib_format_xml_any_srcs) $(stdlib_rt) $(stdlib_io) $(stdlib_bufio) $(stdlib_strings) $(stdlib_ascii) $(stdlib_strio) $(stdlib_os) +$(HARECACHE)/format/xml/format_xml-any.ssa: $(stdlib_format_xml_any_srcs) $(stdlib_rt) $(stdlib_io_$(PLATFORM)) $(stdlib_bufio_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_ascii_$(PLATFORM)) $(stdlib_strio_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/format/xml @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nformat::xml \ @@ -628,7 +839,7 @@ stdlib_fs_any_srcs= \ $(STDLIB)/fs/fs.ha \ $(STDLIB)/fs/util.ha -$(HARECACHE)/fs/fs-any.ssa: $(stdlib_fs_any_srcs) $(stdlib_rt) $(stdlib_io) $(stdlib_strings) $(stdlib_path) $(stdlib_time) $(stdlib_errors) +$(HARECACHE)/fs/fs-any.ssa: $(stdlib_fs_any_srcs) $(stdlib_rt) $(stdlib_io_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_path_$(PLATFORM)) $(stdlib_time_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/fs @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nfs \ @@ -640,7 +851,7 @@ stdlib_fs_mem_any_srcs= \ $(STDLIB)/fs/mem/stream.ha \ $(STDLIB)/fs/mem/util.ha -$(HARECACHE)/fs/mem/fs_mem-any.ssa: $(stdlib_fs_mem_any_srcs) $(stdlib_rt) $(stdlib_bufio) $(stdlib_errors) $(stdlib_fs) $(stdlib_hash) $(stdlib_hash_fnv) $(stdlib_io) $(stdlib_path) $(stdlib_strconv) $(stdlib_strings) $(stdlib_types) +$(HARECACHE)/fs/mem/fs_mem-any.ssa: $(stdlib_fs_mem_any_srcs) $(stdlib_rt) $(stdlib_bufio_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_fs_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_hash_fnv_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_path_$(PLATFORM)) $(stdlib_strconv_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_types_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/fs/mem @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nfs::mem \ @@ -650,7 +861,7 @@ $(HARECACHE)/fs/mem/fs_mem-any.ssa: $(stdlib_fs_mem_any_srcs) $(stdlib_rt) $(std stdlib_getopt_any_srcs= \ $(STDLIB)/getopt/getopts.ha -$(HARECACHE)/getopt/getopt-any.ssa: $(stdlib_getopt_any_srcs) $(stdlib_rt) $(stdlib_encoding_utf8) $(stdlib_fmt) $(stdlib_io) $(stdlib_os) $(stdlib_strings) +$(HARECACHE)/getopt/getopt-any.ssa: $(stdlib_getopt_any_srcs) $(stdlib_rt) $(stdlib_encoding_utf8_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/getopt @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ngetopt \ @@ -665,7 +876,7 @@ stdlib_hare_ast_any_srcs= \ $(STDLIB)/hare/ast/type.ha \ $(STDLIB)/hare/ast/unit.ha -$(HARECACHE)/hare/ast/hare_ast-any.ssa: $(stdlib_hare_ast_any_srcs) $(stdlib_rt) $(stdlib_hare_lex) $(stdlib_strings) +$(HARECACHE)/hare/ast/hare_ast-any.ssa: $(stdlib_hare_ast_any_srcs) $(stdlib_rt) $(stdlib_hare_lex_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/hare/ast @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nhare::ast \ @@ -676,7 +887,7 @@ stdlib_hare_lex_any_srcs= \ $(STDLIB)/hare/lex/token.ha \ $(STDLIB)/hare/lex/lex.ha -$(HARECACHE)/hare/lex/hare_lex-any.ssa: $(stdlib_hare_lex_any_srcs) $(stdlib_rt) $(stdlib_io) $(stdlib_bufio) $(stdlib_strings) $(stdlib_types) $(stdlib_fmt) $(stdlib_sort) $(stdlib_strio) +$(HARECACHE)/hare/lex/hare_lex-any.ssa: $(stdlib_hare_lex_any_srcs) $(stdlib_rt) $(stdlib_io_$(PLATFORM)) $(stdlib_bufio_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_types_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_sort_$(PLATFORM)) $(stdlib_strio_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/hare/lex @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nhare::lex \ @@ -689,7 +900,7 @@ stdlib_hare_module_any_srcs= \ $(STDLIB)/hare/module/scan.ha \ $(STDLIB)/hare/module/manifest.ha -$(HARECACHE)/hare/module/hare_module-any.ssa: $(stdlib_hare_module_any_srcs) $(stdlib_rt) $(stdlib_hare_ast) $(stdlib_hare_lex) $(stdlib_hare_parse) $(stdlib_hare_unparse) $(stdlib_strio) $(stdlib_fs) $(stdlib_io) $(stdlib_strings) $(stdlib_hash) $(stdlib_crypto_sha256) $(stdlib_dirs) $(stdlib_bytes) $(stdlib_encoding_utf8) $(stdlib_ascii) $(stdlib_fmt) $(stdlib_time) $(stdlib_slice) $(stdlib_bufio) $(stdlib_strconv) $(stdlib_os) $(stdlib_encoding_hex) $(stdlib_sort) $(stdlib_errors) $(stdlib_temp) +$(HARECACHE)/hare/module/hare_module-any.ssa: $(stdlib_hare_module_any_srcs) $(stdlib_rt) $(stdlib_hare_ast_$(PLATFORM)) $(stdlib_hare_lex_$(PLATFORM)) $(stdlib_hare_parse_$(PLATFORM)) $(stdlib_hare_unparse_$(PLATFORM)) $(stdlib_strio_$(PLATFORM)) $(stdlib_fs_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_crypto_sha256_$(PLATFORM)) $(stdlib_dirs_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_encoding_utf8_$(PLATFORM)) $(stdlib_ascii_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_time_$(PLATFORM)) $(stdlib_slice_$(PLATFORM)) $(stdlib_bufio_$(PLATFORM)) $(stdlib_strconv_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_encoding_hex_$(PLATFORM)) $(stdlib_sort_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_temp_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/hare/module @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nhare::module \ @@ -705,7 +916,7 @@ stdlib_hare_parse_any_srcs= \ $(STDLIB)/hare/parse/type.ha \ $(STDLIB)/hare/parse/unit.ha -$(HARECACHE)/hare/parse/hare_parse-any.ssa: $(stdlib_hare_parse_any_srcs) $(stdlib_rt) $(stdlib_hare_ast) $(stdlib_hare_lex) $(stdlib_hare_unparse) $(stdlib_fmt) +$(HARECACHE)/hare/parse/hare_parse-any.ssa: $(stdlib_hare_parse_any_srcs) $(stdlib_rt) $(stdlib_hare_ast_$(PLATFORM)) $(stdlib_hare_lex_$(PLATFORM)) $(stdlib_hare_unparse_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/hare/parse @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nhare::parse \ @@ -721,7 +932,7 @@ stdlib_hare_types_any_srcs= \ $(STDLIB)/hare/types/store.ha \ $(STDLIB)/hare/types/types.ha -$(HARECACHE)/hare/types/hare_types-any.ssa: $(stdlib_hare_types_any_srcs) $(stdlib_rt) $(stdlib_hare_ast) $(stdlib_hare_parse) $(stdlib_hash) $(stdlib_hash_fnv) $(stdlib_endian) +$(HARECACHE)/hare/types/hare_types-any.ssa: $(stdlib_hare_types_any_srcs) $(stdlib_rt) $(stdlib_hare_ast_$(PLATFORM)) $(stdlib_hare_parse_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_hash_fnv_$(PLATFORM)) $(stdlib_endian_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/hare/types @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nhare::types \ @@ -738,7 +949,7 @@ stdlib_hare_unit_any_srcs= \ $(STDLIB)/hare/unit/scope.ha \ $(STDLIB)/hare/unit/unit.ha -$(HARECACHE)/hare/unit/hare_unit-any.ssa: $(stdlib_hare_unit_any_srcs) $(stdlib_rt) $(stdlib_hare_ast) $(stdlib_hare_types) $(stdlib_hash) $(stdlib_hash_fnv) $(stdlib_strings) $(stdlib_hare_lex) $(stdlib_bufio) $(stdlib_hare_parse) +$(HARECACHE)/hare/unit/hare_unit-any.ssa: $(stdlib_hare_unit_any_srcs) $(stdlib_rt) $(stdlib_hare_ast_$(PLATFORM)) $(stdlib_hare_types_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_hash_fnv_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_hare_lex_$(PLATFORM)) $(stdlib_bufio_$(PLATFORM)) $(stdlib_hare_parse_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/hare/unit @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nhare::unit \ @@ -754,7 +965,7 @@ stdlib_hare_unparse_any_srcs= \ $(STDLIB)/hare/unparse/unit.ha \ $(STDLIB)/hare/unparse/util.ha -$(HARECACHE)/hare/unparse/hare_unparse-any.ssa: $(stdlib_hare_unparse_any_srcs) $(stdlib_rt) $(stdlib_fmt) $(stdlib_io) $(stdlib_strio) $(stdlib_hare_ast) +$(HARECACHE)/hare/unparse/hare_unparse-any.ssa: $(stdlib_hare_unparse_any_srcs) $(stdlib_rt) $(stdlib_fmt_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strio_$(PLATFORM)) $(stdlib_hare_ast_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/hare/unparse @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nhare::unparse \ @@ -764,7 +975,7 @@ $(HARECACHE)/hare/unparse/hare_unparse-any.ssa: $(stdlib_hare_unparse_any_srcs) stdlib_hash_any_srcs= \ $(STDLIB)/hash/hash.ha -$(HARECACHE)/hash/hash-any.ssa: $(stdlib_hash_any_srcs) $(stdlib_rt) $(stdlib_io) $(stdlib_fmt) +$(HARECACHE)/hash/hash-any.ssa: $(stdlib_hash_any_srcs) $(stdlib_rt) $(stdlib_io_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/hash @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nhash \ @@ -774,7 +985,7 @@ $(HARECACHE)/hash/hash-any.ssa: $(stdlib_hash_any_srcs) $(stdlib_rt) $(stdlib_io stdlib_hash_adler32_any_srcs= \ $(STDLIB)/hash/adler32/adler32.ha -$(HARECACHE)/hash/adler32/hash_adler32-any.ssa: $(stdlib_hash_adler32_any_srcs) $(stdlib_rt) $(stdlib_endian) $(stdlib_hash) $(stdlib_io) $(stdlib_strings) +$(HARECACHE)/hash/adler32/hash_adler32-any.ssa: $(stdlib_hash_adler32_any_srcs) $(stdlib_rt) $(stdlib_endian_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/hash/adler32 @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nhash::adler32 \ @@ -784,7 +995,7 @@ $(HARECACHE)/hash/adler32/hash_adler32-any.ssa: $(stdlib_hash_adler32_any_srcs) stdlib_hash_crc16_any_srcs= \ $(STDLIB)/hash/crc16/crc16.ha -$(HARECACHE)/hash/crc16/hash_crc16-any.ssa: $(stdlib_hash_crc16_any_srcs) $(stdlib_rt) $(stdlib_endian) $(stdlib_hash) $(stdlib_io) $(stdlib_strings) +$(HARECACHE)/hash/crc16/hash_crc16-any.ssa: $(stdlib_hash_crc16_any_srcs) $(stdlib_rt) $(stdlib_endian_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/hash/crc16 @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nhash::crc16 \ @@ -794,7 +1005,7 @@ $(HARECACHE)/hash/crc16/hash_crc16-any.ssa: $(stdlib_hash_crc16_any_srcs) $(stdl stdlib_hash_crc32_any_srcs= \ $(STDLIB)/hash/crc32/crc32.ha -$(HARECACHE)/hash/crc32/hash_crc32-any.ssa: $(stdlib_hash_crc32_any_srcs) $(stdlib_rt) $(stdlib_endian) $(stdlib_hash) $(stdlib_io) $(stdlib_strings) +$(HARECACHE)/hash/crc32/hash_crc32-any.ssa: $(stdlib_hash_crc32_any_srcs) $(stdlib_rt) $(stdlib_endian_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/hash/crc32 @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nhash::crc32 \ @@ -804,7 +1015,7 @@ $(HARECACHE)/hash/crc32/hash_crc32-any.ssa: $(stdlib_hash_crc32_any_srcs) $(stdl stdlib_hash_crc64_any_srcs= \ $(STDLIB)/hash/crc64/crc64.ha -$(HARECACHE)/hash/crc64/hash_crc64-any.ssa: $(stdlib_hash_crc64_any_srcs) $(stdlib_rt) $(stdlib_endian) $(stdlib_hash) $(stdlib_io) $(stdlib_strings) +$(HARECACHE)/hash/crc64/hash_crc64-any.ssa: $(stdlib_hash_crc64_any_srcs) $(stdlib_rt) $(stdlib_endian_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/hash/crc64 @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nhash::crc64 \ @@ -814,7 +1025,7 @@ $(HARECACHE)/hash/crc64/hash_crc64-any.ssa: $(stdlib_hash_crc64_any_srcs) $(stdl stdlib_hash_fnv_any_srcs= \ $(STDLIB)/hash/fnv/fnv.ha -$(HARECACHE)/hash/fnv/hash_fnv-any.ssa: $(stdlib_hash_fnv_any_srcs) $(stdlib_rt) $(stdlib_hash) $(stdlib_io) $(stdlib_strings) +$(HARECACHE)/hash/fnv/hash_fnv-any.ssa: $(stdlib_hash_fnv_any_srcs) $(stdlib_rt) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/hash/fnv @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nhash::fnv \ @@ -835,12 +1046,33 @@ stdlib_io_linux_srcs= \ $(STDLIB)/io/tee.ha \ $(STDLIB)/io/types.ha -$(HARECACHE)/io/io-linux.ssa: $(stdlib_io_linux_srcs) $(stdlib_rt) $(stdlib_strings) $(stdlib_errors) +# io (+freebsd) +stdlib_io_freebsd_srcs= \ + $(STDLIB)/io/arch+$(ARCH).ha \ + $(STDLIB)/io/println+freebsd.ha \ + $(STDLIB)/io/+freebsd/file.ha \ + $(STDLIB)/io/copy.ha \ + $(STDLIB)/io/drain.ha \ + $(STDLIB)/io/empty.ha \ + $(STDLIB)/io/filestream.ha \ + $(STDLIB)/io/handle.ha \ + $(STDLIB)/io/limit.ha \ + $(STDLIB)/io/stream.ha \ + $(STDLIB)/io/tee.ha \ + $(STDLIB)/io/types.ha + +$(HARECACHE)/io/io-linux.ssa: $(stdlib_io_linux_srcs) $(stdlib_rt) $(stdlib_strings_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/io @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nio \ -t$(HARECACHE)/io/io.td $(stdlib_io_linux_srcs) +$(HARECACHE)/io/io-freebsd.ssa: $(stdlib_io_freebsd_srcs) $(stdlib_rt) $(stdlib_strings_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(HARECACHE)/io + @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nio \ + -t$(HARECACHE)/io/io.td $(stdlib_io_freebsd_srcs) + # iobus::io_uring (+linux) stdlib_iobus_io_uring_linux_srcs= \ $(STDLIB)/iobus/io_uring/bus.ha \ @@ -849,7 +1081,7 @@ stdlib_iobus_io_uring_linux_srcs= \ $(STDLIB)/iobus/io_uring/pool.ha \ $(STDLIB)/iobus/io_uring/types.ha -$(HARECACHE)/iobus/io_uring/iobus_io_uring-linux.ssa: $(stdlib_iobus_io_uring_linux_srcs) $(stdlib_rt) $(stdlib_errors) $(stdlib_io) $(stdlib_linux_io_uring) $(stdlib_net_ip) $(stdlib_unix_poll) +$(HARECACHE)/iobus/io_uring/iobus_io_uring-linux.ssa: $(stdlib_iobus_io_uring_linux_srcs) $(stdlib_rt) $(stdlib_errors_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_linux_io_uring_$(PLATFORM)) $(stdlib_net_ip_$(PLATFORM)) $(stdlib_unix_poll_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/iobus/io_uring @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Niobus::io_uring \ @@ -860,7 +1092,7 @@ stdlib_linux_linux_srcs= \ $(STDLIB)/linux/start.ha \ $(STDLIB)/linux/env.ha -$(HARECACHE)/linux/linux-linux.ssa: $(stdlib_linux_linux_srcs) $(stdlib_rt) $(stdlib_format_elf) +$(HARECACHE)/linux/linux-linux.ssa: $(stdlib_linux_linux_srcs) $(stdlib_rt) $(stdlib_format_elf_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/linux @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nlinux \ @@ -870,7 +1102,7 @@ $(HARECACHE)/linux/linux-linux.ssa: $(stdlib_linux_linux_srcs) $(stdlib_rt) $(st stdlib_linux_signalfd_linux_srcs= \ $(STDLIB)/linux/signalfd/signalfd.ha -$(HARECACHE)/linux/signalfd/linux_signalfd-linux.ssa: $(stdlib_linux_signalfd_linux_srcs) $(stdlib_rt) $(stdlib_errors) +$(HARECACHE)/linux/signalfd/linux_signalfd-linux.ssa: $(stdlib_linux_signalfd_linux_srcs) $(stdlib_rt) $(stdlib_errors_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/linux/signalfd @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nlinux::signalfd \ @@ -885,7 +1117,7 @@ stdlib_linux_io_uring_linux_srcs= \ $(STDLIB)/linux/io_uring/sqe.ha \ $(STDLIB)/linux/io_uring/uring.ha -$(HARECACHE)/linux/io_uring/linux_io_uring-linux.ssa: $(stdlib_linux_io_uring_linux_srcs) $(stdlib_rt) $(stdlib_errors) $(stdlib_types) +$(HARECACHE)/linux/io_uring/linux_io_uring-linux.ssa: $(stdlib_linux_io_uring_linux_srcs) $(stdlib_rt) $(stdlib_errors_$(PLATFORM)) $(stdlib_types_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/linux/io_uring @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nlinux::io_uring \ @@ -895,7 +1127,7 @@ $(HARECACHE)/linux/io_uring/linux_io_uring-linux.ssa: $(stdlib_linux_io_uring_li stdlib_linux_vdso_linux_srcs= \ $(STDLIB)/linux/vdso/vdso.ha -$(HARECACHE)/linux/vdso/linux_vdso-linux.ssa: $(stdlib_linux_vdso_linux_srcs) $(stdlib_rt) $(stdlib_linux) $(stdlib_strings) $(stdlib_format_elf) +$(HARECACHE)/linux/vdso/linux_vdso-linux.ssa: $(stdlib_linux_vdso_linux_srcs) $(stdlib_rt) $(stdlib_linux_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_format_elf_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/linux/vdso @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nlinux::vdso \ @@ -909,7 +1141,7 @@ stdlib_math_any_srcs= \ $(STDLIB)/math/uints.ha \ $(STDLIB)/math/trig.ha -$(HARECACHE)/math/math-any.ssa: $(stdlib_math_any_srcs) $(stdlib_rt) $(stdlib_types) +$(HARECACHE)/math/math-any.ssa: $(stdlib_math_any_srcs) $(stdlib_rt) $(stdlib_types_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/math @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nmath \ @@ -921,12 +1153,24 @@ stdlib_net_linux_srcs= \ $(STDLIB)/net/errors.ha \ $(STDLIB)/net/listener.ha -$(HARECACHE)/net/net-linux.ssa: $(stdlib_net_linux_srcs) $(stdlib_rt) $(stdlib_io) $(stdlib_os) $(stdlib_strings) $(stdlib_net_ip) $(stdlib_errors) $(stdlib_rt) $(stdlib_fmt) +$(HARECACHE)/net/net-linux.ssa: $(stdlib_net_linux_srcs) $(stdlib_rt) $(stdlib_io_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_net_ip_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_rt_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/net @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nnet \ -t$(HARECACHE)/net/net.td $(stdlib_net_linux_srcs) +# net (+freebsd) +stdlib_net_freebsd_srcs= \ + $(STDLIB)/net/+freebsd.ha \ + $(STDLIB)/net/errors.ha \ + $(STDLIB)/net/listener.ha + +$(HARECACHE)/net/net-freebsd.ssa: $(stdlib_net_freebsd_srcs) $(stdlib_rt) $(stdlib_io_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_net_ip_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_rt_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(HARECACHE)/net + @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nnet \ + -t$(HARECACHE)/net/net.td $(stdlib_net_freebsd_srcs) + # net::dial (+any) stdlib_net_dial_any_srcs= \ $(STDLIB)/net/dial/registry.ha \ @@ -934,7 +1178,7 @@ stdlib_net_dial_any_srcs= \ $(STDLIB)/net/dial/ip.ha \ $(STDLIB)/net/dial/resolve.ha -$(HARECACHE)/net/dial/net_dial-any.ssa: $(stdlib_net_dial_any_srcs) $(stdlib_rt) $(stdlib_io) $(stdlib_net) $(stdlib_net_ip) $(stdlib_net_tcp) $(stdlib_net_udp) $(stdlib_net_dns) $(stdlib_crypto_random) $(stdlib_strconv) $(stdlib_strings) $(stdlib_unix_hosts) +$(HARECACHE)/net/dial/net_dial-any.ssa: $(stdlib_net_dial_any_srcs) $(stdlib_rt) $(stdlib_io_$(PLATFORM)) $(stdlib_net_$(PLATFORM)) $(stdlib_net_ip_$(PLATFORM)) $(stdlib_net_tcp_$(PLATFORM)) $(stdlib_net_udp_$(PLATFORM)) $(stdlib_net_dns_$(PLATFORM)) $(stdlib_crypto_random_$(PLATFORM)) $(stdlib_strconv_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_unix_hosts_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/net/dial @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nnet::dial \ @@ -948,7 +1192,7 @@ stdlib_net_dns_any_srcs= \ $(STDLIB)/net/dns/query.ha \ $(STDLIB)/net/dns/types.ha -$(HARECACHE)/net/dns/net_dns-any.ssa: $(stdlib_net_dns_any_srcs) $(stdlib_rt) $(stdlib_ascii) $(stdlib_endian) $(stdlib_net) $(stdlib_net_udp) $(stdlib_net_ip) $(stdlib_fmt) $(stdlib_strings) $(stdlib_unix_resolvconf) $(stdlib_unix_poll) $(stdlib_rt) $(stdlib_time) $(stdlib_errors) +$(HARECACHE)/net/dns/net_dns-any.ssa: $(stdlib_net_dns_any_srcs) $(stdlib_rt) $(stdlib_ascii_$(PLATFORM)) $(stdlib_endian_$(PLATFORM)) $(stdlib_net_$(PLATFORM)) $(stdlib_net_udp_$(PLATFORM)) $(stdlib_net_ip_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_unix_resolvconf_$(PLATFORM)) $(stdlib_unix_poll_$(PLATFORM)) $(stdlib_rt_$(PLATFORM)) $(stdlib_time_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/net/dns @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nnet::dns \ @@ -956,38 +1200,72 @@ $(HARECACHE)/net/dns/net_dns-any.ssa: $(stdlib_net_dns_any_srcs) $(stdlib_rt) $( # net::ip (+linux) stdlib_net_ip_linux_srcs= \ - $(STDLIB)/net/ip/ip.ha \ - $(STDLIB)/net/ip/+linux.ha + $(STDLIB)/net/ip/+linux.ha \ + $(STDLIB)/net/ip/ip.ha -$(HARECACHE)/net/ip/net_ip-linux.ssa: $(stdlib_net_ip_linux_srcs) $(stdlib_rt) $(stdlib_bytes) $(stdlib_io) $(stdlib_strconv) $(stdlib_strings) $(stdlib_strio) $(stdlib_fmt) +# net::ip (+freebsd) +stdlib_net_ip_freebsd_srcs= \ + $(STDLIB)/net/ip/+freebsd.ha \ + $(STDLIB)/net/ip/ip.ha + +$(HARECACHE)/net/ip/net_ip-linux.ssa: $(stdlib_net_ip_linux_srcs) $(stdlib_rt) $(stdlib_bytes_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strconv_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_strio_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/net/ip @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nnet::ip \ -t$(HARECACHE)/net/ip/net_ip.td $(stdlib_net_ip_linux_srcs) +$(HARECACHE)/net/ip/net_ip-freebsd.ssa: $(stdlib_net_ip_freebsd_srcs) $(stdlib_rt) $(stdlib_bytes_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strconv_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_strio_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(HARECACHE)/net/ip + @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nnet::ip \ + -t$(HARECACHE)/net/ip/net_ip.td $(stdlib_net_ip_freebsd_srcs) + # net::tcp (+linux) stdlib_net_tcp_linux_srcs= \ $(STDLIB)/net/tcp/+linux.ha \ $(STDLIB)/net/tcp/listener.ha \ $(STDLIB)/net/tcp/options.ha -$(HARECACHE)/net/tcp/net_tcp-linux.ssa: $(stdlib_net_tcp_linux_srcs) $(stdlib_rt) $(stdlib_io) $(stdlib_net) $(stdlib_net_ip) $(stdlib_os) $(stdlib_rt) +$(HARECACHE)/net/tcp/net_tcp-linux.ssa: $(stdlib_net_tcp_linux_srcs) $(stdlib_rt) $(stdlib_io_$(PLATFORM)) $(stdlib_net_$(PLATFORM)) $(stdlib_net_ip_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_rt_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/net/tcp @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nnet::tcp \ -t$(HARECACHE)/net/tcp/net_tcp.td $(stdlib_net_tcp_linux_srcs) +# net::tcp (+freebsd) +stdlib_net_tcp_freebsd_srcs= \ + $(STDLIB)/net/tcp/+freebsd.ha \ + $(STDLIB)/net/tcp/listener.ha \ + $(STDLIB)/net/tcp/options.ha + +$(HARECACHE)/net/tcp/net_tcp-freebsd.ssa: $(stdlib_net_tcp_freebsd_srcs) $(stdlib_rt) $(stdlib_io_$(PLATFORM)) $(stdlib_net_$(PLATFORM)) $(stdlib_net_ip_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_rt_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(HARECACHE)/net/tcp + @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nnet::tcp \ + -t$(HARECACHE)/net/tcp/net_tcp.td $(stdlib_net_tcp_freebsd_srcs) + # net::udp (+linux) stdlib_net_udp_linux_srcs= \ $(STDLIB)/net/udp/+linux.ha \ $(STDLIB)/net/udp/options.ha -$(HARECACHE)/net/udp/net_udp-linux.ssa: $(stdlib_net_udp_linux_srcs) $(stdlib_rt) $(stdlib_net) $(stdlib_net_ip) $(stdlib_errors) $(stdlib_rt) $(stdlib_os) $(stdlib_io) +$(HARECACHE)/net/udp/net_udp-linux.ssa: $(stdlib_net_udp_linux_srcs) $(stdlib_rt) $(stdlib_net_$(PLATFORM)) $(stdlib_net_ip_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_rt_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/net/udp @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nnet::udp \ -t$(HARECACHE)/net/udp/net_udp.td $(stdlib_net_udp_linux_srcs) +# net::udp (+freebsd) +stdlib_net_udp_freebsd_srcs= \ + $(STDLIB)/net/udp/+freebsd.ha \ + $(STDLIB)/net/udp/options.ha + +$(HARECACHE)/net/udp/net_udp-freebsd.ssa: $(stdlib_net_udp_freebsd_srcs) $(stdlib_rt) $(stdlib_net_$(PLATFORM)) $(stdlib_net_ip_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_rt_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(HARECACHE)/net/udp + @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nnet::udp \ + -t$(HARECACHE)/net/udp/net_udp.td $(stdlib_net_udp_freebsd_srcs) + # net::unix (+linux) stdlib_net_unix_linux_srcs= \ $(STDLIB)/net/unix/+linux.ha \ @@ -996,12 +1274,26 @@ stdlib_net_unix_linux_srcs= \ $(STDLIB)/net/unix/listener.ha \ $(STDLIB)/net/unix/options.ha -$(HARECACHE)/net/unix/net_unix-linux.ssa: $(stdlib_net_unix_linux_srcs) $(stdlib_rt) $(stdlib_net) $(stdlib_errors) $(stdlib_os) $(stdlib_io) $(stdlib_strings) $(stdlib_types) $(stdlib_fmt) $(stdlib_net_dial) +$(HARECACHE)/net/unix/net_unix-linux.ssa: $(stdlib_net_unix_linux_srcs) $(stdlib_rt) $(stdlib_net_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_types_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_net_dial_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/net/unix @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nnet::unix \ -t$(HARECACHE)/net/unix/net_unix.td $(stdlib_net_unix_linux_srcs) +# net::unix (+freebsd) +stdlib_net_unix_freebsd_srcs= \ + $(STDLIB)/net/unix/+freebsd.ha \ + $(STDLIB)/net/unix/addr.ha \ + $(STDLIB)/net/unix/dial.ha \ + $(STDLIB)/net/unix/listener.ha \ + $(STDLIB)/net/unix/options.ha + +$(HARECACHE)/net/unix/net_unix-freebsd.ssa: $(stdlib_net_unix_freebsd_srcs) $(stdlib_rt) $(stdlib_net_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_types_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_net_dial_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(HARECACHE)/net/unix + @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nnet::unix \ + -t$(HARECACHE)/net/unix/net_unix.td $(stdlib_net_unix_freebsd_srcs) + # math::random (+any) stdlib_math_random_any_srcs= \ $(STDLIB)/math/random/random.ha @@ -1021,12 +1313,27 @@ stdlib_os_linux_srcs= \ $(STDLIB)/os/+linux/fs.ha \ $(STDLIB)/os/fs.ha -$(HARECACHE)/os/os-linux.ssa: $(stdlib_os_linux_srcs) $(stdlib_rt) $(stdlib_io) $(stdlib_strings) $(stdlib_types) $(stdlib_fs) $(stdlib_encoding_utf8) $(stdlib_bytes) $(stdlib_bufio) $(stdlib_errors) +$(HARECACHE)/os/os-linux.ssa: $(stdlib_os_linux_srcs) $(stdlib_rt) $(stdlib_io_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_types_$(PLATFORM)) $(stdlib_fs_$(PLATFORM)) $(stdlib_encoding_utf8_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_bufio_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/os @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nos \ -t$(HARECACHE)/os/os.td $(stdlib_os_linux_srcs) +# os (+freebsd) +stdlib_os_freebsd_srcs= \ + $(STDLIB)/os/+freebsd/environ.ha \ + $(STDLIB)/os/+freebsd/exit.ha \ + $(STDLIB)/os/+freebsd/dirfdfs.ha \ + $(STDLIB)/os/+freebsd/stdfd.ha \ + $(STDLIB)/os/+freebsd/fs.ha \ + $(STDLIB)/os/fs.ha + +$(HARECACHE)/os/os-freebsd.ssa: $(stdlib_os_freebsd_srcs) $(stdlib_rt) $(stdlib_io_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_types_$(PLATFORM)) $(stdlib_fs_$(PLATFORM)) $(stdlib_encoding_utf8_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_bufio_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(HARECACHE)/os + @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nos \ + -t$(HARECACHE)/os/os.td $(stdlib_os_freebsd_srcs) + # os::exec (+linux) stdlib_os_exec_linux_srcs= \ $(STDLIB)/os/exec/exec+linux.ha \ @@ -1034,12 +1341,25 @@ stdlib_os_exec_linux_srcs= \ $(STDLIB)/os/exec/types.ha \ $(STDLIB)/os/exec/cmd.ha -$(HARECACHE)/os/exec/os_exec-linux.ssa: $(stdlib_os_exec_linux_srcs) $(stdlib_rt) $(stdlib_os) $(stdlib_strings) $(stdlib_fmt) $(stdlib_bytes) $(stdlib_path) $(stdlib_errors) +$(HARECACHE)/os/exec/os_exec-linux.ssa: $(stdlib_os_exec_linux_srcs) $(stdlib_rt) $(stdlib_os_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_path_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/os/exec @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nos::exec \ -t$(HARECACHE)/os/exec/os_exec.td $(stdlib_os_exec_linux_srcs) +# os::exec (+freebsd) +stdlib_os_exec_freebsd_srcs= \ + $(STDLIB)/os/exec/exec+freebsd.ha \ + $(STDLIB)/os/exec/process+freebsd.ha \ + $(STDLIB)/os/exec/types.ha \ + $(STDLIB)/os/exec/cmd.ha + +$(HARECACHE)/os/exec/os_exec-freebsd.ssa: $(stdlib_os_exec_freebsd_srcs) $(stdlib_rt) $(stdlib_os_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_path_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(HARECACHE)/os/exec + @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nos::exec \ + -t$(HARECACHE)/os/exec/os_exec.td $(stdlib_os_exec_freebsd_srcs) + # path (+any) stdlib_path_any_srcs= \ $(STDLIB)/path/+$(PLATFORM).ha \ @@ -1048,7 +1368,7 @@ stdlib_path_any_srcs= \ $(STDLIB)/path/names.ha \ $(STDLIB)/path/iter.ha -$(HARECACHE)/path/path-any.ssa: $(stdlib_path_any_srcs) $(stdlib_rt) $(stdlib_strings) $(stdlib_bufio) $(stdlib_bytes) +$(HARECACHE)/path/path-any.ssa: $(stdlib_path_any_srcs) $(stdlib_rt) $(stdlib_strings_$(PLATFORM)) $(stdlib_bufio_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/path @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Npath \ @@ -1059,7 +1379,7 @@ stdlib_slice_any_srcs= \ $(STDLIB)/slice/reverse.ha \ $(STDLIB)/slice/void.ha -$(HARECACHE)/slice/slice-any.ssa: $(stdlib_slice_any_srcs) $(stdlib_rt) $(stdlib_types) +$(HARECACHE)/slice/slice-any.ssa: $(stdlib_slice_any_srcs) $(stdlib_rt) $(stdlib_types_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/slice @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nslice \ @@ -1088,7 +1408,7 @@ stdlib_strconv_any_srcs= \ $(STDLIB)/strconv/stof.ha \ $(STDLIB)/strconv/stof_data.ha -$(HARECACHE)/strconv/strconv-any.ssa: $(stdlib_strconv_any_srcs) $(stdlib_rt) $(stdlib_types) $(stdlib_strings) $(stdlib_ascii) $(stdlib_math) +$(HARECACHE)/strconv/strconv-any.ssa: $(stdlib_strconv_any_srcs) $(stdlib_rt) $(stdlib_types_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_ascii_$(PLATFORM)) $(stdlib_math_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/strconv @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nstrconv \ @@ -1108,7 +1428,7 @@ stdlib_strings_any_srcs= \ $(STDLIB)/strings/index.ha \ $(STDLIB)/strings/trim.ha -$(HARECACHE)/strings/strings-any.ssa: $(stdlib_strings_any_srcs) $(stdlib_rt) $(stdlib_bytes) $(stdlib_encoding_utf8) $(stdlib_types) +$(HARECACHE)/strings/strings-any.ssa: $(stdlib_strings_any_srcs) $(stdlib_rt) $(stdlib_bytes_$(PLATFORM)) $(stdlib_encoding_utf8_$(PLATFORM)) $(stdlib_types_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/strings @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nstrings \ @@ -1120,7 +1440,7 @@ stdlib_strio_any_srcs= \ $(STDLIB)/strio/fixed.ha \ $(STDLIB)/strio/ops.ha -$(HARECACHE)/strio/strio-any.ssa: $(stdlib_strio_any_srcs) $(stdlib_rt) $(stdlib_io) $(stdlib_strings) $(stdlib_encoding_utf8) $(stdlib_errors) +$(HARECACHE)/strio/strio-any.ssa: $(stdlib_strio_any_srcs) $(stdlib_rt) $(stdlib_io_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_encoding_utf8_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/strio @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nstrio \ @@ -1130,12 +1450,22 @@ $(HARECACHE)/strio/strio-any.ssa: $(stdlib_strio_any_srcs) $(stdlib_rt) $(stdlib stdlib_temp_linux_srcs= \ $(STDLIB)/temp/+linux.ha -$(HARECACHE)/temp/temp-linux.ssa: $(stdlib_temp_linux_srcs) $(stdlib_rt) $(stdlib_crypto_random) $(stdlib_encoding_hex) $(stdlib_fs) $(stdlib_io) $(stdlib_os) $(stdlib_path) $(stdlib_strio) $(stdlib_fmt) $(stdlib_strings) +$(HARECACHE)/temp/temp-linux.ssa: $(stdlib_temp_linux_srcs) $(stdlib_rt) $(stdlib_crypto_random_$(PLATFORM)) $(stdlib_encoding_hex_$(PLATFORM)) $(stdlib_fs_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_path_$(PLATFORM)) $(stdlib_strio_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/temp @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ntemp \ -t$(HARECACHE)/temp/temp.td $(stdlib_temp_linux_srcs) +# temp (+freebsd) +stdlib_temp_freebsd_srcs= \ + $(STDLIB)/temp/+freebsd.ha + +$(HARECACHE)/temp/temp-freebsd.ssa: $(stdlib_temp_freebsd_srcs) $(stdlib_rt) $(stdlib_crypto_random_$(PLATFORM)) $(stdlib_encoding_hex_$(PLATFORM)) $(stdlib_fs_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_path_$(PLATFORM)) $(stdlib_strio_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(HARECACHE)/temp + @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ntemp \ + -t$(HARECACHE)/temp/temp.td $(stdlib_temp_freebsd_srcs) + # time (+linux) stdlib_time_linux_srcs= \ $(STDLIB)/time/+linux/functions.ha \ @@ -1143,12 +1473,24 @@ stdlib_time_linux_srcs= \ $(STDLIB)/time/arithm.ha \ $(STDLIB)/time/types.ha -$(HARECACHE)/time/time-linux.ssa: $(stdlib_time_linux_srcs) $(stdlib_rt) $(stdlib_linux_vdso) +$(HARECACHE)/time/time-linux.ssa: $(stdlib_time_linux_srcs) $(stdlib_rt) $(stdlib_linux_vdso_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/time @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ntime \ -t$(HARECACHE)/time/time.td $(stdlib_time_linux_srcs) +# time (+freebsd) +stdlib_time_freebsd_srcs= \ + $(STDLIB)/time/+freebsd/functions.ha \ + $(STDLIB)/time/arithm.ha \ + $(STDLIB)/time/types.ha + +$(HARECACHE)/time/time-freebsd.ssa: $(stdlib_time_freebsd_srcs) $(stdlib_rt) + @printf 'HAREC \t$@\n' + @mkdir -p $(HARECACHE)/time + @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ntime \ + -t$(HARECACHE)/time/time.td $(stdlib_time_freebsd_srcs) + # types (+any) stdlib_types_any_srcs= \ $(STDLIB)/types/limits.ha \ @@ -1171,17 +1513,31 @@ stdlib_unix_linux_srcs= \ $(STDLIB)/unix/getuid.ha \ $(STDLIB)/unix/setuid.ha -$(HARECACHE)/unix/unix-linux.ssa: $(stdlib_unix_linux_srcs) $(stdlib_rt) $(stdlib_errors) $(stdlib_fs) +$(HARECACHE)/unix/unix-linux.ssa: $(stdlib_unix_linux_srcs) $(stdlib_rt) $(stdlib_errors_$(PLATFORM)) $(stdlib_fs_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/unix @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nunix \ -t$(HARECACHE)/unix/unix.td $(stdlib_unix_linux_srcs) +# unix (+freebsd) +stdlib_unix_freebsd_srcs= \ + $(STDLIB)/unix/+freebsd/nice.ha \ + $(STDLIB)/unix/+freebsd/pipe.ha \ + $(STDLIB)/unix/+freebsd/umask.ha \ + $(STDLIB)/unix/getuid.ha \ + $(STDLIB)/unix/setuid.ha + +$(HARECACHE)/unix/unix-freebsd.ssa: $(stdlib_unix_freebsd_srcs) $(stdlib_rt) $(stdlib_errors_$(PLATFORM)) $(stdlib_fs_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(HARECACHE)/unix + @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nunix \ + -t$(HARECACHE)/unix/unix.td $(stdlib_unix_freebsd_srcs) + # unix::hosts (+any) stdlib_unix_hosts_any_srcs= \ $(STDLIB)/unix/hosts/lookup.ha -$(HARECACHE)/unix/hosts/unix_hosts-any.ssa: $(stdlib_unix_hosts_any_srcs) $(stdlib_rt) $(stdlib_os) $(stdlib_io) $(stdlib_bufio) $(stdlib_net_ip) $(stdlib_strings) +$(HARECACHE)/unix/hosts/unix_hosts-any.ssa: $(stdlib_unix_hosts_any_srcs) $(stdlib_rt) $(stdlib_os_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_bufio_$(PLATFORM)) $(stdlib_net_ip_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/unix/hosts @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nunix::hosts \ @@ -1193,7 +1549,7 @@ stdlib_unix_passwd_any_srcs= \ $(STDLIB)/unix/passwd/passwd.ha \ $(STDLIB)/unix/passwd/types.ha -$(HARECACHE)/unix/passwd/unix_passwd-any.ssa: $(stdlib_unix_passwd_any_srcs) $(stdlib_rt) $(stdlib_bufio) $(stdlib_io) $(stdlib_os) $(stdlib_strconv) $(stdlib_strings) +$(HARECACHE)/unix/passwd/unix_passwd-any.ssa: $(stdlib_unix_passwd_any_srcs) $(stdlib_rt) $(stdlib_bufio_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_strconv_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/unix/passwd @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nunix::passwd \ @@ -1203,17 +1559,27 @@ $(HARECACHE)/unix/passwd/unix_passwd-any.ssa: $(stdlib_unix_passwd_any_srcs) $(s stdlib_unix_poll_linux_srcs= \ $(STDLIB)/unix/poll/+linux.ha -$(HARECACHE)/unix/poll/unix_poll-linux.ssa: $(stdlib_unix_poll_linux_srcs) $(stdlib_rt) $(stdlib_rt) $(stdlib_errors) $(stdlib_time) +$(HARECACHE)/unix/poll/unix_poll-linux.ssa: $(stdlib_unix_poll_linux_srcs) $(stdlib_rt) $(stdlib_rt_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_time_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/unix/poll @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nunix::poll \ -t$(HARECACHE)/unix/poll/unix_poll.td $(stdlib_unix_poll_linux_srcs) +# unix::poll (+freebsd) +stdlib_unix_poll_freebsd_srcs= \ + $(STDLIB)/unix/poll/+freebsd.ha + +$(HARECACHE)/unix/poll/unix_poll-freebsd.ssa: $(stdlib_unix_poll_freebsd_srcs) $(stdlib_rt) $(stdlib_rt_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) $(stdlib_time_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(HARECACHE)/unix/poll + @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nunix::poll \ + -t$(HARECACHE)/unix/poll/unix_poll.td $(stdlib_unix_poll_freebsd_srcs) + # unix::resolvconf (+any) stdlib_unix_resolvconf_any_srcs= \ $(STDLIB)/unix/resolvconf/load.ha -$(HARECACHE)/unix/resolvconf/unix_resolvconf-any.ssa: $(stdlib_unix_resolvconf_any_srcs) $(stdlib_rt) $(stdlib_os) $(stdlib_io) $(stdlib_bufio) $(stdlib_net_ip) $(stdlib_strings) +$(HARECACHE)/unix/resolvconf/unix_resolvconf-any.ssa: $(stdlib_unix_resolvconf_any_srcs) $(stdlib_rt) $(stdlib_os_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_bufio_$(PLATFORM)) $(stdlib_net_ip_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/unix/resolvconf @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nunix::resolvconf \ @@ -1226,17 +1592,30 @@ stdlib_unix_tty_linux_srcs= \ $(STDLIB)/unix/tty/+linux/open.ha \ $(STDLIB)/unix/tty/+linux/winsize.ha -$(HARECACHE)/unix/tty/unix_tty-linux.ssa: $(stdlib_unix_tty_linux_srcs) $(stdlib_rt) $(stdlib_rt) $(stdlib_fs) $(stdlib_io) $(stdlib_os) +$(HARECACHE)/unix/tty/unix_tty-linux.ssa: $(stdlib_unix_tty_linux_srcs) $(stdlib_rt) $(stdlib_rt_$(PLATFORM)) $(stdlib_fs_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/unix/tty @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nunix::tty \ -t$(HARECACHE)/unix/tty/unix_tty.td $(stdlib_unix_tty_linux_srcs) +# unix::tty (+freebsd) +stdlib_unix_tty_freebsd_srcs= \ + $(STDLIB)/unix/tty/types.ha \ + $(STDLIB)/unix/tty/+freebsd/isatty.ha \ + $(STDLIB)/unix/tty/+freebsd/open.ha \ + $(STDLIB)/unix/tty/+freebsd/winsize.ha + +$(HARECACHE)/unix/tty/unix_tty-freebsd.ssa: $(stdlib_unix_tty_freebsd_srcs) $(stdlib_rt) $(stdlib_rt_$(PLATFORM)) $(stdlib_fs_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(HARECACHE)/unix/tty + @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nunix::tty \ + -t$(HARECACHE)/unix/tty/unix_tty.td $(stdlib_unix_tty_freebsd_srcs) + # uuid (+any) stdlib_uuid_any_srcs= \ $(STDLIB)/uuid/uuid.ha -$(HARECACHE)/uuid/uuid-any.ssa: $(stdlib_uuid_any_srcs) $(stdlib_rt) $(stdlib_crypto_random) $(stdlib_strio) $(stdlib_fmt) $(stdlib_endian) $(stdlib_io) $(stdlib_bytes) $(stdlib_bufio) $(stdlib_strings) $(stdlib_strconv) +$(HARECACHE)/uuid/uuid-any.ssa: $(stdlib_uuid_any_srcs) $(stdlib_rt) $(stdlib_crypto_random_$(PLATFORM)) $(stdlib_strio_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_endian_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) $(stdlib_bufio_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_strconv_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/uuid @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nuuid \ @@ -1275,12 +1654,48 @@ testlib_rt_linux_srcs= \ $(STDLIB)/rt/+test/run.ha \ $(STDLIB)/rt/+test/ztos.ha +# rt (+freebsd) +testlib_rt_freebsd_srcs= \ + $(STDLIB)/rt/+freebsd/abort.ha \ + $(STDLIB)/rt/+freebsd/env.ha \ + $(STDLIB)/rt/+freebsd/errno.ha \ + $(STDLIB)/rt/+freebsd/platformstart.ha \ + $(STDLIB)/rt/+freebsd/segmalloc.ha \ + $(STDLIB)/rt/+freebsd/signal.ha \ + $(STDLIB)/rt/+freebsd/socket.ha \ + $(STDLIB)/rt/+freebsd/syscallno.ha \ + $(STDLIB)/rt/+freebsd/syscalls.ha \ + $(STDLIB)/rt/+freebsd/types.ha \ + $(STDLIB)/rt/+$(ARCH)/jmp.ha \ + $(STDLIB)/rt/+$(ARCH)/backtrace.ha \ + $(STDLIB)/rt/types_arch+$(ARCH).ha \ + $(STDLIB)/rt/ensure.ha \ + $(STDLIB)/rt/jmp.ha \ + $(STDLIB)/rt/malloc.ha \ + $(STDLIB)/rt/memcpy.ha \ + $(STDLIB)/rt/memmove.ha \ + $(STDLIB)/rt/memset.ha \ + $(STDLIB)/rt/strcmp.ha \ + $(STDLIB)/rt/types.ha \ + $(STDLIB)/rt/start+test.ha \ + $(STDLIB)/rt/abort+test.ha \ + $(STDLIB)/rt/+test/+$(PLATFORM).ha \ + $(STDLIB)/rt/+test/cstring.ha \ + $(STDLIB)/rt/+test/run.ha \ + $(STDLIB)/rt/+test/ztos.ha + $(TESTCACHE)/rt/rt-linux.ssa: $(testlib_rt_linux_srcs) $(testlib_rt) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/rt @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nrt \ -t$(TESTCACHE)/rt/rt.td $(testlib_rt_linux_srcs) +$(TESTCACHE)/rt/rt-freebsd.ssa: $(testlib_rt_freebsd_srcs) $(testlib_rt) + @printf 'HAREC \t$@\n' + @mkdir -p $(TESTCACHE)/rt + @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nrt \ + -t$(TESTCACHE)/rt/rt.td $(testlib_rt_freebsd_srcs) + $(TESTCACHE)/rt/start.o: $(STDLIB)/rt/+$(PLATFORM)/start+$(ARCH).s @printf 'AS \t$@\n' @mkdir -p $(TESTCACHE)/rt @@ -1322,303 +1737,471 @@ $(TESTCACHE)/rt/rt-linux.a: $(TESTCACHE)/rt/rt-linux.o $(testlib_asm) @printf 'AR\t$@\n' @$(AR) -csr $@ $(TESTCACHE)/rt/rt-linux.o $(testlib_asm) +$(TESTCACHE)/rt/rt-freebsd.a: $(TESTCACHE)/rt/rt-freebsd.o $(testlib_asm) + @printf 'AR\t$@\n' + @$(AR) -csr $@ $(TESTCACHE)/rt/rt-freebsd.o $(testlib_asm) + testlib_rt=$(TESTCACHE)/rt/rt-$(PLATFORM).a -hare_testlib_deps+=$(testlib_rt) +testlib_deps_linux+=$(testlib_rt) +testlib_deps_freebsd+=$(testlib_rt) +testlib_deps_any+=$(testlib_rt) # gen_lib ascii (any) -testlib_ascii=$(TESTCACHE)/ascii/ascii-any.o -hare_testlib_deps+=$(testlib_ascii) +testlib_ascii_any=$(TESTCACHE)/ascii/ascii-any.o +testlib_deps_any+=$(testlib_ascii_any) +testlib_ascii_linux=$(testlib_ascii_any) +testlib_ascii_freebsd=$(testlib_ascii_any) # gen_lib bufio (any) -testlib_bufio=$(TESTCACHE)/bufio/bufio-any.o -hare_testlib_deps+=$(testlib_bufio) +testlib_bufio_any=$(TESTCACHE)/bufio/bufio-any.o +testlib_deps_any+=$(testlib_bufio_any) +testlib_bufio_linux=$(testlib_bufio_any) +testlib_bufio_freebsd=$(testlib_bufio_any) # gen_lib bytes (any) -testlib_bytes=$(TESTCACHE)/bytes/bytes-any.o -hare_testlib_deps+=$(testlib_bytes) +testlib_bytes_any=$(TESTCACHE)/bytes/bytes-any.o +testlib_deps_any+=$(testlib_bytes_any) +testlib_bytes_linux=$(testlib_bytes_any) +testlib_bytes_freebsd=$(testlib_bytes_any) # gen_lib compress::flate (any) -testlib_compress_flate=$(TESTCACHE)/compress/flate/compress_flate-any.o -hare_testlib_deps+=$(testlib_compress_flate) +testlib_compress_flate_any=$(TESTCACHE)/compress/flate/compress_flate-any.o +testlib_deps_any+=$(testlib_compress_flate_any) +testlib_compress_flate_linux=$(testlib_compress_flate_any) +testlib_compress_flate_freebsd=$(testlib_compress_flate_any) # gen_lib compress::zlib (any) -testlib_compress_zlib=$(TESTCACHE)/compress/zlib/compress_zlib-any.o -hare_testlib_deps+=$(testlib_compress_zlib) +testlib_compress_zlib_any=$(TESTCACHE)/compress/zlib/compress_zlib-any.o +testlib_deps_any+=$(testlib_compress_zlib_any) +testlib_compress_zlib_linux=$(testlib_compress_zlib_any) +testlib_compress_zlib_freebsd=$(testlib_compress_zlib_any) # gen_lib crypto::blake2b (any) -testlib_crypto_blake2b=$(TESTCACHE)/crypto/blake2b/crypto_blake2b-any.o -hare_testlib_deps+=$(testlib_crypto_blake2b) +testlib_crypto_blake2b_any=$(TESTCACHE)/crypto/blake2b/crypto_blake2b-any.o +testlib_deps_any+=$(testlib_crypto_blake2b_any) +testlib_crypto_blake2b_linux=$(testlib_crypto_blake2b_any) +testlib_crypto_blake2b_freebsd=$(testlib_crypto_blake2b_any) # gen_lib crypto::math (any) -testlib_crypto_math=$(TESTCACHE)/crypto/math/crypto_math-any.o -hare_testlib_deps+=$(testlib_crypto_math) +testlib_crypto_math_any=$(TESTCACHE)/crypto/math/crypto_math-any.o +testlib_deps_any+=$(testlib_crypto_math_any) +testlib_crypto_math_linux=$(testlib_crypto_math_any) +testlib_crypto_math_freebsd=$(testlib_crypto_math_any) # gen_lib crypto::random (linux) -testlib_crypto_random=$(TESTCACHE)/crypto/random/crypto_random-linux.o -hare_testlib_deps+=$(testlib_crypto_random) +testlib_crypto_random_linux=$(TESTCACHE)/crypto/random/crypto_random-linux.o +testlib_deps_linux+=$(testlib_crypto_random_linux) + +# gen_lib crypto::random (freebsd) +testlib_crypto_random_freebsd=$(TESTCACHE)/crypto/random/crypto_random-freebsd.o +testlib_deps_freebsd+=$(testlib_crypto_random_freebsd) # gen_lib crypto::md5 (any) -testlib_crypto_md5=$(TESTCACHE)/crypto/md5/crypto_md5-any.o -hare_testlib_deps+=$(testlib_crypto_md5) +testlib_crypto_md5_any=$(TESTCACHE)/crypto/md5/crypto_md5-any.o +testlib_deps_any+=$(testlib_crypto_md5_any) +testlib_crypto_md5_linux=$(testlib_crypto_md5_any) +testlib_crypto_md5_freebsd=$(testlib_crypto_md5_any) # gen_lib crypto::sha1 (any) -testlib_crypto_sha1=$(TESTCACHE)/crypto/sha1/crypto_sha1-any.o -hare_testlib_deps+=$(testlib_crypto_sha1) +testlib_crypto_sha1_any=$(TESTCACHE)/crypto/sha1/crypto_sha1-any.o +testlib_deps_any+=$(testlib_crypto_sha1_any) +testlib_crypto_sha1_linux=$(testlib_crypto_sha1_any) +testlib_crypto_sha1_freebsd=$(testlib_crypto_sha1_any) # gen_lib crypto::sha256 (any) -testlib_crypto_sha256=$(TESTCACHE)/crypto/sha256/crypto_sha256-any.o -hare_testlib_deps+=$(testlib_crypto_sha256) +testlib_crypto_sha256_any=$(TESTCACHE)/crypto/sha256/crypto_sha256-any.o +testlib_deps_any+=$(testlib_crypto_sha256_any) +testlib_crypto_sha256_linux=$(testlib_crypto_sha256_any) +testlib_crypto_sha256_freebsd=$(testlib_crypto_sha256_any) # gen_lib crypto::sha512 (any) -testlib_crypto_sha512=$(TESTCACHE)/crypto/sha512/crypto_sha512-any.o -hare_testlib_deps+=$(testlib_crypto_sha512) +testlib_crypto_sha512_any=$(TESTCACHE)/crypto/sha512/crypto_sha512-any.o +testlib_deps_any+=$(testlib_crypto_sha512_any) +testlib_crypto_sha512_linux=$(testlib_crypto_sha512_any) +testlib_crypto_sha512_freebsd=$(testlib_crypto_sha512_any) # gen_lib dirs (any) -testlib_dirs=$(TESTCACHE)/dirs/dirs-any.o -hare_testlib_deps+=$(testlib_dirs) +testlib_dirs_any=$(TESTCACHE)/dirs/dirs-any.o +testlib_deps_any+=$(testlib_dirs_any) +testlib_dirs_linux=$(testlib_dirs_any) +testlib_dirs_freebsd=$(testlib_dirs_any) # gen_lib encoding::base64 (any) -testlib_encoding_base64=$(TESTCACHE)/encoding/base64/encoding_base64-any.o -hare_testlib_deps+=$(testlib_encoding_base64) +testlib_encoding_base64_any=$(TESTCACHE)/encoding/base64/encoding_base64-any.o +testlib_deps_any+=$(testlib_encoding_base64_any) +testlib_encoding_base64_linux=$(testlib_encoding_base64_any) +testlib_encoding_base64_freebsd=$(testlib_encoding_base64_any) # gen_lib encoding::hex (any) -testlib_encoding_hex=$(TESTCACHE)/encoding/hex/encoding_hex-any.o -hare_testlib_deps+=$(testlib_encoding_hex) +testlib_encoding_hex_any=$(TESTCACHE)/encoding/hex/encoding_hex-any.o +testlib_deps_any+=$(testlib_encoding_hex_any) +testlib_encoding_hex_linux=$(testlib_encoding_hex_any) +testlib_encoding_hex_freebsd=$(testlib_encoding_hex_any) # gen_lib encoding::utf8 (any) -testlib_encoding_utf8=$(TESTCACHE)/encoding/utf8/encoding_utf8-any.o -hare_testlib_deps+=$(testlib_encoding_utf8) +testlib_encoding_utf8_any=$(TESTCACHE)/encoding/utf8/encoding_utf8-any.o +testlib_deps_any+=$(testlib_encoding_utf8_any) +testlib_encoding_utf8_linux=$(testlib_encoding_utf8_any) +testlib_encoding_utf8_freebsd=$(testlib_encoding_utf8_any) # gen_lib endian (any) -testlib_endian=$(TESTCACHE)/endian/endian-any.o -hare_testlib_deps+=$(testlib_endian) +testlib_endian_any=$(TESTCACHE)/endian/endian-any.o +testlib_deps_any+=$(testlib_endian_any) +testlib_endian_linux=$(testlib_endian_any) +testlib_endian_freebsd=$(testlib_endian_any) # gen_lib errors (any) -testlib_errors=$(TESTCACHE)/errors/errors-any.o -hare_testlib_deps+=$(testlib_errors) +testlib_errors_any=$(TESTCACHE)/errors/errors-any.o +testlib_deps_any+=$(testlib_errors_any) +testlib_errors_linux=$(testlib_errors_any) +testlib_errors_freebsd=$(testlib_errors_any) # gen_lib fmt (any) -testlib_fmt=$(TESTCACHE)/fmt/fmt-any.o -hare_testlib_deps+=$(testlib_fmt) +testlib_fmt_any=$(TESTCACHE)/fmt/fmt-any.o +testlib_deps_any+=$(testlib_fmt_any) +testlib_fmt_linux=$(testlib_fmt_any) +testlib_fmt_freebsd=$(testlib_fmt_any) # gen_lib fnmatch (any) -testlib_fnmatch=$(TESTCACHE)/fnmatch/fnmatch-any.o -hare_testlib_deps+=$(testlib_fnmatch) +testlib_fnmatch_any=$(TESTCACHE)/fnmatch/fnmatch-any.o +testlib_deps_any+=$(testlib_fnmatch_any) +testlib_fnmatch_linux=$(testlib_fnmatch_any) +testlib_fnmatch_freebsd=$(testlib_fnmatch_any) # gen_lib format::elf (any) -testlib_format_elf=$(TESTCACHE)/format/elf/format_elf-any.o -hare_testlib_deps+=$(testlib_format_elf) +testlib_format_elf_any=$(TESTCACHE)/format/elf/format_elf-any.o +testlib_deps_any+=$(testlib_format_elf_any) +testlib_format_elf_linux=$(testlib_format_elf_any) +testlib_format_elf_freebsd=$(testlib_format_elf_any) # gen_lib format::ini (any) -testlib_format_ini=$(TESTCACHE)/format/ini/format_ini-any.o -hare_testlib_deps+=$(testlib_format_ini) +testlib_format_ini_any=$(TESTCACHE)/format/ini/format_ini-any.o +testlib_deps_any+=$(testlib_format_ini_any) +testlib_format_ini_linux=$(testlib_format_ini_any) +testlib_format_ini_freebsd=$(testlib_format_ini_any) # gen_lib format::xml (any) -testlib_format_xml=$(TESTCACHE)/format/xml/format_xml-any.o -hare_testlib_deps+=$(testlib_format_xml) +testlib_format_xml_any=$(TESTCACHE)/format/xml/format_xml-any.o +testlib_deps_any+=$(testlib_format_xml_any) +testlib_format_xml_linux=$(testlib_format_xml_any) +testlib_format_xml_freebsd=$(testlib_format_xml_any) # gen_lib fs (any) -testlib_fs=$(TESTCACHE)/fs/fs-any.o -hare_testlib_deps+=$(testlib_fs) +testlib_fs_any=$(TESTCACHE)/fs/fs-any.o +testlib_deps_any+=$(testlib_fs_any) +testlib_fs_linux=$(testlib_fs_any) +testlib_fs_freebsd=$(testlib_fs_any) # gen_lib fs::mem (any) -testlib_fs_mem=$(TESTCACHE)/fs/mem/fs_mem-any.o -hare_testlib_deps+=$(testlib_fs_mem) +testlib_fs_mem_any=$(TESTCACHE)/fs/mem/fs_mem-any.o +testlib_deps_any+=$(testlib_fs_mem_any) +testlib_fs_mem_linux=$(testlib_fs_mem_any) +testlib_fs_mem_freebsd=$(testlib_fs_mem_any) # gen_lib getopt (any) -testlib_getopt=$(TESTCACHE)/getopt/getopt-any.o -hare_testlib_deps+=$(testlib_getopt) +testlib_getopt_any=$(TESTCACHE)/getopt/getopt-any.o +testlib_deps_any+=$(testlib_getopt_any) +testlib_getopt_linux=$(testlib_getopt_any) +testlib_getopt_freebsd=$(testlib_getopt_any) # gen_lib hare::ast (any) -testlib_hare_ast=$(TESTCACHE)/hare/ast/hare_ast-any.o -hare_testlib_deps+=$(testlib_hare_ast) +testlib_hare_ast_any=$(TESTCACHE)/hare/ast/hare_ast-any.o +testlib_deps_any+=$(testlib_hare_ast_any) +testlib_hare_ast_linux=$(testlib_hare_ast_any) +testlib_hare_ast_freebsd=$(testlib_hare_ast_any) # gen_lib hare::lex (any) -testlib_hare_lex=$(TESTCACHE)/hare/lex/hare_lex-any.o -hare_testlib_deps+=$(testlib_hare_lex) +testlib_hare_lex_any=$(TESTCACHE)/hare/lex/hare_lex-any.o +testlib_deps_any+=$(testlib_hare_lex_any) +testlib_hare_lex_linux=$(testlib_hare_lex_any) +testlib_hare_lex_freebsd=$(testlib_hare_lex_any) # gen_lib hare::module (any) -testlib_hare_module=$(TESTCACHE)/hare/module/hare_module-any.o -hare_testlib_deps+=$(testlib_hare_module) +testlib_hare_module_any=$(TESTCACHE)/hare/module/hare_module-any.o +testlib_deps_any+=$(testlib_hare_module_any) +testlib_hare_module_linux=$(testlib_hare_module_any) +testlib_hare_module_freebsd=$(testlib_hare_module_any) # gen_lib hare::parse (any) -testlib_hare_parse=$(TESTCACHE)/hare/parse/hare_parse-any.o -hare_testlib_deps+=$(testlib_hare_parse) +testlib_hare_parse_any=$(TESTCACHE)/hare/parse/hare_parse-any.o +testlib_deps_any+=$(testlib_hare_parse_any) +testlib_hare_parse_linux=$(testlib_hare_parse_any) +testlib_hare_parse_freebsd=$(testlib_hare_parse_any) # gen_lib hare::types (any) -testlib_hare_types=$(TESTCACHE)/hare/types/hare_types-any.o -hare_testlib_deps+=$(testlib_hare_types) +testlib_hare_types_any=$(TESTCACHE)/hare/types/hare_types-any.o +testlib_deps_any+=$(testlib_hare_types_any) +testlib_hare_types_linux=$(testlib_hare_types_any) +testlib_hare_types_freebsd=$(testlib_hare_types_any) # gen_lib hare::unit (any) -testlib_hare_unit=$(TESTCACHE)/hare/unit/hare_unit-any.o -hare_testlib_deps+=$(testlib_hare_unit) +testlib_hare_unit_any=$(TESTCACHE)/hare/unit/hare_unit-any.o +testlib_deps_any+=$(testlib_hare_unit_any) +testlib_hare_unit_linux=$(testlib_hare_unit_any) +testlib_hare_unit_freebsd=$(testlib_hare_unit_any) # gen_lib hare::unparse (any) -testlib_hare_unparse=$(TESTCACHE)/hare/unparse/hare_unparse-any.o -hare_testlib_deps+=$(testlib_hare_unparse) +testlib_hare_unparse_any=$(TESTCACHE)/hare/unparse/hare_unparse-any.o +testlib_deps_any+=$(testlib_hare_unparse_any) +testlib_hare_unparse_linux=$(testlib_hare_unparse_any) +testlib_hare_unparse_freebsd=$(testlib_hare_unparse_any) # gen_lib hash (any) -testlib_hash=$(TESTCACHE)/hash/hash-any.o -hare_testlib_deps+=$(testlib_hash) +testlib_hash_any=$(TESTCACHE)/hash/hash-any.o +testlib_deps_any+=$(testlib_hash_any) +testlib_hash_linux=$(testlib_hash_any) +testlib_hash_freebsd=$(testlib_hash_any) # gen_lib hash::adler32 (any) -testlib_hash_adler32=$(TESTCACHE)/hash/adler32/hash_adler32-any.o -hare_testlib_deps+=$(testlib_hash_adler32) +testlib_hash_adler32_any=$(TESTCACHE)/hash/adler32/hash_adler32-any.o +testlib_deps_any+=$(testlib_hash_adler32_any) +testlib_hash_adler32_linux=$(testlib_hash_adler32_any) +testlib_hash_adler32_freebsd=$(testlib_hash_adler32_any) # gen_lib hash::crc16 (any) -testlib_hash_crc16=$(TESTCACHE)/hash/crc16/hash_crc16-any.o -hare_testlib_deps+=$(testlib_hash_crc16) +testlib_hash_crc16_any=$(TESTCACHE)/hash/crc16/hash_crc16-any.o +testlib_deps_any+=$(testlib_hash_crc16_any) +testlib_hash_crc16_linux=$(testlib_hash_crc16_any) +testlib_hash_crc16_freebsd=$(testlib_hash_crc16_any) # gen_lib hash::crc32 (any) -testlib_hash_crc32=$(TESTCACHE)/hash/crc32/hash_crc32-any.o -hare_testlib_deps+=$(testlib_hash_crc32) +testlib_hash_crc32_any=$(TESTCACHE)/hash/crc32/hash_crc32-any.o +testlib_deps_any+=$(testlib_hash_crc32_any) +testlib_hash_crc32_linux=$(testlib_hash_crc32_any) +testlib_hash_crc32_freebsd=$(testlib_hash_crc32_any) # gen_lib hash::crc64 (any) -testlib_hash_crc64=$(TESTCACHE)/hash/crc64/hash_crc64-any.o -hare_testlib_deps+=$(testlib_hash_crc64) +testlib_hash_crc64_any=$(TESTCACHE)/hash/crc64/hash_crc64-any.o +testlib_deps_any+=$(testlib_hash_crc64_any) +testlib_hash_crc64_linux=$(testlib_hash_crc64_any) +testlib_hash_crc64_freebsd=$(testlib_hash_crc64_any) # gen_lib hash::fnv (any) -testlib_hash_fnv=$(TESTCACHE)/hash/fnv/hash_fnv-any.o -hare_testlib_deps+=$(testlib_hash_fnv) +testlib_hash_fnv_any=$(TESTCACHE)/hash/fnv/hash_fnv-any.o +testlib_deps_any+=$(testlib_hash_fnv_any) +testlib_hash_fnv_linux=$(testlib_hash_fnv_any) +testlib_hash_fnv_freebsd=$(testlib_hash_fnv_any) # gen_lib io (linux) -testlib_io=$(TESTCACHE)/io/io-linux.o -hare_testlib_deps+=$(testlib_io) +testlib_io_linux=$(TESTCACHE)/io/io-linux.o +testlib_deps_linux+=$(testlib_io_linux) + +# gen_lib io (freebsd) +testlib_io_freebsd=$(TESTCACHE)/io/io-freebsd.o +testlib_deps_freebsd+=$(testlib_io_freebsd) # gen_lib iobus::io_uring (linux) -testlib_iobus_io_uring=$(TESTCACHE)/iobus/io_uring/iobus_io_uring-linux.o -hare_testlib_deps+=$(testlib_iobus_io_uring) +testlib_iobus_io_uring_linux=$(TESTCACHE)/iobus/io_uring/iobus_io_uring-linux.o +testlib_deps_linux+=$(testlib_iobus_io_uring_linux) # gen_lib linux (linux) -testlib_linux=$(TESTCACHE)/linux/linux-linux.o -hare_testlib_deps+=$(testlib_linux) +testlib_linux_linux=$(TESTCACHE)/linux/linux-linux.o +testlib_deps_linux+=$(testlib_linux_linux) # gen_lib linux::signalfd (linux) -testlib_linux_signalfd=$(TESTCACHE)/linux/signalfd/linux_signalfd-linux.o -hare_testlib_deps+=$(testlib_linux_signalfd) +testlib_linux_signalfd_linux=$(TESTCACHE)/linux/signalfd/linux_signalfd-linux.o +testlib_deps_linux+=$(testlib_linux_signalfd_linux) # gen_lib linux::io_uring (linux) -testlib_linux_io_uring=$(TESTCACHE)/linux/io_uring/linux_io_uring-linux.o -hare_testlib_deps+=$(testlib_linux_io_uring) +testlib_linux_io_uring_linux=$(TESTCACHE)/linux/io_uring/linux_io_uring-linux.o +testlib_deps_linux+=$(testlib_linux_io_uring_linux) # gen_lib linux::vdso (linux) -testlib_linux_vdso=$(TESTCACHE)/linux/vdso/linux_vdso-linux.o -hare_testlib_deps+=$(testlib_linux_vdso) +testlib_linux_vdso_linux=$(TESTCACHE)/linux/vdso/linux_vdso-linux.o +testlib_deps_linux+=$(testlib_linux_vdso_linux) # gen_lib math (any) -testlib_math=$(TESTCACHE)/math/math-any.o -hare_testlib_deps+=$(testlib_math) +testlib_math_any=$(TESTCACHE)/math/math-any.o +testlib_deps_any+=$(testlib_math_any) +testlib_math_linux=$(testlib_math_any) +testlib_math_freebsd=$(testlib_math_any) # gen_lib net (linux) -testlib_net=$(TESTCACHE)/net/net-linux.o -hare_testlib_deps+=$(testlib_net) +testlib_net_linux=$(TESTCACHE)/net/net-linux.o +testlib_deps_linux+=$(testlib_net_linux) + +# gen_lib net (freebsd) +testlib_net_freebsd=$(TESTCACHE)/net/net-freebsd.o +testlib_deps_freebsd+=$(testlib_net_freebsd) # gen_lib net::dial (any) -testlib_net_dial=$(TESTCACHE)/net/dial/net_dial-any.o -hare_testlib_deps+=$(testlib_net_dial) +testlib_net_dial_any=$(TESTCACHE)/net/dial/net_dial-any.o +testlib_deps_any+=$(testlib_net_dial_any) +testlib_net_dial_linux=$(testlib_net_dial_any) +testlib_net_dial_freebsd=$(testlib_net_dial_any) # gen_lib net::dns (any) -testlib_net_dns=$(TESTCACHE)/net/dns/net_dns-any.o -hare_testlib_deps+=$(testlib_net_dns) +testlib_net_dns_any=$(TESTCACHE)/net/dns/net_dns-any.o +testlib_deps_any+=$(testlib_net_dns_any) +testlib_net_dns_linux=$(testlib_net_dns_any) +testlib_net_dns_freebsd=$(testlib_net_dns_any) # gen_lib net::ip (linux) -testlib_net_ip=$(TESTCACHE)/net/ip/net_ip-linux.o -hare_testlib_deps+=$(testlib_net_ip) +testlib_net_ip_linux=$(TESTCACHE)/net/ip/net_ip-linux.o +testlib_deps_linux+=$(testlib_net_ip_linux) + +# gen_lib net::ip (freebsd) +testlib_net_ip_freebsd=$(TESTCACHE)/net/ip/net_ip-freebsd.o +testlib_deps_freebsd+=$(testlib_net_ip_freebsd) # gen_lib net::tcp (linux) -testlib_net_tcp=$(TESTCACHE)/net/tcp/net_tcp-linux.o -hare_testlib_deps+=$(testlib_net_tcp) +testlib_net_tcp_linux=$(TESTCACHE)/net/tcp/net_tcp-linux.o +testlib_deps_linux+=$(testlib_net_tcp_linux) + +# gen_lib net::tcp (freebsd) +testlib_net_tcp_freebsd=$(TESTCACHE)/net/tcp/net_tcp-freebsd.o +testlib_deps_freebsd+=$(testlib_net_tcp_freebsd) # gen_lib net::udp (linux) -testlib_net_udp=$(TESTCACHE)/net/udp/net_udp-linux.o -hare_testlib_deps+=$(testlib_net_udp) +testlib_net_udp_linux=$(TESTCACHE)/net/udp/net_udp-linux.o +testlib_deps_linux+=$(testlib_net_udp_linux) + +# gen_lib net::udp (freebsd) +testlib_net_udp_freebsd=$(TESTCACHE)/net/udp/net_udp-freebsd.o +testlib_deps_freebsd+=$(testlib_net_udp_freebsd) # gen_lib net::unix (linux) -testlib_net_unix=$(TESTCACHE)/net/unix/net_unix-linux.o -hare_testlib_deps+=$(testlib_net_unix) +testlib_net_unix_linux=$(TESTCACHE)/net/unix/net_unix-linux.o +testlib_deps_linux+=$(testlib_net_unix_linux) + +# gen_lib net::unix (freebsd) +testlib_net_unix_freebsd=$(TESTCACHE)/net/unix/net_unix-freebsd.o +testlib_deps_freebsd+=$(testlib_net_unix_freebsd) # gen_lib math::random (any) -testlib_math_random=$(TESTCACHE)/math/random/math_random-any.o -hare_testlib_deps+=$(testlib_math_random) +testlib_math_random_any=$(TESTCACHE)/math/random/math_random-any.o +testlib_deps_any+=$(testlib_math_random_any) +testlib_math_random_linux=$(testlib_math_random_any) +testlib_math_random_freebsd=$(testlib_math_random_any) # gen_lib os (linux) -testlib_os=$(TESTCACHE)/os/os-linux.o -hare_testlib_deps+=$(testlib_os) +testlib_os_linux=$(TESTCACHE)/os/os-linux.o +testlib_deps_linux+=$(testlib_os_linux) + +# gen_lib os (freebsd) +testlib_os_freebsd=$(TESTCACHE)/os/os-freebsd.o +testlib_deps_freebsd+=$(testlib_os_freebsd) # gen_lib os::exec (linux) -testlib_os_exec=$(TESTCACHE)/os/exec/os_exec-linux.o -hare_testlib_deps+=$(testlib_os_exec) +testlib_os_exec_linux=$(TESTCACHE)/os/exec/os_exec-linux.o +testlib_deps_linux+=$(testlib_os_exec_linux) + +# gen_lib os::exec (freebsd) +testlib_os_exec_freebsd=$(TESTCACHE)/os/exec/os_exec-freebsd.o +testlib_deps_freebsd+=$(testlib_os_exec_freebsd) # gen_lib path (any) -testlib_path=$(TESTCACHE)/path/path-any.o -hare_testlib_deps+=$(testlib_path) +testlib_path_any=$(TESTCACHE)/path/path-any.o +testlib_deps_any+=$(testlib_path_any) +testlib_path_linux=$(testlib_path_any) +testlib_path_freebsd=$(testlib_path_any) # gen_lib slice (any) -testlib_slice=$(TESTCACHE)/slice/slice-any.o -hare_testlib_deps+=$(testlib_slice) +testlib_slice_any=$(TESTCACHE)/slice/slice-any.o +testlib_deps_any+=$(testlib_slice_any) +testlib_slice_linux=$(testlib_slice_any) +testlib_slice_freebsd=$(testlib_slice_any) # gen_lib sort (any) -testlib_sort=$(TESTCACHE)/sort/sort-any.o -hare_testlib_deps+=$(testlib_sort) +testlib_sort_any=$(TESTCACHE)/sort/sort-any.o +testlib_deps_any+=$(testlib_sort_any) +testlib_sort_linux=$(testlib_sort_any) +testlib_sort_freebsd=$(testlib_sort_any) # gen_lib strconv (any) -testlib_strconv=$(TESTCACHE)/strconv/strconv-any.o -hare_testlib_deps+=$(testlib_strconv) +testlib_strconv_any=$(TESTCACHE)/strconv/strconv-any.o +testlib_deps_any+=$(testlib_strconv_any) +testlib_strconv_linux=$(testlib_strconv_any) +testlib_strconv_freebsd=$(testlib_strconv_any) # gen_lib strings (any) -testlib_strings=$(TESTCACHE)/strings/strings-any.o -hare_testlib_deps+=$(testlib_strings) +testlib_strings_any=$(TESTCACHE)/strings/strings-any.o +testlib_deps_any+=$(testlib_strings_any) +testlib_strings_linux=$(testlib_strings_any) +testlib_strings_freebsd=$(testlib_strings_any) # gen_lib strio (any) -testlib_strio=$(TESTCACHE)/strio/strio-any.o -hare_testlib_deps+=$(testlib_strio) +testlib_strio_any=$(TESTCACHE)/strio/strio-any.o +testlib_deps_any+=$(testlib_strio_any) +testlib_strio_linux=$(testlib_strio_any) +testlib_strio_freebsd=$(testlib_strio_any) # gen_lib temp (linux) -testlib_temp=$(TESTCACHE)/temp/temp-linux.o -hare_testlib_deps+=$(testlib_temp) +testlib_temp_linux=$(TESTCACHE)/temp/temp-linux.o +testlib_deps_linux+=$(testlib_temp_linux) + +# gen_lib temp (freebsd) +testlib_temp_freebsd=$(TESTCACHE)/temp/temp-freebsd.o +testlib_deps_freebsd+=$(testlib_temp_freebsd) # gen_lib time (linux) -testlib_time=$(TESTCACHE)/time/time-linux.o -hare_testlib_deps+=$(testlib_time) +testlib_time_linux=$(TESTCACHE)/time/time-linux.o +testlib_deps_linux+=$(testlib_time_linux) + +# gen_lib time (freebsd) +testlib_time_freebsd=$(TESTCACHE)/time/time-freebsd.o +testlib_deps_freebsd+=$(testlib_time_freebsd) # gen_lib types (any) -testlib_types=$(TESTCACHE)/types/types-any.o -hare_testlib_deps+=$(testlib_types) +testlib_types_any=$(TESTCACHE)/types/types-any.o +testlib_deps_any+=$(testlib_types_any) +testlib_types_linux=$(testlib_types_any) +testlib_types_freebsd=$(testlib_types_any) # gen_lib unix (linux) -testlib_unix=$(TESTCACHE)/unix/unix-linux.o -hare_testlib_deps+=$(testlib_unix) +testlib_unix_linux=$(TESTCACHE)/unix/unix-linux.o +testlib_deps_linux+=$(testlib_unix_linux) + +# gen_lib unix (freebsd) +testlib_unix_freebsd=$(TESTCACHE)/unix/unix-freebsd.o +testlib_deps_freebsd+=$(testlib_unix_freebsd) # gen_lib unix::hosts (any) -testlib_unix_hosts=$(TESTCACHE)/unix/hosts/unix_hosts-any.o -hare_testlib_deps+=$(testlib_unix_hosts) +testlib_unix_hosts_any=$(TESTCACHE)/unix/hosts/unix_hosts-any.o +testlib_deps_any+=$(testlib_unix_hosts_any) +testlib_unix_hosts_linux=$(testlib_unix_hosts_any) +testlib_unix_hosts_freebsd=$(testlib_unix_hosts_any) # gen_lib unix::passwd (any) -testlib_unix_passwd=$(TESTCACHE)/unix/passwd/unix_passwd-any.o -hare_testlib_deps+=$(testlib_unix_passwd) +testlib_unix_passwd_any=$(TESTCACHE)/unix/passwd/unix_passwd-any.o +testlib_deps_any+=$(testlib_unix_passwd_any) +testlib_unix_passwd_linux=$(testlib_unix_passwd_any) +testlib_unix_passwd_freebsd=$(testlib_unix_passwd_any) # gen_lib unix::poll (linux) -testlib_unix_poll=$(TESTCACHE)/unix/poll/unix_poll-linux.o -hare_testlib_deps+=$(testlib_unix_poll) +testlib_unix_poll_linux=$(TESTCACHE)/unix/poll/unix_poll-linux.o +testlib_deps_linux+=$(testlib_unix_poll_linux) + +# gen_lib unix::poll (freebsd) +testlib_unix_poll_freebsd=$(TESTCACHE)/unix/poll/unix_poll-freebsd.o +testlib_deps_freebsd+=$(testlib_unix_poll_freebsd) # gen_lib unix::resolvconf (any) -testlib_unix_resolvconf=$(TESTCACHE)/unix/resolvconf/unix_resolvconf-any.o -hare_testlib_deps+=$(testlib_unix_resolvconf) +testlib_unix_resolvconf_any=$(TESTCACHE)/unix/resolvconf/unix_resolvconf-any.o +testlib_deps_any+=$(testlib_unix_resolvconf_any) +testlib_unix_resolvconf_linux=$(testlib_unix_resolvconf_any) +testlib_unix_resolvconf_freebsd=$(testlib_unix_resolvconf_any) # gen_lib unix::tty (linux) -testlib_unix_tty=$(TESTCACHE)/unix/tty/unix_tty-linux.o -hare_testlib_deps+=$(testlib_unix_tty) +testlib_unix_tty_linux=$(TESTCACHE)/unix/tty/unix_tty-linux.o +testlib_deps_linux+=$(testlib_unix_tty_linux) + +# gen_lib unix::tty (freebsd) +testlib_unix_tty_freebsd=$(TESTCACHE)/unix/tty/unix_tty-freebsd.o +testlib_deps_freebsd+=$(testlib_unix_tty_freebsd) # gen_lib uuid (any) -testlib_uuid=$(TESTCACHE)/uuid/uuid-any.o -hare_testlib_deps+=$(testlib_uuid) +testlib_uuid_any=$(TESTCACHE)/uuid/uuid-any.o +testlib_deps_any+=$(testlib_uuid_any) +testlib_uuid_linux=$(testlib_uuid_any) +testlib_uuid_freebsd=$(testlib_uuid_any) # ascii (+any) testlib_ascii_any_srcs= \ $(STDLIB)/ascii/ctype.ha \ $(STDLIB)/ascii/strcmp.ha -$(TESTCACHE)/ascii/ascii-any.ssa: $(testlib_ascii_any_srcs) $(testlib_rt) $(testlib_strings) +$(TESTCACHE)/ascii/ascii-any.ssa: $(testlib_ascii_any_srcs) $(testlib_rt) $(testlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/ascii @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nascii \ @@ -1630,7 +2213,7 @@ testlib_bufio_any_srcs= \ $(STDLIB)/bufio/memstream.ha \ $(STDLIB)/bufio/scanner.ha -$(TESTCACHE)/bufio/bufio-any.ssa: $(testlib_bufio_any_srcs) $(testlib_rt) $(testlib_io) $(testlib_bytes) $(testlib_strings) $(testlib_encoding_utf8) $(testlib_errors) $(testlib_types) +$(TESTCACHE)/bufio/bufio-any.ssa: $(testlib_bufio_any_srcs) $(testlib_rt) $(testlib_io_$(PLATFORM)) $(testlib_bytes_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_encoding_utf8_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) $(testlib_types_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/bufio @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nbufio \ @@ -1646,7 +2229,7 @@ testlib_bytes_any_srcs= \ $(STDLIB)/bytes/tokenize.ha \ $(STDLIB)/bytes/two_way.ha -$(TESTCACHE)/bytes/bytes-any.ssa: $(testlib_bytes_any_srcs) $(testlib_rt) $(testlib_types) +$(TESTCACHE)/bytes/bytes-any.ssa: $(testlib_bytes_any_srcs) $(testlib_rt) $(testlib_types_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/bytes @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nbytes \ @@ -1656,7 +2239,7 @@ $(TESTCACHE)/bytes/bytes-any.ssa: $(testlib_bytes_any_srcs) $(testlib_rt) $(test testlib_compress_flate_any_srcs= \ $(STDLIB)/compress/flate/inflate.ha -$(TESTCACHE)/compress/flate/compress_flate-any.ssa: $(testlib_compress_flate_any_srcs) $(testlib_rt) $(testlib_bufio) $(testlib_bytes) $(testlib_endian) $(testlib_errors) $(testlib_io) $(testlib_fmt) +$(TESTCACHE)/compress/flate/compress_flate-any.ssa: $(testlib_compress_flate_any_srcs) $(testlib_rt) $(testlib_bufio_$(PLATFORM)) $(testlib_bytes_$(PLATFORM)) $(testlib_endian_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/compress/flate @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ncompress::flate \ @@ -1667,7 +2250,7 @@ testlib_compress_zlib_any_srcs= \ $(STDLIB)/compress/zlib/data+test.ha \ $(STDLIB)/compress/zlib/reader.ha -$(TESTCACHE)/compress/zlib/compress_zlib-any.ssa: $(testlib_compress_zlib_any_srcs) $(testlib_rt) $(testlib_bufio) $(testlib_bytes) $(testlib_compress_flate) $(testlib_endian) $(testlib_errors) $(testlib_hash) $(testlib_hash_adler32) $(testlib_io) $(testlib_fmt) +$(TESTCACHE)/compress/zlib/compress_zlib-any.ssa: $(testlib_compress_zlib_any_srcs) $(testlib_rt) $(testlib_bufio_$(PLATFORM)) $(testlib_bytes_$(PLATFORM)) $(testlib_compress_flate_$(PLATFORM)) $(testlib_endian_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) $(testlib_hash_$(PLATFORM)) $(testlib_hash_adler32_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/compress/zlib @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ncompress::zlib \ @@ -1679,7 +2262,7 @@ testlib_crypto_blake2b_any_srcs= \ $(STDLIB)/crypto/blake2b/+test.ha \ $(STDLIB)/crypto/blake2b/vectors+test.ha -$(TESTCACHE)/crypto/blake2b/crypto_blake2b-any.ssa: $(testlib_crypto_blake2b_any_srcs) $(testlib_rt) $(testlib_encoding_hex) $(testlib_fmt) $(testlib_hash) $(testlib_io) $(testlib_strings) $(testlib_strio) $(testlib_crypto_math) $(testlib_endian) +$(TESTCACHE)/crypto/blake2b/crypto_blake2b-any.ssa: $(testlib_crypto_blake2b_any_srcs) $(testlib_rt) $(testlib_encoding_hex_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) $(testlib_hash_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_strio_$(PLATFORM)) $(testlib_crypto_math_$(PLATFORM)) $(testlib_endian_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/crypto/blake2b @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ncrypto::blake2b \ @@ -1700,18 +2283,29 @@ testlib_crypto_random_linux_srcs= \ $(STDLIB)/crypto/random/+linux.ha \ $(STDLIB)/crypto/random/random.ha -$(TESTCACHE)/crypto/random/crypto_random-linux.ssa: $(testlib_crypto_random_linux_srcs) $(testlib_rt) $(testlib_rt) $(testlib_io) $(testlib_errors) +$(TESTCACHE)/crypto/random/crypto_random-linux.ssa: $(testlib_crypto_random_linux_srcs) $(testlib_rt) $(testlib_rt_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/crypto/random @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ncrypto::random \ -t$(TESTCACHE)/crypto/random/crypto_random.td $(testlib_crypto_random_linux_srcs) +# crypto::random (+freebsd) +testlib_crypto_random_freebsd_srcs= \ + $(STDLIB)/crypto/random/+freebsd.ha \ + $(STDLIB)/crypto/random/random.ha + +$(TESTCACHE)/crypto/random/crypto_random-freebsd.ssa: $(testlib_crypto_random_freebsd_srcs) $(testlib_rt) $(testlib_rt_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(TESTCACHE)/crypto/random + @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ncrypto::random \ + -t$(TESTCACHE)/crypto/random/crypto_random.td $(testlib_crypto_random_freebsd_srcs) + # crypto::md5 (+any) testlib_crypto_md5_any_srcs= \ $(STDLIB)/crypto/md5/md5.ha \ $(STDLIB)/crypto/md5/+test.ha -$(TESTCACHE)/crypto/md5/crypto_md5-any.ssa: $(testlib_crypto_md5_any_srcs) $(testlib_rt) $(testlib_hash) $(testlib_io) $(testlib_endian) $(testlib_fmt) $(testlib_strio) $(testlib_strings) +$(TESTCACHE)/crypto/md5/crypto_md5-any.ssa: $(testlib_crypto_md5_any_srcs) $(testlib_rt) $(testlib_hash_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_endian_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) $(testlib_strio_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/crypto/md5 @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ncrypto::md5 \ @@ -1722,7 +2316,7 @@ testlib_crypto_sha1_any_srcs= \ $(STDLIB)/crypto/sha1/sha1.ha \ $(STDLIB)/crypto/sha1/+test.ha -$(TESTCACHE)/crypto/sha1/crypto_sha1-any.ssa: $(testlib_crypto_sha1_any_srcs) $(testlib_rt) $(testlib_hash) $(testlib_io) $(testlib_endian) $(testlib_fmt) $(testlib_strio) $(testlib_strings) +$(TESTCACHE)/crypto/sha1/crypto_sha1-any.ssa: $(testlib_crypto_sha1_any_srcs) $(testlib_rt) $(testlib_hash_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_endian_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) $(testlib_strio_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/crypto/sha1 @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ncrypto::sha1 \ @@ -1733,7 +2327,7 @@ testlib_crypto_sha256_any_srcs= \ $(STDLIB)/crypto/sha256/sha256.ha \ $(STDLIB)/crypto/sha256/+test.ha -$(TESTCACHE)/crypto/sha256/crypto_sha256-any.ssa: $(testlib_crypto_sha256_any_srcs) $(testlib_rt) $(testlib_hash) $(testlib_io) $(testlib_endian) $(testlib_fmt) $(testlib_strio) $(testlib_strings) +$(TESTCACHE)/crypto/sha256/crypto_sha256-any.ssa: $(testlib_crypto_sha256_any_srcs) $(testlib_rt) $(testlib_hash_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_endian_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) $(testlib_strio_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/crypto/sha256 @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ncrypto::sha256 \ @@ -1744,7 +2338,7 @@ testlib_crypto_sha512_any_srcs= \ $(STDLIB)/crypto/sha512/sha512.ha \ $(STDLIB)/crypto/sha512/+test.ha -$(TESTCACHE)/crypto/sha512/crypto_sha512-any.ssa: $(testlib_crypto_sha512_any_srcs) $(testlib_rt) $(testlib_hash) $(testlib_io) $(testlib_endian) $(testlib_fmt) $(testlib_strio) $(testlib_strings) +$(TESTCACHE)/crypto/sha512/crypto_sha512-any.ssa: $(testlib_crypto_sha512_any_srcs) $(testlib_rt) $(testlib_hash_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_endian_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) $(testlib_strio_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/crypto/sha512 @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ncrypto::sha512 \ @@ -1754,7 +2348,7 @@ $(TESTCACHE)/crypto/sha512/crypto_sha512-any.ssa: $(testlib_crypto_sha512_any_sr testlib_dirs_any_srcs= \ $(STDLIB)/dirs/xdg.ha -$(TESTCACHE)/dirs/dirs-any.ssa: $(testlib_dirs_any_srcs) $(testlib_rt) $(testlib_fs) $(testlib_os) $(testlib_path) +$(TESTCACHE)/dirs/dirs-any.ssa: $(testlib_dirs_any_srcs) $(testlib_rt) $(testlib_fs_$(PLATFORM)) $(testlib_os_$(PLATFORM)) $(testlib_path_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/dirs @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ndirs \ @@ -1764,7 +2358,7 @@ $(TESTCACHE)/dirs/dirs-any.ssa: $(testlib_dirs_any_srcs) $(testlib_rt) $(testlib testlib_encoding_base64_any_srcs= \ $(STDLIB)/encoding/base64/base64.ha -$(TESTCACHE)/encoding/base64/encoding_base64-any.ssa: $(testlib_encoding_base64_any_srcs) $(testlib_rt) $(testlib_bufio) $(testlib_bytes) $(testlib_io) $(testlib_strio) $(testlib_strings) +$(TESTCACHE)/encoding/base64/encoding_base64-any.ssa: $(testlib_encoding_base64_any_srcs) $(testlib_rt) $(testlib_bufio_$(PLATFORM)) $(testlib_bytes_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_strio_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/encoding/base64 @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nencoding::base64 \ @@ -1774,7 +2368,7 @@ $(TESTCACHE)/encoding/base64/encoding_base64-any.ssa: $(testlib_encoding_base64_ testlib_encoding_hex_any_srcs= \ $(STDLIB)/encoding/hex/hex.ha -$(TESTCACHE)/encoding/hex/encoding_hex-any.ssa: $(testlib_encoding_hex_any_srcs) $(testlib_rt) $(testlib_ascii) $(testlib_bytes) $(testlib_fmt) $(testlib_io) $(testlib_strconv) $(testlib_strio) $(testlib_strings) +$(TESTCACHE)/encoding/hex/encoding_hex-any.ssa: $(testlib_encoding_hex_any_srcs) $(testlib_rt) $(testlib_ascii_$(PLATFORM)) $(testlib_bytes_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_strconv_$(PLATFORM)) $(testlib_strio_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/encoding/hex @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nencoding::hex \ @@ -1786,7 +2380,7 @@ testlib_encoding_utf8_any_srcs= \ $(STDLIB)/encoding/utf8/encode.ha \ $(STDLIB)/encoding/utf8/rune.ha -$(TESTCACHE)/encoding/utf8/encoding_utf8-any.ssa: $(testlib_encoding_utf8_any_srcs) $(testlib_rt) $(testlib_types) +$(TESTCACHE)/encoding/utf8/encoding_utf8-any.ssa: $(testlib_encoding_utf8_any_srcs) $(testlib_rt) $(testlib_types_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/encoding/utf8 @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nencoding::utf8 \ @@ -1823,7 +2417,7 @@ $(TESTCACHE)/errors/errors-any.ssa: $(testlib_errors_any_srcs) $(testlib_rt) testlib_fmt_any_srcs= \ $(STDLIB)/fmt/fmt.ha -$(TESTCACHE)/fmt/fmt-any.ssa: $(testlib_fmt_any_srcs) $(testlib_rt) $(testlib_bufio) $(testlib_io) $(testlib_os) $(testlib_strconv) $(testlib_strings) $(testlib_types) +$(TESTCACHE)/fmt/fmt-any.ssa: $(testlib_fmt_any_srcs) $(testlib_rt) $(testlib_bufio_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_os_$(PLATFORM)) $(testlib_strconv_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_types_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/fmt @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nfmt \ @@ -1834,7 +2428,7 @@ testlib_fnmatch_any_srcs= \ $(STDLIB)/fnmatch/fnmatch.ha \ $(STDLIB)/fnmatch/+test.ha -$(TESTCACHE)/fnmatch/fnmatch-any.ssa: $(testlib_fnmatch_any_srcs) $(testlib_rt) $(testlib_strings) $(testlib_bytes) $(testlib_sort) $(testlib_ascii) $(testlib_io) $(testlib_fmt) +$(TESTCACHE)/fnmatch/fnmatch-any.ssa: $(testlib_fnmatch_any_srcs) $(testlib_rt) $(testlib_strings_$(PLATFORM)) $(testlib_bytes_$(PLATFORM)) $(testlib_sort_$(PLATFORM)) $(testlib_ascii_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/fnmatch @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nfnmatch \ @@ -1858,7 +2452,7 @@ testlib_format_ini_any_srcs= \ $(STDLIB)/format/ini/types.ha \ $(STDLIB)/format/ini/+test.ha -$(TESTCACHE)/format/ini/format_ini-any.ssa: $(testlib_format_ini_any_srcs) $(testlib_rt) $(testlib_bufio) $(testlib_encoding_utf8) $(testlib_fmt) $(testlib_io) $(testlib_strings) +$(TESTCACHE)/format/ini/format_ini-any.ssa: $(testlib_format_ini_any_srcs) $(testlib_rt) $(testlib_bufio_$(PLATFORM)) $(testlib_encoding_utf8_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/format/ini @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nformat::ini \ @@ -1871,7 +2465,7 @@ testlib_format_xml_any_srcs= \ $(STDLIB)/format/xml/chars.ha \ $(STDLIB)/format/xml/+test.ha -$(TESTCACHE)/format/xml/format_xml-any.ssa: $(testlib_format_xml_any_srcs) $(testlib_rt) $(testlib_io) $(testlib_bufio) $(testlib_strings) $(testlib_ascii) $(testlib_strio) $(testlib_os) +$(TESTCACHE)/format/xml/format_xml-any.ssa: $(testlib_format_xml_any_srcs) $(testlib_rt) $(testlib_io_$(PLATFORM)) $(testlib_bufio_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_ascii_$(PLATFORM)) $(testlib_strio_$(PLATFORM)) $(testlib_os_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/format/xml @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nformat::xml \ @@ -1883,7 +2477,7 @@ testlib_fs_any_srcs= \ $(STDLIB)/fs/fs.ha \ $(STDLIB)/fs/util.ha -$(TESTCACHE)/fs/fs-any.ssa: $(testlib_fs_any_srcs) $(testlib_rt) $(testlib_io) $(testlib_strings) $(testlib_path) $(testlib_time) $(testlib_errors) +$(TESTCACHE)/fs/fs-any.ssa: $(testlib_fs_any_srcs) $(testlib_rt) $(testlib_io_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_path_$(PLATFORM)) $(testlib_time_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/fs @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nfs \ @@ -1896,7 +2490,7 @@ testlib_fs_mem_any_srcs= \ $(STDLIB)/fs/mem/util.ha \ $(STDLIB)/fs/mem/+test.ha -$(TESTCACHE)/fs/mem/fs_mem-any.ssa: $(testlib_fs_mem_any_srcs) $(testlib_rt) $(testlib_bufio) $(testlib_errors) $(testlib_fs) $(testlib_hash) $(testlib_hash_fnv) $(testlib_io) $(testlib_path) $(testlib_strconv) $(testlib_strings) $(testlib_types) +$(TESTCACHE)/fs/mem/fs_mem-any.ssa: $(testlib_fs_mem_any_srcs) $(testlib_rt) $(testlib_bufio_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) $(testlib_fs_$(PLATFORM)) $(testlib_hash_$(PLATFORM)) $(testlib_hash_fnv_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_path_$(PLATFORM)) $(testlib_strconv_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_types_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/fs/mem @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nfs::mem \ @@ -1906,7 +2500,7 @@ $(TESTCACHE)/fs/mem/fs_mem-any.ssa: $(testlib_fs_mem_any_srcs) $(testlib_rt) $(t testlib_getopt_any_srcs= \ $(STDLIB)/getopt/getopts.ha -$(TESTCACHE)/getopt/getopt-any.ssa: $(testlib_getopt_any_srcs) $(testlib_rt) $(testlib_encoding_utf8) $(testlib_fmt) $(testlib_io) $(testlib_os) $(testlib_strings) +$(TESTCACHE)/getopt/getopt-any.ssa: $(testlib_getopt_any_srcs) $(testlib_rt) $(testlib_encoding_utf8_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_os_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/getopt @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ngetopt \ @@ -1921,7 +2515,7 @@ testlib_hare_ast_any_srcs= \ $(STDLIB)/hare/ast/type.ha \ $(STDLIB)/hare/ast/unit.ha -$(TESTCACHE)/hare/ast/hare_ast-any.ssa: $(testlib_hare_ast_any_srcs) $(testlib_rt) $(testlib_hare_lex) $(testlib_strings) +$(TESTCACHE)/hare/ast/hare_ast-any.ssa: $(testlib_hare_ast_any_srcs) $(testlib_rt) $(testlib_hare_lex_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/hare/ast @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nhare::ast \ @@ -1933,7 +2527,7 @@ testlib_hare_lex_any_srcs= \ $(STDLIB)/hare/lex/lex.ha \ $(STDLIB)/hare/lex/+test.ha -$(TESTCACHE)/hare/lex/hare_lex-any.ssa: $(testlib_hare_lex_any_srcs) $(testlib_rt) $(testlib_io) $(testlib_bufio) $(testlib_strings) $(testlib_types) $(testlib_fmt) $(testlib_sort) $(testlib_strio) +$(TESTCACHE)/hare/lex/hare_lex-any.ssa: $(testlib_hare_lex_any_srcs) $(testlib_rt) $(testlib_io_$(PLATFORM)) $(testlib_bufio_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_types_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) $(testlib_sort_$(PLATFORM)) $(testlib_strio_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/hare/lex @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nhare::lex \ @@ -1946,7 +2540,7 @@ testlib_hare_module_any_srcs= \ $(STDLIB)/hare/module/scan.ha \ $(STDLIB)/hare/module/manifest.ha -$(TESTCACHE)/hare/module/hare_module-any.ssa: $(testlib_hare_module_any_srcs) $(testlib_rt) $(testlib_hare_ast) $(testlib_hare_lex) $(testlib_hare_parse) $(testlib_hare_unparse) $(testlib_strio) $(testlib_fs) $(testlib_io) $(testlib_strings) $(testlib_hash) $(testlib_crypto_sha256) $(testlib_dirs) $(testlib_bytes) $(testlib_encoding_utf8) $(testlib_ascii) $(testlib_fmt) $(testlib_time) $(testlib_slice) $(testlib_bufio) $(testlib_strconv) $(testlib_os) $(testlib_encoding_hex) $(testlib_sort) $(testlib_errors) $(testlib_temp) +$(TESTCACHE)/hare/module/hare_module-any.ssa: $(testlib_hare_module_any_srcs) $(testlib_rt) $(testlib_hare_ast_$(PLATFORM)) $(testlib_hare_lex_$(PLATFORM)) $(testlib_hare_parse_$(PLATFORM)) $(testlib_hare_unparse_$(PLATFORM)) $(testlib_strio_$(PLATFORM)) $(testlib_fs_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_hash_$(PLATFORM)) $(testlib_crypto_sha256_$(PLATFORM)) $(testlib_dirs_$(PLATFORM)) $(testlib_bytes_$(PLATFORM)) $(testlib_encoding_utf8_$(PLATFORM)) $(testlib_ascii_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) $(testlib_time_$(PLATFORM)) $(testlib_slice_$(PLATFORM)) $(testlib_bufio_$(PLATFORM)) $(testlib_strconv_$(PLATFORM)) $(testlib_os_$(PLATFORM)) $(testlib_encoding_hex_$(PLATFORM)) $(testlib_sort_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) $(testlib_temp_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/hare/module @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nhare::module \ @@ -1968,7 +2562,7 @@ testlib_hare_parse_any_srcs= \ $(STDLIB)/hare/parse/+test/types.ha \ $(STDLIB)/hare/parse/+test/unit.ha -$(TESTCACHE)/hare/parse/hare_parse-any.ssa: $(testlib_hare_parse_any_srcs) $(testlib_rt) $(testlib_bufio) $(testlib_fmt) $(testlib_hare_ast) $(testlib_hare_lex) $(testlib_hare_unparse) $(testlib_io) $(testlib_strings) $(testlib_strio) $(testlib_fmt) +$(TESTCACHE)/hare/parse/hare_parse-any.ssa: $(testlib_hare_parse_any_srcs) $(testlib_rt) $(testlib_bufio_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) $(testlib_hare_ast_$(PLATFORM)) $(testlib_hare_lex_$(PLATFORM)) $(testlib_hare_unparse_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_strio_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/hare/parse @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nhare::parse \ @@ -1985,7 +2579,7 @@ testlib_hare_types_any_srcs= \ $(STDLIB)/hare/types/types.ha \ $(STDLIB)/hare/types/+test.ha -$(TESTCACHE)/hare/types/hare_types-any.ssa: $(testlib_hare_types_any_srcs) $(testlib_rt) $(testlib_hare_ast) $(testlib_hare_parse) $(testlib_hash) $(testlib_hash_fnv) $(testlib_endian) +$(TESTCACHE)/hare/types/hare_types-any.ssa: $(testlib_hare_types_any_srcs) $(testlib_rt) $(testlib_hare_ast_$(PLATFORM)) $(testlib_hare_parse_$(PLATFORM)) $(testlib_hash_$(PLATFORM)) $(testlib_hash_fnv_$(PLATFORM)) $(testlib_endian_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/hare/types @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nhare::types \ @@ -2003,7 +2597,7 @@ testlib_hare_unit_any_srcs= \ $(STDLIB)/hare/unit/unit.ha \ $(STDLIB)/hare/unit/+test.ha -$(TESTCACHE)/hare/unit/hare_unit-any.ssa: $(testlib_hare_unit_any_srcs) $(testlib_rt) $(testlib_hare_ast) $(testlib_hare_types) $(testlib_hash) $(testlib_hash_fnv) $(testlib_strings) $(testlib_hare_lex) $(testlib_bufio) $(testlib_hare_parse) +$(TESTCACHE)/hare/unit/hare_unit-any.ssa: $(testlib_hare_unit_any_srcs) $(testlib_rt) $(testlib_hare_ast_$(PLATFORM)) $(testlib_hare_types_$(PLATFORM)) $(testlib_hash_$(PLATFORM)) $(testlib_hash_fnv_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_hare_lex_$(PLATFORM)) $(testlib_bufio_$(PLATFORM)) $(testlib_hare_parse_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/hare/unit @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nhare::unit \ @@ -2019,7 +2613,7 @@ testlib_hare_unparse_any_srcs= \ $(STDLIB)/hare/unparse/unit.ha \ $(STDLIB)/hare/unparse/util.ha -$(TESTCACHE)/hare/unparse/hare_unparse-any.ssa: $(testlib_hare_unparse_any_srcs) $(testlib_rt) $(testlib_fmt) $(testlib_io) $(testlib_strio) $(testlib_hare_ast) +$(TESTCACHE)/hare/unparse/hare_unparse-any.ssa: $(testlib_hare_unparse_any_srcs) $(testlib_rt) $(testlib_fmt_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_strio_$(PLATFORM)) $(testlib_hare_ast_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/hare/unparse @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nhare::unparse \ @@ -2029,7 +2623,7 @@ $(TESTCACHE)/hare/unparse/hare_unparse-any.ssa: $(testlib_hare_unparse_any_srcs) testlib_hash_any_srcs= \ $(STDLIB)/hash/hash.ha -$(TESTCACHE)/hash/hash-any.ssa: $(testlib_hash_any_srcs) $(testlib_rt) $(testlib_io) $(testlib_fmt) +$(TESTCACHE)/hash/hash-any.ssa: $(testlib_hash_any_srcs) $(testlib_rt) $(testlib_io_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/hash @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nhash \ @@ -2039,7 +2633,7 @@ $(TESTCACHE)/hash/hash-any.ssa: $(testlib_hash_any_srcs) $(testlib_rt) $(testlib testlib_hash_adler32_any_srcs= \ $(STDLIB)/hash/adler32/adler32.ha -$(TESTCACHE)/hash/adler32/hash_adler32-any.ssa: $(testlib_hash_adler32_any_srcs) $(testlib_rt) $(testlib_endian) $(testlib_hash) $(testlib_io) $(testlib_strings) +$(TESTCACHE)/hash/adler32/hash_adler32-any.ssa: $(testlib_hash_adler32_any_srcs) $(testlib_rt) $(testlib_endian_$(PLATFORM)) $(testlib_hash_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/hash/adler32 @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nhash::adler32 \ @@ -2049,7 +2643,7 @@ $(TESTCACHE)/hash/adler32/hash_adler32-any.ssa: $(testlib_hash_adler32_any_srcs) testlib_hash_crc16_any_srcs= \ $(STDLIB)/hash/crc16/crc16.ha -$(TESTCACHE)/hash/crc16/hash_crc16-any.ssa: $(testlib_hash_crc16_any_srcs) $(testlib_rt) $(testlib_endian) $(testlib_hash) $(testlib_io) $(testlib_strings) +$(TESTCACHE)/hash/crc16/hash_crc16-any.ssa: $(testlib_hash_crc16_any_srcs) $(testlib_rt) $(testlib_endian_$(PLATFORM)) $(testlib_hash_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/hash/crc16 @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nhash::crc16 \ @@ -2059,7 +2653,7 @@ $(TESTCACHE)/hash/crc16/hash_crc16-any.ssa: $(testlib_hash_crc16_any_srcs) $(tes testlib_hash_crc32_any_srcs= \ $(STDLIB)/hash/crc32/crc32.ha -$(TESTCACHE)/hash/crc32/hash_crc32-any.ssa: $(testlib_hash_crc32_any_srcs) $(testlib_rt) $(testlib_endian) $(testlib_hash) $(testlib_io) $(testlib_strings) +$(TESTCACHE)/hash/crc32/hash_crc32-any.ssa: $(testlib_hash_crc32_any_srcs) $(testlib_rt) $(testlib_endian_$(PLATFORM)) $(testlib_hash_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/hash/crc32 @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nhash::crc32 \ @@ -2069,7 +2663,7 @@ $(TESTCACHE)/hash/crc32/hash_crc32-any.ssa: $(testlib_hash_crc32_any_srcs) $(tes testlib_hash_crc64_any_srcs= \ $(STDLIB)/hash/crc64/crc64.ha -$(TESTCACHE)/hash/crc64/hash_crc64-any.ssa: $(testlib_hash_crc64_any_srcs) $(testlib_rt) $(testlib_endian) $(testlib_hash) $(testlib_io) $(testlib_strings) +$(TESTCACHE)/hash/crc64/hash_crc64-any.ssa: $(testlib_hash_crc64_any_srcs) $(testlib_rt) $(testlib_endian_$(PLATFORM)) $(testlib_hash_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/hash/crc64 @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nhash::crc64 \ @@ -2079,7 +2673,7 @@ $(TESTCACHE)/hash/crc64/hash_crc64-any.ssa: $(testlib_hash_crc64_any_srcs) $(tes testlib_hash_fnv_any_srcs= \ $(STDLIB)/hash/fnv/fnv.ha -$(TESTCACHE)/hash/fnv/hash_fnv-any.ssa: $(testlib_hash_fnv_any_srcs) $(testlib_rt) $(testlib_hash) $(testlib_io) $(testlib_strings) +$(TESTCACHE)/hash/fnv/hash_fnv-any.ssa: $(testlib_hash_fnv_any_srcs) $(testlib_rt) $(testlib_hash_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/hash/fnv @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nhash::fnv \ @@ -2103,12 +2697,36 @@ testlib_io_linux_srcs= \ $(STDLIB)/io/+test/limit.ha \ $(STDLIB)/io/+test/stream.ha -$(TESTCACHE)/io/io-linux.ssa: $(testlib_io_linux_srcs) $(testlib_rt) $(testlib_strings) $(testlib_errors) +# io (+freebsd) +testlib_io_freebsd_srcs= \ + $(STDLIB)/io/arch+$(ARCH).ha \ + $(STDLIB)/io/println+freebsd.ha \ + $(STDLIB)/io/+freebsd/file.ha \ + $(STDLIB)/io/copy.ha \ + $(STDLIB)/io/drain.ha \ + $(STDLIB)/io/empty.ha \ + $(STDLIB)/io/filestream.ha \ + $(STDLIB)/io/handle.ha \ + $(STDLIB)/io/limit.ha \ + $(STDLIB)/io/stream.ha \ + $(STDLIB)/io/tee.ha \ + $(STDLIB)/io/types.ha \ + $(STDLIB)/io/+test/copy.ha \ + $(STDLIB)/io/+test/limit.ha \ + $(STDLIB)/io/+test/stream.ha + +$(TESTCACHE)/io/io-linux.ssa: $(testlib_io_linux_srcs) $(testlib_rt) $(testlib_strings_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/io @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nio \ -t$(TESTCACHE)/io/io.td $(testlib_io_linux_srcs) +$(TESTCACHE)/io/io-freebsd.ssa: $(testlib_io_freebsd_srcs) $(testlib_rt) $(testlib_strings_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(TESTCACHE)/io + @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nio \ + -t$(TESTCACHE)/io/io.td $(testlib_io_freebsd_srcs) + # iobus::io_uring (+linux) testlib_iobus_io_uring_linux_srcs= \ $(STDLIB)/iobus/io_uring/bus.ha \ @@ -2117,7 +2735,7 @@ testlib_iobus_io_uring_linux_srcs= \ $(STDLIB)/iobus/io_uring/pool.ha \ $(STDLIB)/iobus/io_uring/types.ha -$(TESTCACHE)/iobus/io_uring/iobus_io_uring-linux.ssa: $(testlib_iobus_io_uring_linux_srcs) $(testlib_rt) $(testlib_errors) $(testlib_io) $(testlib_linux_io_uring) $(testlib_net_ip) $(testlib_unix_poll) +$(TESTCACHE)/iobus/io_uring/iobus_io_uring-linux.ssa: $(testlib_iobus_io_uring_linux_srcs) $(testlib_rt) $(testlib_errors_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_linux_io_uring_$(PLATFORM)) $(testlib_net_ip_$(PLATFORM)) $(testlib_unix_poll_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/iobus/io_uring @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Niobus::io_uring \ @@ -2128,7 +2746,7 @@ testlib_linux_linux_srcs= \ $(STDLIB)/linux/start.ha \ $(STDLIB)/linux/env.ha -$(TESTCACHE)/linux/linux-linux.ssa: $(testlib_linux_linux_srcs) $(testlib_rt) $(testlib_format_elf) +$(TESTCACHE)/linux/linux-linux.ssa: $(testlib_linux_linux_srcs) $(testlib_rt) $(testlib_format_elf_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/linux @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nlinux \ @@ -2138,7 +2756,7 @@ $(TESTCACHE)/linux/linux-linux.ssa: $(testlib_linux_linux_srcs) $(testlib_rt) $( testlib_linux_signalfd_linux_srcs= \ $(STDLIB)/linux/signalfd/signalfd.ha -$(TESTCACHE)/linux/signalfd/linux_signalfd-linux.ssa: $(testlib_linux_signalfd_linux_srcs) $(testlib_rt) $(testlib_errors) +$(TESTCACHE)/linux/signalfd/linux_signalfd-linux.ssa: $(testlib_linux_signalfd_linux_srcs) $(testlib_rt) $(testlib_errors_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/linux/signalfd @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nlinux::signalfd \ @@ -2153,7 +2771,7 @@ testlib_linux_io_uring_linux_srcs= \ $(STDLIB)/linux/io_uring/sqe.ha \ $(STDLIB)/linux/io_uring/uring.ha -$(TESTCACHE)/linux/io_uring/linux_io_uring-linux.ssa: $(testlib_linux_io_uring_linux_srcs) $(testlib_rt) $(testlib_errors) $(testlib_types) +$(TESTCACHE)/linux/io_uring/linux_io_uring-linux.ssa: $(testlib_linux_io_uring_linux_srcs) $(testlib_rt) $(testlib_errors_$(PLATFORM)) $(testlib_types_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/linux/io_uring @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nlinux::io_uring \ @@ -2163,7 +2781,7 @@ $(TESTCACHE)/linux/io_uring/linux_io_uring-linux.ssa: $(testlib_linux_io_uring_l testlib_linux_vdso_linux_srcs= \ $(STDLIB)/linux/vdso/vdso.ha -$(TESTCACHE)/linux/vdso/linux_vdso-linux.ssa: $(testlib_linux_vdso_linux_srcs) $(testlib_rt) $(testlib_linux) $(testlib_strings) $(testlib_format_elf) +$(TESTCACHE)/linux/vdso/linux_vdso-linux.ssa: $(testlib_linux_vdso_linux_srcs) $(testlib_rt) $(testlib_linux_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_format_elf_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/linux/vdso @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nlinux::vdso \ @@ -2178,7 +2796,7 @@ testlib_math_any_srcs= \ $(STDLIB)/math/trig.ha \ $(STDLIB)/math/data+test.ha -$(TESTCACHE)/math/math-any.ssa: $(testlib_math_any_srcs) $(testlib_rt) $(testlib_types) +$(TESTCACHE)/math/math-any.ssa: $(testlib_math_any_srcs) $(testlib_rt) $(testlib_types_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/math @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nmath \ @@ -2190,12 +2808,24 @@ testlib_net_linux_srcs= \ $(STDLIB)/net/errors.ha \ $(STDLIB)/net/listener.ha -$(TESTCACHE)/net/net-linux.ssa: $(testlib_net_linux_srcs) $(testlib_rt) $(testlib_io) $(testlib_os) $(testlib_strings) $(testlib_net_ip) $(testlib_errors) $(testlib_rt) $(testlib_fmt) +$(TESTCACHE)/net/net-linux.ssa: $(testlib_net_linux_srcs) $(testlib_rt) $(testlib_io_$(PLATFORM)) $(testlib_os_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_net_ip_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) $(testlib_rt_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/net @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nnet \ -t$(TESTCACHE)/net/net.td $(testlib_net_linux_srcs) +# net (+freebsd) +testlib_net_freebsd_srcs= \ + $(STDLIB)/net/+freebsd.ha \ + $(STDLIB)/net/errors.ha \ + $(STDLIB)/net/listener.ha + +$(TESTCACHE)/net/net-freebsd.ssa: $(testlib_net_freebsd_srcs) $(testlib_rt) $(testlib_io_$(PLATFORM)) $(testlib_os_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_net_ip_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) $(testlib_rt_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(TESTCACHE)/net + @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nnet \ + -t$(TESTCACHE)/net/net.td $(testlib_net_freebsd_srcs) + # net::dial (+any) testlib_net_dial_any_srcs= \ $(STDLIB)/net/dial/registry.ha \ @@ -2203,7 +2833,7 @@ testlib_net_dial_any_srcs= \ $(STDLIB)/net/dial/ip.ha \ $(STDLIB)/net/dial/resolve.ha -$(TESTCACHE)/net/dial/net_dial-any.ssa: $(testlib_net_dial_any_srcs) $(testlib_rt) $(testlib_io) $(testlib_net) $(testlib_net_ip) $(testlib_net_tcp) $(testlib_net_udp) $(testlib_net_dns) $(testlib_crypto_random) $(testlib_strconv) $(testlib_strings) $(testlib_unix_hosts) +$(TESTCACHE)/net/dial/net_dial-any.ssa: $(testlib_net_dial_any_srcs) $(testlib_rt) $(testlib_io_$(PLATFORM)) $(testlib_net_$(PLATFORM)) $(testlib_net_ip_$(PLATFORM)) $(testlib_net_tcp_$(PLATFORM)) $(testlib_net_udp_$(PLATFORM)) $(testlib_net_dns_$(PLATFORM)) $(testlib_crypto_random_$(PLATFORM)) $(testlib_strconv_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_unix_hosts_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/net/dial @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nnet::dial \ @@ -2217,7 +2847,7 @@ testlib_net_dns_any_srcs= \ $(STDLIB)/net/dns/query.ha \ $(STDLIB)/net/dns/types.ha -$(TESTCACHE)/net/dns/net_dns-any.ssa: $(testlib_net_dns_any_srcs) $(testlib_rt) $(testlib_ascii) $(testlib_endian) $(testlib_net) $(testlib_net_udp) $(testlib_net_ip) $(testlib_fmt) $(testlib_strings) $(testlib_unix_resolvconf) $(testlib_unix_poll) $(testlib_rt) $(testlib_time) $(testlib_errors) +$(TESTCACHE)/net/dns/net_dns-any.ssa: $(testlib_net_dns_any_srcs) $(testlib_rt) $(testlib_ascii_$(PLATFORM)) $(testlib_endian_$(PLATFORM)) $(testlib_net_$(PLATFORM)) $(testlib_net_udp_$(PLATFORM)) $(testlib_net_ip_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_unix_resolvconf_$(PLATFORM)) $(testlib_unix_poll_$(PLATFORM)) $(testlib_rt_$(PLATFORM)) $(testlib_time_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/net/dns @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nnet::dns \ @@ -2225,39 +2855,74 @@ $(TESTCACHE)/net/dns/net_dns-any.ssa: $(testlib_net_dns_any_srcs) $(testlib_rt) # net::ip (+linux) testlib_net_ip_linux_srcs= \ - $(STDLIB)/net/ip/ip.ha \ $(STDLIB)/net/ip/+linux.ha \ + $(STDLIB)/net/ip/ip.ha \ + $(STDLIB)/net/ip/+test.ha + +# net::ip (+freebsd) +testlib_net_ip_freebsd_srcs= \ + $(STDLIB)/net/ip/+freebsd.ha \ + $(STDLIB)/net/ip/ip.ha \ $(STDLIB)/net/ip/+test.ha -$(TESTCACHE)/net/ip/net_ip-linux.ssa: $(testlib_net_ip_linux_srcs) $(testlib_rt) $(testlib_bytes) $(testlib_io) $(testlib_strconv) $(testlib_strings) $(testlib_strio) $(testlib_fmt) +$(TESTCACHE)/net/ip/net_ip-linux.ssa: $(testlib_net_ip_linux_srcs) $(testlib_rt) $(testlib_bytes_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_strconv_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_strio_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/net/ip @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nnet::ip \ -t$(TESTCACHE)/net/ip/net_ip.td $(testlib_net_ip_linux_srcs) +$(TESTCACHE)/net/ip/net_ip-freebsd.ssa: $(testlib_net_ip_freebsd_srcs) $(testlib_rt) $(testlib_bytes_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_strconv_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_strio_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(TESTCACHE)/net/ip + @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nnet::ip \ + -t$(TESTCACHE)/net/ip/net_ip.td $(testlib_net_ip_freebsd_srcs) + # net::tcp (+linux) testlib_net_tcp_linux_srcs= \ $(STDLIB)/net/tcp/+linux.ha \ $(STDLIB)/net/tcp/listener.ha \ $(STDLIB)/net/tcp/options.ha -$(TESTCACHE)/net/tcp/net_tcp-linux.ssa: $(testlib_net_tcp_linux_srcs) $(testlib_rt) $(testlib_io) $(testlib_net) $(testlib_net_ip) $(testlib_os) $(testlib_rt) +$(TESTCACHE)/net/tcp/net_tcp-linux.ssa: $(testlib_net_tcp_linux_srcs) $(testlib_rt) $(testlib_io_$(PLATFORM)) $(testlib_net_$(PLATFORM)) $(testlib_net_ip_$(PLATFORM)) $(testlib_os_$(PLATFORM)) $(testlib_rt_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/net/tcp @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nnet::tcp \ -t$(TESTCACHE)/net/tcp/net_tcp.td $(testlib_net_tcp_linux_srcs) +# net::tcp (+freebsd) +testlib_net_tcp_freebsd_srcs= \ + $(STDLIB)/net/tcp/+freebsd.ha \ + $(STDLIB)/net/tcp/listener.ha \ + $(STDLIB)/net/tcp/options.ha + +$(TESTCACHE)/net/tcp/net_tcp-freebsd.ssa: $(testlib_net_tcp_freebsd_srcs) $(testlib_rt) $(testlib_io_$(PLATFORM)) $(testlib_net_$(PLATFORM)) $(testlib_net_ip_$(PLATFORM)) $(testlib_os_$(PLATFORM)) $(testlib_rt_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(TESTCACHE)/net/tcp + @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nnet::tcp \ + -t$(TESTCACHE)/net/tcp/net_tcp.td $(testlib_net_tcp_freebsd_srcs) + # net::udp (+linux) testlib_net_udp_linux_srcs= \ $(STDLIB)/net/udp/+linux.ha \ $(STDLIB)/net/udp/options.ha -$(TESTCACHE)/net/udp/net_udp-linux.ssa: $(testlib_net_udp_linux_srcs) $(testlib_rt) $(testlib_net) $(testlib_net_ip) $(testlib_errors) $(testlib_rt) $(testlib_os) $(testlib_io) +$(TESTCACHE)/net/udp/net_udp-linux.ssa: $(testlib_net_udp_linux_srcs) $(testlib_rt) $(testlib_net_$(PLATFORM)) $(testlib_net_ip_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) $(testlib_rt_$(PLATFORM)) $(testlib_os_$(PLATFORM)) $(testlib_io_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/net/udp @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nnet::udp \ -t$(TESTCACHE)/net/udp/net_udp.td $(testlib_net_udp_linux_srcs) +# net::udp (+freebsd) +testlib_net_udp_freebsd_srcs= \ + $(STDLIB)/net/udp/+freebsd.ha \ + $(STDLIB)/net/udp/options.ha + +$(TESTCACHE)/net/udp/net_udp-freebsd.ssa: $(testlib_net_udp_freebsd_srcs) $(testlib_rt) $(testlib_net_$(PLATFORM)) $(testlib_net_ip_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) $(testlib_rt_$(PLATFORM)) $(testlib_os_$(PLATFORM)) $(testlib_io_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(TESTCACHE)/net/udp + @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nnet::udp \ + -t$(TESTCACHE)/net/udp/net_udp.td $(testlib_net_udp_freebsd_srcs) + # net::unix (+linux) testlib_net_unix_linux_srcs= \ $(STDLIB)/net/unix/+linux.ha \ @@ -2266,12 +2931,26 @@ testlib_net_unix_linux_srcs= \ $(STDLIB)/net/unix/listener.ha \ $(STDLIB)/net/unix/options.ha -$(TESTCACHE)/net/unix/net_unix-linux.ssa: $(testlib_net_unix_linux_srcs) $(testlib_rt) $(testlib_net) $(testlib_errors) $(testlib_os) $(testlib_io) $(testlib_strings) $(testlib_types) $(testlib_fmt) $(testlib_net_dial) +$(TESTCACHE)/net/unix/net_unix-linux.ssa: $(testlib_net_unix_linux_srcs) $(testlib_rt) $(testlib_net_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) $(testlib_os_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_types_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) $(testlib_net_dial_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/net/unix @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nnet::unix \ -t$(TESTCACHE)/net/unix/net_unix.td $(testlib_net_unix_linux_srcs) +# net::unix (+freebsd) +testlib_net_unix_freebsd_srcs= \ + $(STDLIB)/net/unix/+freebsd.ha \ + $(STDLIB)/net/unix/addr.ha \ + $(STDLIB)/net/unix/dial.ha \ + $(STDLIB)/net/unix/listener.ha \ + $(STDLIB)/net/unix/options.ha + +$(TESTCACHE)/net/unix/net_unix-freebsd.ssa: $(testlib_net_unix_freebsd_srcs) $(testlib_rt) $(testlib_net_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) $(testlib_os_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_types_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) $(testlib_net_dial_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(TESTCACHE)/net/unix + @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nnet::unix \ + -t$(TESTCACHE)/net/unix/net_unix.td $(testlib_net_unix_freebsd_srcs) + # math::random (+any) testlib_math_random_any_srcs= \ $(STDLIB)/math/random/random.ha @@ -2291,12 +2970,27 @@ testlib_os_linux_srcs= \ $(STDLIB)/os/+linux/fs.ha \ $(STDLIB)/os/fs.ha -$(TESTCACHE)/os/os-linux.ssa: $(testlib_os_linux_srcs) $(testlib_rt) $(testlib_io) $(testlib_strings) $(testlib_types) $(testlib_fs) $(testlib_encoding_utf8) $(testlib_bytes) $(testlib_bufio) $(testlib_errors) +$(TESTCACHE)/os/os-linux.ssa: $(testlib_os_linux_srcs) $(testlib_rt) $(testlib_io_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_types_$(PLATFORM)) $(testlib_fs_$(PLATFORM)) $(testlib_encoding_utf8_$(PLATFORM)) $(testlib_bytes_$(PLATFORM)) $(testlib_bufio_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/os @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nos \ -t$(TESTCACHE)/os/os.td $(testlib_os_linux_srcs) +# os (+freebsd) +testlib_os_freebsd_srcs= \ + $(STDLIB)/os/+freebsd/environ.ha \ + $(STDLIB)/os/+freebsd/exit.ha \ + $(STDLIB)/os/+freebsd/dirfdfs.ha \ + $(STDLIB)/os/+freebsd/stdfd.ha \ + $(STDLIB)/os/+freebsd/fs.ha \ + $(STDLIB)/os/fs.ha + +$(TESTCACHE)/os/os-freebsd.ssa: $(testlib_os_freebsd_srcs) $(testlib_rt) $(testlib_io_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_types_$(PLATFORM)) $(testlib_fs_$(PLATFORM)) $(testlib_encoding_utf8_$(PLATFORM)) $(testlib_bytes_$(PLATFORM)) $(testlib_bufio_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(TESTCACHE)/os + @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nos \ + -t$(TESTCACHE)/os/os.td $(testlib_os_freebsd_srcs) + # os::exec (+linux) testlib_os_exec_linux_srcs= \ $(STDLIB)/os/exec/exec+linux.ha \ @@ -2304,12 +2998,25 @@ testlib_os_exec_linux_srcs= \ $(STDLIB)/os/exec/types.ha \ $(STDLIB)/os/exec/cmd.ha -$(TESTCACHE)/os/exec/os_exec-linux.ssa: $(testlib_os_exec_linux_srcs) $(testlib_rt) $(testlib_os) $(testlib_strings) $(testlib_fmt) $(testlib_bytes) $(testlib_path) $(testlib_errors) +$(TESTCACHE)/os/exec/os_exec-linux.ssa: $(testlib_os_exec_linux_srcs) $(testlib_rt) $(testlib_os_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) $(testlib_bytes_$(PLATFORM)) $(testlib_path_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/os/exec @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nos::exec \ -t$(TESTCACHE)/os/exec/os_exec.td $(testlib_os_exec_linux_srcs) +# os::exec (+freebsd) +testlib_os_exec_freebsd_srcs= \ + $(STDLIB)/os/exec/exec+freebsd.ha \ + $(STDLIB)/os/exec/process+freebsd.ha \ + $(STDLIB)/os/exec/types.ha \ + $(STDLIB)/os/exec/cmd.ha + +$(TESTCACHE)/os/exec/os_exec-freebsd.ssa: $(testlib_os_exec_freebsd_srcs) $(testlib_rt) $(testlib_os_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) $(testlib_bytes_$(PLATFORM)) $(testlib_path_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(TESTCACHE)/os/exec + @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nos::exec \ + -t$(TESTCACHE)/os/exec/os_exec.td $(testlib_os_exec_freebsd_srcs) + # path (+any) testlib_path_any_srcs= \ $(STDLIB)/path/+$(PLATFORM).ha \ @@ -2318,7 +3025,7 @@ testlib_path_any_srcs= \ $(STDLIB)/path/names.ha \ $(STDLIB)/path/iter.ha -$(TESTCACHE)/path/path-any.ssa: $(testlib_path_any_srcs) $(testlib_rt) $(testlib_strings) $(testlib_bufio) $(testlib_bytes) +$(TESTCACHE)/path/path-any.ssa: $(testlib_path_any_srcs) $(testlib_rt) $(testlib_strings_$(PLATFORM)) $(testlib_bufio_$(PLATFORM)) $(testlib_bytes_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/path @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Npath \ @@ -2329,7 +3036,7 @@ testlib_slice_any_srcs= \ $(STDLIB)/slice/reverse.ha \ $(STDLIB)/slice/void.ha -$(TESTCACHE)/slice/slice-any.ssa: $(testlib_slice_any_srcs) $(testlib_rt) $(testlib_types) +$(TESTCACHE)/slice/slice-any.ssa: $(testlib_slice_any_srcs) $(testlib_rt) $(testlib_types_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/slice @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nslice \ @@ -2361,7 +3068,7 @@ testlib_strconv_any_srcs= \ $(STDLIB)/strconv/+test/stou.ha \ $(STDLIB)/strconv/+test/stoi.ha -$(TESTCACHE)/strconv/strconv-any.ssa: $(testlib_strconv_any_srcs) $(testlib_rt) $(testlib_types) $(testlib_strings) $(testlib_ascii) $(testlib_math) +$(TESTCACHE)/strconv/strconv-any.ssa: $(testlib_strconv_any_srcs) $(testlib_rt) $(testlib_types_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_ascii_$(PLATFORM)) $(testlib_math_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/strconv @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nstrconv \ @@ -2381,7 +3088,7 @@ testlib_strings_any_srcs= \ $(STDLIB)/strings/index.ha \ $(STDLIB)/strings/trim.ha -$(TESTCACHE)/strings/strings-any.ssa: $(testlib_strings_any_srcs) $(testlib_rt) $(testlib_bytes) $(testlib_encoding_utf8) $(testlib_types) +$(TESTCACHE)/strings/strings-any.ssa: $(testlib_strings_any_srcs) $(testlib_rt) $(testlib_bytes_$(PLATFORM)) $(testlib_encoding_utf8_$(PLATFORM)) $(testlib_types_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/strings @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nstrings \ @@ -2393,7 +3100,7 @@ testlib_strio_any_srcs= \ $(STDLIB)/strio/fixed.ha \ $(STDLIB)/strio/ops.ha -$(TESTCACHE)/strio/strio-any.ssa: $(testlib_strio_any_srcs) $(testlib_rt) $(testlib_io) $(testlib_strings) $(testlib_encoding_utf8) $(testlib_errors) +$(TESTCACHE)/strio/strio-any.ssa: $(testlib_strio_any_srcs) $(testlib_rt) $(testlib_io_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_encoding_utf8_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/strio @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nstrio \ @@ -2403,12 +3110,22 @@ $(TESTCACHE)/strio/strio-any.ssa: $(testlib_strio_any_srcs) $(testlib_rt) $(test testlib_temp_linux_srcs= \ $(STDLIB)/temp/+linux.ha -$(TESTCACHE)/temp/temp-linux.ssa: $(testlib_temp_linux_srcs) $(testlib_rt) $(testlib_crypto_random) $(testlib_encoding_hex) $(testlib_fs) $(testlib_io) $(testlib_os) $(testlib_path) $(testlib_strio) $(testlib_fmt) $(testlib_strings) +$(TESTCACHE)/temp/temp-linux.ssa: $(testlib_temp_linux_srcs) $(testlib_rt) $(testlib_crypto_random_$(PLATFORM)) $(testlib_encoding_hex_$(PLATFORM)) $(testlib_fs_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_os_$(PLATFORM)) $(testlib_path_$(PLATFORM)) $(testlib_strio_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/temp @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ntemp \ -t$(TESTCACHE)/temp/temp.td $(testlib_temp_linux_srcs) +# temp (+freebsd) +testlib_temp_freebsd_srcs= \ + $(STDLIB)/temp/+freebsd.ha + +$(TESTCACHE)/temp/temp-freebsd.ssa: $(testlib_temp_freebsd_srcs) $(testlib_rt) $(testlib_crypto_random_$(PLATFORM)) $(testlib_encoding_hex_$(PLATFORM)) $(testlib_fs_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_os_$(PLATFORM)) $(testlib_path_$(PLATFORM)) $(testlib_strio_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(TESTCACHE)/temp + @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ntemp \ + -t$(TESTCACHE)/temp/temp.td $(testlib_temp_freebsd_srcs) + # time (+linux) testlib_time_linux_srcs= \ $(STDLIB)/time/+linux/functions.ha \ @@ -2416,12 +3133,24 @@ testlib_time_linux_srcs= \ $(STDLIB)/time/arithm.ha \ $(STDLIB)/time/types.ha -$(TESTCACHE)/time/time-linux.ssa: $(testlib_time_linux_srcs) $(testlib_rt) $(testlib_linux_vdso) +$(TESTCACHE)/time/time-linux.ssa: $(testlib_time_linux_srcs) $(testlib_rt) $(testlib_linux_vdso_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/time @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ntime \ -t$(TESTCACHE)/time/time.td $(testlib_time_linux_srcs) +# time (+freebsd) +testlib_time_freebsd_srcs= \ + $(STDLIB)/time/+freebsd/functions.ha \ + $(STDLIB)/time/arithm.ha \ + $(STDLIB)/time/types.ha + +$(TESTCACHE)/time/time-freebsd.ssa: $(testlib_time_freebsd_srcs) $(testlib_rt) + @printf 'HAREC \t$@\n' + @mkdir -p $(TESTCACHE)/time + @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ntime \ + -t$(TESTCACHE)/time/time.td $(testlib_time_freebsd_srcs) + # types (+any) testlib_types_any_srcs= \ $(STDLIB)/types/limits.ha \ @@ -2445,17 +3174,31 @@ testlib_unix_linux_srcs= \ $(STDLIB)/unix/getuid.ha \ $(STDLIB)/unix/setuid.ha -$(TESTCACHE)/unix/unix-linux.ssa: $(testlib_unix_linux_srcs) $(testlib_rt) $(testlib_errors) $(testlib_fs) +$(TESTCACHE)/unix/unix-linux.ssa: $(testlib_unix_linux_srcs) $(testlib_rt) $(testlib_errors_$(PLATFORM)) $(testlib_fs_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/unix @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nunix \ -t$(TESTCACHE)/unix/unix.td $(testlib_unix_linux_srcs) +# unix (+freebsd) +testlib_unix_freebsd_srcs= \ + $(STDLIB)/unix/+freebsd/nice.ha \ + $(STDLIB)/unix/+freebsd/pipe.ha \ + $(STDLIB)/unix/+freebsd/umask.ha \ + $(STDLIB)/unix/getuid.ha \ + $(STDLIB)/unix/setuid.ha + +$(TESTCACHE)/unix/unix-freebsd.ssa: $(testlib_unix_freebsd_srcs) $(testlib_rt) $(testlib_errors_$(PLATFORM)) $(testlib_fs_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(TESTCACHE)/unix + @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nunix \ + -t$(TESTCACHE)/unix/unix.td $(testlib_unix_freebsd_srcs) + # unix::hosts (+any) testlib_unix_hosts_any_srcs= \ $(STDLIB)/unix/hosts/lookup.ha -$(TESTCACHE)/unix/hosts/unix_hosts-any.ssa: $(testlib_unix_hosts_any_srcs) $(testlib_rt) $(testlib_os) $(testlib_io) $(testlib_bufio) $(testlib_net_ip) $(testlib_strings) +$(TESTCACHE)/unix/hosts/unix_hosts-any.ssa: $(testlib_unix_hosts_any_srcs) $(testlib_rt) $(testlib_os_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_bufio_$(PLATFORM)) $(testlib_net_ip_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/unix/hosts @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nunix::hosts \ @@ -2467,7 +3210,7 @@ testlib_unix_passwd_any_srcs= \ $(STDLIB)/unix/passwd/passwd.ha \ $(STDLIB)/unix/passwd/types.ha -$(TESTCACHE)/unix/passwd/unix_passwd-any.ssa: $(testlib_unix_passwd_any_srcs) $(testlib_rt) $(testlib_bufio) $(testlib_io) $(testlib_os) $(testlib_strconv) $(testlib_strings) +$(TESTCACHE)/unix/passwd/unix_passwd-any.ssa: $(testlib_unix_passwd_any_srcs) $(testlib_rt) $(testlib_bufio_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_os_$(PLATFORM)) $(testlib_strconv_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/unix/passwd @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nunix::passwd \ @@ -2477,17 +3220,27 @@ $(TESTCACHE)/unix/passwd/unix_passwd-any.ssa: $(testlib_unix_passwd_any_srcs) $( testlib_unix_poll_linux_srcs= \ $(STDLIB)/unix/poll/+linux.ha -$(TESTCACHE)/unix/poll/unix_poll-linux.ssa: $(testlib_unix_poll_linux_srcs) $(testlib_rt) $(testlib_rt) $(testlib_errors) $(testlib_time) +$(TESTCACHE)/unix/poll/unix_poll-linux.ssa: $(testlib_unix_poll_linux_srcs) $(testlib_rt) $(testlib_rt_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) $(testlib_time_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/unix/poll @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nunix::poll \ -t$(TESTCACHE)/unix/poll/unix_poll.td $(testlib_unix_poll_linux_srcs) +# unix::poll (+freebsd) +testlib_unix_poll_freebsd_srcs= \ + $(STDLIB)/unix/poll/+freebsd.ha + +$(TESTCACHE)/unix/poll/unix_poll-freebsd.ssa: $(testlib_unix_poll_freebsd_srcs) $(testlib_rt) $(testlib_rt_$(PLATFORM)) $(testlib_errors_$(PLATFORM)) $(testlib_time_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(TESTCACHE)/unix/poll + @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nunix::poll \ + -t$(TESTCACHE)/unix/poll/unix_poll.td $(testlib_unix_poll_freebsd_srcs) + # unix::resolvconf (+any) testlib_unix_resolvconf_any_srcs= \ $(STDLIB)/unix/resolvconf/load.ha -$(TESTCACHE)/unix/resolvconf/unix_resolvconf-any.ssa: $(testlib_unix_resolvconf_any_srcs) $(testlib_rt) $(testlib_os) $(testlib_io) $(testlib_bufio) $(testlib_net_ip) $(testlib_strings) +$(TESTCACHE)/unix/resolvconf/unix_resolvconf-any.ssa: $(testlib_unix_resolvconf_any_srcs) $(testlib_rt) $(testlib_os_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_bufio_$(PLATFORM)) $(testlib_net_ip_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/unix/resolvconf @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nunix::resolvconf \ @@ -2500,17 +3253,30 @@ testlib_unix_tty_linux_srcs= \ $(STDLIB)/unix/tty/+linux/open.ha \ $(STDLIB)/unix/tty/+linux/winsize.ha -$(TESTCACHE)/unix/tty/unix_tty-linux.ssa: $(testlib_unix_tty_linux_srcs) $(testlib_rt) $(testlib_rt) $(testlib_fs) $(testlib_io) $(testlib_os) +$(TESTCACHE)/unix/tty/unix_tty-linux.ssa: $(testlib_unix_tty_linux_srcs) $(testlib_rt) $(testlib_rt_$(PLATFORM)) $(testlib_fs_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_os_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/unix/tty @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nunix::tty \ -t$(TESTCACHE)/unix/tty/unix_tty.td $(testlib_unix_tty_linux_srcs) +# unix::tty (+freebsd) +testlib_unix_tty_freebsd_srcs= \ + $(STDLIB)/unix/tty/types.ha \ + $(STDLIB)/unix/tty/+freebsd/isatty.ha \ + $(STDLIB)/unix/tty/+freebsd/open.ha \ + $(STDLIB)/unix/tty/+freebsd/winsize.ha + +$(TESTCACHE)/unix/tty/unix_tty-freebsd.ssa: $(testlib_unix_tty_freebsd_srcs) $(testlib_rt) $(testlib_rt_$(PLATFORM)) $(testlib_fs_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_os_$(PLATFORM)) + @printf 'HAREC \t$@\n' + @mkdir -p $(TESTCACHE)/unix/tty + @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nunix::tty \ + -t$(TESTCACHE)/unix/tty/unix_tty.td $(testlib_unix_tty_freebsd_srcs) + # uuid (+any) testlib_uuid_any_srcs= \ $(STDLIB)/uuid/uuid.ha -$(TESTCACHE)/uuid/uuid-any.ssa: $(testlib_uuid_any_srcs) $(testlib_rt) $(testlib_crypto_random) $(testlib_strio) $(testlib_fmt) $(testlib_endian) $(testlib_io) $(testlib_bytes) $(testlib_bufio) $(testlib_strings) $(testlib_strconv) +$(TESTCACHE)/uuid/uuid-any.ssa: $(testlib_uuid_any_srcs) $(testlib_rt) $(testlib_crypto_random_$(PLATFORM)) $(testlib_strio_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) $(testlib_endian_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_bytes_$(PLATFORM)) $(testlib_bufio_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_strconv_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/uuid @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nuuid \ diff --git a/temp/+freebsd.ha b/temp/+freebsd.ha @@ -0,0 +1,98 @@ +use crypto::random; +use encoding::hex; +use errors; +use fmt; +use fs; +use io; +use os; +use path; +use strio; +use strings; + +fn get_tmpdir() str = os::tryenv("TMPDIR", "/tmp"); + +// Creates an unnamed temporary file. The file may or may not have a name; not +// all systems support the creation of temporary inodes which are not linked to +// any directory. If it is necessary to create a real file, it will be removed +// when the stream is closed. +// +// The I/O mode must be either [[io::mode::WRITE]] or [[io::mode::RDWR]]. +// +// Only one variadic argument may be provided, if at all, to specify the mode of +// the new file. The default is 0o644. +export fn file( + iomode: io::mode, + mode: fs::mode... +) (io::file | fs::error) = { + // TODO: Add a custom "close" function which removes the named file + let file = named(os::cwd, get_tmpdir(), iomode, mode...)?; + free(file.1); + return file.0; +}; + +// Creates a named temporary file in the given directory of the given +// filesystem. The caller is responsible for removing the file and freeing the +// name when they're done with it. +// +// The I/O mode must be either [[io::mode::WRITE]] or [[io::mode::RDWR]]. +// +// Only one variadic argument may be provided, if at all, to specify the mode of +// the new file. The default is 0o644. +export fn named( + fs: *fs::fs, + path: str, + iomode: io::mode, + mode: fs::mode... +) ((io::file, str) | fs::error) = { + assert(iomode == io::mode::WRITE || iomode == io::mode::RDWR); + assert(len(mode) == 0 || len(mode) == 1); + + let fmode = if (len(mode) != 0) mode[0] else 0o644: fs::mode; + let oflags = fs::flags::EXCL | fs::flags::CLOEXEC; + if (iomode == io::mode::RDWR) { + oflags |= fs::flags::RDWR; + } else { + oflags |= fs::flags::WRONLY; + }; + + // TODO: Use path::pathbuf + static let pathbuf: [4096]u8 = [0...]; + for (true) { + let rand: [size(u64)]u8 = [0...]; + random::buffer(rand); + const id = *(&rand[0]: *u64); + const fpath = fmt::bsprintf(pathbuf, "{}/temp.{}", path, id); + match (fs::create_file(fs, fpath, fmode, oflags)) { + case errors::exists => + continue; + case err: fs::error => + return err; + case f: io::file => + return (f, strings::dup(fpath)); + }; + }; + abort(); // Unreachable +}; + +// Creates a temporary directory. This function only guarantees that the +// directory will have a unique name and be placed in the system temp directory, +// but not that it will be removed automatically; the caller must remove it when +// they're done using it via [[os::rmdir]] or [[os::rmdirall]]. +// +// The caller must free the return value. +export fn dir() str = { + let buf: [8]u8 = [0...], name: [16]u8 = [0...]; + random::buffer(buf[..]); + + let sink = strio::fixed(name); + defer io::close(sink); + hex::encode(sink, buf) as size; + let name = strio::string(sink); + + let path = path::join(get_tmpdir(), name); + match (os::mkdir(path)) { + case err: fs::error => abort("Could not create temp directory"); + case void => void; + }; + return path; +}; diff --git a/time/+freebsd/functions.ha b/time/+freebsd/functions.ha @@ -0,0 +1,86 @@ +use rt; + +// Converts a [[duration]] to an [[rt::timespec]]. This function is +// non-portable. +export fn duration_to_timespec(n: duration, ts: *rt::timespec) void = { + ts.tv_sec = n / SECOND; + ts.tv_nsec = n % SECOND; +}; + +// Converts an [[instant]] to an [[rt::timespec]]. This function is +// non-portable. +export fn instant_to_timespec(t: instant, ts: *rt::timespec) void = { + ts.tv_sec = t.sec; + ts.tv_nsec = t.nsec; +}; + +// Converts a [[rt::timespec]] to an [[rt::instant]]. This function is +// non-portable. +export fn timespec_to_instant(ts: rt::timespec) instant = instant { + sec = ts.tv_sec, + nsec = ts.tv_nsec, +}; + +// Yields the process to the kernel and returns after the requested duration. +export fn sleep(n: duration) void = { + let in = rt::timespec { ... }; + duration_to_timespec(n, &in); + let req = &in; + + for (true) { + let res = rt::timespec { ... }; + match (rt::nanosleep(req, &res)) { + case void => + return; + case err: rt::errno => + switch (err) { + case rt::EINTR => + req = &res; + case => + abort("Unexpected error from nanosleep"); + }; + }; + }; +}; + +// An enumeration of clocks available on this system. Different clocks represent +// times from different epochs, and have different characteristics with regards +// to leap seconds, NTP adjustments, and so on. All systems provide the REALTIME +// and MONOTONIC clocks at least; use of other clocks is not guaranteed to be +// portable. +export type clock = enum { + // The current wall-clock time. This may jump forwards or backwards in + // time to account for leap seconds, NTP adjustments, etc. + REALTIME = 0, + + // The current monotonic time. This clock measures from some undefined + // epoch and is not affected by leap seconds, NTP adjustments, and + // changes to the system time: it always increases by one second per + // second. + MONOTONIC = 4, + + // TODO: Document these + VIRTUAL = 1, + PROF = 2, + UPTIME = 5, + UPTIME_PRECISE = 7, + UPTIME_FAST = 8, + REALTIME_PRECISE = 9, + REALTIME_FAST = 10, + MONOTONIC_PRECISE = 11, + MONOTONIC_FAST = 12, + SECOND = 13, + THREAD_CPUTIME_ID = 14, + PROCESS_CPUTIME_ID = 15, +}; + +// Returns the current time for a given clock. +export fn now(clock: clock) instant = { + let tp = rt::timespec { ... }; + match (rt::clock_gettime(clock, &tp)) { + case void => + return timespec_to_instant(tp); + case err: rt::errno => + abort("Unexpected error from clock_gettime"); + }; +}; diff --git a/time/+linux/functions.ha b/time/+linux/functions.ha @@ -107,9 +107,9 @@ export fn now(clock: clock) instant = { abort("Unexpected error from clock_gettime"); }; match (rt::clock_gettime(clock, &tp)) { - case void => - return timespec_to_instant(tp); - case err: rt::errno => - abort("Unexpected error from clock_gettime"); + case void => + return timespec_to_instant(tp); + case err: rt::errno => + abort("Unexpected error from clock_gettime"); }; }; diff --git a/unix/+freebsd/nice.ha b/unix/+freebsd/nice.ha @@ -0,0 +1,24 @@ +use errors; +use rt; + +// Adds the argument to the niceness of the current process. The input should be +// between -20 and 19 (inclusive); lower numbers represent a higher priority. +// Generally, you must have elevated permissions to reduce your niceness, but +// not to increase it. +export fn nice(inc: int) (void | errors::error) = { + let prio = inc; + if (inc > -40 && inc <= 40) { + prio += rt::getpriority(rt::PRIO_PROCESS, 0) as int; + }; + if (prio > 19) { + prio = 19; + }; + if (prio < -20) { + prio = -20; + }; + match (rt::setpriority(rt::PRIO_PROCESS, 0, prio)) { + case void => void; + case err: rt::errno => + return errors::errno(err); + }; +}; diff --git a/unix/+freebsd/pipe.ha b/unix/+freebsd/pipe.ha @@ -0,0 +1,29 @@ +use errors; +use io; +use rt; + +// Flags to use for the [[io::file]]s returned by [[pipe]] +// Only CLOEXEC and NONBLOCK are guaranteed to be available. +export type pipe_flag = enum { + CLOEXEC = rt::O_CLOEXEC, + DIRECT = rt::O_DIRECT, + NONBLOCK = rt::O_NONBLOCK, +}; + +// Create a pair of two linked [[io::file]]s, such that any data written to the +// second [[io::file]] may be read from the first. If no [[pipe_flag]]s are +// provided, [[pipe_flag::CLOEXEC]] is used. If you pass your own flags, it is +// recommended that you add it unless you know that you don't want it. +export fn pipe(flags: pipe_flag...) ((io::file, io::file) | errors::error) = { + let fds: [2]int = [0...]; + let flag: pipe_flag = if (len(flags) == 0) pipe_flag::CLOEXEC else 0; + for (let i = 0z; i < len(flags); i += 1) { + flag |= flags[i]; + }; + match (rt::pipe2(&fds, flag)) { + case void => void; + case e: rt::errno => + return errors::errno(e); + }; + return (fds[0], fds[1]); +}; diff --git a/unix/+freebsd/umask.ha b/unix/+freebsd/umask.ha @@ -0,0 +1,7 @@ +use errors; +use fs; +use rt; + +// Sets the file mode creation mask for the current process and return the +// previous value of the mask. +export fn umask(mode: fs::mode) fs::mode = rt::umask(mode: rt::mode_t)!: fs::mode; diff --git a/unix/poll/+freebsd.ha b/unix/poll/+freebsd.ha @@ -0,0 +1,48 @@ +use errors; +use io; +use rt; +use time; + +// Events bitfield for the events and revents field of [[pollfd]]. +export type event = enum i16 { + POLLIN = 1, + POLLPRI = 2, + POLLOUT = 4, + POLLERR = 8, + POLLHUP = 16, +}; + +// A single file descriptor to be polled. +export type pollfd = struct { + fd: io::file, + events: event, + revents: event, +}; + +// Pass this [[time::duration]] to [[poll]] to cause it wait indefinitely for +// the next event. +export def INDEF: time::duration = -1; + +// Pass this [[time::duration]] to [[poll]] to cause it to return immediately if +// no events are available. +export def NONBLOCK: time::duration = 0; + +// Polls for the desired events on a slice of [[pollfd]]s, blocking until an +// event is available, or the timeout expires. Set the timeout to [[INDEF]] to +// block forever, or [[NONBLOCK]] to return immediately if no events are +// available. Returns the number of [[pollfd]] items which have events, i.e. +// those which have revents set to a nonzero value. +export fn poll( + fds: []pollfd, + timeout: time::duration, +) (uint | errors::error) = { + let ts = rt::timespec { ... }; + time::duration_to_timespec(timeout, &ts); + let ts = if (timeout == INDEF) null else &ts; + match (rt::ppoll(fds: *[*]pollfd, len(fds): rt::nfds_t, ts, null)) { + case err: rt::errno => + return errors::errno(err); + case n: int => + return n: uint; + }; +}; diff --git a/unix/tty/+freebsd/isatty.ha b/unix/tty/+freebsd/isatty.ha @@ -0,0 +1,14 @@ +use rt; +use io; +use os; + +// Returns whether the given stream is connected to a terminal. +export fn isatty(fd: io::file) bool = { + let wsz = rt::winsize { ... }; + match (rt::ioctl(fd, rt::TIOCGWINSZ, &wsz: *void)) { + case e: rt::errno => + return false; + case r: int => + return r == 0; + }; +}; diff --git a/unix/tty/+freebsd/open.ha b/unix/tty/+freebsd/open.ha @@ -0,0 +1,15 @@ +use errors; +use fs; +use io; +use os; + +// Returns a stream connected to the TTY of the current process. The caller must +// close it using [[io::close]]. +export fn open() (io::file | error) = { + match (os::open("/dev/tty", fs::flags::RDWR, fs::flags::CLOEXEC)) { + case f: io::file => + return f; + case fs::error => + return errors::noentry; + }; +}; diff --git a/unix/tty/+freebsd/winsize.ha b/unix/tty/+freebsd/winsize.ha @@ -0,0 +1,25 @@ +use errors; +use io; +use os; +use rt; + +// Returns the dimensions of underlying terminal for an [[io::file]]. +export fn winsize(fd: io::file) (ttysize | error) = { + let wsz = rt::winsize { ... }; + match (rt::ioctl(fd, rt::TIOCGWINSZ, &wsz: *void)) { + case e: rt::errno => + switch (e: int) { + case rt::EBADF => + return errors::invalid; + case rt::ENOTTY => + return errors::unsupported; + case => + abort("Unexpected error from ioctl"); + }; + case int => + return ttysize { + rows = wsz.ws_row, + columns = wsz.ws_col, + }; + }; +};