hare

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

commit 2365ddceeb4688826c6bdef3986c22d23112fdb7
parent 686f94ddf02f46d2629b06471c4a9d8325ebe613
Author: Lorenz (xha) <me@xha.li>
Date:   Sat, 25 Nov 2023 15:18:06 +0100

OpenBSD: add rt

Co-authored-by: Lennart Jablonka <humm@ljabl.com>
Signed-off-by: Lorenz (xha) <me@xha.li>

Diffstat:
Art/+openbsd/env.ha | 6++++++
Art/+openbsd/errno.ha | 501+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Art/+openbsd/hare+test.sc | 7+++++++
Art/+openbsd/hare.sc | 2++
Art/+openbsd/libc.ha | 20++++++++++++++++++++
Art/+openbsd/platform_abort.ha | 23+++++++++++++++++++++++
Art/+openbsd/signal.ha | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Art/+openbsd/socket.ha | 150+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Art/+openbsd/start+test.ha | 28++++++++++++++++++++++++++++
Art/+openbsd/start.ha | 26++++++++++++++++++++++++++
Art/+openbsd/start.s | 4++++
Art/+openbsd/syscalls.ha | 1271+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Art/+openbsd/types.ha | 737+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
13 files changed, 2848 insertions(+), 0 deletions(-)

