aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-02-25 16:00:00 -0800
committerGitHub <noreply@github.com>2021-02-25 16:00:00 -0800
commit7edb204edfa41e11776ac009da5a20fb1c907f5f (patch)
tree9c6eae297ebc492c0a1a94a4d3d25fc3bcd07bd9 /lib/std
parent297eabd4accbcae42bfe821078a79e4af06a2dde (diff)
parent37a1d08de2ce263439713180f57741d16fb27e23 (diff)
downloadzig-7edb204edfa41e11776ac009da5a20fb1c907f5f.tar.gz
zig-7edb204edfa41e11776ac009da5a20fb1c907f5f.zip
Merge pull request #7546 from hoanga/haiku-support
initial support for haiku
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/Thread.zig62
-rw-r--r--lib/std/c/haiku.zig43
-rw-r--r--lib/std/crypto/tlcsprng.zig1
-rw-r--r--lib/std/debug.zig17
-rw-r--r--lib/std/fs.zig86
-rw-r--r--lib/std/fs/get_app_data_dir.zig12
-rw-r--r--lib/std/os.zig32
-rw-r--r--lib/std/os/bits.zig1
-rw-r--r--lib/std/os/bits/haiku.zig1450
-rw-r--r--lib/std/os/haiku.zig8
-rw-r--r--lib/std/process.zig20
-rw-r--r--lib/std/target.zig8
12 files changed, 1699 insertions, 41 deletions
diff --git a/lib/std/Thread.zig b/lib/std/Thread.zig
index 80de19fe19..77277bd154 100644
--- a/lib/std/Thread.zig
+++ b/lib/std/Thread.zig
@@ -487,31 +487,42 @@ pub const CpuCountError = error{
};
pub fn cpuCount() CpuCountError!usize {
- if (std.Target.current.os.tag == .linux) {
- const cpu_set = try os.sched_getaffinity(0);
- return @as(usize, os.CPU_COUNT(cpu_set)); // TODO should not need this usize cast
- }
- if (std.Target.current.os.tag == .windows) {
- return os.windows.peb().NumberOfProcessors;
- }
- if (std.Target.current.os.tag == .openbsd) {
- var count: c_int = undefined;
- var count_size: usize = @sizeOf(c_int);
- const mib = [_]c_int{ os.CTL_HW, os.HW_NCPUONLINE };
- os.sysctl(&mib, &count, &count_size, null, 0) catch |err| switch (err) {
- error.NameTooLong, error.UnknownName => unreachable,
- else => |e| return e,
- };
- return @intCast(usize, count);
+ switch (std.Target.current.os.tag) {
+ .linux => {
+ const cpu_set = try os.sched_getaffinity(0);
+ return @as(usize, os.CPU_COUNT(cpu_set)); // TODO should not need this usize cast
+ },
+ .windows => {
+ return os.windows.peb().NumberOfProcessors;
+ },
+ .openbsd => {
+ var count: c_int = undefined;
+ var count_size: usize = @sizeOf(c_int);
+ const mib = [_]c_int{ os.CTL_HW, os.HW_NCPUONLINE };
+ os.sysctl(&mib, &count, &count_size, null, 0) catch |err| switch (err) {
+ error.NameTooLong, error.UnknownName => unreachable,
+ else => |e| return e,
+ };
+ return @intCast(usize, count);
+ },
+ .haiku => {
+ var count: u32 = undefined;
+ var system_info: os.system_info = undefined;
+ const rc = os.system.get_system_info(&system_info);
+ count = system_info.cpu_count;
+ return @intCast(usize, count);
+ },
+ else => {
+ var count: c_int = undefined;
+ var count_len: usize = @sizeOf(c_int);
+ const name = if (comptime std.Target.current.isDarwin()) "hw.logicalcpu" else "hw.ncpu";
+ os.sysctlbynameZ(name, &count, &count_len, null, 0) catch |err| switch (err) {
+ error.NameTooLong, error.UnknownName => unreachable,
+ else => |e| return e,
+ };
+ return @intCast(usize, count);
+ },
}
- var count: c_int = undefined;
- var count_len: usize = @sizeOf(c_int);
- const name = if (comptime std.Target.current.isDarwin()) "hw.logicalcpu" else "hw.ncpu";
- os.sysctlbynameZ(name, &count, &count_len, null, 0) catch |err| switch (err) {
- error.NameTooLong, error.UnknownName => unreachable,
- else => |e| return e,
- };
- return @intCast(usize, count);
}
pub fn getCurrentThreadId() u64 {
@@ -538,6 +549,9 @@ pub fn getCurrentThreadId() u64 {
.openbsd => {
return @bitCast(u32, c.getthrid());
},
+ .haiku => {
+ return @bitCast(u32, c.find_thread(null));
+ },
else => {
@compileError("getCurrentThreadId not implemented for this platform");
},
diff --git a/lib/std/c/haiku.zig b/lib/std/c/haiku.zig
index 0f695a9446..e361a7520e 100644
--- a/lib/std/c/haiku.zig
+++ b/lib/std/c/haiku.zig
@@ -3,6 +3,49 @@
// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
// The MIT license requires this copyright notice to be included in all copies
// and substantial portions of the software.
+
+//
+const std = @import("../std.zig");
+const builtin = std.builtin;
+
+usingnamespace std.c;
+
+extern "c" fn _errnop() *c_int;
+
+pub const _errno = _errnop;
+
+pub extern "c" fn find_directory(which: c_int, volume: i32, createIt: bool, path_ptr: [*]u8, length: i32) u64;
+
+pub extern "c" fn find_thread(thread_name: ?*c_void) i32;
+
+pub extern "c" fn get_system_info(system_info: *system_info) usize;
+
+// TODO revisit if abi changes or better option becomes apparent
+pub extern "c" fn _get_next_image_info(team: c_int, cookie: *i32, image_info: *image_info) usize;
+
+pub extern "c" fn _kern_read_dir(fd: c_int, buf_ptr: [*]u8, nbytes: usize, maxcount: u32) usize;
+
+pub extern "c" fn _kern_read_stat(fd: c_int, path_ptr: [*]u8, traverse_link: bool, libc_stat: *libc_stat, stat_size: i32) usize;
+
+pub extern "c" fn _kern_get_current_team() i32;
+
+pub const sem_t = extern struct {
+ _magic: u32,
+ _kern: extern struct {
+ _count: u32,
+ _flags: u32,
+ },
+ _padding: u32,
+};
+
+pub const pthread_attr_t = extern struct {
+ __detach_state: i32,
+ __sched_priority: i32,
+ __stack_size: i32,
+ __guard_size: i32,
+ __stack_address: ?*c_void,
+};
+
pub const pthread_mutex_t = extern struct {
flags: u32 = 0,
lock: i32 = 0,
diff --git a/lib/std/crypto/tlcsprng.zig b/lib/std/crypto/tlcsprng.zig
index 07844efc1b..115a7ab882 100644
--- a/lib/std/crypto/tlcsprng.zig
+++ b/lib/std/crypto/tlcsprng.zig
@@ -29,6 +29,7 @@ const os_has_fork = switch (std.Target.current.os.tag) {
.solaris,
.tvos,
.watchos,
+ .haiku,
=> true,
else => false,
diff --git a/lib/std/debug.zig b/lib/std/debug.zig
index a434fe0e8b..f32c1a6156 100644
--- a/lib/std/debug.zig
+++ b/lib/std/debug.zig
@@ -1125,12 +1125,15 @@ pub const DebugInfo = struct {
}
pub fn getModuleForAddress(self: *DebugInfo, address: usize) !*ModuleDebugInfo {
- if (comptime std.Target.current.isDarwin())
- return self.lookupModuleDyld(address)
- else if (builtin.os.tag == .windows)
- return self.lookupModuleWin32(address)
- else
+ if (comptime std.Target.current.isDarwin()) {
+ return self.lookupModuleDyld(address);
+ } else if (builtin.os.tag == .windows) {
+ return self.lookupModuleWin32(address);
+ } else if (builtin.os.tag == .haiku) {
+ return self.lookupModuleHaiku(address);
+ } else {
return self.lookupModuleDl(address);
+ }
}
fn lookupModuleDyld(self: *DebugInfo, address: usize) !*ModuleDebugInfo {
@@ -1336,6 +1339,10 @@ pub const DebugInfo = struct {
return obj_di;
}
+
+ fn lookupModuleHaiku(self: *DebugInfo, address: usize) !*ModuleDebugInfo {
+ @panic("TODO implement lookup module for Haiku");
+ }
};
const SymbolInfo = struct {
diff --git a/lib/std/fs.zig b/lib/std/fs.zig
index 53108ebe23..79385708af 100644
--- a/lib/std/fs.zig
+++ b/lib/std/fs.zig
@@ -39,7 +39,7 @@ pub const Watch = @import("fs/watch.zig").Watch;
/// fit into a UTF-8 encoded array of this length.
/// The byte count includes room for a null sentinel byte.
pub const MAX_PATH_BYTES = switch (builtin.os.tag) {
- .linux, .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => os.PATH_MAX,
+ .linux, .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .haiku => os.PATH_MAX,
// Each UTF-16LE character may be expanded to 3 UTF-8 bytes.
// If it would require 4 UTF-8 bytes, then there would be a surrogate
// pair in the UTF-16LE, and we (over)account 3 bytes for it that way.
@@ -427,6 +427,78 @@ pub const Dir = struct {
}
}
},
+ .haiku => struct {
+ dir: Dir,
+ buf: [8192]u8, // TODO align(@alignOf(os.dirent64)),
+ index: usize,
+ end_index: usize,
+
+ const Self = @This();
+
+ pub const Error = IteratorError;
+
+ /// Memory such as file names referenced in this returned entry becomes invalid
+ /// with subsequent calls to `next`, as well as when this `Dir` is deinitialized.
+ pub fn next(self: *Self) Error!?Entry {
+ start_over: while (true) {
+ // TODO: find a better max
+ const HAIKU_MAX_COUNT = 10000;
+ if (self.index >= self.end_index) {
+ const rc = os.system._kern_read_dir(
+ self.dir.fd,
+ &self.buf,
+ self.buf.len,
+ HAIKU_MAX_COUNT,
+ );
+ if (rc == 0) return null;
+ if (rc < 0) {
+ switch (os.errno(rc)) {
+ os.EBADF => unreachable, // Dir is invalid or was opened without iteration ability
+ os.EFAULT => unreachable,
+ os.ENOTDIR => unreachable,
+ os.EINVAL => unreachable,
+ else => |err| return os.unexpectedErrno(err),
+ }
+ }
+ self.index = 0;
+ self.end_index = @intCast(usize, rc);
+ }
+ const haiku_entry = @ptrCast(*align(1) os.dirent, &self.buf[self.index]);
+ const next_index = self.index + haiku_entry.reclen();
+ self.index = next_index;
+ const name = mem.spanZ(@ptrCast([*:0]u8, &haiku_entry.d_name));
+
+ if (mem.eql(u8, name, ".") or mem.eql(u8, name, "..") or (haiku_entry.d_ino == 0)) {
+ continue :start_over;
+ }
+
+ var stat_info: os.libc_stat = undefined;
+ const rc2 = os.system._kern_read_stat(
+ self.dir.fd,
+ &haiku_entry.d_name,
+ false,
+ &stat_info,
+ 0,
+ );
+ const statmode = stat_info.mode & os.S_IFMT;
+
+ const entry_kind = switch (statmode) {
+ os.S_IFDIR => Entry.Kind.Directory,
+ os.S_IFBLK => Entry.Kind.BlockDevice,
+ os.S_IFCHR => Entry.Kind.CharacterDevice,
+ os.S_IFLNK => Entry.Kind.SymLink,
+ os.S_IFREG => Entry.Kind.File,
+ os.S_IFIFO => Entry.Kind.NamedPipe,
+ else => Entry.Kind.Unknown,
+ };
+
+ return Entry{
+ .name = name,
+ .kind = entry_kind,
+ };
+ }
+ }
+ },
.linux => struct {
dir: Dir,
buf: [8192]u8, // TODO align(@alignOf(os.dirent64)),
@@ -621,14 +693,20 @@ pub const Dir = struct {
pub fn iterate(self: Dir) Iterator {
switch (builtin.os.tag) {
- .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => return Iterator{
+ .macos,
+ .ios,
+ .freebsd,
+ .netbsd,
+ .dragonfly,
+ .openbsd,
+ => return Iterator{
.dir = self,
.seek = 0,
.index = 0,
.end_index = 0,
.buf = undefined,
},
- .linux => return Iterator{
+ .linux, .haiku => return Iterator{
.dir = self,
.index = 0,
.end_index = 0,
@@ -2339,7 +2417,7 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
// TODO could this slice from 0 to out_len instead?
return mem.spanZ(std.meta.assumeSentinel(out_buffer.ptr, 0));
},
- .openbsd => {
+ .openbsd, .haiku => {
// OpenBSD doesn't support getting the path of a running process, so try to guess it
if (os.argv.len == 0)
return error.FileNotFound;
diff --git a/lib/std/fs/get_app_data_dir.zig b/lib/std/fs/get_app_data_dir.zig
index 5ac7f323b6..18f8458eb2 100644
--- a/lib/std/fs/get_app_data_dir.zig
+++ b/lib/std/fs/get_app_data_dir.zig
@@ -56,6 +56,18 @@ pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataD
};
return fs.path.join(allocator, &[_][]const u8{ home_dir, ".local", "share", appname });
},
+ .haiku => {
+ var dir_path_ptr: [*:0]u8 = undefined;
+ // TODO look into directory_which
+ const be_user_settings = 0xbbe;
+ const rc = os.system.find_directory(be_user_settings, -1, true, dir_path_ptr, 1) ;
+ const settings_dir = try allocator.dupeZ(u8, mem.spanZ(dir_path_ptr));
+ defer allocator.free(settings_dir);
+ switch (rc) {
+ 0 => return fs.path.join(allocator, &[_][]const u8{ settings_dir, appname }),
+ else => return error.AppDataDirUnavailable,
+ }
+ },
else => @compileError("Unsupported OS"),
}
}
diff --git a/lib/std/os.zig b/lib/std/os.zig
index 61d9749415..6b13ec94c9 100644
--- a/lib/std/os.zig
+++ b/lib/std/os.zig
@@ -32,6 +32,7 @@ const MAX_PATH_BYTES = std.fs.MAX_PATH_BYTES;
pub const darwin = @import("os/darwin.zig");
pub const dragonfly = @import("os/dragonfly.zig");
pub const freebsd = @import("os/freebsd.zig");
+pub const haiku = @import("os/haiku.zig");
pub const netbsd = @import("os/netbsd.zig");
pub const openbsd = @import("os/openbsd.zig");
pub const linux = @import("os/linux.zig");
@@ -52,6 +53,7 @@ test {
_ = uefi;
_ = wasi;
_ = windows;
+ _ = haiku;
_ = @import("os/test.zig");
}
@@ -66,6 +68,7 @@ else if (builtin.link_libc)
else switch (builtin.os.tag) {
.macos, .ios, .watchos, .tvos => darwin,
.freebsd => freebsd,
+ .haiku => haiku,
.linux => linux,
.netbsd => netbsd,
.openbsd => openbsd,
@@ -599,7 +602,7 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void {
/// On these systems, the read races with concurrent writes to the same file descriptor.
pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize {
const have_pread_but_not_preadv = switch (std.Target.current.os.tag) {
- .windows, .macos, .ios, .watchos, .tvos => true,
+ .windows, .macos, .ios, .watchos, .tvos, .haiku => true,
else => false,
};
if (have_pread_but_not_preadv) {
@@ -932,7 +935,7 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize {
/// If `iov.len` is larger than will fit in a `u31`, a partial write will occur.
pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usize {
const have_pwrite_but_not_pwritev = switch (std.Target.current.os.tag) {
- .windows, .macos, .ios, .watchos, .tvos => true,
+ .windows, .macos, .ios, .watchos, .tvos, .haiku => true,
else => false,
};
@@ -3889,6 +3892,21 @@ pub fn pipe2(flags: u32) PipeError![2]fd_t {
}
}
}
+ if (std.Target.current.os.tag == .haiku) {
+ var fds: [2]fd_t = try pipe();
+ if (flags == 0) return fds;
+ errdefer {
+ close(fds[0]);
+ close(fds[1]);
+ }
+ for (fds) |fd| switch (errno(system.fcntl(fd, F_SETFL, flags))) {
+ 0 => {},
+ EINVAL => unreachable, // Invalid flags
+ EBADF => unreachable, // Always a race condition
+ else => |err| return unexpectedErrno(err),
+ };
+ return fds;
+ }
const new_flags = flags & ~@as(u32, O_CLOEXEC);
// Set every other flag affecting the file status using F_SETFL.
@@ -3921,7 +3939,10 @@ pub fn sysctl(
newlen: usize,
) SysCtlError!void {
if (builtin.os.tag == .wasi) {
- @panic("unsupported");
+ @panic("unsupported"); // TODO should be compile error, not panic
+ }
+ if (builtin.os.tag == .haiku) {
+ @panic("unsupported"); // TODO should be compile error, not panic
}
const name_len = math.cast(c_uint, name.len) catch return error.NameTooLong;
@@ -3945,7 +3966,10 @@ pub fn sysctlbynameZ(
newlen: usize,
) SysCtlError!void {
if (builtin.os.tag == .wasi) {
- @panic("unsupported");
+ @panic("unsupported"); // TODO should be compile error, not panic
+ }
+ if (builtin.os.tag == .haiku) {
+ @panic("unsupported"); // TODO should be compile error, not panic
}
switch (errno(system.sysctlbyname(name, oldp, oldlenp, newp, newlen))) {
diff --git a/lib/std/os/bits.zig b/lib/std/os/bits.zig
index 01bf502363..5d1de28bad 100644
--- a/lib/std/os/bits.zig
+++ b/lib/std/os/bits.zig
@@ -15,6 +15,7 @@ pub usingnamespace switch (std.Target.current.os.tag) {
.macos, .ios, .tvos, .watchos => @import("bits/darwin.zig"),
.dragonfly => @import("bits/dragonfly.zig"),
.freebsd => @import("bits/freebsd.zig"),
+ .haiku => @import("bits/haiku.zig"),
.linux => @import("bits/linux.zig"),
.netbsd => @import("bits/netbsd.zig"),
.openbsd => @import("bits/openbsd.zig"),
diff --git a/lib/std/os/bits/haiku.zig b/lib/std/os/bits/haiku.zig
new file mode 100644
index 0000000000..59631fd40e
--- /dev/null
+++ b/lib/std/os/bits/haiku.zig
@@ -0,0 +1,1450 @@
+// SPDX-License-Identifier: MIT
+// Copyright (c) 2015-2020 Zig Contributors
+// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
+// The MIT license requires this copyright notice to be included in all copies
+// and substantial portions of the software.
+const std = @import("../../std.zig");
+const maxInt = std.math.maxInt;
+
+pub const fd_t = c_int;
+pub const pid_t = c_int;
+pub const uid_t = u32;
+pub const gid_t = u32;
+pub const mode_t = c_uint;
+
+pub const socklen_t = u32;
+
+/// Renamed from `kevent` to `Kevent` to avoid conflict with function name.
+pub const Kevent = extern struct {
+ ident: usize,
+ filter: i16,
+ flags: u16,
+ fflags: u32,
+ data: i64,
+ udata: usize,
+ // TODO ext
+};
+
+// Modes and flags for dlopen()
+// include/dlfcn.h
+
+pub const POLLIN = 0x0001;
+pub const POLLERR = 0x0004;
+pub const POLLNVAL = 0x1000;
+pub const POLLHUP = 0x0080;
+
+/// Bind function calls lazily.
+pub const RTLD_LAZY = 1;
+
+/// Bind function calls immediately.
+pub const RTLD_NOW = 2;
+
+pub const RTLD_MODEMASK = 0x3;
+
+/// Make symbols globally available.
+pub const RTLD_GLOBAL = 0x100;
+
+/// Opposite of RTLD_GLOBAL, and the default.
+pub const RTLD_LOCAL = 0;
+
+/// Trace loaded objects and exit.
+pub const RTLD_TRACE = 0x200;
+
+/// Do not remove members.
+pub const RTLD_NODELETE = 0x01000;
+
+/// Do not load if not already loaded.
+pub const RTLD_NOLOAD = 0x02000;
+
+pub const dl_phdr_info = extern struct {
+ dlpi_addr: usize,
+ dlpi_name: ?[*:0]const u8,
+ dlpi_phdr: [*]std.elf.Phdr,
+ dlpi_phnum: u16,
+};
+
+pub const Flock = extern struct {
+ l_start: off_t,
+ l_len: off_t,
+ l_pid: pid_t,
+ l_type: i16,
+ l_whence: i16,
+ l_sysid: i32,
+ __unused: [4]u8,
+};
+
+pub const msghdr = extern struct {
+ /// optional address
+ msg_name: ?*sockaddr,
+
+ /// size of address
+ msg_namelen: socklen_t,
+
+ /// scatter/gather array
+ msg_iov: [*]iovec,
+
+ /// # elements in msg_iov
+ msg_iovlen: i32,
+
+ /// ancillary data
+ msg_control: ?*c_void,
+
+ /// ancillary data buffer len
+ msg_controllen: socklen_t,
+
+ /// flags on received message
+ msg_flags: i32,
+};
+
+pub const msghdr_const = extern struct {
+ /// optional address
+ msg_name: ?*const sockaddr,
+
+ /// size of address
+ msg_namelen: socklen_t,
+
+ /// scatter/gather array
+ msg_iov: [*]iovec_const,
+
+ /// # elements in msg_iov
+ msg_iovlen: i32,
+
+ /// ancillary data
+ msg_control: ?*c_void,
+
+ /// ancillary data buffer len
+ msg_controllen: socklen_t,
+
+ /// flags on received message
+ msg_flags: i32,
+};
+
+pub const off_t = i64;
+pub const ino_t = u64;
+
+pub const nfds_t = u32;
+
+pub const pollfd = extern struct {
+ fd: i32,
+ events: i16,
+ revents: i16,
+};
+
+pub const libc_stat = extern struct {
+ dev: i32,
+ ino: u64,
+ mode: u32,
+ nlink: i32,
+ uid: i32,
+ gid: i32,
+ size: i64,
+ rdev: i32,
+ blksize: i32,
+ atim: timespec,
+ mtim: timespec,
+ ctim: timespec,
+ crtim: timespec,
+ st_type: u32,
+ blocks: i64,
+
+ pub fn atime(self: @This()) timespec {
+ return self.atim;
+ }
+ pub fn mtime(self: @This()) timespec {
+ return self.mtim;
+ }
+ pub fn ctime(self: @This()) timespec {
+ return self.ctim;
+ }
+ pub fn crtime(self: @This()) timespec {
+ return self.crtim;
+ }
+};
+
+pub const timespec = extern struct {
+ tv_sec: isize,
+ tv_nsec: isize,
+};
+
+pub const dirent = extern struct {
+ d_dev: i32,
+ d_pdev: i32,
+ d_ino: i64,
+ d_pino: i64,
+ d_reclen: u16,
+ d_name: [256]u8,
+
+ pub fn reclen(self: dirent) u16 {
+ return self.d_reclen;
+ }
+};
+
+pub const image_info = extern struct {
+ id: u32, //image_id
+ type: u32, // image_type
+ sequence: i32,
+ init_order: i32,
+ init_routine: *c_void,
+ term_routine: *c_void,
+ device: i32,
+ node: i32,
+ name: [1024]u8,
+ text: *c_void,
+ data: *c_void,
+ text_size: i32,
+ data_size: i32,
+ api_version: i32,
+ abi: i32,
+};
+
+pub const system_info = extern struct {
+ boot_time: i64,
+ cpu_count: u32,
+ max_pages: u64,
+ used_pages: u64,
+ cached_pages: u64,
+ block_cache_pages: u64,
+ ignored_pages: u64,
+ needed_memory: u64,
+ free_memory: u64,
+ max_swap_pages: u64,
+ free_swap_pages: u64,
+ page_faults: u32,
+ max_sems: u32,
+ used_sems: u32,
+ max_ports: u32,
+ used_ports: u32,
+ max_threads: u32,
+ used_threads: u32,
+ max_teams: u32,
+ used_teams: u32,
+ kernel_name: [256]u8,
+ kernel_build_date: [32]u8,
+ kernel_build_time: [32]u8,
+ kernel_version: i64,
+ abi: u32,
+};
+
+pub const in_port_t = u16;
+pub const sa_family_t = u8;
+
+pub const sockaddr = extern struct {
+ /// total length
+ len: u8,
+
+ /// address family
+ family: sa_family_t,
+
+ /// actually longer; address value
+ data: [14]u8,
+};
+
+pub const sockaddr_in = extern struct {
+ len: u8 = @sizeOf(sockaddr_in),
+ family: sa_family_t = AF_INET,
+ port: in_port_t,
+ addr: u32,
+ zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
+};
+
+pub const sockaddr_in6 = extern struct {
+ len: u8 = @sizeOf(sockaddr_in6),
+ family: sa_family_t = AF_INET6,
+ port: in_port_t,
+ flowinfo: u32,
+ addr: [16]u8,
+ scope_id: u32,
+};
+
+pub const sockaddr_un = extern struct {
+ len: u8 = @sizeOf(sockaddr_un),
+ family: sa_family_t = AF_UNIX,
+ path: [104]u8,
+};
+
+pub const CTL_KERN = 1;
+pub const CTL_DEBUG = 5;
+
+pub const KERN_PROC = 14; // struct: process entries
+pub const KERN_PROC_PATHNAME = 12; // path to executable
+
+pub const PATH_MAX = 1024;
+
+pub const STDIN_FILENO = 0;
+pub const STDOUT_FILENO = 1;
+pub const STDERR_FILENO = 2;
+
+pub const PROT_NONE = 0;
+pub const PROT_READ = 1;
+pub const PROT_WRITE = 2;
+pub const PROT_EXEC = 4;
+
+pub const CLOCK_REALTIME = 0;
+pub const CLOCK_VIRTUAL = 1;
+pub const CLOCK_PROF = 2;
+pub const CLOCK_MONOTONIC = 4;
+pub const CLOCK_UPTIME = 5;
+pub const CLOCK_UPTIME_PRECISE = 7;
+pub const CLOCK_UPTIME_FAST = 8;
+pub const CLOCK_REALTIME_PRECISE = 9;
+pub const CLOCK_REALTIME_FAST = 10;
+pub const CLOCK_MONOTONIC_PRECISE = 11;
+pub const CLOCK_MONOTONIC_FAST = 12;
+pub const CLOCK_SECOND = 13;
+pub const CLOCK_THREAD_CPUTIME_ID = 14;
+pub const CLOCK_PROCESS_CPUTIME_ID = 15;
+
+pub const MAP_FAILED = @intToPtr(*c_void, maxInt(usize));
+pub const MAP_SHARED = 0x0001;
+pub const MAP_PRIVATE = 0x0002;
+pub const MAP_FIXED = 0x0010;
+pub const MAP_STACK = 0x0400;
+pub const MAP_NOSYNC = 0x0800;
+pub const MAP_ANON = 0x1000;
+pub const MAP_ANONYMOUS = MAP_ANON;
+pub const MAP_FILE = 0;
+
+pub const MAP_GUARD = 0x00002000;
+pub const MAP_EXCL = 0x00004000;
+pub const MAP_NOCORE = 0x00020000;
+pub const MAP_PREFAULT_READ = 0x00040000;
+pub const MAP_32BIT = 0x00080000;
+
+pub const WNOHANG = 1;
+pub const WUNTRACED = 2;
+pub const WSTOPPED = WUNTRACED;
+pub const WCONTINUED = 4;
+pub const WNOWAIT = 8;
+pub const WEXITED = 16;
+pub const WTRAPPED = 32;
+
+pub const SA_ONSTACK = 0x0001;
+pub const SA_RESTART = 0x0002;
+pub const SA_RESETHAND = 0x0004;
+pub const SA_NOCLDSTOP = 0x0008;
+pub const SA_NODEFER = 0x0010;
+pub const SA_NOCLDWAIT = 0x0020;
+pub const SA_SIGINFO = 0x0040;
+
+pub const SIGHUP = 1;
+pub const SIGINT = 2;
+pub const SIGQUIT = 3;
+pub const SIGILL = 4;
+pub const SIGTRAP = 5;
+pub const SIGABRT = 6;
+pub const SIGIOT = SIGABRT;
+pub const SIGEMT = 7;
+pub const SIGFPE = 8;
+pub const SIGKILL = 9;
+pub const SIGBUS = 10;
+pub const SIGSEGV = 11;
+pub const SIGSYS = 12;
+pub const SIGPIPE = 13;
+pub const SIGALRM = 14;
+pub const SIGTERM = 15;
+pub const SIGURG = 16;
+pub const SIGSTOP = 17;
+pub const SIGTSTP = 18;
+pub const SIGCONT = 19;
+pub const SIGCHLD = 20;
+pub const SIGTTIN = 21;
+pub const SIGTTOU = 22;
+pub const SIGIO = 23;
+pub const SIGXCPU = 24;
+pub const SIGXFSZ = 25;
+pub const SIGVTALRM = 26;
+pub const SIGPROF = 27;
+pub const SIGWINCH = 28;
+pub const SIGINFO = 29;
+pub const SIGUSR1 = 30;
+pub const SIGUSR2 = 31;
+pub const SIGTHR = 32;
+pub const SIGLWP = SIGTHR;
+pub const SIGLIBRT = 33;
+
+pub const SIGRTMIN = 65;
+pub const SIGRTMAX = 126;
+
+// access function
+pub const F_OK = 0; // test for existence of file
+pub const X_OK = 1; // test for execute or search permission
+pub const W_OK = 2; // test for write permission
+pub const R_OK = 4; // test for read permission
+
+pub const O_RDONLY = 0x0000;
+pub const O_WRONLY = 0x0001;
+pub const O_RDWR = 0x0002;
+pub const O_ACCMODE = 0x0003;
+
+pub const O_SHLOCK = 0x0010;
+pub const O_EXLOCK = 0x0020;
+
+pub const O_CREAT = 0x0200;
+pub const O_EXCL = 0x0800;
+pub const O_NOCTTY = 0x8000;
+pub const O_TRUNC = 0x0400;
+pub const O_APPEND = 0x0008;
+pub const O_NONBLOCK = 0x0004;
+pub const O_DSYNC = 0o10000;
+pub const O_SYNC = 0x0080;
+pub const O_RSYNC = 0o4010000;
+pub const O_DIRECTORY = 0x20000;
+pub const O_NOFOLLOW = 0x0100;
+pub const O_CLOEXEC = 0x00100000;
+
+pub const O_ASYNC = 0x0040;
+pub const O_DIRECT = 0x00010000;
+pub const O_NOATIME = 0o1000000;
+pub const O_PATH = 0o10000000;
+pub const O_TMPFILE = 0o20200000;
+pub const O_NDELAY = O_NONBLOCK;
+
+pub const F_DUPFD = 0;
+pub const F_GETFD = 1;
+pub const F_SETFD = 2;
+pub const F_GETFL = 3;
+pub const F_SETFL = 4;
+
+pub const F_GETOWN = 5;
+pub const F_SETOWN = 6;
+
+pub const F_GETLK = 11;
+pub const F_SETLK = 12;
+pub const F_SETLKW = 13;
+
+pub const F_RDLCK = 1;
+pub const F_WRLCK = 3;
+pub const F_UNLCK = 2;
+
+pub const LOCK_SH = 1;
+pub const LOCK_EX = 2;
+pub const LOCK_UN = 8;
+pub const LOCK_NB = 4;
+
+pub const F_SETOWN_EX = 15;
+pub const F_GETOWN_EX = 16;
+
+pub const F_GETOWNER_UIDS = 17;
+
+pub const FD_CLOEXEC = 1;
+
+pub const SEEK_SET = 0;
+pub const SEEK_CUR = 1;
+pub const SEEK_END = 2;
+
+pub const SIG_BLOCK = 1;
+pub const SIG_UNBLOCK = 2;
+pub const SIG_SETMASK = 3;
+
+pub const SOCK_STREAM = 1;
+pub const SOCK_DGRAM = 2;
+pub const SOCK_RAW = 3;
+pub const SOCK_RDM = 4;
+pub const SOCK_SEQPACKET = 5;
+
+pub const SOCK_CLOEXEC = 0x10000000;
+pub const SOCK_NONBLOCK = 0x20000000;
+
+pub const SO_DEBUG = 0x00000001;
+pub const SO_ACCEPTCONN = 0x00000002;
+pub const SO_REUSEADDR = 0x00000004;
+pub const SO_KEEPALIVE = 0x00000008;
+pub const SO_DONTROUTE = 0x00000010;
+pub const SO_BROADCAST = 0x00000020;
+pub const SO_USELOOPBACK = 0x00000040;
+pub const SO_LINGER = 0x00000080;
+pub const SO_OOBINLINE = 0x00000100;
+pub const SO_REUSEPORT = 0x00000200;
+pub const SO_TIMESTAMP = 0x00000400;
+pub const SO_NOSIGPIPE = 0x00000800;
+pub const SO_ACCEPTFILTER = 0x00001000;
+pub const SO_BINTIME = 0x00002000;
+pub const SO_NO_OFFLOAD = 0x00004000;
+pub const SO_NO_DDP = 0x00008000;
+pub const SO_REUSEPORT_LB = 0x00010000;
+
+pub const SO_SNDBUF = 0x1001;
+pub const SO_RCVBUF = 0x1002;
+pub const SO_SNDLOWAT = 0x1003;
+pub const SO_RCVLOWAT = 0x1004;
+pub const SO_SNDTIMEO = 0x1005;
+pub const SO_RCVTIMEO = 0x1006;
+pub const SO_ERROR = 0x1007;
+pub const SO_TYPE = 0x1008;
+pub const SO_LABEL = 0x1009;
+pub const SO_PEERLABEL = 0x1010;
+pub const SO_LISTENQLIMIT = 0x1011;
+pub const SO_LISTENQLEN = 0x1012;
+pub const SO_LISTENINCQLEN = 0x1013;
+pub const SO_SETFIB = 0x1014;
+pub const SO_USER_COOKIE = 0x1015;
+pub const SO_PROTOCOL = 0x1016;
+pub const SO_PROTOTYPE = SO_PROTOCOL;
+pub const SO_TS_CLOCK = 0x1017;
+pub const SO_MAX_PACING_RATE = 0x1018;
+pub const SO_DOMAIN = 0x1019;
+
+pub const SOL_SOCKET = 0xffff;
+
+pub const PF_UNSPEC = AF_UNSPEC;
+pub const PF_LOCAL = AF_LOCAL;
+pub const PF_UNIX = PF_LOCAL;
+pub const PF_INET = AF_INET;
+pub const PF_IMPLINK = AF_IMPLINK;
+pub const PF_PUP = AF_PUP;
+pub const PF_CHAOS = AF_CHAOS;
+pub const PF_NETBIOS = AF_NETBIOS;
+pub const PF_ISO = AF_ISO;
+pub const PF_OSI = AF_ISO;
+pub const PF_ECMA = AF_ECMA;
+pub const PF_DATAKIT = AF_DATAKIT;
+pub const PF_CCITT = AF_CCITT;
+pub const PF_DECnet = AF_DECnet;
+pub const PF_DLI = AF_DLI;
+pub const PF_LAT = AF_LAT;
+pub const PF_HYLINK = AF_HYLINK;
+pub const PF_APPLETALK = AF_APPLETALK;
+pub const PF_ROUTE = AF_ROUTE;
+pub const PF_LINK = AF_LINK;
+pub const PF_XTP = pseudo_AF_XTP;
+pub const PF_COIP = AF_COIP;
+pub const PF_CNT = AF_CNT;
+pub const PF_SIP = AF_SIP;
+pub const PF_IPX = AF_IPX;
+pub const PF_RTIP = pseudo_AF_RTIP;
+pub const PF_PIP = psuedo_AF_PIP;
+pub const PF_ISDN = AF_ISDN;
+pub const PF_KEY = pseudo_AF_KEY;
+pub const PF_INET6 = pseudo_AF_INET6;
+pub const PF_NATM = AF_NATM;
+pub const PF_ATM = AF_ATM;
+pub const PF_NETGRAPH = AF_NETGRAPH;
+pub const PF_SLOW = AF_SLOW;
+pub const PF_SCLUSTER = AF_SCLUSTER;
+pub const PF_ARP = AF_ARP;
+pub const PF_BLUETOOTH = AF_BLUETOOTH;
+pub const PF_IEEE80211 = AF_IEEE80211;
+pub const PF_INET_SDP = AF_INET_SDP;
+pub const PF_INET6_SDP = AF_INET6_SDP;
+pub const PF_MAX = AF_MAX;
+
+pub const AF_UNSPEC = 0;
+pub const AF_UNIX = 1;
+pub const AF_LOCAL = AF_UNIX;
+pub const AF_FILE = AF_LOCAL;
+pub const AF_INET = 2;
+pub const AF_IMPLINK = 3;
+pub const AF_PUP = 4;
+pub const AF_CHAOS = 5;
+pub const AF_NETBIOS = 6;
+pub const AF_ISO = 7;
+pub const AF_OSI = AF_ISO;
+pub const AF_ECMA = 8;
+pub const AF_DATAKIT = 9;
+pub const AF_CCITT = 10;
+pub const AF_SNA = 11;
+pub const AF_DECnet = 12;
+pub const AF_DLI = 13;
+pub const AF_LAT = 14;
+pub const AF_HYLINK = 15;
+pub const AF_APPLETALK = 16;
+pub const AF_ROUTE = 17;
+pub const AF_LINK = 18;
+pub const pseudo_AF_XTP = 19;
+pub const AF_COIP = 20;
+pub const AF_CNT = 21;
+pub const pseudo_AF_RTIP = 22;
+pub const AF_IPX = 23;
+pub const AF_SIP = 24;
+pub const pseudo_AF_PIP = 25;
+pub const AF_ISDN = 26;
+pub const AF_E164 = AF_ISDN;
+pub const pseudo_AF_KEY = 27;
+pub const AF_INET6 = 28;
+pub const AF_NATM = 29;
+pub const AF_ATM = 30;
+pub const pseudo_AF_HDRCMPLT = 31;
+pub const AF_NETGRAPH = 32;
+pub const AF_SLOW = 33;
+pub const AF_SCLUSTER = 34;
+pub const AF_ARP = 35;
+pub const AF_BLUETOOTH = 36;
+pub const AF_IEEE80211 = 37;
+pub const AF_INET_SDP = 40;
+pub const AF_INET6_SDP = 42;
+pub const AF_MAX = 42;
+
+pub const DT_UNKNOWN = 0;
+pub const DT_FIFO = 1;
+pub const DT_CHR = 2;
+pub const DT_DIR = 4;
+pub const DT_BLK = 6;
+pub const DT_REG = 8;
+pub const DT_LNK = 10;
+pub const DT_SOCK = 12;
+pub const DT_WHT = 14;
+
+/// add event to kq (implies enable)
+pub const EV_ADD = 0x0001;
+
+/// delete event from kq
+pub const EV_DELETE = 0x0002;
+
+/// enable event
+pub const EV_ENABLE = 0x0004;
+
+/// disable event (not reported)
+pub const EV_DISABLE = 0x0008;
+
+/// only report one occurrence
+pub const EV_ONESHOT = 0x0010;
+
+/// clear event state after reporting
+pub const EV_CLEAR = 0x0020;
+
+/// force immediate event output
+/// ... with or without EV_ERROR
+/// ... use KEVENT_FLAG_ERROR_EVENTS
+/// on syscalls supporting flags
+pub const EV_RECEIPT = 0x0040;
+
+/// disable event after reporting
+pub const EV_DISPATCH = 0x0080;
+
+pub const EVFILT_READ = -1;
+pub const EVFILT_WRITE = -2;
+
+/// attached to aio requests
+pub const EVFILT_AIO = -3;
+
+/// attached to vnodes
+pub const EVFILT_VNODE = -4;
+
+/// attached to struct proc
+pub const EVFILT_PROC = -5;
+
+/// attached to struct proc
+pub const EVFILT_SIGNAL = -6;
+
+/// timers
+pub const EVFILT_TIMER = -7;
+
+/// Process descriptors
+pub const EVFILT_PROCDESC = -8;
+
+/// Filesystem events
+pub const EVFILT_FS = -9;
+
+pub const EVFILT_LIO = -10;
+
+/// User events
+pub const EVFILT_USER = -11;
+
+/// Sendfile events
+pub const EVFILT_SENDFILE = -12;
+
+pub const EVFILT_EMPTY = -13;
+
+/// On input, NOTE_TRIGGER causes the event to be triggered for output.
+pub const NOTE_TRIGGER = 0x01000000;
+
+/// ignore input fflags
+pub const NOTE_FFNOP = 0x00000000;
+
+/// and fflags
+pub const NOTE_FFAND = 0x40000000;
+
+/// or fflags
+pub const NOTE_FFOR = 0x80000000;
+
+/// copy fflags
+pub const NOTE_FFCOPY = 0xc0000000;
+
+/// mask for operations
+pub const NOTE_FFCTRLMASK = 0xc0000000;
+pub const NOTE_FFLAGSMASK = 0x00ffffff;
+
+/// low water mark
+pub const NOTE_LOWAT = 0x00000001;
+
+/// behave like poll()
+pub const NOTE_FILE_POLL = 0x00000002;
+
+/// vnode was removed
+pub const NOTE_DELETE = 0x00000001;
+
+/// data contents changed
+pub const NOTE_WRITE = 0x00000002;
+
+/// size increased
+pub const NOTE_EXTEND = 0x00000004;
+
+/// attributes changed
+pub const NOTE_ATTRIB = 0x00000008;
+
+/// link count changed
+pub const NOTE_LINK = 0x00000010;
+
+/// vnode was renamed
+pub const NOTE_RENAME = 0x00000020;
+
+/// vnode access was revoked
+pub const NOTE_REVOKE = 0x00000040;
+
+/// vnode was opened
+pub const NOTE_OPEN = 0x00000080;
+
+/// file closed, fd did not allow write
+pub const NOTE_CLOSE = 0x00000100;
+
+/// file closed, fd did allow write
+pub const NOTE_CLOSE_WRITE = 0x00000200;
+
+/// file was read
+pub const NOTE_READ = 0x00000400;
+
+/// process exited
+pub const NOTE_EXIT = 0x80000000;
+
+/// process forked
+pub const NOTE_FORK = 0x40000000;
+
+/// process exec'd
+pub const NOTE_EXEC = 0x20000000;
+
+/// mask for signal & exit status
+pub const NOTE_PDATAMASK = 0x000fffff;
+pub const NOTE_PCTRLMASK = (~NOTE_PDATAMASK);
+
+/// data is seconds
+pub const NOTE_SECONDS = 0x00000001;
+
+/// data is milliseconds
+pub const NOTE_MSECONDS = 0x00000002;
+
+/// data is microseconds
+pub const NOTE_USECONDS = 0x00000004;
+
+/// data is nanoseconds
+pub const NOTE_NSECONDS = 0x00000008;
+
+/// timeout is absolute
+pub const NOTE_ABSTIME = 0x00000010;
+
+pub const TIOCEXCL = 0x2000740d;
+pub const TIOCNXCL = 0x2000740e;
+pub const TIOCSCTTY = 0x20007461;
+pub const TIOCGPGRP = 0x40047477;
+pub const TIOCSPGRP = 0x80047476;
+pub const TIOCOUTQ = 0x40047473;
+pub const TIOCSTI = 0x80017472;
+pub const TIOCGWINSZ = 0x40087468;
+pub const TIOCSWINSZ = 0x80087467;
+pub const TIOCMGET = 0x4004746a;
+pub const TIOCMBIS = 0x8004746c;
+pub const TIOCMBIC = 0x8004746b;
+pub const TIOCMSET = 0x8004746d;
+pub const FIONREAD = 0x4004667f;
+pub const TIOCCONS = 0x80047462;
+pub const TIOCPKT = 0x80047470;
+pub const FIONBIO = 0x8004667e;
+pub const TIOCNOTTY = 0x20007471;
+pub const TIOCSETD = 0x8004741b;
+pub const TIOCGETD = 0x4004741a;
+pub const TIOCSBRK = 0x2000747b;
+pub const TIOCCBRK = 0x2000747a;
+pub const TIOCGSID = 0x40047463;
+pub const TIOCGPTN = 0x4004740f;
+pub const TIOCSIG = 0x2004745f;
+
+pub fn WEXITSTATUS(s: u32) u32 {
+ return (s & 0xff00) >> 8;
+}
+pub fn WTERMSIG(s: u32) u32 {
+ return s & 0x7f;
+}
+pub fn WSTOPSIG(s: u32) u32 {
+ return WEXITSTATUS(s);
+}
+pub fn WIFEXITED(s: u32) bool {
+ return WTERMSIG(s) == 0;
+}
+pub fn WIFSTOPPED(s: u32) bool {
+ return @intCast(u16, (((s & 0xffff) *% 0x10001) >> 8)) > 0x7f00;
+}
+pub fn WIFSIGNALED(s: u32) bool {
+ return (s & 0xffff) -% 1 < 0xff;
+}
+
+pub const winsize = extern struct {
+ ws_row: u16,
+ ws_col: u16,
+ ws_xpixel: u16,
+ ws_ypixel: u16,
+};
+
+const NSIG = 32;
+
+pub const SIG_ERR = @intToPtr(fn (i32) callconv(.C) void, maxInt(usize));
+pub const SIG_DFL = @intToPtr(fn (i32) callconv(.C) void, 0);
+pub const SIG_IGN = @intToPtr(fn (i32) callconv(.C) void, 1);
+
+/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
+pub const Sigaction = extern struct {
+ /// signal handler
+ __sigaction_u: extern union {
+ __sa_handler: fn (i32) callconv(.C) void,
+ __sa_sigaction: fn (i32, *__siginfo, usize) callconv(.C) void,
+ },
+
+ /// see signal options
+ sa_flags: u32,
+
+ /// signal mask to apply
+ sa_mask: sigset_t,
+};
+
+pub const _SIG_WORDS = 4;
+pub const _SIG_MAXSIG = 128;
+
+pub inline fn _SIG_IDX(sig: usize) usize {
+ return sig - 1;
+}
+pub inline fn _SIG_WORD(sig: usize) usize {
+ return_SIG_IDX(sig) >> 5;
+}
+pub inline fn _SIG_BIT(sig: usize) usize {
+ return 1 << (_SIG_IDX(sig) & 31);
+}
+pub inline fn _SIG_VALID(sig: usize) usize {
+ return sig <= _SIG_MAXSIG and sig > 0;
+}
+
+pub const sigset_t = extern struct {
+ __bits: [_SIG_WORDS]u32,
+};
+
+pub const EPERM = 1; // Operation not permitted
+pub const ENOENT = 2; // No such file or directory
+pub const ESRCH = 3; // No such process
+pub const EINTR = 4; // Interrupted system call
+pub const EIO = 5; // Input/output error
+pub const ENXIO = 6; // Device not configured
+pub const E2BIG = 7; // Argument list too long
+pub const ENOEXEC = 8; // Exec format error
+pub const EBADF = 9; // Bad file descriptor
+pub const ECHILD = 10; // No child processes
+pub const EDEADLK = 11; // Resource deadlock avoided
+// 11 was EAGAIN
+pub const ENOMEM = 12; // Cannot allocate memory
+pub const EACCES = 13; // Permission denied
+pub const EFAULT = 14; // Bad address
+pub const ENOTBLK = 15; // Block device required
+pub const EBUSY = 16; // Device busy
+pub const EEXIST = 17; // File exists
+pub const EXDEV = 18; // Cross-device link
+pub const ENODEV = 19; // Operation not supported by device
+pub const ENOTDIR = 20; // Not a directory
+pub const EISDIR = 21; // Is a directory
+pub const EINVAL = 22; // Invalid argument
+pub const ENFILE = 23; // Too many open files in system
+pub const EMFILE = 24; // Too many open files
+pub const ENOTTY = 25; // Inappropriate ioctl for device
+pub const ETXTBSY = 26; // Text file busy
+pub const EFBIG = 27; // File too large
+pub const ENOSPC = 28; // No space left on device
+pub const ESPIPE = 29; // Illegal seek
+pub const EROFS = 30; // Read-only filesystem
+pub const EMLINK = 31; // Too many links
+pub const EPIPE = 32; // Broken pipe
+
+// math software
+pub const EDOM = 33; // Numerical argument out of domain
+pub const ERANGE = 34; // Result too large
+
+// non-blocking and interrupt i/o
+pub const EAGAIN = 35; // Resource temporarily unavailable
+pub const EWOULDBLOCK = EAGAIN; // Operation would block
+pub const EINPROGRESS = 36; // Operation now in progress
+pub const EALREADY = 37; // Operation already in progress
+
+// ipc/network software -- argument errors
+pub const ENOTSOCK = 38; // Socket operation on non-socket
+pub const EDESTADDRREQ = 39; // Destination address required
+pub const EMSGSIZE = 40; // Message too long
+pub const EPROTOTYPE = 41; // Protocol wrong type for socket
+pub const ENOPROTOOPT = 42; // Protocol not available
+pub const EPROTONOSUPPORT = 43; // Protocol not supported
+pub const ESOCKTNOSUPPORT = 44; // Socket type not supported
+pub const EOPNOTSUPP = 45; // Operation not supported
+pub const ENOTSUP = EOPNOTSUPP; // Operation not supported
+pub const EPFNOSUPPORT = 46; // Protocol family not supported
+pub const EAFNOSUPPORT = 47; // Address family not supported by protocol family
+pub const EADDRINUSE = 48; // Address already in use
+pub const EADDRNOTAVAIL = 49; // Can't assign requested address
+
+// ipc/network software -- operational errors
+pub const ENETDOWN = 50; // Network is down
+pub const ENETUNREACH = 51; // Network is unreachable
+pub const ENETRESET = 52; // Network dropped connection on reset
+pub const ECONNABORTED = 53; // Software caused connection abort
+pub const ECONNRESET = 54; // Connection reset by peer
+pub const ENOBUFS = 55; // No buffer space available
+pub const EISCONN = 56; // Socket is already connected
+pub const ENOTCONN = 57; // Socket is not connected
+pub const ESHUTDOWN = 58; // Can't send after socket shutdown
+pub const ETOOMANYREFS = 59; // Too many references: can't splice
+pub const ETIMEDOUT = 60; // Operation timed out
+pub const ECONNREFUSED = 61; // Connection refused
+
+pub const ELOOP = 62; // Too many levels of symbolic links
+pub const ENAMETOOLONG = 63; // File name too long
+
+// should be rearranged
+pub const EHOSTDOWN = 64; // Host is down
+pub const EHOSTUNREACH = 65; // No route to host
+pub const ENOTEMPTY = 66; // Directory not empty
+
+// quotas & mush
+pub const EPROCLIM = 67; // Too many processes
+pub const EUSERS = 68; // Too many users
+pub const EDQUOT = 69; // Disc quota exceeded
+
+// Network File System
+pub const ESTALE = 70; // Stale NFS file handle
+pub const EREMOTE = 71; // Too many levels of remote in path
+pub const EBADRPC = 72; // RPC struct is bad
+pub const ERPCMISMATCH = 73; // RPC version wrong
+pub const EPROGUNAVAIL = 74; // RPC prog. not avail
+pub const EPROGMISMATCH = 75; // Program version wrong
+pub const EPROCUNAVAIL = 76; // Bad procedure for program
+
+pub const ENOLCK = 77; // No locks available
+pub const ENOSYS = 78; // Function not implemented
+
+pub const EFTYPE = 79; // Inappropriate file type or format
+pub const EAUTH = 80; // Authentication error
+pub const ENEEDAUTH = 81; // Need authenticator
+pub const EIDRM = 82; // Identifier removed
+pub const ENOMSG = 83; // No message of desired type
+pub const EOVERFLOW = 84; // Value too large to be stored in data type
+pub const ECANCELED = 85; // Operation canceled
+pub const EILSEQ = 86; // Illegal byte sequence
+pub const ENOATTR = 87; // Attribute not found
+
+pub const EDOOFUS = 88; // Programming error
+
+pub const EBADMSG = 89; // Bad message
+pub const EMULTIHOP = 90; // Multihop attempted
+pub const ENOLINK = 91; // Link has been severed
+pub const EPROTO = 92; // Protocol error
+
+pub const ENOTCAPABLE = 93; // Capabilities insufficient
+pub const ECAPMODE = 94; // Not permitted in capability mode
+pub const ENOTRECOVERABLE = 95; // State not recoverable
+pub const EOWNERDEAD = 96; // Previous owner died
+
+pub const ELAST = 96; // Must be equal largest errno
+
+pub const MINSIGSTKSZ = switch (builtin.arch) {
+ .i386, .x86_64 => 2048,
+ .arm, .aarch64 => 4096,
+ else => @compileError("MINSIGSTKSZ not defined for this architecture"),
+};
+pub const SIGSTKSZ = MINSIGSTKSZ + 32768;
+
+pub const SS_ONSTACK = 1;
+pub const SS_DISABLE = 4;
+
+pub const stack_t = extern struct {
+ ss_sp: [*]u8,
+ ss_size: isize,
+ ss_flags: i32,
+};
+
+pub const S_IFMT = 0o170000;
+
+pub const S_IFIFO = 0o010000;
+pub const S_IFCHR = 0o020000;
+pub const S_IFDIR = 0o040000;
+pub const S_IFBLK = 0o060000;
+pub const S_IFREG = 0o100000;
+pub const S_IFLNK = 0o120000;
+pub const S_IFSOCK = 0o140000;
+pub const S_IFWHT = 0o160000;
+
+pub const S_ISUID = 0o4000;
+pub const S_ISGID = 0o2000;
+pub const S_ISVTX = 0o1000;
+pub const S_IRWXU = 0o700;
+pub const S_IRUSR = 0o400;
+pub const S_IWUSR = 0o200;
+pub const S_IXUSR = 0o100;
+pub const S_IRWXG = 0o070;
+pub const S_IRGRP = 0o040;
+pub const S_IWGRP = 0o020;
+pub const S_IXGRP = 0o010;
+pub const S_IRWXO = 0o007;
+pub const S_IROTH = 0o004;
+pub const S_IWOTH = 0o002;
+pub const S_IXOTH = 0o001;
+
+pub fn S_ISFIFO(m: u32) bool {
+ return m & S_IFMT == S_IFIFO;
+}
+
+pub fn S_ISCHR(m: u32) bool {
+ return m & S_IFMT == S_IFCHR;
+}
+
+pub fn S_ISDIR(m: u32) bool {
+ return m & S_IFMT == S_IFDIR;
+}
+
+pub fn S_ISBLK(m: u32) bool {
+ return m & S_IFMT == S_IFBLK;
+}
+
+pub fn S_ISREG(m: u32) bool {
+ return m & S_IFMT == S_IFREG;
+}
+
+pub fn S_ISLNK(m: u32) bool {
+ return m & S_IFMT == S_IFLNK;
+}
+
+pub fn S_ISSOCK(m: u32) bool {
+ return m & S_IFMT == S_IFSOCK;
+}
+
+pub fn S_IWHT(m: u32) bool {
+ return m & S_IFMT == S_IFWHT;
+}
+
+pub const HOST_NAME_MAX = 255;
+
+/// Magic value that specify the use of the current working directory
+/// to determine the target of relative file paths in the openat() and
+/// similar syscalls.
+pub const AT_FDCWD = -100;
+
+/// Check access using effective user and group ID
+pub const AT_EACCESS = 0x0100;
+
+/// Do not follow symbolic links
+pub const AT_SYMLINK_NOFOLLOW = 0x0200;
+
+/// Follow symbolic link
+pub const AT_SYMLINK_FOLLOW = 0x0400;
+
+/// Remove directory instead of file
+pub const AT_REMOVEDIR = 0x0800;
+
+pub const addrinfo = extern struct {
+ flags: i32,
+ family: i32,
+ socktype: i32,
+ protocol: i32,
+ addrlen: socklen_t,
+ canonname: ?[*:0]u8,
+ addr: ?*sockaddr,
+ next: ?*addrinfo,
+};
+
+/// Fail if not under dirfd
+pub const AT_BENEATH = 0x1000;
+
+/// dummy for IP
+pub const IPPROTO_IP = 0;
+
+/// control message protocol
+pub const IPPROTO_ICMP = 1;
+
+/// tcp
+pub const IPPROTO_TCP = 6;
+
+/// user datagram protocol
+pub const IPPROTO_UDP = 17;
+
+/// IP6 header
+pub const IPPROTO_IPV6 = 41;
+
+/// raw IP packet
+pub const IPPROTO_RAW = 255;
+
+/// IP6 hop-by-hop options
+pub const IPPROTO_HOPOPTS = 0;
+
+/// group mgmt protocol
+pub const IPPROTO_IGMP = 2;
+
+/// gateway^2 (deprecated)
+pub const IPPROTO_GGP = 3;
+
+/// IPv4 encapsulation
+pub const IPPROTO_IPV4 = 4;
+
+/// for compatibility
+pub const IPPROTO_IPIP = IPPROTO_IPV4;
+
+/// Stream protocol II
+pub const IPPROTO_ST = 7;
+
+/// exterior gateway protocol
+pub const IPPROTO_EGP = 8;
+
+/// private interior gateway
+pub const IPPROTO_PIGP = 9;
+
+/// BBN RCC Monitoring
+pub const IPPROTO_RCCMON = 10;
+
+/// network voice protocol
+pub const IPPROTO_NVPII = 11;
+
+/// pup
+pub const IPPROTO_PUP = 12;
+
+/// Argus
+pub const IPPROTO_ARGUS = 13;
+
+/// EMCON
+pub const IPPROTO_EMCON = 14;
+
+/// Cross Net Debugger
+pub const IPPROTO_XNET = 15;
+
+/// Chaos
+pub const IPPROTO_CHAOS = 16;
+
+/// Multiplexing
+pub const IPPROTO_MUX = 18;
+
+/// DCN Measurement Subsystems
+pub const IPPROTO_MEAS = 19;
+
+/// Host Monitoring
+pub const IPPROTO_HMP = 20;
+
+/// Packet Radio Measurement
+pub const IPPROTO_PRM = 21;
+
+/// xns idp
+pub const IPPROTO_IDP = 22;
+
+/// Trunk-1
+pub const IPPROTO_TRUNK1 = 23;
+
+/// Trunk-2
+pub const IPPROTO_TRUNK2 = 24;
+
+/// Leaf-1
+pub const IPPROTO_LEAF1 = 25;
+
+/// Leaf-2
+pub const IPPROTO_LEAF2 = 26;
+
+/// Reliable Data
+pub const IPPROTO_RDP = 27;
+
+/// Reliable Transaction
+pub const IPPROTO_IRTP = 28;
+
+/// tp-4 w/ class negotiation
+pub const IPPROTO_TP = 29;
+
+/// Bulk Data Transfer
+pub const IPPROTO_BLT = 30;
+
+/// Network Services
+pub const IPPROTO_NSP = 31;
+
+/// Merit Internodal
+pub const IPPROTO_INP = 32;
+
+/// Datagram Congestion Control Protocol
+pub const IPPROTO_DCCP = 33;
+
+/// Third Party Connect
+pub const IPPROTO_3PC = 34;
+
+/// InterDomain Policy Routing
+pub const IPPROTO_IDPR = 35;
+
+/// XTP
+pub const IPPROTO_XTP = 36;
+
+/// Datagram Delivery
+pub const IPPROTO_DDP = 37;
+
+/// Control Message Transport
+pub const IPPROTO_CMTP = 38;
+
+/// TP++ Transport
+pub const IPPROTO_TPXX = 39;
+
+/// IL transport protocol
+pub const IPPROTO_IL = 40;
+
+/// Source Demand Routing
+pub const IPPROTO_SDRP = 42;
+
+/// IP6 routing header
+pub const IPPROTO_ROUTING = 43;
+
+/// IP6 fragmentation header
+pub const IPPROTO_FRAGMENT = 44;
+
+/// InterDomain Routing
+pub const IPPROTO_IDRP = 45;
+
+/// resource reservation
+pub const IPPROTO_RSVP = 46;
+
+/// General Routing Encap.
+pub const IPPROTO_GRE = 47;
+
+/// Mobile Host Routing
+pub const IPPROTO_MHRP = 48;
+
+/// BHA
+pub const IPPROTO_BHA = 49;
+
+/// IP6 Encap Sec. Payload
+pub const IPPROTO_ESP = 50;
+
+/// IP6 Auth Header
+pub const IPPROTO_AH = 51;
+
+/// Integ. Net Layer Security
+pub const IPPROTO_INLSP = 52;
+
+/// IP with encryption
+pub const IPPROTO_SWIPE = 53;
+
+/// Next Hop Resolution
+pub const IPPROTO_NHRP = 54;
+
+/// IP Mobility
+pub const IPPROTO_MOBILE = 55;
+
+/// Transport Layer Security
+pub const IPPROTO_TLSP = 56;
+
+/// SKIP
+pub const IPPROTO_SKIP = 57;
+
+/// ICMP6
+pub const IPPROTO_ICMPV6 = 58;
+
+/// IP6 no next header
+pub const IPPROTO_NONE = 59;
+
+/// IP6 destination option
+pub const IPPROTO_DSTOPTS = 60;
+
+/// any host internal protocol
+pub const IPPROTO_AHIP = 61;
+
+/// CFTP
+pub const IPPROTO_CFTP = 62;
+
+/// "hello" routing protocol
+pub const IPPROTO_HELLO = 63;
+
+/// SATNET/Backroom EXPAK
+pub const IPPROTO_SATEXPAK = 64;
+
+/// Kryptolan
+pub const IPPROTO_KRYPTOLAN = 65;
+
+/// Remote Virtual Disk
+pub const IPPROTO_RVD = 66;
+
+/// Pluribus Packet Core
+pub const IPPROTO_IPPC = 67;
+
+/// Any distributed FS
+pub const IPPROTO_ADFS = 68;
+
+/// Satnet Monitoring
+pub const IPPROTO_SATMON = 69;
+
+/// VISA Protocol
+pub const IPPROTO_VISA = 70;
+
+/// Packet Core Utility
+pub const IPPROTO_IPCV = 71;
+
+/// Comp. Prot. Net. Executive
+pub const IPPROTO_CPNX = 72;
+
+/// Comp. Prot. HeartBeat
+pub const IPPROTO_CPHB = 73;
+
+/// Wang Span Network
+pub const IPPROTO_WSN = 74;
+
+/// Packet Video Protocol
+pub const IPPROTO_PVP = 75;
+
+/// BackRoom SATNET Monitoring
+pub const IPPROTO_BRSATMON = 76;
+
+/// Sun net disk proto (temp.)
+pub const IPPROTO_ND = 77;
+
+/// WIDEBAND Monitoring
+pub const IPPROTO_WBMON = 78;
+
+/// WIDEBAND EXPAK
+pub const IPPROTO_WBEXPAK = 79;
+
+/// ISO cnlp
+pub const IPPROTO_EON = 80;
+
+/// VMTP
+pub const IPPROTO_VMTP = 81;
+
+/// Secure VMTP
+pub const IPPROTO_SVMTP = 82;
+
+/// Banyon VINES
+pub const IPPROTO_VINES = 83;
+
+/// TTP
+pub const IPPROTO_TTP = 84;
+
+/// NSFNET-IGP
+pub const IPPROTO_IGP = 85;
+
+/// dissimilar gateway prot.
+pub const IPPROTO_DGP = 86;
+
+/// TCF
+pub const IPPROTO_TCF = 87;
+
+/// Cisco/GXS IGRP
+pub const IPPROTO_IGRP = 88;
+
+/// OSPFIGP
+pub const IPPROTO_OSPFIGP = 89;
+
+/// Strite RPC protocol
+pub const IPPROTO_SRPC = 90;
+
+/// Locus Address Resoloution
+pub const IPPROTO_LARP = 91;
+
+/// Multicast Transport
+pub const IPPROTO_MTP = 92;
+
+/// AX.25 Frames
+pub const IPPROTO_AX25 = 93;
+
+/// IP encapsulated in IP
+pub const IPPROTO_IPEIP = 94;
+
+/// Mobile Int.ing control
+pub const IPPROTO_MICP = 95;
+
+/// Semaphore Comm. security
+pub const IPPROTO_SCCSP = 96;
+
+/// Ethernet IP encapsulation
+pub const IPPROTO_ETHERIP = 97;
+
+/// encapsulation header
+pub const IPPROTO_ENCAP = 98;
+
+/// any private encr. scheme
+pub const IPPROTO_APES = 99;
+
+/// GMTP
+pub const IPPROTO_GMTP = 100;
+
+/// payload compression (IPComp)
+pub const IPPROTO_IPCOMP = 108;
+
+/// SCTP
+pub const IPPROTO_SCTP = 132;
+
+/// IPv6 Mobility Header
+pub const IPPROTO_MH = 135;
+
+/// UDP-Lite
+pub const IPPROTO_UDPLITE = 136;
+
+/// IP6 Host Identity Protocol
+pub const IPPROTO_HIP = 139;
+
+/// IP6 Shim6 Protocol
+pub const IPPROTO_SHIM6 = 140;
+
+/// Protocol Independent Mcast
+pub const IPPROTO_PIM = 103;
+
+/// CARP
+pub const IPPROTO_CARP = 112;
+
+/// PGM
+pub const IPPROTO_PGM = 113;
+
+/// MPLS-in-IP
+pub const IPPROTO_MPLS = 137;
+
+/// PFSYNC
+pub const IPPROTO_PFSYNC = 240;
+
+/// Reserved
+pub const IPPROTO_RESERVED_253 = 253;
+
+/// Reserved
+pub const IPPROTO_RESERVED_254 = 254;
+
+pub const rlimit_resource = extern enum(c_int) {
+ CPU = 0,
+ FSIZE = 1,
+ DATA = 2,
+ STACK = 3,
+ CORE = 4,
+ RSS = 5,
+ MEMLOCK = 6,
+ NPROC = 7,
+ NOFILE = 8,
+ SBSIZE = 9,
+ VMEM = 10,
+ AS = 10,
+ NPTS = 11,
+ SWAP = 12,
+ KQUEUES = 13,
+ UMTXP = 14,
+
+ _,
+};
+
+pub const rlim_t = i64;
+
+/// No limit
+pub const RLIM_INFINITY: rlim_t = (1 << 63) - 1;
+
+pub const RLIM_SAVED_MAX = RLIM_INFINITY;
+pub const RLIM_SAVED_CUR = RLIM_INFINITY;
+
+pub const rlimit = extern struct {
+ /// Soft limit
+ cur: rlim_t,
+ /// Hard limit
+ max: rlim_t,
+};
+
+pub const SHUT_RD = 0;
+pub const SHUT_WR = 1;
+pub const SHUT_RDWR = 2;
+
+// TODO fill out if needed
+pub const directory_which = extern enum(c_int) {
+ B_USER_SETTINGS_DIRECTORY = 0xbbe,
+
+ _,
+};
diff --git a/lib/std/os/haiku.zig b/lib/std/os/haiku.zig
new file mode 100644
index 0000000000..a713a009ad
--- /dev/null
+++ b/lib/std/os/haiku.zig
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: MIT
+// Copyright (c) 2015-2020 Zig Contributors
+// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
+// The MIT license requires this copyright notice to be included in all copies
+// and substantial portions of the software.
+const std = @import("../std.zig");
+pub usingnamespace std.c;
+pub usingnamespace @import("bits.zig");
diff --git a/lib/std/process.zig b/lib/std/process.zig
index 3529bf52cb..3ad73db420 100644
--- a/lib/std/process.zig
+++ b/lib/std/process.zig
@@ -609,7 +609,7 @@ pub const UserInfo = struct {
/// POSIX function which gets a uid from username.
pub fn getUserInfo(name: []const u8) !UserInfo {
return switch (builtin.os.tag) {
- .linux, .macos, .watchos, .tvos, .ios, .freebsd, .netbsd, .openbsd => posixGetUserInfo(name),
+ .linux, .macos, .watchos, .tvos, .ios, .freebsd, .netbsd, .openbsd, .haiku => posixGetUserInfo(name),
else => @compileError("Unsupported OS"),
};
}
@@ -777,6 +777,24 @@ pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0]
}
return paths.toOwnedSlice();
},
+ // revisit if Haiku implements dl_iterat_phdr (https://dev.haiku-os.org/ticket/15743)
+ .haiku => {
+ var paths = List.init(allocator);
+ errdefer {
+ const slice = paths.toOwnedSlice();
+ for (slice) |item| {
+ allocator.free(item);
+ }
+ allocator.free(slice);
+ }
+
+ var b = "/boot/system/runtime_loader";
+ const item = try allocator.dupeZ(u8, mem.spanZ(b));
+ errdefer allocator.free(item);
+ try paths.append(item);
+
+ return paths.toOwnedSlice();
+ },
else => @compileError("getSelfExeSharedLibPaths unimplemented for this target"),
}
}
diff --git a/lib/std/target.zig b/lib/std/target.zig
index 227d783889..7e05f35932 100644
--- a/lib/std/target.zig
+++ b/lib/std/target.zig
@@ -379,6 +379,7 @@ pub const Target = struct {
.watchos,
.dragonfly,
.openbsd,
+ .haiku,
=> true,
.linux,
@@ -390,7 +391,6 @@ pub const Target = struct {
.kfreebsd,
.lv2,
.solaris,
- .haiku,
.minix,
.rtems,
.nacl,
@@ -468,7 +468,6 @@ pub const Target = struct {
.dragonfly,
.lv2,
.solaris,
- .haiku,
.minix,
.rtems,
.nacl,
@@ -495,6 +494,7 @@ pub const Target = struct {
.kfreebsd,
.netbsd,
.hurd,
+ .haiku,
=> return .gnu,
.windows,
.uefi,
@@ -1562,6 +1562,9 @@ pub const Target = struct {
.other,
=> return result,
+ // TODO revisit when multi-arch for Haiku is available
+ .haiku => return copy(&result, "/system/runtime_loader"),
+
// TODO go over each item in this list and either move it to the above list, or
// implement the standard dynamic linker path code for it.
.ananas,
@@ -1570,7 +1573,6 @@ pub const Target = struct {
.kfreebsd,
.lv2,
.solaris,
- .haiku,
.minix,
.rtems,
.nacl,