Commit 4dac9f54dd

Jacob G-W <jacoblevgw@gmail.com>
2023-06-14 21:39:40
plan9: flesh out stdlib enough to allow not using simplified start logic
1 parent 153def1
Changed files (5)
lib/std/os/plan9/errno.zig
@@ -0,0 +1,76 @@
+//! Ported from /sys/include/ape/errno.h
+pub const E = enum(u16) {
+    SUCCESS = 0,
+    DOM = 1000,
+    RANGE = 1001,
+    PLAN9 = 1002,
+
+    @"2BIG" = 1,
+    ACCES = 2,
+    AGAIN = 3,
+    // WOULDBLOCK = 3, // TODO errno.h has 2 names for 3
+    BADF = 4,
+    BUSY = 5,
+    CHILD = 6,
+    DEADLK = 7,
+    EXIST = 8,
+    FAULT = 9,
+    FBIG = 10,
+    INTR = 11,
+    INVAL = 12,
+    IO = 13,
+    ISDIR = 14,
+    MFILE = 15,
+    MLINK = 16,
+    NAMETOOLONG = 17,
+    NFILE = 18,
+    NODEV = 19,
+    NOENT = 20,
+    NOEXEC = 21,
+    NOLCK = 22,
+    NOMEM = 23,
+    NOSPC = 24,
+    NOSYS = 25,
+    NOTDIR = 26,
+    NOTEMPTY = 27,
+    NOTTY = 28,
+    NXIO = 29,
+    PERM = 30,
+    PIPE = 31,
+    ROFS = 32,
+    SPIPE = 33,
+    SRCH = 34,
+    XDEV = 35,
+
+    // bsd networking software
+    NOTSOCK = 36,
+    PROTONOSUPPORT = 37,
+    // PROTOTYPE = 37, // TODO errno.h has two names for 37
+    CONNREFUSED = 38,
+    AFNOSUPPORT = 39,
+    NOBUFS = 40,
+    OPNOTSUPP = 41,
+    ADDRINUSE = 42,
+    DESTADDRREQ = 43,
+    MSGSIZE = 44,
+    NOPROTOOPT = 45,
+    SOCKTNOSUPPORT = 46,
+    PFNOSUPPORT = 47,
+    ADDRNOTAVAIL = 48,
+    NETDOWN = 49,
+    NETUNREACH = 50,
+    NETRESET = 51,
+    CONNABORTED = 52,
+    ISCONN = 53,
+    NOTCONN = 54,
+    SHUTDOWN = 55,
+    TOOMANYREFS = 56,
+    TIMEDOUT = 57,
+    HOSTDOWN = 58,
+    HOSTUNREACH = 59,
+    GREG = 60,
+
+    // These added in 1003.1b-1993
+    CANCELED = 61,
+    INPROGRESS = 62,
+};
lib/std/os/plan9/x86_64.zig
@@ -66,7 +66,7 @@ pub fn syscall4(sys: plan9.SYS, arg0: usize, arg1: usize, arg2: usize, arg3: usi
         : [arg0] "{r8}" (arg0),
           [arg1] "{r9}" (arg1),
           [arg2] "{r10}" (arg2),
-          [arg2] "{r11}" (arg3),
+          [arg3] "{r11}" (arg3),
           [syscall_number] "{rbp}" (@enumToInt(sys)),
         : "rcx", "rax", "rbp", "r11", "memory"
     );
lib/std/os/plan9.zig
@@ -5,6 +5,78 @@ pub const syscall_bits = switch (builtin.cpu.arch) {
     .x86_64 => @import("plan9/x86_64.zig"),
     else => @compileError("more plan9 syscall implementations (needs more inline asm in stage2"),
 };
