From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: sin-ack <sin-ack@users.noreply.github.com>
Date: Sun, 30 Oct 2022 19:30:50 +0000
Subject: [PATCH] Implement Minerva support in std
---
zig/lib/std/Thread.zig | 2 +-
zig/lib/std/c.zig | 1 +
zig/lib/std/c/minerva.zig | 709 +++++++++++++++++++++++++++
zig/lib/std/c/minerva/constants.zig | 6 +
zig/lib/std/debug.zig | 5 +-
zig/lib/std/fs.zig | 79 ++-
zig/lib/std/fs/get_app_data_dir.zig | 2 +-
zig/lib/std/os.zig | 4 +-
zig/lib/std/target.zig | 1 +
9 files changed, 801 insertions(+), 8 deletions(-)
create mode 100644 zig/lib/std/c/minerva.zig
create mode 100644 zig/lib/std/c/minerva/constants.zig
diff --git a/zig/lib/std/Thread.zig b/zig/lib/std/Thread.zig
index 74f8e98df4bf212830933c150d6d7f0242007bda..fe8fc416fcb0c1ec4ec414c9f01e4d6639c1d87b 100644
--- a/zig/lib/std/Thread.zig
+++ b/zig/lib/std/Thread.zig
@@ -636,7 +636,7 @@ const PosixThreadImpl = struct {
};
return @as(usize, @intCast(count));
},
- .solaris => {
+ .solaris, .minerva => {
// The "proper" way to get the cpu count would be to query
// /dev/kstat via ioctls, and traverse a linked list for each
// cpu.
diff --git a/zig/lib/std/c.zig b/zig/lib/std/c.zig
index 66875eadd0347c930632254901d37f1b4f4fabcc..c78c8aa3d0daa67279a17c359870ac3052e43bb9 100644
--- a/zig/lib/std/c.zig
+++ b/zig/lib/std/c.zig
@@ -54,6 +54,7 @@ pub usingnamespace switch (builtin.os.tag) {
.minix => @import("c/minix.zig"),
.emscripten => @import("c/emscripten.zig"),
.wasi => @import("c/wasi.zig"),
+ .minerva => @import("c/minerva.zig"),
else => struct {},
};
diff --git a/zig/lib/std/c/minerva.zig b/zig/lib/std/c/minerva.zig
new file mode 100644
index 0000000000000000000000000000000000000000..d85d44ee1f0c71706f6c17f15183ece261a42e28
--- /dev/null
+++ b/zig/lib/std/c/minerva.zig
@@ -0,0 +1,709 @@
+const builtin = @import("builtin");
+pub const std = @import("std");
+pub const MinervaConstants = @import("minerva/constants.zig");
+
+const native_arch = builtin.cpu.arch;
+
+pub const fd_t = c_int;
+pub const dev_t = u64;
+pub const ino_t = u64;
+pub const off_t = i64;
+pub const nlink_t = u64;
+
+// see Kernel/API/POSIX/sys/socket.h
+pub const sa_family_t = u16;
+
+// see Kernel/API/POSIX/sys/types.h
+pub const socklen_t = u32;
+
+// see Userland/Libraries/LibC/netdb.h
+pub const addrinfo = struct {
+ flags: u16,
+ family: sa_family_t,
+ socktype: u16,
+ protocol: u16,
+ addrlen: socklen_t,
+ addr: ?*sockaddr,
+ canonname: ?[*:0]const u8,
+ next: ?*addrinfo,
+};
+
+// see Kernel/API/POSIX/sys/socket.h
+pub const AF = struct {
+ pub const MASK = 0xff;
+ pub const UNSPEC = 0;
+ pub const LOCAL = 1;
+ pub const UNIX = LOCAL;
+ pub const INET = 2;
+ pub const INET6 = 3;
+ pub const MAX = 4;
+};
+
+// see Userland/Libraries/LibC/netdb.h
+pub const AI = struct {
+ pub const PASSIVE = 1;
+ pub const CANONNAME = 2;
+ pub const NUMERICHOST = 4;
+ pub const NUMERICSERV = 8;
+ pub const V4MAPPED = 16;
+ pub const ALL = 32;
+ pub const ADDRCONFIG = 64;
+};
+
+pub const E = enum(i32) {
+ SUCCESS = MinervaConstants.ESUCCESS,
+ PERM = MinervaConstants.EPERM,
+ NOENT = MinervaConstants.ENOENT,
+ SRCH = MinervaConstants.ESRCH,
+ INTR = MinervaConstants.EINTR,
+ IO = MinervaConstants.EIO,
+ NXIO = MinervaConstants.ENXIO,
+ @"2BIG" = MinervaConstants.E2BIG,
+ NOEXEC = MinervaConstants.ENOEXEC,
+ BADF = MinervaConstants.EBADF,
+ CHILD = MinervaConstants.ECHILD,
+ AGAIN = MinervaConstants.EAGAIN,
+ NOMEM = MinervaConstants.ENOMEM,
+ ACCES = MinervaConstants.EACCES,
+ FAULT = MinervaConstants.EFAULT,
+ NOTBLK = MinervaConstants.ENOTBLK,
+ BUSY = MinervaConstants.EBUSY,
+ EXIST = MinervaConstants.EEXIST,
+ XDEV = MinervaConstants.EXDEV,
+ NODEV = MinervaConstants.ENODEV,
+ NOTDIR = MinervaConstants.ENOTDIR,
+ ISDIR = MinervaConstants.EISDIR,
+ INVAL = MinervaConstants.EINVAL,
+ NFILE = MinervaConstants.ENFILE,
+ MFILE = MinervaConstants.EMFILE,
+ NOTTY = MinervaConstants.ENOTTY,
+ TXTBSY = MinervaConstants.ETXTBSY,
+ FBIG = MinervaConstants.EFBIG,
+ NOSPC = MinervaConstants.ENOSPC,
+ SPIPE = MinervaConstants.ESPIPE,
+ ROFS = MinervaConstants.EROFS,
+ MLINK = MinervaConstants.EMLINK,
+ PIPE = MinervaConstants.EPIPE,
+ RANGE = MinervaConstants.ERANGE,
+ NAMETOOLONG = MinervaConstants.ENAMETOOLONG,
+ LOOP = MinervaConstants.ELOOP,
+ OVERFLOW = MinervaConstants.EOVERFLOW,
+ OPNOTSUPP = MinervaConstants.EOPNOTSUPP,
+ NOSYS = MinervaConstants.ENOSYS,
+ NOTIMPL = MinervaConstants.ENOTIMPL,
+ AFNOSUPPORT = MinervaConstants.EAFNOSUPPORT,
+ NOTSOCK = MinervaConstants.ENOTSOCK,
+ ADDRINUSE = MinervaConstants.EADDRINUSE,
+ NOTEMPTY = MinervaConstants.ENOTEMPTY,
+ DOM = MinervaConstants.EDOM,
+ CONNREFUSED = MinervaConstants.ECONNREFUSED,
+ HOSTDOWN = MinervaConstants.EHOSTDOWN,
+ ADDRNOTAVAIL = MinervaConstants.EADDRNOTAVAIL,
+ ISCONN = MinervaConstants.EISCONN,
+ CONNABORTED = MinervaConstants.ECONNABORTED,
+ ALREADY = MinervaConstants.EALREADY,
+ CONNRESET = MinervaConstants.ECONNRESET,
+ DESTADDRREQ = MinervaConstants.EDESTADDRREQ,
+ HOSTUNREACH = MinervaConstants.EHOSTUNREACH,
+ ILSEQ = MinervaConstants.EILSEQ,
+ MSGSIZE = MinervaConstants.EMSGSIZE,
+ NETDOWN = MinervaConstants.ENETDOWN,
+ NETUNREACH = MinervaConstants.ENETUNREACH,
+ NETRESET = MinervaConstants.ENETRESET,
+ NOBUFS = MinervaConstants.ENOBUFS,
+ NOLCK = MinervaConstants.ENOLCK,
+ NOMSG = MinervaConstants.ENOMSG,
+ NOPROTOOPT = MinervaConstants.ENOPROTOOPT,
+ NOTCONN = MinervaConstants.ENOTCONN,
+ SHUTDOWN = MinervaConstants.ESHUTDOWN,
+ TOOMANYREFS = MinervaConstants.ETOOMANYREFS,
+ SOCKTNOSUPPORT = MinervaConstants.ESOCKTNOSUPPORT,
+ PROTONOSUPPORT = MinervaConstants.EPROTONOSUPPORT,
+ DEADLK = MinervaConstants.EDEADLK,
+ TIMEDOUT = MinervaConstants.ETIMEDOUT,
+ PROTOTYPE = MinervaConstants.EPROTOTYPE,
+ INPROGRESS = MinervaConstants.EINPROGRESS,
+ NOTHREAD = MinervaConstants.ENOTHREAD,
+ PROTO = MinervaConstants.EPROTO,
+ NOTSUP = MinervaConstants.ENOTSUP,
+ PFNOSUPPORT = MinervaConstants.EPFNOSUPPORT,
+ DIRINTOSELF = MinervaConstants.EDIRINTOSELF,
+ DQUOT = MinervaConstants.EDQUOT,
+ NOTRECOVERABLE = MinervaConstants.ENOTRECOVERABLE,
+ CANCELED = MinervaConstants.ECANCELED,
+ PROMISEVIOLATION = MinervaConstants.EPROMISEVIOLATION,
+ STALE = MinervaConstants.ESTALE,
+};
+
+// see Userland/Libraries/LibC/netdb.h
+pub const EAI = enum(c_int) {
+ ADDRFAMILY = 1,
+ AGAIN = 2,
+ BADFLAGS = 3,
+ FAIL = 4,
+ FAMILY = 5,
+ MEMORY = 6,
+ NODATA = 7,
+ NONAME = 8,
+ SERVICE = 9,
+ SOCKTYPE = 10,
+ SYSTEM = 11,
+ OVERFLOW = 12,
+ _,
+};
+
+// see Kernel/API/POSIX/sys/limits.h
+pub const HOST_NAME_MAX = MinervaConstants.HOST_NAME_MAX;
+pub const NAME_MAX = MinervaConstants.NAME_MAX;
+pub const PATH_MAX = MinervaConstants.PATH_MAX;
+
+pub const time_t = i64;
+pub const timespec = extern struct {
+ tv_sec: time_t,
+ tv_nsec: c_long,
+};
+
+pub const mode_t = u16;
+
+pub const AT = struct {
+ pub const FDCWD = MinervaConstants.AT_FDCWD;
+ pub const SYMLINK_NOFOLLOW = MinervaConstants.AT_SYMLINK_NOFOLLOW;
+ pub const REMOVEDIR = MinervaConstants.AT_REMOVEDIR;
+};
+
+pub const _errno = struct {
+ extern "c" fn __errno_location() *c_int;
+}.__errno_location;
+
+pub const pthread_attr_t = *anyopaque;
+
+pub const LOCK = struct {
+ pub const SH = MinervaConstants.LOCK_SH;
+ pub const EX = MinervaConstants.LOCK_EX;
+ pub const UN = MinervaConstants.LOCK_UN;
+ pub const NB = MinervaConstants.LOCK_NB;
+};
+
+pub const STDIN_FILENO = MinervaConstants.STDIN_FILENO;
+pub const STDOUT_FILENO = MinervaConstants.STDOUT_FILENO;
+pub const STDERR_FILENO = MinervaConstants.STDERR_FILENO;
+
+pub const F = struct {
+ pub const DUPFD = MinervaConstants.F_DUPFD;
+ pub const GETFD = MinervaConstants.F_GETFD;
+ pub const SETFD = MinervaConstants.F_SETFD;
+ pub const GETFL = MinervaConstants.F_GETFL;
+ pub const SETFL = MinervaConstants.F_SETFL;
+ pub const ISTTY = MinervaConstants.F_ISTTY;
+ pub const GETLK = MinervaConstants.F_GETLK;
+ pub const SETLK = MinervaConstants.F_SETLK;
+ pub const SETLKW = MinervaConstants.F_SETLKW;
+};
+
+pub const FD_CLOEXEC = MinervaConstants.FD_CLOEXEC;
+
+pub const O = struct {
+ pub const RDONLY = MinervaConstants.O_RDONLY;
+ pub const WRONLY = MinervaConstants.O_WRONLY;
+ pub const RDWR = MinervaConstants.O_RDWR;
+ pub const ACCMODE = MinervaConstants.O_ACCMODE;
+ pub const EXEC = MinervaConstants.O_EXEC;
+ pub const CREAT = MinervaConstants.O_CREAT;
+ pub const EXCL = MinervaConstants.O_EXCL;
+ pub const NOCTTY = MinervaConstants.O_NOCTTY;
+ pub const TRUNC = MinervaConstants.O_TRUNC;
+ pub const APPEND = MinervaConstants.O_APPEND;
+ pub const NONBLOCK = MinervaConstants.O_NONBLOCK;
+ pub const DIRECTORY = MinervaConstants.O_DIRECTORY;
+ pub const NOFOLLOW = MinervaConstants.O_NOFOLLOW;
+ pub const CLOEXEC = MinervaConstants.O_CLOEXEC;
+ pub const DIRECT = MinervaConstants.O_DIRECT;
+ pub const SYNC = MinervaConstants.O_SYNC;
+};
+
+pub const R_OK = MinervaConstants.R_OK;
+pub const W_OK = MinervaConstants.W_OK;
+pub const X_OK = MinervaConstants.X_OK;
+pub const F_OK = MinervaConstants.F_OK;
+
+pub const CLOCK = struct {
+ pub const REALTIME = MinervaConstants.CLOCK_REALTIME;
+ pub const MONOTONIC = MinervaConstants.CLOCK_MONOTONIC;
+ pub const MONOTONIC_RAW = MinervaConstants.CLOCK_MONOTONIC_RAW;
+ pub const REALTIME_COARSE = MinervaConstants.CLOCK_REALTIME_COARSE;
+ pub const MONOTONIC_COARSE = MinervaConstants.CLOCK_MONOTONIC_COARSE;
+};
+
+pub const IOV_MAX = MinervaConstants.IOV_MAX;
+
+// see Kernel/API/POSIX/sys/socket.h
+pub const IPPROTO = struct {
+ pub const IP = 0;
+ pub const ICMP = 1;
+ pub const IGMP = 2;
+ pub const IPIP = 4;
+ pub const TCP = 6;
+ pub const UDP = 17;
+ pub const IPV6 = 41;
+ pub const ESP = 50;
+ pub const AH = 51;
+ pub const ICMPV6 = 58;
+ pub const RAW = 255;
+};
+
+// see Kernel/API/POSIX/types.h
+pub const pthread_mutex_t = extern struct {
+ lock: u32 = 0,
+ owner: ?std.c.pthread_t = null,
+ level: c_int = 0,
+ type: c_int = 0, // __PTHREAD_MUTEX_NORMAL
+};
+
+pub const pthread_cond_t = extern struct {
+ mutex: ?*pthread_mutex_t = null,
+ value: u32 = 0,
+ clockid: c_int = CLOCK.MONOTONIC_COARSE, // clockid_t
+};
+
+pub const pthread_rwlock_t = extern struct {
+ ptr: u64 = 0
+};
+
+pub const PTHREAD_STACK_MIN = MinervaConstants.PTHREAD_STACK_MIN;
+
+pub const uid_t = u32;
+pub const gid_t = u32;
+
+pub const blksize_t = u64;
+pub const blkcnt_t = u64;
+
+pub const Stat = extern struct {
+ dev: dev_t,
+ ino: ino_t,
+ mode: mode_t,
+ nlink: nlink_t,
+ uid: uid_t,
+ gid: gid_t,
+ rdev: dev_t,
+ size: off_t,
+ blksize: blksize_t,
+ blocks: blkcnt_t,
+ atim: timespec,
+ mtim: timespec,
+ ctim: timespec,
+
+ 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 const pid_t = c_int;
+
+pub const S = struct {
+ pub const IFMT = MinervaConstants.S_IFMT;
+ pub const IFDIR = MinervaConstants.S_IFDIR;
+ pub const IFCHR = MinervaConstants.S_IFCHR;
+ pub const IFBLK = MinervaConstants.S_IFBLK;
+ pub const IFREG = MinervaConstants.S_IFREG;
+ pub const IFIFO = MinervaConstants.S_IFIFO;
+ pub const IFLNK = MinervaConstants.S_IFLNK;
+ pub const IFSOCK = MinervaConstants.S_IFSOCK;
+
+ pub const ISUID = MinervaConstants.S_ISUID;
+ pub const ISGID = MinervaConstants.S_ISGID;
+ pub const ISVTX = MinervaConstants.S_ISVTX;
+ pub const IRUSR = MinervaConstants.S_IRUSR;
+ pub const IWUSR = MinervaConstants.S_IWUSR;
+ pub const IXUSR = MinervaConstants.S_IXUSR;
+ pub const IREAD = MinervaConstants.S_IREAD;
+ pub const IWRITE = MinervaConstants.S_IWRITE;
+ pub const IEXEC = MinervaConstants.S_IEXEC;
+ pub const IRGRP = MinervaConstants.S_IRGRP;
+ pub const IWGRP = MinervaConstants.S_IWGRP;
+ pub const IXGRP = MinervaConstants.S_IXGRP;
+ pub const IROTH = MinervaConstants.S_IROTH;
+ pub const IWOTH = MinervaConstants.S_IWOTH;
+ pub const IXOTH = MinervaConstants.S_IXOTH;
+
+ pub const IRWXU = MinervaConstants.S_IRWXU;
+
+ pub const IRWXG = MinervaConstants.S_IRWXG;
+ pub const IRWXO = MinervaConstants.S_IRWXO;
+
+ pub fn ISREG(m: u32) bool {
+ return m & IFMT == IFREG;
+ }
+
+ pub fn ISLNK(m: u32) bool {
+ return m & IFMT == IFLNK;
+ }
+
+ pub fn ISBLK(m: u32) bool {
+ return m & IFMT == IFBLK;
+ }
+
+ pub fn ISDIR(m: u32) bool {
+ return m & IFMT == IFDIR;
+ }
+
+ pub fn ISCHR(m: u32) bool {
+ return m & IFMT == IFCHR;
+ }
+
+ pub fn ISFIFO(m: u32) bool {
+ return m & IFMT == IFIFO;
+ }
+
+ pub fn ISSOCK(m: u32) bool {
+ return m & IFMT == IFSOCK;
+ }
+};
+
+pub const SEEK = struct {
+ pub const SET = MinervaConstants.SEEK_SET;
+ pub const CUR = MinervaConstants.SEEK_CUR;
+ pub const END = MinervaConstants.SEEK_END;
+};
+
+// see Kernel/API/POSIX/signal_numbers.h
+pub const SIG = struct {
+ pub const ABRT = MinervaConstants.SIGABRT;
+ pub const ALRM = MinervaConstants.SIGALRM;
+ pub const BUS = MinervaConstants.SIGBUS;
+ pub const CANCEL = MinervaConstants.SIGCANCEL;
+ pub const CHLD = MinervaConstants.SIGCHLD;
+ pub const CONT = MinervaConstants.SIGCONT;
+ pub const FPE = MinervaConstants.SIGFPE;
+ pub const HUP = MinervaConstants.SIGHUP;
+ pub const ILL = MinervaConstants.SIGILL;
+ pub const INFO = MinervaConstants.SIGINFO;
+ pub const INT = MinervaConstants.SIGINT;
+ pub const INVAL = MinervaConstants.SIGINVAL;
+ pub const IO = MinervaConstants.SIGIO;
+ pub const KILL = MinervaConstants.SIGKILL;
+ pub const PIPE = MinervaConstants.SIGPIPE;
+ pub const PROF = MinervaConstants.SIGPROF;
+ pub const QUIT = MinervaConstants.SIGQUIT;
+ pub const SEGV = MinervaConstants.SIGSEGV;
+ pub const STKFLT = MinervaConstants.SIGSTKFLT;
+ pub const STOP = MinervaConstants.SIGSTOP;
+ pub const SYS = MinervaConstants.SIGSYS;
+ pub const TERM = MinervaConstants.SIGTERM;
+ pub const TRAP = MinervaConstants.SIGTRAP;
+ pub const TSTP = MinervaConstants.SIGTSTP;
+ pub const TTIN = MinervaConstants.SIGTTIN;
+ pub const TTOU = MinervaConstants.SIGTTOU;
+ pub const URG = MinervaConstants.SIGURG;
+ pub const USR1 = MinervaConstants.SIGUSR1;
+ pub const USR2 = MinervaConstants.SIGUSR2;
+ pub const VTALRM = MinervaConstants.SIGVTALRM;
+ pub const WINCH = MinervaConstants.SIGWINCH;
+ pub const XCPU = MinervaConstants.SIGXCPU;
+ pub const XFSZ = MinervaConstants.SIGXFSZ;
+
+ // see Kernel/API/POSIX/signal.h
+ pub const ERR = @as(?Sigaction.handler_fn, @ptrFromInt(-1));
+ pub const DFL = @as(?Sigaction.handler_fn, @ptrFromInt(0));
+ pub const IGN = @as(?Sigaction.handler_fn, @ptrFromInt(1));
+};
+
+pub const sigval = extern union {
+ int: i32,
+ ptr: *anyopaque,
+};
+
+pub const siginfo_t = extern struct {
+ signo: c_int,
+ code: c_int,
+ errno: c_int,
+ pid: pid_t,
+ uid: uid_t,
+ addr: ?*const anyopaque,
+ status: c_int,
+ band: c_int,
+ value: sigval,
+};
+
+pub const sigset_t = u32;
+pub const empty_sigset: sigset_t = 0;
+
+pub const Sigaction = extern struct {
+ pub const handler_fn = *const fn (c_int) align(1) callconv(.C) void;
+ pub const sigaction_fn = *const fn (c_int, *const siginfo_t, ?*const anyopaque) callconv(.C) void;
+
+ handler: extern union {
+ handler: ?handler_fn,
+ sigaction: ?sigaction_fn,
+ },
+ mask: sigset_t,
+ flags: c_uint,
+};
+
+pub const SO = struct {
+ pub const ACCEPTCONN = MinervaConstants.SO_ACCEPTCONN;
+ pub const BINDTODEVICE = MinervaConstants.SO_BINDTODEVICE;
+ pub const BROADCAST = MinervaConstants.SO_BROADCAST;
+ pub const DEBUG = MinervaConstants.SO_DEBUG;
+ pub const DONTROUTE = MinervaConstants.SO_DONTROUTE;
+ pub const ERROR = MinervaConstants.SO_ERROR;
+ pub const KEEPALIVE = MinervaConstants.SO_KEEPALIVE;
+ pub const LINGER = MinervaConstants.SO_LINGER;
+ pub const OOBINLINE = MinervaConstants.SO_OOBINLINE;
+ pub const PEERCRED = MinervaConstants.SO_PEERCRED;
+ pub const RCVBUF = MinervaConstants.SO_RCVBUF;
+ pub const RCVLOWAT = MinervaConstants.SO_RCVLOWAT;
+ pub const RCVTIMEO = MinervaConstants.SO_RCVTIMEO;
+ pub const REUSEADDR = MinervaConstants.SO_REUSEADDR;
+ pub const SNDBUF = MinervaConstants.SO_SNDBUF;
+ pub const SNDLOWAT = MinervaConstants.SO_SNDLOWAT;
+ pub const SNDTIMEO = MinervaConstants.SO_SNDTIMEO;
+ pub const TIMESTAMP = MinervaConstants.SO_TIMESTAMP;
+ pub const TYPE = MinervaConstants.SO_TYPE;
+};
+
+pub const SOL = struct {
+ pub const SOCKET = MinervaConstants.SOL_SOCKET;
+};
+
+// see Kernel/API/POSIX/netinet/in.h
+pub const in_port_t = u16;
+
+pub const in_addr = u32;
+pub const in6_addr = [16]u8;
+
+// see Kernel/API/POSIX/sys/socket.h
+pub const sockaddr = extern struct {
+ /// address family
+ family: sa_family_t,
+ /// actually longer; address value
+ data: [14]u8,
+
+ // see Kernel/API/POSIX/netinet/in.h
+ pub const in = extern struct {
+ family: sa_family_t = AF.INET,
+ port: in_port_t,
+ addr: in_addr,
+ zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
+ };
+
+ pub const in6 = extern struct {
+ family: sa_family_t = AF.INET6,
+ port: in_port_t,
+ flowinfo: u32,
+ addr: in6_addr,
+ scope_id: u32,
+ };
+
+ // see Kernel/API/POSIX/sys/un.h
+ /// Definitions for UNIX IPC domain.
+ pub const un = extern struct {
+ family: sa_family_t = AF.LOCAL,
+
+ /// path name
+ path: [106]u8,
+ };
+};
+
+pub const POLL = struct {
+ pub const IN = MinervaConstants.POLLIN;
+ pub const RDNORM = MinervaConstants.POLLRDNORM;
+ pub const PRI = MinervaConstants.POLLPRI;
+ pub const OUT = MinervaConstants.POLLOUT;
+ pub const WRNORM = MinervaConstants.POLLWRNORM;
+ pub const ERR = MinervaConstants.POLLERR;
+ pub const HUP = MinervaConstants.POLLHUP;
+ pub const NVAL = MinervaConstants.POLLNVAL;
+ pub const WRBAND = MinervaConstants.POLLWRBAND;
+ pub const RDHUP = MinervaConstants.POLLRDHUP;
+};
+
+// see Kernel/API/POSIX/signal.h
+pub const SA = struct {
+ pub const NOCLDSTOP = MinervaConstants.SA_NOCLDSTOP;
+ pub const NOCLDWAIT = MinervaConstants.SA_NOCLDWAIT;
+ pub const SIGINFO = MinervaConstants.SA_SIGINFO;
+ pub const RESTART = MinervaConstants.SA_RESTART;
+ pub const RESETHAND = MinervaConstants.SA_RESETHAND;
+ pub const ONSTACK = MinervaConstants.SA_ONSTACK;
+ pub const NODEFER = MinervaConstants.SA_NODEFER;
+
+ // see Toolchain/Tarballs/gcc-13.1.0/libsanitizer/sanitizer_common/sanitizer_linux.cpp
+ pub const RESTORER = 0x04000000;
+};
+
+//see Kernel/API/POSIX/sys/socket.h
+pub const SHUT = struct {
+ pub const RD = MinervaConstants.SHUT_RD;
+ pub const WR = MinervaConstants.SHUT_WR;
+ pub const RDWR = MinervaConstants.SHUT_RDWR;
+};
+
+pub const SOCK = struct {
+ pub const TYPE_MASK = 0xff;
+ pub const STREAM = 1;
+ pub const DGRAM = 2;
+ pub const RAW = 3;
+ pub const RDM = 4;
+ pub const SEQPACKET = 5;
+ pub const NONBLOCK = 2048;
+ pub const CLOEXEC = 524288;
+};
+
+pub const pollfd = struct {
+ fd: c_int,
+ events: c_short,
+ revents: c_short,
+};
+
+pub const nfds_t = c_uint;
+
+// see Userland/Libraries/LibC/signal.h
+pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
+
+// see Kernel/API/POSIX/signal.h
+pub const stack_t = struct {
+ sp: *anyopaque,
+ flags: c_int,
+ size: usize
+};
+
+pub const mcontext_t = switch (native_arch) {
+ .x86_64 =>
+ // see Kernel/Arch/x86_64/mcontext.h
+ struct {
+ rax: u64,
+ rcx: u64,
+ rdx: u64,
+ rbx: u64,
+ rsp: u64,
+ rbp: u64,
+ rsi: u64,
+ rdi: u64,
+ rip: u64,
+ r8: u64,
+ r9: u64,
+ r10: u64,
+ r11: u64,
+ r12: u64,
+ r13: u64,
+ r14: u64,
+ r15: u64,
+ rflags: u64,
+ cs: u32,
+ ss: u32,
+ ds: u32,
+ es: u32,
+ fs: u32,
+ gs: u32
+ },
+ .aarch64 =>
+ // see Kernel/Arch/aarch64/mcontext.h
+ struct {
+ x: [31]u64,
+ sp: u64,
+ pc: u64
+ },
+ else => @compileError("Arch {native_arch} not implemented for minerva")
+};
+
+// see Kernel/API/POSIX/ucontext.h
+pub const ucontext_t = struct {
+ uc_link: *ucontext_t,
+ uc_sigmask: sigset_t,
+ uc_stack: stack_t,
+ uc_mcontext: mcontext_t
+};
+
+pub const W = struct {
+ pub const NOHANG = MinervaConstants.WNOHANG;
+ pub const UNTRACED = MinervaConstants.WUNTRACED;
+ pub const STOPPED = MinervaConstants.WSTOPPED;
+ pub const EXITED = MinervaConstants.WEXITED;
+ pub const CONTINUED = MinervaConstants.WCONTINUED;
+ pub const NOWAIT = MinervaConstants.WNOWAIT;
+
+ pub fn EXITSTATUS(s: u32) u8 {
+ return @intCast((s & 0xff00) >> 8);
+ }
+
+ pub fn STOPSIG(s: u32) u32 {
+ return EXITSTATUS(s);
+ }
+
+ pub fn TERMSIG(s: u32) u32 {
+ return s & 0x7f;
+ }
+
+ pub fn IFEXITED(s: u32) bool {
+ return TERMSIG(s) == 0;
+ }
+
+ pub fn IFSTOPPED(s: u32) bool {
+ return (s & 0xff) == 0x7f;
+ }
+
+ pub fn IFSIGNALED(s: u32) bool {
+ return (@as(u8, @intCast((s & 0x7f) + 1)) >> 1) > 0;
+ }
+
+ pub fn IFCONTINUED(s: u32) bool {
+ return s == 0xffff;
+ }
+};
+
+pub const dirent = extern struct {
+ d_ino: ino_t,
+ d_off: off_t,
+ d_reclen: c_ushort,
+ d_type: u8,
+ d_name: [256]u8,
+};
+pub extern "c" fn readdir_r(dir: *std.c.DIR, entry: *dirent, result: *?*dirent) i32;
+
+pub const PROT = struct {
+ pub const READ = MinervaConstants.PROT_READ;
+ pub const WRITE = MinervaConstants.PROT_WRITE;
+ pub const EXEC = MinervaConstants.PROT_EXEC;
+ pub const NONE = MinervaConstants.PROT_NONE;
+};
+
+pub const MAP = struct {
+ pub const FILE = MinervaConstants.MAP_FILE;
+ pub const SHARED = MinervaConstants.MAP_SHARED;
+ pub const PRIVATE = MinervaConstants.MAP_PRIVATE;
+ pub const FIXED = MinervaConstants.MAP_FIXED;
+ pub const ANONYMOUS = MinervaConstants.MAP_ANONYMOUS;
+ pub const ANON = MinervaConstants.MAP_ANON;
+ pub const STACK = MinervaConstants.MAP_STACK;
+ pub const NORESERVE = MinervaConstants.MAP_NORESERVE;
+ pub const RANDOMIZED = MinervaConstants.MAP_RANDOMIZED;
+ pub const PURGEABLE = MinervaConstants.MAP_PURGEABLE;
+ pub const FIXED_NOREPLACE = MinervaConstants.MAP_FIXED_NOREPLACE;
+ pub const FAILED: *anyopaque = @ptrFromInt(@as(usize, @bitCast(@as(isize, -1))));
+};
+
+pub const MSF = struct {
+ pub const SYNC = MinervaConstants.MS_SYNC;
+ pub const ASYNC = MinervaConstants.MS_ASYNC;
+ pub const INVALIDATE = MinervaConstants.MS_INVALIDATE;
+};
+
+pub extern "c" fn sysconf(sc: c_int) c_long;
+pub const _SC = struct {
+ pub const NPROCESSORS_ONLN = MinervaConstants._SC_NPROCESSORS_ONLN;
+};
+
+pub const dl_phdr_info = extern struct {
+ dlpi_addr: std.elf.Addr,
+ dlpi_name: ?[*:0]const u8,
+ dlpi_phdr: [*]std.elf.Phdr,
+ dlpi_phnum: std.elf.Half,
+};
+pub const dl_iterate_phdr_callback = *const fn (info: *dl_phdr_info, size: usize, data: ?*anyopaque) callconv(.C) c_int;
+pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*anyopaque) c_int;
diff --git a/zig/lib/std/c/minerva/constants.zig b/zig/lib/std/c/minerva/constants.zig
new file mode 100644
index 0000000000000000000000000000000000000000..94d7b1c091f7affb5c968738a8719cbbe526650b
--- /dev/null
+++ b/zig/lib/std/c/minerva/constants.zig
@@ -0,0 +1,6 @@
+comptime {
+ @compileError(
+ "A Zig compilation targeting Minerva can only be done by installing the Minerva Zig port. " ++
+ "This file is replaced by the actual POSIX constants during the port build process.",
+ );
+}
diff --git a/zig/lib/std/debug.zig b/zig/lib/std/debug.zig
index 6de21ddd1be833db60a8460cfe15ca6cd36fb90a..ff8465975624ec09453f62824ee5d75bc8d0be4a 100644
--- a/zig/lib/std/debug.zig
+++ b/zig/lib/std/debug.zig
@@ -167,7 +167,7 @@ pub fn relocateContext(context: *ThreadContext) void {
};
}
-pub const have_getcontext = @hasDecl(os.system, "getcontext") and
+pub const have_getcontext = @hasDecl(os.system, "getcontext") and builtin.os.tag != .minerva and
builtin.os.tag != .openbsd and
(builtin.os.tag != .linux or switch (builtin.cpu.arch) {
.x86,
@@ -984,6 +984,7 @@ pub fn openSelfDebugInfo(allocator: mem.Allocator) OpenSelfDebugInfoError!DebugI
.dragonfly,
.openbsd,
.macos,
+ .minerva,
.solaris,
.windows,
=> return try DebugInfo.init(allocator),
@@ -2223,7 +2224,7 @@ pub const ModuleDebugInfo = switch (native_os) {
};
}
},
- .linux, .netbsd, .freebsd, .dragonfly, .openbsd, .haiku, .solaris => struct {
+ .linux, .netbsd, .freebsd, .dragonfly, .openbsd, .haiku, .solaris, .minerva => struct {
base_address: usize,
dwarf: DW.DwarfInfo,
mapped_memory: []align(mem.page_size) const u8,
diff --git a/zig/lib/std/fs.zig b/zig/lib/std/fs.zig
index f01bcb4f22c86a7a237fb43fa219ba6071c646d3..8beea7604a3965e322706e329476609a8ff198ac 100644
--- a/zig/lib/std/fs.zig
+++ b/zig/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, .openbsd, .netbsd, .dragonfly, .haiku, .solaris, .plan9 => os.PATH_MAX,
+ .linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .haiku, .solaris, .plan9, .minerva => 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.
@@ -59,7 +59,7 @@ pub const MAX_PATH_BYTES = switch (builtin.os.tag) {
/// (depending on the platform) this assumption may not hold for every configuration.
/// The byte count does not include a null sentinel byte.
pub const MAX_NAME_BYTES = switch (builtin.os.tag) {
- .linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly => os.NAME_MAX,
+ .linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .minerva => os.NAME_MAX,
// Haiku's NAME_MAX includes the null terminator, so subtract one.
.haiku => os.NAME_MAX - 1,
.solaris => os.system.MAXNAMLEN,
@@ -528,6 +528,74 @@ pub const IterableDir = struct {
self.first_iter = true;
}
},
+ .minerva => struct {
+ dir: Dir,
+ dir_ptr: *os.system.DIR,
+
+ const Self = @This();
+
+ pub const Error = IteratorError;
+
+ pub fn next(self: *Self) Error!?Entry {
+ const errno_location = os.system._errno();
+ start_over: while (true) {
+ // HACK: readdir_r currently doesn't work properly on
+ // Minerva. Until it does, we need to rely on
+ // readdir which has legacy errno behavior.
+ const saved_errno = errno_location.*;
+ errno_location.* = 0;
+ const entry = os.system.readdir(self.dir_ptr);
+ if (entry == null) {
+ if (errno_location.* != 0) {
+ switch (os.errno(-1)) {
+ .OVERFLOW => unreachable,
+ .BADF => unreachable,
+ .NOENT => unreachable,
+ else => |err| return os.unexpectedErrno(err),
+ }
+ }
+
+ // No error, just end of directory.
+ errno_location.* = saved_errno;
+ return null;
+ }
+
+ const name = mem.sliceTo(@as([*:0]u8, @ptrCast(&entry.?.d_name)), 0);
+ if (mem.eql(u8, name, ".") or mem.eql(u8, name, ".."))
+ continue :start_over;
+
+ const stat_info = os.fstatat(
+ self.dir.fd,
+ name,
+ os.AT.SYMLINK_NOFOLLOW,
+ ) catch |err| switch (err) {
+ error.NameTooLong => unreachable,
+ error.SymLinkLoop => unreachable,
+ error.FileNotFound => unreachable, // lost the race
+ else => |e| return e,
+ };
+ const entry_kind: Entry.Kind = switch (stat_info.mode & os.S.IFMT) {
+ os.S.IFIFO => .named_pipe,
+ os.S.IFCHR => .character_device,
+ os.S.IFDIR => .directory,
+ os.S.IFBLK => .block_device,
+ os.S.IFREG => .file,
+ os.S.IFLNK => .sym_link,
+ os.S.IFSOCK => .unix_domain_socket,
+ else => .unknown,
+ };
+ return Entry{
+ .name = name,
+ .kind = entry_kind,
+ };
+ }
+ }
+
+ pub fn reset(self: *Self) void {
+ // FIXME: Very small chance this may fail.
+ self.dir_ptr = os.system.fdopendir(self.dir.fd).?;
+ }
+ },
.haiku => struct {
dir: Dir,
buf: [1024]u8, // TODO align(@alignOf(os.dirent64)),
@@ -913,6 +981,11 @@ pub const IterableDir = struct {
.buf = undefined,
.first_iter = first_iter_start_value,
},
+ .minerva => return Iterator{
+ .dir = self.dir,
+ // FIXME: Very small chance this may fail.
+ .dir_ptr = os.system.fdopendir(self.dir.fd).?,
+ },
.windows => return Iterator{
.dir = self.dir,
.index = 0,
@@ -3004,7 +3077,7 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
return result;
}
switch (builtin.os.tag) {
- .linux => return os.readlinkZ("/proc/self/exe", out_buffer),
+ .linux, .minerva => return os.readlinkZ("/proc/self/exe", out_buffer),
.solaris => return os.readlinkZ("/proc/self/path/a.out", out_buffer),
.freebsd, .dragonfly => {
var mib = [4]c_int{ os.CTL.KERN, os.KERN.PROC, os.KERN.PROC_PATHNAME, -1 };
diff --git a/zig/lib/std/fs/get_app_data_dir.zig b/zig/lib/std/fs/get_app_data_dir.zig
index 2f599c32130e2be12f44fa015df91816614d5f5b..896dde5ab8e0e573dc137d9a86be8298abef8a1a 100644
--- a/zig/lib/std/fs/get_app_data_dir.zig
+++ b/zig/lib/std/fs/get_app_data_dir.zig
@@ -44,7 +44,7 @@ pub fn getAppDataDir(allocator: mem.Allocator, appname: []const u8) GetAppDataDi
};
return fs.path.join(allocator, &[_][]const u8{ home_dir, "Library", "Application Support", appname });
},
- .linux, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris => {
+ .linux, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris, .minerva => {
if (os.getenv("XDG_DATA_HOME")) |xdg| {
return fs.path.join(allocator, &[_][]const u8{ xdg, appname });
}
diff --git a/zig/lib/std/os.zig b/zig/lib/std/os.zig
index e4ac38051e3558ec796f9eefc96c5d8950425e3f..188c0f490bf10d588fbf4c6040bde416b88decf8 100644
--- a/zig/lib/std/os.zig
+++ b/zig/lib/std/os.zig
@@ -32,6 +32,7 @@ pub const freebsd = std.c;
pub const haiku = std.c;
pub const netbsd = std.c;
pub const openbsd = std.c;
+pub const minerva = std.c;
pub const solaris = std.c;
pub const linux = @import("os/linux.zig");
pub const plan9 = @import("os/plan9.zig");
@@ -5179,6 +5180,7 @@ pub fn isGetFdPathSupportedOnTarget(os: std.Target.Os) bool {
.linux,
.solaris,
.freebsd,
+ .minerva,
=> true,
// zig fmt: on
.dragonfly => os.version_range.semver.max.order(.{ .major = 6, .minor = 0, .patch = 0 }) != .lt,
@@ -5219,7 +5221,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
const len = mem.indexOfScalar(u8, out_buffer[0..], @as(u8, 0)) orelse MAX_PATH_BYTES;
return out_buffer[0..len];
},
- .linux => {
+ .linux, .minerva => {
var procfs_buf: ["/proc/self/fd/-2147483648\x00".len]u8 = undefined;
const proc_path = std.fmt.bufPrintZ(procfs_buf[0..], "/proc/self/fd/{d}", .{fd}) catch unreachable;
diff --git a/zig/lib/std/target.zig b/zig/lib/std/target.zig
index 608f0e958144fc53dfb67fa2efa29690a60599ba..08dc72f28c8bd06137b46510dffeae6a8358cce7 100644
--- a/zig/lib/std/target.zig
+++ b/zig/lib/std/target.zig
@@ -2121,6 +2121,7 @@ pub const Target = struct {
.ananas,
.fuchsia,
.minix,
+ .minerva,
=> switch (target.cpu.arch) {
.msp430 => switch (c_type) {
.char => return 8,