Newer
Older
minerva / Ports / zig / patches / 0012-Implement-Minerva-support-in-std.patch
@minerva minerva on 13 Jul 33 KB Initial commit
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,