+pub const E = @import("plan9/errno.zig").E;
+/// Get the errno from a syscall return value, or 0 for no error.
+pub fn getErrno(r: usize) E {
+    const signed_r = @bitCast(isize, r);
+    const int = if (signed_r > -4096 and signed_r < 0) -signed_r else 0;
+    return @intToEnum(E, int);
+}
+pub const SIG = struct {
+    /// hangup
+    pub const HUP = 1;
+    /// interrupt
+    pub const INT = 2;
+    /// quit
+    pub const QUIT = 3;
+    /// illegal instruction (not reset when caught)
+    pub const ILL = 4;
+    /// used by abort
+    pub const ABRT = 5;
+    /// floating point exception
+    pub const FPE = 6;
+    /// kill (cannot be caught or ignored)
+    pub const KILL = 7;
+    /// segmentation violation
+    pub const SEGV = 8;
+    /// write on a pipe with no one to read it
+    pub const PIPE = 9;
+    /// alarm clock
+    pub const ALRM = 10;
+    /// software termination signal from kill
+    pub const TERM = 11;
+    /// user defined signal 1
+    pub const USR1 = 12;
+    /// user defined signal 2
+    pub const USR2 = 13;
+    /// bus error
+    pub const BUS = 14;
+    // The following symbols must be defined, but the signals needn't be supported
+    /// child process terminated or stopped
+    pub const CHLD = 15;
+    /// continue if stopped
+    pub const CONT = 16;
+    /// stop
+    pub const STOP = 17;
+    /// interactive stop
+    pub const TSTP = 18;
+    /// read from ctl tty by member of background
+    pub const TTIN = 19;
+    /// write to ctl tty by member of background
+    pub const TTOU = 20;
+};
+pub const sigset_t = c_long;
+pub const empty_sigset = 0;
+pub const siginfo_t = c_long; // TODO plan9 doesn't have sigaction_fn. Sigaction is not a union, but we incude it here to be compatible.
+pub const Sigaction = extern struct {
+    pub const handler_fn = *const fn (c_int) 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_int,
+};
+// TODO implement sigaction
+// right now it is just a shim to allow using start.zig code
+pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) usize {
+    _ = oact;
+    _ = act;
+    _ = sig;
+    return 0;
+}
 pub const SYS = enum(usize) {
     SYSR1 = 0,
     _ERRSTR = 1,
@@ -64,6 +136,10 @@ pub fn pwrite(fd: usize, buf: [*]const u8, count: usize, offset: usize) usize {
     return syscall_bits.syscall4(.PWRITE, fd, @ptrToInt(buf), count, offset);
 }
 
+pub fn pread(fd: usize, buf: [*]const u8, count: usize, offset: usize) usize {
+    return syscall_bits.syscall4(.PREAD, fd, @ptrToInt(buf), count, offset);
+}
+
 pub fn open(path: [*:0]const u8, omode: OpenMode) usize {
     return syscall_bits.syscall2(.OPEN, @ptrToInt(path), @enumToInt(omode));
 }
@@ -72,8 +148,19 @@ pub fn create(path: [*:0]const u8, omode: OpenMode, perms: usize) usize {
     return syscall_bits.syscall3(.CREATE, @ptrToInt(path), @enumToInt(omode), perms);
 }
 
-pub fn exits(status: ?[*:0]const u8) void {
+pub fn exit(status: u8) noreturn {
+    if (status == 0) {
+        exits(null);
+    } else {
+        // TODO plan9 does not have exit codes. You either exit with 0 or a string
+        const arr: [1:0]u8 = .{status};
+        exits(&arr);
+    }
+}
+
+pub fn exits(status: ?[*:0]const u8) noreturn {
     _ = syscall_bits.syscall1(.EXITS, if (status) |s| @ptrToInt(s) else 0);
+    unreachable;
 }
 
 pub fn close(fd: usize) usize {
lib/std/os.zig
@@ -67,6 +67,7 @@ else if (builtin.link_libc or is_windows)
     std.c
 else switch (builtin.os.tag) {
     .linux => linux,
+    .plan9 => plan9,
     .wasi => wasi,
     .uefi => uefi,
     else => struct {},
lib/std/start.zig
@@ -18,7 +18,6 @@ const start_sym_name = if (native_arch.isMIPS()) "__start" else "_start";
 // Until then, we have simplified logic here for self-hosted. TODO remove this once
 // self-hosted is capable enough to handle all of the real start.zig logic.
 pub const simplified_logic =
-    (builtin.zig_backend == .stage2_x86_64 and builtin.os.tag == .plan9) or
     builtin.zig_backend == .stage2_x86 or
     builtin.zig_backend == .stage2_aarch64 or
     builtin.zig_backend == .stage2_arm or