diff --git a/rt/+openbsd/env.ha b/rt/+openbsd/env.ha @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MPL-2.0 +// (c) Hare authors <https://harelang.org> + +export let argc: size = 0; +export let argv: *[*]*u8 = null: *[*]*u8; +export let envp: *[*]nullable *u8 = null: *[*]nullable *u8; diff --git a/rt/+openbsd/errno.ha b/rt/+openbsd/errno.ha @@ -0,0 +1,501 @@ +// SPDX-License-Identifier: MPL-2.0 +// (c) Hare authors <https://harelang.org> + +// $OpenBSD: errno.h,v 1.25 2017/09/05 03:06:26 jsg Exp $ + +// Represents an error returned from the OpenBSD kernel. +export type errno = !int; + +// Obtains a human-friendly reading of an [[errno]] (e.g. "Operation not +// permitted"). +export fn strerror(err: errno) str = { + switch (err) { + case EPERM => + return "Operation not permitted"; + case ENOENT => + return "No such file or directory"; + case ESRCH => + return "No such process"; + case EINTR => + return "Interrupted system call"; + case EIO => + return "Input/output error"; + case ENXIO => + return "Device not configured"; + case E2BIG => + return "Argument list too long"; + case ENOEXEC => + return "Exec format error"; + case EBADF => + return "Bad file descriptor"; + case ECHILD => + return "No child processes"; + case EDEADLK => + return "Resource deadlock avoided"; + case ENOMEM => + return "Cannot allocate memory"; + case EACCES => + return "Permission denied"; + case EFAULT => + return "Bad address"; + case ENOTBLK => + return "Block device required"; + case EBUSY => + return "Device busy"; + case EEXIST => + return "File exists"; + case EXDEV => + return "Cross-device link"; + case ENODEV => + return "Operation not supported by device"; + case ENOTDIR => + return "Not a directory"; + case EISDIR => + return "Is a directory"; + case EINVAL => + return "Invalid argument"; + case ENFILE => + return "Too many open files in system"; + case EMFILE => + return "Too many open files"; + case ENOTTY => + return "Inappropriate ioctl for device"; + case ETXTBSY => + return "Text file busy"; + case EFBIG => + return "File too large"; + case ENOSPC => + return "No space left on device"; + case ESPIPE => + return "Illegal seek"; + case EROFS => + return "Read-only file system"; + case EMLINK => + return "Too many links"; + case EPIPE => + return "Broken pipe"; + case EDOM => + return "Numerical argument out of domain"; + case ERANGE => + return "Result too large"; + case EAGAIN => + return "Resource temporarily unavailable"; + case EINPROGRESS => + return "Operation now in progress"; + case EALREADY => + return "Operation already in progress"; + case ENOTSOCK => + return "Socket operation on non-socket"; + case EDESTADDRREQ => + return "Destination address required"; + case EMSGSIZE => + return "Message too long"; + case EPROTOTYPE => + return "Protocol wrong type for socket"; + case ENOPROTOOPT => + return "Protocol not available"; + case EPROTONOSUPPORT => + return "Protocol not supported"; + case ESOCKTNOSUPPORT => + return "Socket type not supported"; + case EOPNOTSUPP => + return "Operation not supported"; + case EPFNOSUPPORT => + return "Protocol family not supported"; + case EAFNOSUPPORT => + return "Address family not supported by protocol family"; + case EADDRINUSE => + return "Address already in use"; + case EADDRNOTAVAIL => + return "Can't assign requested address"; + case ENETDOWN => + return "Network is down"; + case ENETUNREACH => + return "Network is unreachable"; + case ENETRESET => + return "Network dropped connection on reset"; + case ECONNABORTED => + return "Software caused connection abort"; + case ECONNRESET => + return "Connection reset by peer"; + case ENOBUFS => + return "No buffer space available"; + case EISCONN => + return "Socket is already connected"; + case ENOTCONN => + return "Socket is not connected"; + case ESHUTDOWN => + return "Can't send after socket shutdown"; + case ETOOMANYREFS => + return "Too many references: can't splice"; + case ETIMEDOUT => + return "Operation timed out"; + case ECONNREFUSED => + return "Connection refused"; + case ELOOP => + return "Too many levels of symbolic links"; + case ENAMETOOLONG => + return "File name too long"; + case EHOSTDOWN => + return "Host is down"; + case EHOSTUNREACH => + return "No route to host"; + case ENOTEMPTY => + return "Directory not empty"; + case EPROCLIM => + return "Too many processes"; + case EUSERS => + return "Too many users"; + case EDQUOT => + return "Disk quota exceeded"; + case ESTALE => + return "Stale NFS file handle"; + case EREMOTE => + return "Too many levels of remote in path"; + case EBADRPC => + return "RPC struct is bad"; + case ERPCMISMATCH => + return "RPC version wrong"; + case EPROGUNAVAIL => + return "RPC program not available"; + case EPROGMISMATCH => + return "Program version wrong"; + case EPROCUNAVAIL => + return "Bad procedure for program"; + case ENOLCK => + return "No locks available"; + case ENOSYS => + return "Function not implemented"; + case EFTYPE => + return "Inappropriate file type or format"; + case EAUTH => + return "Authentication error"; + case ENEEDAUTH => + return "Need authenticator"; + case EIPSEC => + return "IPsec processing failure"; + case ENOATTR => + return "Attribute not found"; + case EILSEQ => + return "Illegal byte sequence"; + case ENOMEDIUM => + return "No medium found"; + case EMEDIUMTYPE => + return "Wrong medium type"; + case EOVERFLOW => + return "Value too large to be stored in data type"; + case ECANCELED => + return "Operation canceled"; + case EIDRM => + return "Identifier removed"; + case ENOMSG => + return "No message of desired type"; + case ENOTSUP => + return "Not supported"; + case EBADMSG => + return "Bad message"; + case ENOTRECOVERABLE => + return "State not recoverable"; + case EOWNERDEAD => + return "Previous owner died"; + case EPROTO => + return "Protocol error"; + case => + return unknown_errno(err); + }; +}; + +// Gets the programmer-friendly name for an [[errno]] (e.g. EPERM). +export fn errname(err: errno) str = { + switch (err) { + case EPERM => + return "EPERM"; + case ENOENT => + return "ENOENT"; + case ESRCH => + return "ESRCH"; + case EINTR => + return "EINTR"; + case EIO => + return "EIO"; + case ENXIO => + return "ENXIO"; + case E2BIG => + return "E2BIG"; + case ENOEXEC => + return "ENOEXEC"; + case EBADF => + return "EBADF"; + case ECHILD => + return "ECHILD"; + case EDEADLK => + return "EDEADLK"; + case ENOMEM => + return "ENOMEM"; + case EACCES => + return "EACCES"; + case EFAULT => + return "EFAULT"; + case ENOTBLK => + return "ENOTBLK"; + case EBUSY => + return "EBUSY"; + case EEXIST => + return "EEXIST"; + case EXDEV => + return "EXDEV"; + case ENODEV => + return "ENODEV"; + case ENOTDIR => + return "ENOTDIR"; + case EISDIR => + return "EISDIR"; + case EINVAL => + return "EINVAL"; + case ENFILE => + return "ENFILE"; + case EMFILE => + return "EMFILE"; + case ENOTTY => + return "ENOTTY"; + case ETXTBSY => + return "ETXTBSY"; + case EFBIG => + return "EFBIG"; + case ENOSPC => + return "ENOSPC"; + case ESPIPE => + return "ESPIPE"; + case EROFS => + return "EROFS"; + case EMLINK => + return "EMLINK"; + case EPIPE => + return "EPIPE"; + case EDOM => + return "EDOM"; + case ERANGE => + return "ERANGE"; + case EAGAIN => + return "EAGAIN"; + case EINPROGRESS => + return "EINPROGRESS"; + case EALREADY => + return "EALREADY"; + case ENOTSOCK => + return "ENOTSOCK"; + case EDESTADDRREQ => + return "EDESTADDRREQ"; + case EMSGSIZE => + return "EMSGSIZE"; + case EPROTOTYPE => + return "EPROTOTYPE"; + case ENOPROTOOPT => + return "ENOPROTOOPT"; + case EPROTONOSUPPORT => + return "EPROTONOSUPPORT"; + case ESOCKTNOSUPPORT => + return "ESOCKTNOSUPPORT"; + case EOPNOTSUPP => + return "EOPNOTSUPP"; + case EPFNOSUPPORT => + return "EPFNOSUPPORT"; + case EAFNOSUPPORT => + return "EAFNOSUPPORT"; + case EADDRINUSE => + return "EADDRINUSE"; + case EADDRNOTAVAIL => + return "EADDRNOTAVAIL"; + case ENETDOWN => + return "ENETDOWN"; + case ENETUNREACH => + return "ENETUNREACH"; + case ENETRESET => + return "ENETRESET"; + case ECONNABORTED => + return "ECONNABORTED"; + case ECONNRESET => + return "ECONNRESET"; + case ENOBUFS => + return "ENOBUFS"; + case EISCONN => + return "EISCONN"; + case ENOTCONN => + return "ENOTCONN"; + case ESHUTDOWN => + return "ESHUTDOWN"; + case ETOOMANYREFS => + return "ETOOMANYREFS"; + case ETIMEDOUT => + return "ETIMEDOUT"; + case ECONNREFUSED => + return "ECONNREFUSED"; + case ELOOP => + return "ELOOP"; + case ENAMETOOLONG => + return "ENAMETOOLONG"; + case EHOSTDOWN => + return "EHOSTDOWN"; + case EHOSTUNREACH => + return "EHOSTUNREACH"; + case ENOTEMPTY => + return "ENOTEMPTY"; + case EPROCLIM => + return "EPROCLIM"; + case EUSERS => + return "EUSERS"; + case EDQUOT => + return "EDQUOT"; + case ESTALE => + return "ESTALE"; + case EREMOTE => + return "EREMOTE"; + case EBADRPC => + return "EBADRPC"; + case ERPCMISMATCH => + return "ERPCMISMATCH"; + case EPROGUNAVAIL => + return "EPROGUNAVAIL"; + case EPROGMISMATCH => + return "EPROGMISMATCH"; + case EPROCUNAVAIL => + return "EPROCUNAVAIL"; + case ENOLCK => + return "ENOLCK"; + case ENOSYS => + return "ENOSYS"; + case EFTYPE => + return "EFTYPE"; + case EAUTH => + return "EAUTH"; + case ENEEDAUTH => + return "ENEEDAUTH"; + case EIPSEC => + return "EIPSEC"; + case ENOATTR => + return "ENOATTR"; + case EILSEQ => + return "EILSEQ"; + case ENOMEDIUM => + return "ENOMEDIUM"; + case EMEDIUMTYPE => + return "EMEDIUMTYPE"; + case EOVERFLOW => + return "EOVERFLOW"; + case ECANCELED => + return "ECANCELED"; + case EIDRM => + return "EIDRM"; + case ENOMSG => + return "ENOMSG"; + case ENOTSUP => + return "ENOTSUP"; + case EBADMSG => + return "EBADMSG"; + case ENOTRECOVERABLE => + return "ENOTRECOVERABLE"; + case EOWNERDEAD => + return "EOWNERDEAD"; + case EPROTO => + return "EPROTO"; + case => + return unknown_errno(err); + }; +}; + +export def EPERM: errno = 1; +export def ENOENT: errno = 2; +export def ESRCH: errno = 3; +export def EINTR: errno = 4; +export def EIO: errno = 5; +export def ENXIO: errno = 6; +export def E2BIG: errno = 7; +export def ENOEXEC: errno = 8; +export def EBADF: errno = 9; +export def ECHILD: errno = 10; +export def EDEADLK: errno = 11; +export def ENOMEM: errno = 12; +export def EACCES: errno = 13; +export def EFAULT: errno = 14; +export def ENOTBLK: errno = 15; +export def EBUSY: errno = 16; +export def EEXIST: errno = 17; +export def EXDEV: errno = 18; +export def ENODEV: errno = 19; +export def ENOTDIR: errno = 20; +export def EISDIR: errno = 21; +export def EINVAL: errno = 22; +export def ENFILE: errno = 23; +export def EMFILE: errno = 24; +export def ENOTTY: errno = 25; +export def ETXTBSY: errno = 26; +export def EFBIG: errno = 27; +export def ENOSPC: errno = 28; +export def ESPIPE: errno = 29; +export def EROFS: errno = 30; +export def EMLINK: errno = 31; +export def EPIPE: errno = 32; +export def EDOM: errno = 33; +export def ERANGE: errno = 34; +export def EAGAIN: errno = 35; +export def EWOULDBLOCK: errno = EAGAIN; +export def EINPROGRESS: errno = 36; +export def EALREADY: errno = 37; +export def ENOTSOCK: errno = 38; +export def EDESTADDRREQ: errno = 39; +export def EMSGSIZE: errno = 40; +export def EPROTOTYPE: errno = 41; +export def ENOPROTOOPT: errno = 42; +export def EPROTONOSUPPORT: errno = 43; +export def ESOCKTNOSUPPORT: errno = 44; +export def EOPNOTSUPP: errno = 45; +export def EPFNOSUPPORT: errno = 46; +export def EAFNOSUPPORT: errno = 47; +export def EADDRINUSE: errno = 48; +export def EADDRNOTAVAIL: errno = 49; +export def ENETDOWN: errno = 50; +export def ENETUNREACH: errno = 51; +export def ENETRESET: errno = 52; +export def ECONNABORTED: errno = 53; +export def ECONNRESET: errno = 54; +export def ENOBUFS: errno = 55; +export def EISCONN: errno = 56; +export def ENOTCONN: errno = 57; +export def ESHUTDOWN: errno = 58; +export def ETOOMANYREFS: errno = 59; +export def ETIMEDOUT: errno = 60; +export def ECONNREFUSED: errno = 61; +export def ELOOP: errno = 62; +export def ENAMETOOLONG: errno = 63; +export def EHOSTDOWN: errno = 64; +export def EHOSTUNREACH: errno = 65; +export def ENOTEMPTY: errno = 66; +export def EPROCLIM: errno = 67; +export def EUSERS: errno = 68; +export def EDQUOT: errno = 69; +export def ESTALE: errno = 70; +export def EREMOTE: errno = 71; +export def EBADRPC: errno = 72; +export def ERPCMISMATCH: errno = 73; +export def EPROGUNAVAIL: errno = 74; +export def EPROGMISMATCH: errno = 75; +export def EPROCUNAVAIL: errno = 76; +export def ENOLCK: errno = 77; +export def ENOSYS: errno = 78; +export def EFTYPE: errno = 79; +export def EAUTH: errno = 80; +export def ENEEDAUTH: errno = 81; +export def EIPSEC: errno = 82; +export def ENOATTR: errno = 83; +export def EILSEQ: errno = 84; +export def ENOMEDIUM: errno = 85; +export def EMEDIUMTYPE: errno = 86; +export def EOVERFLOW: errno = 87; +export def ECANCELED: errno = 88; +export def EIDRM: errno = 89; +export def ENOMSG: errno = 90; +export def ENOTSUP: errno = 91; +export def EBADMSG: errno = 92; +export def ENOTRECOVERABLE: errno = 93; +export def EOWNERDEAD: errno = 94; +export def EPROTO: errno = 95; diff --git a/rt/+openbsd/hare+test.sc b/rt/+openbsd/hare+test.sc @@ -0,0 +1,7 @@ +SECTIONS { + .test_array : { + PROVIDE(__test_array_start = .); + KEEP(*(.test_array*)) + PROVIDE(__test_array_end = .); + } +} INSERT AFTER .bss; /* .bss was choosen arbitrarily. */ diff --git a/rt/+openbsd/hare.sc b/rt/+openbsd/hare.sc @@ -0,0 +1 @@ +/* empty linker script; not needed for OpenBSD */ +\ No newline at end of file diff --git a/rt/+openbsd/libc.ha b/rt/+openbsd/libc.ha @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MPL-2.0 +// (c) Hare authors <https://harelang.org> + +// Miscellaneous libc functions + +export @symbol("arc4random_buf") fn arc4random_buf( + buf: *opaque, + nbytes: size +) void; + +@symbol("ptsname") fn libc_ptsname(flides: int) *u8; + +export fn ptsname(flides: int) (*u8 | errno) = { + let res = libc_ptsname(flides); + + if (res == null) { + return *__errno(): errno; + }; + return res; +}; diff --git a/rt/+openbsd/platform_abort.ha b/rt/+openbsd/platform_abort.ha @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MPL-2.0 +// (c) Hare authors <https://harelang.org> + +fn platform_abort(path: *str, line: u64, col: u64, msg: str) void = { + const prefix = "Abort: "; + const sep = ":"; + const sepspace = ": "; + const linefeed = "\n"; + write(STDERR_FILENO, *(&prefix: **opaque): *const u8, len(prefix)): void; + write(STDERR_FILENO, *(path: **opaque): *const u8, len(path)): void; + write(STDERR_FILENO, *(&sep: **opaque): *const u8, len(sep)): void; + let (line, z) = u64tos(line); + write(STDERR_FILENO, line, z): void; + write(STDERR_FILENO, *(&sep: **opaque): *const u8, len(sep)): void; + let (col, z) = u64tos(col); + write(STDERR_FILENO, col, z): void; + write(STDERR_FILENO, *(&sepspace: **opaque): *const u8, + len(sepspace)): void; + write(STDERR_FILENO, *(&msg: **opaque): *const u8, len(msg)): void; + write(STDERR_FILENO, *(&linefeed: **opaque): *const u8, 1): void; + kill(getpid(), SIGABRT): void; + for (true) void; +}; diff --git a/rt/+openbsd/signal.ha b/rt/+openbsd/signal.ha @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: MPL-2.0 +// (c) Hare authors <https://harelang.org> + +export fn sigemptyset(set: *sigset) void = { + *set = 0; +}; + +export fn sigaddset(set: *sigset, signum: int) (void | errno) = { + if (signum < 1 || signum > NSIG) { + return *__errno(): errno; + }; + *set |= 1u << (signum: uint - 1); +}; + +export fn sigdelset(set: *sigset, signum: int) (void | errno) = { + if (signum < 1 || signum > NSIG) { + return *__errno(): errno; + }; + *set &= ~(1u << (signum: uint - 1)); +}; + +export fn sigismember(set: *sigset, signum: int) (bool | errno) = { + if (signum < 1 || signum > NSIG) { + return *__errno(): errno; + }; + return (*set & (1u << (signum: uint - 1))) != 0; +}; + +export fn sigfillset(set: *sigset) (void | errno) = { + *set = ~0u; +}; + +// Test sigset operations do not fail for valid signal numbers. +@test fn sigset_valid_signum() void = { + let set: sigset = 0; + sigemptyset(&set); + + assert(!(sigismember(&set, 1) is errno), "Unexpected error"); + assert(!(sigismember(&set, 15) is errno), "Unexpected error"); + assert(!(sigismember(&set, NSIG) is errno), "Unexpected error"); + + assert(!(sigaddset(&set, 1) is errno), "Unexpected error"); + assert(!(sigaddset(&set, 15) is errno), "Unexpected error"); + assert(!(sigaddset(&set, NSIG) is errno), "Unexpected error"); + + // It's ok to add a signal that is already present in the set. + assert(!(sigaddset(&set, 1) is errno), "Unexpected error"); + + assert(!(sigdelset(&set, 1) is errno), "Unexpected error"); + assert(!(sigdelset(&set, 15) is errno), "Unexpected error"); + assert(!(sigdelset(&set, NSIG) is errno), "Unexpected error"); + + // It's ok to delete a signal that is not present in the set. + assert(!(sigdelset(&set, 10) is errno), "Unexpected error"); +}; + +// Test sigset operations fail for invalid signal numbers. +@test fn sigset_invalid_signum() void = { + let set: sigset = 0; + sigemptyset(&set); + + assert(sigismember(&set, -1) is errno, "Expected error"); + assert(sigismember(&set, 0) is errno, "Expected error"); + assert(sigismember(&set, NSIG + 1) is errno, "Expected error"); + + assert(sigaddset(&set, -1) is errno, "Expected error"); + assert(sigaddset(&set, 0) is errno, "Expected error"); + assert(sigaddset(&set, NSIG + 1) is errno, "Expected error"); + + assert(sigdelset(&set, -1) is errno, "Expected error"); + assert(sigdelset(&set, 0) is errno, "Expected error"); + assert(sigdelset(&set, NSIG + 1) is errno, "Expected error"); +}; diff --git a/rt/+openbsd/socket.ha b/rt/+openbsd/socket.ha @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: MPL-2.0 +// (c) Hare authors <https://harelang.org> + +export type socklen_t = u32; +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]u8, +}; + +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]u8, +}; + +export type sockaddr = struct { + union { + in: sockaddr_in, + in6: sockaddr_in6, + un: sockaddr_un, + }, +}; + +export def SCM_RIGHTS: int = 0x01; +export def SCM_TIMESTAMP: int = 0x04; + +export type msghdr = struct { + msg_name: nullable *opaque, + msg_namelen: socklen_t, + msg_iov: nullable *[*]iovec, + msg_iovlen: uint, + msg_control: nullable *opaque, + msg_controllen: socklen_t, + msg_flags: int +}; + +export type cmsghdr = struct { + cmsg_len: socklen_t, + cmsg_level: int, + cmsg_type: int, +}; + +export type cmsg = struct { + hdr: cmsghdr, + cmsg_data: [*]u8, +}; + +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 = 0x8000; +export def SOCK_NONBLOCK: int = 0x4000; + +export def SOL_SOCKET: int = 0xffff; + +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_NS: 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_INET6: 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_NATM: sa_family_t = 27; +export def AF_ENCAP: sa_family_t = 28; +export def AF_SIP: sa_family_t = 29; +export def AF_KEY: sa_family_t = 30; +export def pseudo_AF_HDRCMPLT: sa_family_t = 31; + +export def SO_DEBUG: int = 0x0001; +export def SO_ACCEPTCONN: int = 0x0002; +export def SO_REUSEADDR: int = 0x0004; +export def SO_KEEPALIVE: int = 0x0008; +export def SO_DONTROUTE: int = 0x0010; +export def SO_BROADCAST: int = 0x0020; +export def SO_USELOOPBACK: int = 0x0040; +export def SO_LINGER: int = 0x0080; +export def SO_OOBINLINE: int = 0x0100; +export def SO_REUSEPORT: int = 0x0200; +export def SO_TIMESTAMP: int = 0x0800; +export def SO_BINDANY: int = 0x1000; +export def SO_ZEROIZE: int = 0x2000; + +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_NETPROC: int = 0x1020; +export def SO_RTABLE: int = 0x1021; +export def SO_PEERCRED: int = 0x1022; +export def SO_SPLICE: int = 0x1023; +export def SO_DOMAIN: int = 0x1024; +export def SO_PROTOCOL: int = 0x1025; diff --git a/rt/+openbsd/start+test.ha b/rt/+openbsd/start+test.ha @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MPL-2.0 +// (c) Hare authors <https://harelang.org> + +// The real main function. +@symbol(".main") fn main() void; + +@symbol("__test_main") fn test_main() size; + +// The setup of envp and args is done here. This is called by crt0 before +// normal init functions are called. +export @symbol("preinit_hare") fn preinit_hare( + c_argc: int, + c_argv: *[*]*u8, + c_envp: *[*]nullable *u8 +) void = { + argc = c_argc: size; + argv = c_argv; + envp = c_envp; +}; + +// The purpose of this "fake" main function is to make sure we exit with the +// correct exit code in the case that rt::exit() is not called from within the +// program. The intilization and finilization functions are not run from here, +// they are ran by crt0. +export @symbol("main") fn _main() void = { + const ret = if (test_main() > 0) 1 else 0; + exit(ret); +}; diff --git a/rt/+openbsd/start.ha b/rt/+openbsd/start.ha @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MPL-2.0 +// (c) Hare authors <https://harelang.org> + +// The real main function. +@symbol(".main") fn main() void; + +// The setup of envp and args is done here. This is called by crt0 before +// normal init functions are called. +export @symbol("preinit_hare") fn preinit_hare( + c_argc: int, + c_argv: *[*]*u8, + c_envp: *[*]nullable *u8 +) void = { + argc = c_argc: size; + argv = c_argv; + envp = c_envp; +}; + +// The purpose of this "fake" main function is to make sure we exit with the +// correct exit code in the case that rt::exit() is not called from within the +// program. The intilization and finilization functions are not run from here, +// they are ran by crt0. +export @symbol("main") fn _main() void = { + main(); + exit(0); +}; diff --git a/rt/+openbsd/start.s b/rt/+openbsd/start.s @@ -0,0 +1,4 @@ +.section ".preinit_array" +.balign 8 +.init.initfunc.0: + .quad preinit_hare+0 diff --git a/rt/+openbsd/syscalls.ha b/rt/+openbsd/syscalls.ha @@ -0,0 +1,1271 @@ +// SPDX-License-Identifier: MPL-2.0 +// (c) Hare authors <https://harelang.org> + +let pathbuf: [PATH_MAX]u8 = [0...]; +export type path = (str | []u8 | *const u8); + +fn copy_cpath(path: path, buf: []u8) (*const u8 | errno) = { + let path = match (path) { + case let c: *const u8 => + return c; + case let s: str => + let ptr = &s: *struct { + buf: *[*]u8, + length: size, + capacity: size, + }; + yield ptr.buf[..ptr.length]; + case let b: []u8 => + yield b; + }; + if (len(path) + 1 >= len(buf)) { + return ENAMETOOLONG; + }; + memcpy(buf: *[*]u8, path: *[*]u8, len(path)); + buf[len(path)] = 0; + return buf: *[*]u8: *const u8; +}; + +// NUL terminates a string and stores it in a static buffer of PATH_MAX bytes in +// length. +fn cpath(path: path) (*const u8 | errno) = { + return copy_cpath(path, pathbuf); +}; + +// /usr/include/errno.h: #define errno (*__errno()) +@symbol("__errno") fn __errno() *int; + +// exit +export @symbol("exit") fn exit(status: int) never; + +// fork + +@symbol("fork") fn libc_fork() int; + +export fn fork() (int | void | errno) = { + let res = libc_fork(); + if (res == -1) { + return *__errno(): errno; + }; + if (res == 0) { + return; + }; + return res; +}; + +// read + +@symbol("read") fn libc_read(d: int, buf: *opaque, nbytes: size) size; + +export fn read(fd: int, buf: *opaque, count: size) (size | errno) = { + let res: u64 = libc_read(fd, buf, count); + if (res == -1) { + return *__errno(): errno; + }; + return res; +}; + +// write + +@symbol("write") fn libc_write(d: int, buf: *const opaque, nbytes: size) size; + +export fn write(fd: int, buf: *const opaque, count: size) (size | errno) = { + let res: u64 = libc_write(fd, buf, count); + if (res == -1) { + return *__errno(): errno; + }; + return res; +}; + +// open + +@symbol("open") fn libc_open(path: *opaque, flags: int, mode: int) int; + +export fn open(path: path, flags: int, mode: int) (int | errno) = { + let res = libc_open(cpath(path)?, flags, mode); + if (res == -1) { + return *__errno(): errno; + }; + return res; +}; + +// posix_openpt (libc function not a syscall) + +@symbol("posix_openpt") fn libc_openpt(oflag: int) int; + +export fn posix_openpt(flags: int) (int | errno) = { + let res = libc_openpt(flags); + if (res == -1) { + return *__errno(): errno; + }; + return res; +}; + +// close + +@symbol("close") fn libc_close(d: int) int; + +export fn close(fd: int) (void | errno) = { + let res = libc_close(fd); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// getentropy +// __tfork +// link +// unlink +// wait4 + +@symbol("wait4") fn libc_wait4( + wpid: int, + status: nullable *int, + options: int, + rusage: nullable *rusage +) int; + +export fn wait4( + pid: int, + wstatus: nullable *int, + options: int, + rusage: nullable *rusage, +) (int | errno) = { + let res = libc_wait4(pid, wstatus, options, rusage); + if (res == -1) { + return *__errno(): errno; + }; + return res; +}; + +// chdir + +@symbol("chdir") fn libc_chdir(path: *const u8) int; + +export fn chdir(path: path) (void | errno) = { + let res = libc_chdir(cpath(path)?); + + if (res == -1) { + return *__errno(): errno; + }; +}; + +// fchdir + +@symbol("fchdir") fn libc_fchdir(fd: int) int; + +export fn fchdir(fd: int) (void | errno) = { + let res = libc_fchdir(fd); + + if (res == -1) { + return *__errno(): errno; + }; +}; + +// mknod +// chmod +// chown +// obreak +// getdtablecount +// getrusage +// getpid + +export @symbol("getpid") fn getpid() int; + +// mount +// unmount +// setuid + +@symbol("setuid") fn libc_setuid(uid: uid_t) int; + +export fn setuid(uid: uid_t) (void | errno) = { + let res = libc_setuid(uid); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// getuid + +export @symbol("getuid") fn getuid() uid_t; + +// geteuid + +export @symbol("geteuid") fn geteuid() uid_t; + +// ptrace +// recvmsg + +@symbol("recvmsg") fn libc_recvmsg(s: int, msg: *const msghdr, flags: int) i64; + +export fn recvmsg(fd: int, msg: *const msghdr, flags: int) (int | errno) = { + let res = libc_recvmsg(fd, msg, flags); + if (res == -1) { + return *__errno(): errno; + }; + // TODO: could overflow + return res: int; +}; + +// sendmsg + +@symbol("sendmsg") fn libc_sendmsg(s: int, msg: *const msghdr, flags: int) i64; + +export fn sendmsg(fd: int, msg: *const msghdr, flags: int) (int | errno) = { + let res = libc_sendmsg(fd, msg, flags); + if (res == -1) { + return *__errno(): errno; + }; + // TODO: could overflow + return res: int; +}; + +// recvfrom + +@symbol("recvfrom") fn libc_recvfrom( + s: int, + buf: *opaque, + length: size, + flags: int, + from: nullable *sockaddr, + fromlen: nullable *u32, +) i64; + +export fn recvfrom( + sockfd: int, + buf: *opaque, + length: size, + flags: int, + from: nullable *sockaddr, + fromlen: nullable *u32 +) (size | errno) = { + let res = libc_recvfrom(sockfd, buf, length, flags, from, fromlen); + if (res == -1) { + return *__errno(): errno; + }; + return res: size; +}; + +// accept +// getpeername + +@symbol("getpeername") fn libc_getpeername( + s: int, + name: *sockaddr, + namelen: *u32 +) int; + +export fn getpeername( + sockfd: int, + addr: *sockaddr, + addrlen: *u32 +) (void | errno) = { + let res = libc_getpeername(sockfd, addr, addrlen); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// getsockname + +@symbol("getsockname") fn libc_getsockname( + sockfd: int, + addr: nullable *sockaddr, + addrlen: nullable *u32 +) int; + +export fn getsockname( + sockfd: int, + addr: nullable *sockaddr, + addrlen: nullable *u32 +) (void | errno) = { + let res = libc_getsockname(sockfd, addr, addrlen); + if (res == -1) { + return *__errno(): errno; + }; + +}; +// access + +@symbol("access") fn libc_access(path: *const u8, amode: int) int; + +export fn access(path: path, amode: int) (bool | errno) = { + let res = libc_access(cpath(path)?, amode); + if (res == -1) { + let err = *__errno(): errno; + + switch (res) { + case EACCES => + return false; + case => + return err; + }; + }; + + return true; +}; + + +// chflags +// fchflags +// sync +// msyscall +// stat +// getppid +// lstat +// dup +// fstatat + +@symbol("fstatat") fn libc_fstatat(fd: int, path: *const u8, sb: *stat, flag: int) int; + +export fn fstatat( + dirfd: int, + path: path, + stat: *stat, + flag: int +) (void | errno) = { + let res = libc_fstatat(dirfd, cpath(path)?, stat, flag); + if (res == -1) { + return *__errno(): errno; + }; +}; + + +// getegid + +export @symbol("getegid") fn getegid() gid_t; + +// profil +// ktrace +// sigaction + +export @symbol("sigaction") fn libc_sigaction( + sig: int, + act: *const sigact, + oact: nullable *sigact +) int; + +export fn sigaction( + signum: int, + act: *const sigact, + old: nullable *sigact, +) (void | errno) = { + let res = libc_sigaction(signum, act, old); + if (res == -1) { + return *__errno(): errno; + }; +}; +// getgid + +export @symbol("getgid") fn getgid() gid_t; + +// sigprocmask + +@symbol("sigprocmask") fn libc_sigprocmask( + how: int, + set: nullable *const sigset, + old: nullable *sigset +) int; + +export fn sigprocmask( + how: int, + set: nullable *const sigset, + old: nullable *sigset +) (void | errno) = { + let res = libc_sigprocmask(how, set, old); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// mmap + +@symbol("mmap") fn libc_mmap( + addr: nullable *opaque, + len_: size, + prot: int, + flags: int, + fd: int, + pos: i64 +) nullable *opaque; + +export fn mmap( + addr: nullable *opaque, + len_: size, + prot: int, + flags: int, + fd: int, + pos: i64 +) (*opaque | errno) = { + let res = libc_mmap(addr, len_, prot, flags, fd, pos); + + if (res == null) { + return *__errno(): errno; + }; + return res: *opaque; +}; + +// setlogin +// acct +// sigpending +// fstat +// ioctl + +@symbol("ioctl") fn libc_ioctl(fd: int, req: u64, arg: u64) int; + +export type ioctl_arg = (nullable *opaque | u64); + +export fn ioctl(fd: int, req: u64, arg: ioctl_arg) (int | errno) = { + let res = match (arg) { + case let u: u64 => + yield libc_ioctl(fd, req, u); + case let ptr: nullable *opaque => + yield libc_ioctl(fd, req, ptr: uintptr: u64); + }; + if (res == -1) { + return *__errno(): errno; + }; + return res; +}; + +// reboot +// revoke +// symlink +// readlink +// execve + +@symbol("execve") fn libc_execve(path: *const u8, argv: *[*]nullable *const u8, + envp: *[*]nullable *const u8) int; + +export fn execve(path: path, argv: *[*]nullable *const u8, + envp: *[*]nullable *const u8) errno = { + let res = libc_execve(cpath(path)?, argv, envp); + return *__errno(): errno; +}; + +// umask + +@symbol("umask") fn libc_umask(numask: mode_t) mode_t; + +export fn umask(mode: mode_t) (mode_t | errno) = { + // Always successful on OpenBSD. + return libc_umask(mode); +}; + +// chroot + +@symbol("chroot") fn libc_chroot(dirname: *const u8) int; + +export fn chroot(path: path) (void | errno) = { + let res = libc_chroot(cpath(path)?); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// getfsstat +// statfs +// fstatfs +// fhstatfs +// vfork +// gettimeofday +// settimeofday +// setitimer +// getitimer +// select +// kevent +// munmap + +@symbol("munmap") fn libc_munmap(addr: *opaque, len_: size) int; + +export fn munmap(addr: *opaque, len_: size) (void | errno) = { + let res = munmap(addr, len_); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// mprotect +// madvise +// utimes +// futimes +// mquery +// getgroups + +@symbol("getgroups") fn libc_getgroups(gidsetlen: int, gidset: *[*]u32) int; + +export fn getgroups(gids: []uint) (uint | errno) = { + let res = libc_getgroups(len(gids): int, gids: *[*]u32); + if (res == -1) { + return *__errno(): errno; + }; + return res: uint; +}; + +// setgroups + +@symbol("setgroups") fn libc_setgroups( + ngroups: int, + gidset: *[*]u32 +) int; + +export fn setgroups(gids: []uint) (void | errno) = { + let res = libc_setgroups(len(gids): int, gids: *[*]u32); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// getpgrp +// setpgid +// futex +// utimensat +// futimens +// kbind +// clock_gettime + +@symbol("clock_gettime") fn libc_clock_gettime(clock: int, now: *timespec) int; + +export fn clock_gettime(clock: int, now: *timespec) (void | errno) = { + let res = libc_clock_gettime(clock, now); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// clock_settime +// clock_getres +// dup2 + +@symbol("dup2") fn libc_dup2(oldd: int, newd: int) int; + +export fn dup2(oldfd: int, newfd: int) (int | errno) = { + let res = libc_dup2(oldfd, newfd); + if (res == -1) { + return *__errno(): errno; + }; + return res; +}; + +// nanosleep + +@symbol("nanosleep") fn libc_nanosleep( + timeout: *const timespec, + remainder: *timespec +) int; + +export fn nanosleep( + timeout: *const timespec, + remainder: *timespec +) (void | errno) = { + let res = libc_nanosleep(timeout, remainder); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// fcntl + +@symbol("fcntl") fn libc_fcntl(fd: int, cmd: int, arg: u64) int; + +export type fcntl_arg = (void | int | *st_flock | *u64); + +export fn fcntl(fd: int, cmd: int, arg: fcntl_arg) (int | errno) = { + let res = match (arg) { + case void => + yield libc_fcntl(fd, cmd, 0); + case let i: int => + yield libc_fcntl(fd, cmd, i: u64); + case let l: *st_flock => + yield libc_fcntl(fd, cmd, l: uintptr: u64); + case let u: *u64 => + yield libc_fcntl(fd, cmd, u: uintptr: u64); + }; + if (res == -1) { + return *__errno(): errno; + }; + return res; +}; + +// accept4 + +@symbol("accept4") fn libc_accept4( + s: int, + addr: nullable *sockaddr, + adddrlen: nullable *u32, + flags: int +) int; + +export fn accept4( + sockfd: int, + addr: nullable *sockaddr, + addrlen: nullable *u32, + flags: int +) (int | errno) = { + let res = libc_accept4(sockfd, addr, addrlen, flags); + if (res == -1) { + return *__errno(): errno; + }; + return res; +}; + +// __thrsleep +// fsync +// setpriority + +@symbol("setpriority") fn libc_setpriority( + which: int, + who: id_t, + prio: int +) int; + +export fn setpriority(which: int, who: id_t, prio: int) (void | errno) = { + let res = libc_setpriority(which, who, prio); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// socket + +@symbol("socket") fn libc_socket(domain: int, t: int, protocol: int) int; + +export fn socket(domain: int, t: int, protocol: int) (int | errno) = { + let res = libc_socket(domain, t, protocol); + if (res == -1) { + return *__errno(): errno; + }; + return res; +}; + +// connect + +@symbol("connect") fn libc_connect( + sockfd: int, + addr: *const sockaddr, + addrlen: u32 +) int; + +export fn connect( + sockfd: int, + addr: *const sockaddr, + addrlen: u32 +) (void | errno) = { + let res = libc_connect(sockfd, addr, addrlen); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// getdents + +@symbol("getdents") fn libc_getdents(fd: int, buf: *opaque, nbytes: size) int; + +export fn getdents(dirfd: int, buf: *opaque, nbytes: size) (int | errno) = { + let res = libc_getdents(dirfd, buf, nbytes); + if (res == -1) { + return *__errno(): errno; + }; + return res; +}; + +// getpriority + +@symbol("getpriority") fn libc_getpriority(which: int, who: id_t) int; + +export fn getpriority(which: int, who: id_t) (int | errno) = { + let res = libc_getpriority(which, who); + if (res == -1) { + return *__errno(): errno; + }; + return res; +}; + +// pipe2 + +@symbol("pipe2") fn libc_pipe2(pipefd: *[2]int, flags: int) int; + +export fn pipe2(pipefd: *[2]int, flags: int) (void | errno) = { + let res = libc_pipe2(pipefd, flags); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// dup3 +// sigreturn +// bind + +@symbol("bind") fn libc_bind( + sockfd: int, + addr: *const sockaddr, + addrlen: u32 +) int; + +export fn bind( + sockfd: int, + addr: *const sockaddr, + addrlen: u32 +) (void | errno) = { + let res = libc_bind(sockfd, addr, addrlen); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// setsockopt + +@symbol("setsockopt") fn libc_setsockopt( + s: int, + level: int, + optname: int, + optval: *opaque, + optlen: u32 +) int; + +export fn setsockopt( + sockfd: int, + level: int, + optname: int, + optval: *opaque, + optlen: u32 +) (void | errno) = { + let res = libc_setsockopt(sockfd, level, optname, optval, optlen); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// listen + +@symbol("listen") fn libc_listen(s: int, backlog: int) int; + +// TODO: backlog should be int. +export fn listen(sockfd: int, backlog: u32) (void | errno) = { + let res = libc_listen(sockfd, backlog: int); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// chflagsat +// pledge +// ppoll + +@symbol("ppoll") fn libc_ppoll( + fds: *[*]pollfd, + nfds: nfds_t, + timeout: const nullable *timespec, + mask: const nullable *sigset, +) int; + +export fn ppoll( + fds: *[*]pollfd, + nfds: nfds_t, + timeout: const nullable *timespec, + sigmask: const nullable *sigset, +) (int | errno) = { + let ret = libc_ppoll(fds, nfds, timeout, sigmask); + + if (ret == -1) { + return *__errno(): errno; + }; + return ret; +}; + +// pselect +// sigsuspend +// sendsyslog +// unveil +// __realpath +// recvmmsg +// sendmmsg +// getsockopt + +@symbol("getsockopt") fn libc_getsockopt( + s: int, + level: int, + optname: int, + optval: nullable *opaque, + optlen: nullable *u32 +) int; + +export fn getsockopt( + sockfd: int, + level: int, + optname: int, + optval: nullable *opaque, + optlen: nullable *u32 +) (void | errno) = { + let res = libc_getsockopt(sockfd, level, optname, optval, optlen); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// thrkill +// readv + +@symbol("readv") fn libc_readv(d: int, iov: const *[*]iovec, iovcnt: int) size; + +export fn readv(fd: int, iov: const *[*]iovec, iovcnt: int) (size | errno) = { + let res: u64 = libc_readv(fd, iov, iovcnt); + + if (res == -1) { + return *__errno(): errno; + }; + return res; +}; + +// writev + +@symbol("readv") fn libc_writev(d: int, iov: const *[*]iovec, iovcnt: int) size; + +export fn writev(fd: int, iov: const *[*]iovec, iovcnt: int) (size | errno) = { + let res: u64 = libc_writev(fd, iov, iovcnt); + + if (res == -1) { + return *__errno(): errno; + }; + return res; +}; + +// kill + +@symbol("kill") fn libc_kill(pid: int, signal: int) int; + +export fn kill(pid: int, signal: int) (void | errno) = { + let res = libc_kill(pid, signal); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// fchown +// fchmod +// setreuid +// setregid +// rename +// flock + +@symbol("flock") fn libc_flock(fd: int, operation: int) int; + +export fn flock(fd: int, op: int) (void | errno) = { + let res = libc_flock(fd, op); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// mkfifo +// sendto + +@symbol("sendto") fn libc_sendto( + s: int, + msg: *opaque, + length: size, + flags: int, + to: nullable *sockaddr, + tolen: socklen_t +) i64; + +export fn sendto( + sockfd: int, + buf: *opaque, + length: size, + flags: int, + dest_addr: nullable *sockaddr, + addrlen: u32 +) (size | errno) = { + let res = libc_sendto(sockfd, buf, length, flags, dest_addr, addrlen); + if (res == -1) { + return *__errno(): errno; + }; + return res: size; +}; + +// shutdown + +@symbol("shutdown") fn libc_shutdown(s: int, how: int) int; + +export fn shutdown(s: int, how: int) (void | errno) = { + let res = libc_shutdown(s, how); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// socketpair + +@symbol("socketpair") fn libc_socketpair( + domain: int, + type_: int, + protocol: int, + sv: *[*]int +) int; + +export fn socketpair( + domain: int, + type_: int, + protocol: int, + sv: *[*]int +) (void | errno) = { + let res = libc_socketpair(domain, type_, protocol, sv); + if (res == -1) { + return *__errno(): errno; + }; + +}; +// mkdir +// rmdir +// adjtime +// getlogin_r +// getthrname +// setthrname +// pinsyscall +// setsid +// quotactl +// ypconnect +// nfssvc +// mimmutable +// waitid +// getfh +// __tmpfd +// sysarch +// lseek + +@symbol("lseek") fn libc_lseek(fildes: int, pos: i64, whence: int) i64; + +export fn lseek(fd: int, off: i64, whence: int) (i64 | errno) = { + let res = libc_lseek(fd, off, whence); + if (res == -1) { + return *__errno(): errno; + }; + return res; +}; + +// truncate +// ftruncate + +@symbol("ftruncate") fn libc_ftruncate(fd: int, length: i64) int; + +export fn ftruncate(fd: int, length: i64) (void | errno) = { + let res = libc_ftruncate(fd, length); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// pread +// pwrite +// preadv +// pwritev +// setgid + +@symbol("setgid") fn libc_setgid(gid: gid_t) int; + +export fn setgid(gid: gid_t) (void | errno) = { + let res = libc_setgid(gid); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// setegid + +@symbol("setegid") fn libc_setegid(gid: gid_t) int; + +export fn setegid(gid: gid_t) (void | errno) = { + let res = libc_setegid(gid); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// seteuid + +@symbol("seteuid") fn libc_seteuid(uid: uid_t) int; + +export fn seteuid(uid: uid_t) (void | errno) = { + let res = libc_seteuid(uid); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// pathconf +// fpathconf +// swapctl +// getrlimit +// setrlimit +// sysctl + +@symbol("sysctl") fn libc_sysctl( + name: *[*]int, + namelen: uint, + oldp: nullable *opaque, + oldlenp: nullable *size, + newp: nullable *opaque, + newlen: size +) int; + +export fn sysctl( + name: []int, + namelen: uint, + oldp: nullable *opaque, + oldlenp: nullable *size, + newp: nullable *opaque, + newlen: size +) (void | errno) = { + let res = libc_sysctl(name: *[*]int, namelen, oldp, oldlenp, newp, newlen); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// mlock +// munlock +// getpgid +// utrace +// semget +// msgget +// msgsnd +// msgrcv +// shmat +// shmdt +// minherit +// poll +// issetugid +// lchown +// getsid +// msync +// pipe +// fhopen +// kqueue +// kqueue1 +// mlockall +// munlockall +// getresuid +// setresuid +// getresgid +// setresgid +// closefrom +// sigaltstack +// shmget +// semop +// fhstat +// __semctl +// shmctl +// msgctl +// sched_yield +// getthrid +// __thrwakeup +// __threxit +// __thrsigdivert +// getcwd + +@symbol("getcwd") fn libc_getcwd(buf: *u8, bufsz: size) *u8; + +export fn getcwd() (*const u8 | errno) = { + static let pathbuf: [PATH_MAX]u8 = [0...]; + + let res = libc_getcwd(&pathbuf: *u8, len(pathbuf)); + if (res == null) { + return *__errno(): errno; + }; + + return res; +}; + +// adjfreq +// setrtable +// getrtable +// faccessat +// fchmodat + +@symbol("fchmodat") fn libc_fchmodat( + fd: int, + path: *const u8, + mode: mode_t, + flag: int +) int; + +export fn fchmodat( + dirfd: int, + path: path, + mode: mode_t, + flag: int +) (void | errno) = { + let res = libc_fchmodat(dirfd, cpath(path)?, mode, flag); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// fchownat + +@symbol("fchownat") fn libc_fchownat( + fd: int, + path: *const u8, + owner: uid_t, + group: gid_t, + flag: int +) int; + +export fn fchownat( + dirfd: int, + path: path, + uid: uid_t, + gid: gid_t, + flag: int +) (void | errno) = { + let res = libc_fchownat(dirfd, cpath(path)?, uid, gid, flag); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// linkat + +@symbol("linkat") fn libc_linkat( + fd1: int, + name1: *const u8, + fd2: int, + name2: *const u8, + flag: int +) int; + +export fn linkat( + olddirfd: int, + oldpath: path, + newdirfd: int, + newpath: path, + flags: int, +) (void | errno) = { + let oldpath = cpath(oldpath)?; + static let newpathbuf: [PATH_MAX]u8 = [0...]; + let newpath = copy_cpath(newpath, newpathbuf)?; + + let res = libc_linkat(olddirfd, oldpath, newdirfd, newpath, flags); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// mkdirat + +@symbol("mkdirat") fn libc_mkdirat(fd: int, path: *const u8, mode: mode_t) int; + +export fn mkdirat(dirfd: int, path: path, mode: mode_t) (void | errno) = { + let res = libc_mkdirat(dirfd, cpath(path)?, mode); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// mkfifoat +// mknodat +// openat + +@symbol("openat") fn libc_openat( + fd: int, + path: *const u8, + flags: int, + mode: uint, +) int; + +export fn openat( + dirfd: int, + path: path, + flags: int, + mode: uint, +) (int | errno) = { + let res = libc_openat(dirfd, cpath(path)?, flags, mode); + if (res == -1) { + return *__errno(): errno; + }; + return res; +}; + +// readlinkat + +@symbol("readlinkat") fn libc_readlinkat( + fd: int, + path: *const u8, + buf: *u8, + bufsiz: size +) i64; + +export fn readlinkat( + dirfd: int, + path: path, + buf: []u8, +) (size | errno) = { + let res = libc_readlinkat(dirfd, cpath(path)?, &buf: *u8, len(buf)); + if (res == -1) { + return *__errno(): errno; + }; + return res: size; +}; + +// renameat + +@symbol("renameat") fn libc_renameat( + fromfd: int, + from: *const u8, + tofd: int, + to: *const u8 +) int; + +export fn renameat( + olddirfd: int, + oldpath: str, + newdirfd: int, + newpath: str, +) (void | errno) = { + static let newpathbuf: [PATH_MAX]u8 = [0...]; + let newpath = copy_cpath(newpath, newpathbuf)?; + + let res = libc_renameat(olddirfd, cpath(oldpath)?, newdirfd, + &newpathbuf: *u8); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// symlinkat + +@symbol("symlinkat") fn libc_symlinkat( + name1: *const u8, + fd: int, + name2: *const u8 +) int; + +export fn symlinkat( + target: path, + newdirfd: int, + linkpath: path, +) (void | errno) = { + let target = cpath(target)?; + static let linkpathbuf: [PATH_MAX]u8 = [0...]; + let linkpath = copy_cpath(linkpath, linkpathbuf)?; + + let res = libc_symlinkat(target, newdirfd, linkpath); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// unlinkat + +@symbol("unlinkat") fn libc_unlinkat(fd: int, path: *const u8, flag: int) int; + +export fn unlinkat(dirfd: int, path: path, flags: int) (void | errno) = { + let res = libc_unlinkat(dirfd, cpath(path)?, flags); + if (res == -1) { + return *__errno(): errno; + }; +}; + +// __set_tcb +// __get_tcb diff --git a/rt/+openbsd/types.ha b/rt/+openbsd/types.ha @@ -0,0 +1,737 @@ +// SPDX-License-Identifier: MPL-2.0 +// (c) Hare authors <https://harelang.org> + +export type time_t = i64; +export type clock_t = i64; +export type clockid_t = i32; +export type suseconds_t = i64; +export type dev_t = i32; +export type ino_t = u64; +export type nlink_t = u32; +export type id_t = u32; +export type pid_t = i32; +export type uid_t = u32; +export type gid_t = u32; +export type off_t = i64; +export type blkcnt_t = i64; +export type blksize_t = i32; +export type nfds_t = uint; +export type mode_t = u32; +export type sigset = uint; + +// Maximum length of a file path including the NUL terminator. +export def PATH_MAX: size = 1024; + +export def PATH_PTMDEV: str = "/dev/ptm"; +export def PTMGET: u64 = 0x40287401; + +export type ptmget = struct { + cfd: int, + sfd: int, + cn: [16]u8, + sn: [16]u8 +}; + +export def S_ISUID: mode_t = 0o4000; +export def S_ISGID: mode_t = 0o2000; +export def S_ISTXT: mode_t = 0o1000; +export def S_IRWXU: mode_t = 0o700; +export def S_IRUSR: mode_t = 0o400; +export def S_IWUSR: mode_t = 0o200; +export def S_IXUSR: mode_t = 0o100; +export def S_IRWXG: mode_t = 0o070; +export def S_IRGRP: mode_t = 0o040; +export def S_IWGRP: mode_t = 0o020; +export def S_IXGRP: mode_t = 0o010; +export def S_IRWXO: mode_t = 0o007; +export def S_IROTH: mode_t = 0o004; +export def S_IWOTH: mode_t = 0o002; +export def S_IXOTH: mode_t = 0o001; +export def S_IFMT: mode_t = 0o170000; +export def S_IFIFO: mode_t = 0o010000; +export def S_IFCHR: mode_t = 0o020000; +export def S_IFDIR: mode_t = 0o040000; +export def S_IFBLK: mode_t = 0o060000; +export def S_IFREG: mode_t = 0o100000; +export def S_IFLNK: mode_t = 0o120000; +export def S_IFSOCK: mode_t = 0o140000; +export def S_ISVTX: mode_t = 0o001000; + +export def O_RDONLY: int = 0x0000; +export def O_WRONLY: int = 0x0001; +export def O_RDWR: int = 0x0002; +export def O_ACCMODE: int = 0x0003; +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_DSYNC: int = O_SYNC; +export def O_RSYNC: int = O_SYNC; +export def O_NOCTTY: int = 0x8000; +export def O_CLOEXEC: int = 0x10000; +export def O_DIRECTORY: int = 0x20000; + +export def WAIT_ANY: pid_t = -1; +export def WAIT_MYPGRP: pid_t = 0; + +export def WNOHANG: int = 0x01; +export def WUNTRACED: int = 0x02; +export def WSTOPPED: int = WUNTRACED; +export def WEXITED: int = 0x04; +export def WCONTINUED: int = 0x08; +export def WNOWAIT: int = 0x10; +export def WTRAPPED: int = 0x20; + +export fn wtermsig(status: int) int = status & 0o177; + +export fn wifexited(status: int) bool = wtermsig(status) == 0; +export fn wexitstatus(status: int) int = (status >> 8) & 0xff; + +export fn wifsignaled(status: int) bool = + wtermsig(status) != 0o177 && wtermsig(status) != 0; + +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 RUSAGE_SELF: int = 0; +export def RUSAGE_CHILDREN: int = -1; +export def RUSAGE_THREAD: int = 1; + +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 AT_FDCWD: int = -100; +export def AT_EACCESS: int = 0x01; +export def AT_SYMLINK_NOFOLLOW: int = 0x02; +export def AT_SYMLINK_FOLLOW: int = 0x04; +export def AT_REMOVEDIR: int = 0x08; + +export def PROT_NONE: int = 0x00; +export def PROT_READ: int = 0x01; +export def PROT_WRITE: int = 0x02; +export def PROT_EXEC: int = 0x04; + +export def MAP_SHARED: int = 0x0001; +export def MAP_PRIVATE: int = 0x0002; +export def MAP_FIXED: int = 0x0010; +export def __MAP_NOREPLACE: int = 0x0800; +export def MAP_ANON: int = 0x1000; +export def __MAP_NOFAULT: int = 0x2000; +export def MAP_STACK: int = 0x4000; +export def MAP_CONCEAL: int = 0x8000; + +export def MAP_FLAGMASK: int = 0xfff7; + +export def RB_AUTOBOOT: int = 0x00000; +export def RB_ASKNAME: int = 0x00001; +export def RB_SINGLE: int = 0x00002; +export def RB_NOSYNC: int = 0x00004; +export def RB_HALT: int = 0x00008; +export def RB_INITNAME: int = 0x00010; +export def RB_DFLTROOT: int = 0x00020; +export def RB_KDB: int = 0x00040; +export def RB_RDONLY: int = 0x00080; +export def RB_DUMP: int = 0x00100; +export def RB_MINIROOT: int = 0x00200; +export def RB_CONFIG: int = 0x00400; +export def RB_TIMEBAD: int = 0x00800; +export def RB_POWERDOWN: int = 0x01000; +export def RB_SERCONS: int = 0x02000; +export def RB_USERREQ: int = 0x04000; +export def RB_RESET: int = 0x08000; +export def RB_GOODRANDOM: int = 0x10000; +export def RB_UNHIBERNATE: int = 0x20000; + +export def NGROUPS_MAX: size = 16; + +export type timespec = struct { + tv_sec: time_t, + tv_nsec: i64, +}; + +export def CLOCK_REALTIME: clockid_t = 0; +export def CLOCK_PROCESS_CPUTIME_ID: clockid_t = 2; +export def CLOCK_MONOTONIC: clockid_t = 3; +export def CLOCK_THREAD_CPUTIME_ID: clockid_t = 4; +export def CLOCK_UPTIME: clockid_t = 5; +export def CLOCK_BOOTTIME: clockid_t = 6; + +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_GETLK: int = 7; +export def F_SETLK: int = 8; +export def F_SETLKW: int = 9; +export def F_DUPFD_CLOEXEC: int = 10; +export def F_ISATTY: int = 11; + +export def FD_CLOEXEC: int = 1; + +export def F_RDLCK: i16 = 1; +export def F_UNLCK: i16 = 2; +export def F_WRLCK: i16 = 3; + +export type st_flock = struct { + l_start: off_t, + l_len: off_t, + l_pid: pid_t, + l_type: i16, + l_whence: i16, +}; + +export type dirent = struct { + d_fileno: ino_t, + d_off: off_t, + d_reclen: u16, + d_type: u8, + d_namlen: u8, + __d_padding: [4]u8, + d_name: [*]u8, +}; + +export def MAXNAMLEN: size = 255; + +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 type pollfd = struct { + fd: int, + events: i16, + revents: i16, +}; + +export def POLLIN: i16 = 0x0001; +export def POLLPRI: i16 = 0x0002; +export def POLLOUT: i16 = 0x0004; +export def POLLERR: i16 = 0x0008; +export def POLLHUP: i16 = 0x0010; +export def POLLNVAL: i16 = 0x0020; +export def POLLRDNORM: i16 = 0x0040; +export def POLLNORM: i16 = POLLRDNORM; +export def POLLWRNORM: i16 = POLLOUT; +export def POLLRDBAND: i16 = 0x0080; +export def POLLWRBAND: i16 = 0x0100; + +export type iovec = struct { + iov_base: *opaque, + iov_len: size, +}; + +export def NSIG: int = 32; + +export type sigact = struct { + union { + sa_handler: *fn (int) void, + sa_sigaction: *fn (int, *siginfo, *opaque) void, + }, + sa_mask: sigset, + sa_flags: int, +}; + +export type siginfo = struct { + si_signo: int, + si_code: int, + si_errno: int, + _data: union { + _pad: [128/4 - 3]int, + _proc: struct { + _pid: pid_t, + _uid: uid_t, + _pdata: union { + _kill: struct { + _value: sigval, + }, + _cid: struct { + _utime: clock_t, + _stime: clock_t, + _status: int + }, + }, + }, + _fault: struct { + _addr: nullable *opaque, + _trapno: int, + }, + }, +}; + +export type sigval = union { + sival_int: int, + sival_ptr: *opaque, +}; + +export type timeval = struct { + tv_sec: time_t, + tv_usec: suseconds_t, +}; + +export type stat = struct { + st_mode: mode_t, + st_dev: dev_t, + st_ino: ino_t, + st_nlink: nlink_t, + st_uid: uid_t, + st_gid: gid_t, + st_rdev: dev_t, + st_atim: timespec, + st_mtim: timespec, + st_ctim: timespec, + st_size: off_t, + st_blocks: blkcnt_t, + st_blksize: blksize_t, + st_flags: u32, + st_gen: u32, + st_birthtim: timespec, +}; + +export type winsize = struct { + ws_row: u16, + ws_col: u16, + ws_xpixel: u16, + ws_ypixel: u16, +}; + +export type termios = struct { + c_iflag: tcflag, + c_oflag: tcflag, + c_cflag: tcflag, + c_lflag: tcflag, + c_cc: [NCCS]cc, +}; + +export def NCCS: size = 20; + +export type tcflag = enum uint { + // c_iflag bits + IGNBRK = 0x00000001, + BRKINT = 0x00000002, + IGNPAR = 0x00000004, + PARMRK = 0x00000008, + INPCK = 0x00000010, + ISTRIP = 0x00000020, + INLCR = 0x00000040, + IGNCR = 0x00000080, + ICRNL = 0x00000100, + IXON = 0x00000200, + IXOFF = 0x00000400, + IXANY = 0x00000800, + IMAXBEL = 0x00002000, + + // c_oflag bits + OPOST = 0x00000001, + ONLCR = 0x00000002, + TABDLY = 0x00000004, + TAB0 = 0x00000000, + TAB3 = 0x00000004, + ONOEOT = 0x00000008, + OCRNL = 0x00000010, + ONOCR = 0x00000020, + ONLRET = 0x00000040, + + // c_cflag bits + CIGNORE = 0x00000001, + CSIZE = 0x00000300, + CS5 = 0x00000000, + CS6 = 0x00000100, + CS7 = 0x00000200, + CS8 = 0x00000300, + CSTOPB = 0x00000400, + CREAD = 0x00000800, + PARENB = 0x00001000, + PARODD = 0x00002000, + HUPCL = 0x00004000, + CLOCAL = 0x00008000, + CCTS_OFLOW = 0x00010000, + CRTS_IFLOW = 0x00020000, + CRTSCTS = (CCTS_OFLOW | CRTS_IFLOW), + CDTR_IFLOW = 0x00040000, + CDSR_OFLOW = 0x00080000, + CCAR_OFLOW = 0x00100000, + CNO_RTSDTR = 0x00200000, + + // c_lflag bits + ECHOKE = 0x00000001, + ECHOE = 0x00000002, + ECHOK = 0x00000004, + ECHO = 0x00000008, + ECHONL = 0x00000010, + ECHOPRT = 0x00000020, + ECHOCTL = 0x00000040, + ISIG = 0x00000080, + ICANON = 0x00000100, + ALTWERASE = 0x00000200, + IEXTEN = 0x00000400, + EXTPROC = 0x00000800, + TOSTOP = 0x00400000, + FLUSHO = 0x00800000, + NOKERNINFO = 0x02000000, + PENDIN = 0x20000000, + NOFLSH = 0x80000000, +}; + +export type cc = enum u8 { + VEOF = 0, + VEOL = 1, + VEOL2 = 2, + VERASE = 3, + VWERASE = 4, + VKILL = 5, + VREPRINT = 6, + VERASE2 = 7, + VINTR = 8, + VQUIT = 9, + VSUSP = 10, + VDSUSP = 11, + VSTART = 12, + VSTOP = 13, + VLNEXT = 14, + VDISCARD = 15, + VMIN = 16, + VTIME = 17, + VSTATUS = 18, +}; + +export def TIOCGWINSZ: u64 = 0x40087468; +export def TIOCSWINSZ: u64 = 0x80087467; +export def TIOCGETA: u64 = 0x402c7413; +export def TIOCSETA: u64 = 0x802c7414; + +export def SIG_DFL: uintptr = 0; +export def SIG_IGN: uintptr = 1; + +export def SIG_BLOCK: int = 1; +export def SIG_UNBLOCK: int = 2; +export def SIG_SETMASK: int = 3; + +export def SA_ONSTACK: int = 0x0001; +export def SA_RESTART: int = 0x0002; +export def SA_RESETHAND: int = 0x0004; +export def SA_NOCLDSTOP: int = 0x0008; +export def SA_NODEFER: int = 0x0010; +export def SA_NOCLDWAIT: int = 0x0020; +export def SA_SIGINFO: u64 = 0x0040; + +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 SIGEMT: int = 7; +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 SIGURG: int = 16; +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 PRIO_PROCESS: int = 0; +export def PRIO_PGRP: int = 1; +export def PRIO_USER: int = 2; + +export def STDIN_FILENO: int = 0; +export def STDOUT_FILENO: int = 1; +export def STDERR_FILENO: int = 2; + +export def SEEK_SET: int = 0; +export def SEEK_CUR: int = 1; +export def SEEK_END: int = 2; + +export def LOCK_SH: int = 1; +export def LOCK_EX: int = 2; +export def LOCK_NB: int = 4; +export def LOCK_UN: int = 8; + +// sysctl +export def CTL_KERN: int = 1; +export def CTL_VM: int = 2; +export def CTL_FS: int = 3; +export def CTL_NET: int = 4; +export def CTL_DEBUG: int = 5; +export def CTL_HW: int = 6; +export def CTL_MACHDEP: int = 7; +export def CTL_DDB: int = 9; +export def CTL_VFS: int = 10; + +export def KERN_OSTYPE: int = 1; +export def KERN_OSRELEASE: int = 2; +export def KERN_OSREV: int = 3; +export def KERN_VERSION: int = 4; +export def KERN_MAXVNODES: int = 5; +export def KERN_MAXPROC: int = 6; +export def KERN_MAXFILES: int = 7; +export def KERN_ARGMAX: int = 8; +export def KERN_SECURELVL: int = 9; +export def KERN_HOSTNAME: int = 10; +export def KERN_HOSTID: int = 11; +export def KERN_CLOCKRATE: int = 12; +export def KERN_PROF: int = 16; +export def KERN_POSIX1: int = 17; +export def KERN_NGROUPS: int = 18; +export def KERN_JOB_CONTROL: int = 19; +export def KERN_SAVED_IDS: int = 20; +export def KERN_BOOTTIME: int = 21; +export def KERN_DOMAINNAME: int = 22; +export def KERN_MAXPARTITIONS: int = 23; +export def KERN_RAWPARTITION: int = 24; +export def KERN_MAXTHREAD: int = 25; +export def KERN_NTHREADS: int = 26; +export def KERN_OSVERSION: int = 27; +export def KERN_SOMAXCONN: int = 28; +export def KERN_SOMINCONN: int = 29; +export def KERN_NOSUIDCOREDUMP: int = 32; +export def KERN_FSYNC: int = 33; +export def KERN_SYSVMSG: int = 34; +export def KERN_SYSVSEM: int = 35; +export def KERN_SYSVSHM: int = 36; +export def KERN_MSGBUFSIZE: int = 38; +export def KERN_MALLOCSTATS: int = 39; +export def KERN_CPTIME: int = 40; +export def KERN_NCHSTATS: int = 41; +export def KERN_FORKSTAT: int = 42; +export def KERN_TTY: int = 44; +export def KERN_CCPU: int = 45; +export def KERN_FSCALE: int = 46; +export def KERN_NPROCS: int = 47; +export def KERN_MSGBUF: int = 48; +export def KERN_POOL: int = 49; +export def KERN_STACKGAPRANDOM: int = 50; +export def KERN_SYSVIPC_INFO: int = 51; +export def KERN_ALLOWKMEM: int = 52; +export def KERN_WITNESSWATCH: int = 53; +export def KERN_SPLASSERT: int = 54; +export def KERN_PROC_ARGS: int = 55; +export def KERN_NFILES: int = 56; +export def KERN_TTYCOUNT: int = 57; +export def KERN_NUMVNODES: int = 58; +export def KERN_MBSTAT: int = 59; +export def KERN_WITNESS: int = 60; +export def KERN_SEMINFO: int = 61; +export def KERN_SHMINFO: int = 62; +export def KERN_INTRCNT: int = 63; +export def KERN_WATCHDOG: int = 64; +export def KERN_ALLOWDT: int = 65; +export def KERN_PROC: int = 66; +export def KERN_MAXCLUSTERS: int = 67; +export def KERN_EVCOUNT: int = 68; +export def KERN_TIMECOUNTER: int = 69; +export def KERN_MAXLOCKSPERUID: int = 70; +export def KERN_CPTIME2: int = 71; +export def KERN_CACHEPCT: int = 72; +export def KERN_FILE: int = 73; +export def KERN_WXABORT: int = 74; +export def KERN_CONSDEV: int = 75; +export def KERN_NETLIVELOCKS: int = 76; +export def KERN_POOL_DEBUG: int = 77; +export def KERN_PROC_CWD: int = 78; +export def KERN_PROC_NOBROADCASTKILL: int = 79; +export def KERN_PROC_VMMAP: int = 80; +export def KERN_GLOBAL_PTRACE: int = 81; +export def KERN_CONSBUFSIZE: int = 82; +export def KERN_CONSBUF: int = 83; +export def KERN_AUDIO: int = 84; +export def KERN_CPUSTATS: int = 85; +export def KERN_PFSTATUS: int = 86; +export def KERN_TIMEOUT_STATS: int = 87; +export def KERN_UTC_OFFSET: int = 88; +export def KERN_VIDEO: int = 89; +export def KERN_CLOCKINTR: int = 90; +export def KERN_AUTOCONF_SERIAL: int = 91; +export def KERN_MAXID: int = 92; + +export def KERN_PROC_ALL: int = 0; +export def KERN_PROC_PID: int = 1; +export def KERN_PROC_PGRP: int = 2; +export def KERN_PROC_SESSION: int = 3; +export def KERN_PROC_TTY: int = 4; +export def KERN_PROC_UID: int = 5; +export def KERN_PROC_RUID: int = 6; +export def KERN_PROC_KTHREAD: int = 7; +export def KERN_PROC_SHOW_THREADS: int = 0x40000000; + +export def KERN_SYSVIPC_MSG_INFO: int = 1; +export def KERN_SYSVIPC_SEM_INFO: int = 2; +export def KERN_SYSVIPC_SHM_INFO: int = 3; + +export def KERN_PROC_ARGV: int = 1; +export def KERN_PROC_NARGV: int = 2; +export def KERN_PROC_ENV: int = 3; +export def KERN_PROC_NENV: int = 4; + +export def KERN_AUDIO_RECORD: int = 1; +export def KERN_AUDIO_MAXID: int = 2; + +export def KERN_VIDEO_RECORD: int = 1; +export def KERN_VIDEO_MAXID: int = 2; + +export def KERN_FILE_BYFILE: int = 1; +export def KERN_FILE_BYPID: int = 2; +export def KERN_FILE_BYUID: int = 3; +export def KERN_FILESLOP: int = 10; + +export def KERN_FILE_TEXT: int = -1; +export def KERN_FILE_CDIR: int = -2; +export def KERN_FILE_RDIR: int = -3; +export def KERN_FILE_TRACE: int = -4; + +export def KI_MNAMELEN: int = 96; +export def KI_UNPPATHLEN: int = 104; + +export def KERN_INTRCNT_NUM: int = 1; +export def KERN_INTRCNT_CNT: int = 2; +export def KERN_INTRCNT_NAME: int = 3; +export def KERN_INTRCNT_VECTOR: int = 4; +export def KERN_INTRCNT_MAXID: int = 5; + +export def KERN_WATCHDOG_PERIOD: int = 1; +export def KERN_WATCHDOG_AUTO: int = 2; +export def KERN_WATCHDOG_MAXID: int = 3; + +export def KERN_TIMECOUNTER_TICK: int = 1; +export def KERN_TIMECOUNTER_TIMESTEPWARNINGS: int = 2; +export def KERN_TIMECOUNTER_HARDWARE: int = 3; +export def KERN_TIMECOUNTER_CHOICE: int = 4; +export def KERN_TIMECOUNTER_MAXID: int = 5; + +export def KERN_CLOCKINTR_STATS: int = 1; +export def KERN_CLOCKINTR_MAXID: int = 2; + +export def FS_POSIX: int = 1; +export def FS_MAXID: int = 2; + +export def FS_POSIX_SETUID: int = 1; +export def FS_POSIX_MAXID: int = 2; + +export def HW_MACHINE: int = 1; +export def HW_MODEL: int = 2; +export def HW_NCPU: int = 3; +export def HW_BYTEORDER: int = 4; +export def HW_PHYSMEM: int = 5; +export def HW_USERMEM: int = 6; +export def HW_PAGESIZE: int = 7; +export def HW_DISKNAMES: int = 8; +export def HW_DISKSTATS: int = 9; +export def HW_DISKCOUNT: int = 10; +export def HW_SENSORS: int = 11; +export def HW_CPUSPEED: int = 12; +export def HW_SETPERF: int = 13; +export def HW_VENDOR: int = 14; +export def HW_PRODUCT: int = 15; +export def HW_VERSION: int = 16; +export def HW_SERIALNO: int = 17; +export def HW_UUID: int = 18; +export def HW_PHYSMEM64: int = 19; +export def HW_USERMEM64: int = 20; +export def HW_NCPUFOUND: int = 21; +export def HW_ALLOWPOWERDOWN: int = 22; +export def HW_PERFPOLICY: int = 23; +export def HW_SMT: int = 24; +export def HW_NCPUONLINE: int = 25; +export def HW_POWER: int = 26; +export def HW_BATTERY: int = 27; +export def HW_UCOMNAMES: int = 28; +export def HW_MAXID: int = 30; + +export def HW_BATTERY_CHARGEMODE: int = 1; +export def HW_BATTERY_CHARGESTART: int = 2; +export def HW_BATTERY_CHARGESTOP: int = 3; +export def HW_BATTERY_MAXID: int = 4; + +export def CTL_DEBUG_NAME: int = 0; +export def CTL_DEBUG_VALUE: int = 1; +export def CTL_DEBUG_MAXID: int = 20; + +export def SI_NOINFO: int = 32767; +export def SI_USER: int = 0; +export def SI_LWP: int = -1; +export def SI_QUEUE: int = -2; +export def SI_TIMER: int = -3; + +export def ILL_ILLOPC: int = 1; +export def ILL_ILLOPN: int = 2; +export def ILL_ILLADR: int = 3; +export def ILL_ILLTRP: int = 4; +export def ILL_PRVOPC: int = 5; +export def ILL_PRVREG: int = 6; +export def ILL_COPROC: int = 7; +export def ILL_BADSTK: int = 8; + +export def FPE_INTDIV: int = 1; +export def FPE_INTOVF: int = 2; +export def FPE_FLTDIV: int = 3; +export def FPE_FLTOVF: int = 4; +export def FPE_FLTUND: int = 5; +export def FPE_FLTRES: int = 6; +export def FPE_FLTINV: int = 7; +export def FPE_FLTSUB: int = 8; + +export def SEGV_MAPERR: int = 1; +export def SEGV_ACCERR: int = 2; + +export def BUS_ADRALN: int = 1; +export def BUS_ADRERR: int = 2; +export def BUS_OBJERR: int = 3; + +export def TRAP_BRKPT: int = 1; +export def TRAP_TRACE: int = 2; + +export def CLD_EXITED: int = 1; +export def CLD_KILLED: int = 2; +export def CLD_DUMPED: int = 3; +export def CLD_TRAPPED: int = 4; +export def CLD_STOPPED: int = 5; +export def CLD_CONTINUED: int = 6;