| ... | @@ -5,6 +5,78 @@ pub const syscall_bits = switch (builtin.cpu.arch) { | ... | @@ -5,6 +5,78 @@ pub const syscall_bits = switch (builtin.cpu.arch) { |
| 5 | .x86_64 => @import("plan9/x86_64.zig"), | 5 | .x86_64 => @import("plan9/x86_64.zig"), |
| 6 | else => @compileError("more plan9 syscall implementations (needs more inline asm in stage2"), | 6 | else => @compileError("more plan9 syscall implementations (needs more inline asm in stage2"), |
| 7 | }; | 7 | }; |
| | 8 | pub const E = @import("plan9/errno.zig").E; |
| | 9 | /// Get the errno from a syscall return value, or 0 for no error. |
| | 10 | pub fn getErrno(r: usize) E { |
| | 11 | const signed_r = @bitCast(isize, r); |
| | 12 | const int = if (signed_r > -4096 and signed_r < 0) -signed_r else 0; |
| | 13 | return @intToEnum(E, int); |
| | 14 | } |
| | 15 | pub const SIG = struct { |
| | 16 | /// hangup |
| | 17 | pub const HUP = 1; |
| | 18 | /// interrupt |
| | 19 | pub const INT = 2; |
| | 20 | /// quit |
| | 21 | pub const QUIT = 3; |
| | 22 | /// illegal instruction (not reset when caught) |
| | 23 | pub const ILL = 4; |
| | 24 | /// used by abort |
| | 25 | pub const ABRT = 5; |
| | 26 | /// floating point exception |
| | 27 | pub const FPE = 6; |
| | 28 | /// kill (cannot be caught or ignored) |
| | 29 | pub const KILL = 7; |
| | 30 | /// segmentation violation |
| | 31 | pub const SEGV = 8; |
| | 32 | /// write on a pipe with no one to read it |
| | 33 | pub const PIPE = 9; |
| | 34 | /// alarm clock |
| | 35 | pub const ALRM = 10; |
| | 36 | /// software termination signal from kill |
| | 37 | pub const TERM = 11; |
| | 38 | /// user defined signal 1 |
| | 39 | pub const USR1 = 12; |
| | 40 | /// user defined signal 2 |
| | 41 | pub const USR2 = 13; |
| | 42 | /// bus error |
| | 43 | pub const BUS = 14; |
| | 44 | // The following symbols must be defined, but the signals needn't be supported |
| | 45 | /// child process terminated or stopped |
| | 46 | pub const CHLD = 15; |
| | 47 | /// continue if stopped |
| | 48 | pub const CONT = 16; |
| | 49 | /// stop |
| | 50 | pub const STOP = 17; |
| | 51 | /// interactive stop |
| | 52 | pub const TSTP = 18; |
| | 53 | /// read from ctl tty by member of background |
| | 54 | pub const TTIN = 19; |
| | 55 | /// write to ctl tty by member of background |
| | 56 | pub const TTOU = 20; |
| | 57 | }; |
| | 58 | pub const sigset_t = c_long; |
| | 59 | pub const empty_sigset = 0; |
| | 60 | 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. |
| | 61 | pub const Sigaction = extern struct { |
| | 62 | pub const handler_fn = *const fn (c_int) callconv(.C) void; |
| | 63 | pub const sigaction_fn = *const fn (c_int, *const siginfo_t, ?*const anyopaque) callconv(.C) void; |
| | 64 | |
| | 65 | handler: extern union { |
| | 66 | handler: ?handler_fn, |
| | 67 | sigaction: ?sigaction_fn, |
| | 68 | }, |
| | 69 | mask: sigset_t, |
| | 70 | flags: c_int, |
| | 71 | }; |
| | 72 | // TODO implement sigaction |
| | 73 | // right now it is just a shim to allow using start.zig code |
| | 74 | pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) usize { |
| | 75 | _ = oact; |
| | 76 | _ = act; |
| | 77 | _ = sig; |
| | 78 | return 0; |
| | 79 | } |
| 8 | pub const SYS = enum(usize) { | 80 | pub const SYS = enum(usize) { |
| 9 | SYSR1 = 0, | 81 | SYSR1 = 0, |
| 10 | _ERRSTR = 1, | 82 | _ERRSTR = 1, |
| ... | @@ -64,6 +136,10 @@ pub fn pwrite(fd: usize, buf: [*]const u8, count: usize, offset: usize) usize { | ... | @@ -64,6 +136,10 @@ pub fn pwrite(fd: usize, buf: [*]const u8, count: usize, offset: usize) usize { |
| 64 | return syscall_bits.syscall4(.PWRITE, fd, @ptrToInt(buf), count, offset); | 136 | return syscall_bits.syscall4(.PWRITE, fd, @ptrToInt(buf), count, offset); |
| 65 | } | 137 | } |
| 66 | | 138 | |
| | 139 | pub fn pread(fd: usize, buf: [*]const u8, count: usize, offset: usize) usize { |
| | 140 | return syscall_bits.syscall4(.PREAD, fd, @ptrToInt(buf), count, offset); |
| | 141 | } |
| | 142 | |
| 67 | pub fn open(path: [*:0]const u8, omode: OpenMode) usize { | 143 | pub fn open(path: [*:0]const u8, omode: OpenMode) usize { |
| 68 | return syscall_bits.syscall2(.OPEN, @ptrToInt(path), @enumToInt(omode)); | 144 | return syscall_bits.syscall2(.OPEN, @ptrToInt(path), @enumToInt(omode)); |
| 69 | } | 145 | } |
| ... | @@ -72,8 +148,19 @@ pub fn create(path: [*:0]const u8, omode: OpenMode, perms: usize) usize { | ... | @@ -72,8 +148,19 @@ pub fn create(path: [*:0]const u8, omode: OpenMode, perms: usize) usize { |
| 72 | return syscall_bits.syscall3(.CREATE, @ptrToInt(path), @enumToInt(omode), perms); | 148 | return syscall_bits.syscall3(.CREATE, @ptrToInt(path), @enumToInt(omode), perms); |
| 73 | } | 149 | } |
| 74 | | 150 | |
| 75 | pub fn exits(status: ?[*:0]const u8) void { | 151 | pub fn exit(status: u8) noreturn { |
| | 152 | if (status == 0) { |
| | 153 | exits(null); |
| | 154 | } else { |
| | 155 | // TODO plan9 does not have exit codes. You either exit with 0 or a string |
| | 156 | const arr: [1:0]u8 = .{status}; |
| | 157 | exits(&arr); |
| | 158 | } |
| | 159 | } |
| | 160 | |
| | 161 | pub fn exits(status: ?[*:0]const u8) noreturn { |
| 76 | _ = syscall_bits.syscall1(.EXITS, if (status) |s| @ptrToInt(s) else 0); | 162 | _ = syscall_bits.syscall1(.EXITS, if (status) |s| @ptrToInt(s) else 0); |
| | 163 | unreachable; |
| 77 | } | 164 | } |
| 78 | | 165 | |
| 79 | pub fn close(fd: usize) usize { | 166 | pub fn close(fd: usize) usize { |