| ... | ... | @@ -5,6 +5,78 @@ pub const syscall_bits = switch (builtin.cpu.arch) { |
| 5 | 5 | .x86_64 => @import("plan9/x86_64.zig"), |
| 6 | 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 | 80 | pub const SYS = enum(usize) { |
| 9 | 81 | SYSR1 = 0, |
| 10 | 82 | _ERRSTR = 1, |
| ... | ... | @@ -64,6 +136,10 @@ pub fn pwrite(fd: usize, buf: [*]const u8, count: usize, offset: usize) usize { |
| 64 | 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 | 143 | pub fn open(path: [*:0]const u8, omode: OpenMode) usize { |
| 68 | 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 | 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 | 162 | _ = syscall_bits.syscall1(.EXITS, if (status) |s| @ptrToInt(s) else 0); |
| 163 | unreachable; |
| 77 | 164 | } |
| 78 | 165 | |
| 79 | 166 | pub fn close(fd: usize) usize { |