diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-02-25 16:00:00 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-25 16:00:00 -0800 |
| commit | 7edb204edfa41e11776ac009da5a20fb1c907f5f (patch) | |
| tree | 9c6eae297ebc492c0a1a94a4d3d25fc3bcd07bd9 /lib/std | |
| parent | 297eabd4accbcae42bfe821078a79e4af06a2dde (diff) | |
| parent | 37a1d08de2ce263439713180f57741d16fb27e23 (diff) | |
| download | zig-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.zig | 62 | ||||
| -rw-r--r-- | lib/std/c/haiku.zig | 43 | ||||
| -rw-r--r-- | lib/std/crypto/tlcsprng.zig | 1 | ||||
| -rw-r--r-- | lib/std/debug.zig | 17 | ||||
| -rw-r--r-- | lib/std/fs.zig | 86 | ||||
| -rw-r--r-- | lib/std/fs/get_app_data_dir.zig | 12 | ||||
| -rw-r--r-- | lib/std/os.zig | 32 | ||||
| -rw-r--r-- | lib/std/os/bits.zig | 1 | ||||
| -rw-r--r-- | lib/std/os/bits/haiku.zig | 1450 | ||||
| -rw-r--r-- | lib/std/os/haiku.zig | 8 | ||||
| -rw-r--r-- | lib/std/process.zig | 20 | ||||
| -rw-r--r-- | lib/std/target.zig | 8 |
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, |
