From e2b9c153bdfa2c5e4005d5957062e0eaf3b339a2 Mon Sep 17 00:00:00 2001 From: Marc Tiehuis Date: Fri, 20 Oct 2017 06:16:56 +0000 Subject: Add initial freebsd stdlib functionality Trivial program now compiles with now warnings. --- std/os/index.zig | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'std/os/index.zig') diff --git a/std/os/index.zig b/std/os/index.zig index d9e6c3c81d..f332e8212a 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -24,10 +24,12 @@ test "std.os" { pub const windows = @import("windows/index.zig"); pub const darwin = @import("darwin.zig"); pub const linux = @import("linux/index.zig"); +pub const freebsd = @import("freebsd.zig"); pub const zen = @import("zen.zig"); pub const posix = switch (builtin.os) { Os.linux => linux, Os.macosx, Os.ios => darwin, + Os.freebsd => freebsd, Os.zen => zen, else => @compileError("Unsupported OS"), }; @@ -174,7 +176,7 @@ pub fn abort() noreturn { c.abort(); } switch (builtin.os) { - Os.linux, Os.macosx, Os.ios => { + Os.linux, Os.macosx, Os.ios, Os.freebsd => { _ = posix.raise(posix.SIGABRT); _ = posix.raise(posix.SIGKILL); while (true) {} @@ -196,7 +198,7 @@ pub fn exit(status: u8) noreturn { c.exit(status); } switch (builtin.os) { - Os.linux, Os.macosx, Os.ios => { + Os.linux, Os.macosx, Os.ios, Os.freebsd => { posix.exit(status); }, Os.windows => { -- cgit v1.2.3 From 102cb61e401ba2266938882d8a7d751a31a49ab2 Mon Sep 17 00:00:00 2001 From: Marc Tiehuis Date: Mon, 9 Jul 2018 20:54:36 +1200 Subject: Get freebsd std compiling again --- std/os/freebsd.zig | 535 ++++++++++++++++------------------------------ std/os/freebsd_errno.zig | 200 ++++++++--------- std/os/freebsd_x86_64.zig | 143 +++++++------ std/os/index.zig | 2 +- 4 files changed, 366 insertions(+), 514 deletions(-) (limited to 'std/os/index.zig') diff --git a/std/os/freebsd.zig b/std/os/freebsd.zig index 7fd233aef7..ee7e93d653 100644 --- a/std/os/freebsd.zig +++ b/std/os/freebsd.zig @@ -1,11 +1,11 @@ +const c = @import("../c/index.zig"); const assert = @import("../debug.zig").assert; const builtin = @import("builtin"); const arch = switch (builtin.arch) { - builtin.Arch.x86_64 => @import("freebsd_x86_64.zig"), - builtin.Arch.i386 => @import("freebsd_i386.zig"), + builtin.Arch.x86_64 => @import("x86_64.zig"), else => @compileError("unsupported arch"), }; -pub use @import("freebsd_errno.zig"); +pub use @import("errno.zig"); pub const PATH_MAX = 1024; @@ -13,85 +13,86 @@ pub const STDIN_FILENO = 0; pub const STDOUT_FILENO = 1; pub const STDERR_FILENO = 2; -pub const PROT_NONE = 0; -pub const PROT_READ = 1; -pub const PROT_WRITE = 2; -pub const PROT_EXEC = 4; - -pub const MAP_FAILED = @maxValue(usize); -pub const MAP_SHARED = 0x0001; -pub const MAP_PRIVATE = 0x0002; -pub const MAP_FIXED = 0x0010; -pub const MAP_STACK = 0x0400; -pub const MAP_NOSYNC = 0x0800; -pub const MAP_ANON = 0x1000; -pub const MAP_ANONYMOUS = MAP_ANON; -pub const MAP_FILE = 0; - -pub const MAP_GUARD = 0x00002000; -pub const MAP_EXCL = 0x00004000; -pub const MAP_NOCORE = 0x00020000; +pub const PROT_NONE = 0; +pub const PROT_READ = 1; +pub const PROT_WRITE = 2; +pub const PROT_EXEC = 4; + +pub const MAP_FAILED = @maxValue(usize); +pub const MAP_SHARED = 0x0001; +pub const MAP_PRIVATE = 0x0002; +pub const MAP_FIXED = 0x0010; +pub const MAP_STACK = 0x0400; +pub const MAP_NOSYNC = 0x0800; +pub const MAP_ANON = 0x1000; +pub const MAP_ANONYMOUS = MAP_ANON; +pub const MAP_FILE = 0; +pub const MAP_NORESERVE = 0; + +pub const MAP_GUARD = 0x00002000; +pub const MAP_EXCL = 0x00004000; +pub const MAP_NOCORE = 0x00020000; pub const MAP_PREFAULT_READ = 0x00040000; -pub const MAP_32BIT = 0x00080000; +pub const MAP_32BIT = 0x00080000; -pub const WNOHANG = 1; -pub const WUNTRACED = 2; -pub const WSTOPPED = WUNTRACED; +pub const WNOHANG = 1; +pub const WUNTRACED = 2; +pub const WSTOPPED = WUNTRACED; pub const WCONTINUED = 4; -pub const WNOWAIT = 8; -pub const WEXITED = 16; -pub const WTRAPPED = 32; +pub const WNOWAIT = 8; +pub const WEXITED = 16; +pub const WTRAPPED = 32; -pub const SA_ONSTACK = 0x0001; -pub const SA_RESTART = 0x0002; +pub const SA_ONSTACK = 0x0001; +pub const SA_RESTART = 0x0002; pub const SA_RESETHAND = 0x0004; pub const SA_NOCLDSTOP = 0x0008; -pub const SA_NODEFER = 0x0010; +pub const SA_NODEFER = 0x0010; pub const SA_NOCLDWAIT = 0x0020; -pub const SA_SIGINFO = 0x0040; - -pub const SIGHUP = 1; -pub const SIGINT = 2; -pub const SIGQUIT = 3; -pub const SIGILL = 4; -pub const SIGTRAP = 5; -pub const SIGABRT = 6; -pub const SIGIOT = SIGABRT; -pub const SIGEMT = 7; -pub const SIGFPE = 8; -pub const SIGKILL = 9; -pub const SIGBUS = 10; -pub const SIGSEGV = 11; -pub const SIGSYS = 12; -pub const SIGPIPE = 13; -pub const SIGALRM = 14; -pub const SIGTERM = 15; -pub const SIGURG = 16; -pub const SIGSTOP = 17; -pub const SIGTSTP = 18; -pub const SIGCONT = 19; -pub const SIGCHLD = 20; -pub const SIGTTIN = 21; -pub const SIGTTOU = 22; -pub const SIGIO = 23; -pub const SIGXCPU = 24; -pub const SIGXFSZ = 25; +pub const SA_SIGINFO = 0x0040; + +pub const SIGHUP = 1; +pub const SIGINT = 2; +pub const SIGQUIT = 3; +pub const SIGILL = 4; +pub const SIGTRAP = 5; +pub const SIGABRT = 6; +pub const SIGIOT = SIGABRT; +pub const SIGEMT = 7; +pub const SIGFPE = 8; +pub const SIGKILL = 9; +pub const SIGBUS = 10; +pub const SIGSEGV = 11; +pub const SIGSYS = 12; +pub const SIGPIPE = 13; +pub const SIGALRM = 14; +pub const SIGTERM = 15; +pub const SIGURG = 16; +pub const SIGSTOP = 17; +pub const SIGTSTP = 18; +pub const SIGCONT = 19; +pub const SIGCHLD = 20; +pub const SIGTTIN = 21; +pub const SIGTTOU = 22; +pub const SIGIO = 23; +pub const SIGXCPU = 24; +pub const SIGXFSZ = 25; pub const SIGVTALRM = 26; -pub const SIGPROF = 27; -pub const SIGWINCH = 28; -pub const SIGINFO = 29; -pub const SIGUSR1 = 30; -pub const SIGUSR2 = 31; -pub const SIGTHR = 32; -pub const SIGLWP = SIGTHR; -pub const SIGLIBRT = 33; - -pub const SIGRTMIN = 65; -pub const SIGRTMAX = 126; +pub const SIGPROF = 27; +pub const SIGWINCH = 28; +pub const SIGINFO = 29; +pub const SIGUSR1 = 30; +pub const SIGUSR2 = 31; +pub const SIGTHR = 32; +pub const SIGLWP = SIGTHR; +pub const SIGLIBRT = 33; + +pub const SIGRTMIN = 65; +pub const SIGRTMAX = 126; pub const O_RDONLY = 0o0; pub const O_WRONLY = 0o1; -pub const O_RDWR = 0o2; +pub const O_RDWR = 0o2; pub const O_ACCMODE = 0o3; pub const O_CREAT = arch.O_CREAT; @@ -119,7 +120,7 @@ pub const SEEK_SET = 0; pub const SEEK_CUR = 1; pub const SEEK_END = 2; -pub const SIG_BLOCK = 1; +pub const SIG_BLOCK = 1; pub const SIG_UNBLOCK = 2; pub const SIG_SETMASK = 3; @@ -272,7 +273,6 @@ pub const DT_LNK = 10; pub const DT_SOCK = 12; pub const DT_WHT = 14; - pub const TCGETS = 0x5401; pub const TCSETS = 0x5402; pub const TCSETSW = 0x5403; @@ -329,15 +329,30 @@ pub const TIOCGPKT = 0x80045438; pub const TIOCGPTLCK = 0x80045439; pub const TIOCGEXCL = 0x80045440; -fn unsigned(s: i32) -> u32 { @bitCast(u32, s) } -fn signed(s: u32) -> i32 { @bitCast(i32, s) } -pub fn WEXITSTATUS(s: i32) -> i32 { signed((unsigned(s) & 0xff00) >> 8) } -pub fn WTERMSIG(s: i32) -> i32 { signed(unsigned(s) & 0x7f) } -pub fn WSTOPSIG(s: i32) -> i32 { WEXITSTATUS(s) } -pub fn WIFEXITED(s: i32) -> bool { WTERMSIG(s) == 0 } -pub fn WIFSTOPPED(s: i32) -> bool { (u16)(((unsigned(s)&0xffff)*%0x10001)>>8) > 0x7f00 } -pub fn WIFSIGNALED(s: i32) -> bool { (unsigned(s)&0xffff)-%1 < 0xff } - +fn unsigned(s: i32) u32 { + return @bitCast(u32, s); +} +fn signed(s: u32) i32 { + return @bitCast(i32, s); +} +pub fn WEXITSTATUS(s: i32) i32 { + return signed((unsigned(s) & 0xff00) >> 8); +} +pub fn WTERMSIG(s: i32) i32 { + return signed(unsigned(s) & 0x7f); +} +pub fn WSTOPSIG(s: i32) i32 { + return WEXITSTATUS(s); +} +pub fn WIFEXITED(s: i32) bool { + return WTERMSIG(s) == 0; +} +pub fn WIFSTOPPED(s: i32) bool { + return (u16)(((unsigned(s) & 0xffff) *% 0x10001) >> 8) > 0x7f00; +} +pub fn WIFSIGNALED(s: i32) bool { + return (unsigned(s) & 0xffff) -% 1 < 0xff; +} pub const winsize = extern struct { ws_row: u16, @@ -347,182 +362,160 @@ pub const winsize = extern struct { }; /// Get the errno from a syscall return value, or 0 for no error. -pub fn getErrno(r: usize) -> usize { +pub fn getErrno(r: usize) usize { const signed_r = @bitCast(isize, r); - if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0 + return if (signed_r > -4096 and signed_r < 0) @intCast(usize, -signed_r) else 0; } -pub fn dup2(old: i32, new: i32) -> usize { - arch.syscall2(arch.SYS_dup2, usize(old), usize(new)) +pub fn dup2(old: i32, new: i32) usize { + return arch.syscall2(arch.SYS_dup2, usize(old), usize(new)); } -pub fn chdir(path: &const u8) -> usize { - arch.syscall1(arch.SYS_chdir, @ptrToInt(path)) +pub fn chdir(path: [*]const u8) usize { + return arch.syscall1(arch.SYS_chdir, @ptrToInt(path)); } -pub fn execve(path: &const u8, argv: &const ?&const u8, envp: &const ?&const u8) -> usize { - arch.syscall3(arch.SYS_execve, @ptrToInt(path), @ptrToInt(argv), @ptrToInt(envp)) +pub fn execve(path: [*]const u8, argv: [*]const ?[*]const u8, envp: [*]const ?[*]const u8) usize { + return arch.syscall3(arch.SYS_execve, @ptrToInt(path), @ptrToInt(argv), @ptrToInt(envp)); } -pub fn fork() -> usize { - arch.syscall0(arch.SYS_fork) +pub fn fork() usize { + return arch.syscall0(arch.SYS_fork); } -pub fn getcwd(buf: &u8, size: usize) -> usize { - arch.syscall2(arch.SYS_getcwd, @ptrToInt(buf), size) +pub fn getcwd(buf: [*]u8, size: usize) usize { + return arch.syscall2(arch.SYS___getcwd, @ptrToInt(buf), size); } -pub fn getdents(fd: i32, dirp: &u8, count: usize) -> usize { - arch.syscall3(arch.SYS_getdents, usize(fd), @ptrToInt(dirp), count) +pub fn getdents(fd: i32, dirp: [*]u8, count: usize) usize { + return arch.syscall3(arch.SYS_getdents, usize(fd), @ptrToInt(dirp), count); } -pub fn isatty(fd: i32) -> bool { +pub fn isatty(fd: i32) bool { var wsz: winsize = undefined; - return arch.syscall3(arch.SYS_ioctl, usize(fd), TIOCGWINSZ, @ptrToInt(&wsz)) == 0; + return arch.syscall3(arch.SYS_ioctl, @intCast(usize, fd), TIOCGWINSZ, @ptrToInt(&wsz)) == 0; } -pub fn readlink(noalias path: &const u8, noalias buf_ptr: &u8, buf_len: usize) -> usize { - arch.syscall3(arch.SYS_readlink, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len) +pub fn readlink(noalias path: [*]const u8, noalias buf_ptr: [*]u8, buf_len: usize) usize { + return arch.syscall3(arch.SYS_readlink, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len); } -pub fn mkdir(path: &const u8, mode: u32) -> usize { - arch.syscall2(arch.SYS_mkdir, @ptrToInt(path), mode) +pub fn mkdir(path: [*]const u8, mode: u32) usize { + return arch.syscall2(arch.SYS_mkdir, @ptrToInt(path), mode); } -pub fn mmap(address: ?&u8, length: usize, prot: usize, flags: usize, fd: i32, offset: isize) - -> usize -{ - arch.syscall6(arch.SYS_mmap, @ptrToInt(address), length, prot, flags, usize(fd), - @bitCast(usize, offset)) +pub fn mmap(address: ?*u8, length: usize, prot: usize, flags: usize, fd: i32, offset: isize) usize { + return arch.syscall6(arch.SYS_mmap, @ptrToInt(address), length, prot, flags, @intCast(usize, fd), @bitCast(usize, offset)); } -pub fn munmap(address: &u8, length: usize) -> usize { - arch.syscall2(arch.SYS_munmap, @ptrToInt(address), length) +pub fn munmap(address: usize, length: usize) usize { + return arch.syscall2(arch.SYS_munmap, address, length); } -pub fn read(fd: i32, buf: &u8, count: usize) -> usize { - arch.syscall3(arch.SYS_read, usize(fd), @ptrToInt(buf), count) +pub fn read(fd: i32, buf: [*]u8, count: usize) usize { + return arch.syscall3(arch.SYS_read, @intCast(usize, fd), @ptrToInt(buf), count); } -pub fn rmdir(path: &const u8) -> usize { - arch.syscall1(arch.SYS_rmdir, @ptrToInt(path)) +pub fn rmdir(path: [*]const u8) usize { + return arch.syscall1(arch.SYS_rmdir, @ptrToInt(path)); } -pub fn symlink(existing: &const u8, new: &const u8) -> usize { - arch.syscall2(arch.SYS_symlink, @ptrToInt(existing), @ptrToInt(new)) +pub fn symlink(existing: [*]const u8, new: [*]const u8) usize { + return arch.syscall2(arch.SYS_symlink, @ptrToInt(existing), @ptrToInt(new)); } -pub fn pread(fd: i32, buf: &u8, count: usize, offset: usize) -> usize { - arch.syscall4(arch.SYS_pread, usize(fd), @ptrToInt(buf), count, offset) +pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: usize) usize { + return arch.syscall4(arch.SYS_pread, usize(fd), @ptrToInt(buf), count, offset); } -pub fn pipe(fd: &[2]i32) -> usize { - pipe2(fd, 0) +pub fn pipe(fd: *[2]i32) usize { + return pipe2(fd, 0); } -pub fn pipe2(fd: &[2]i32, flags: usize) -> usize { - arch.syscall2(arch.SYS_pipe2, @ptrToInt(fd), flags) +pub fn pipe2(fd: *[2]i32, flags: usize) usize { + return arch.syscall2(arch.SYS_pipe2, @ptrToInt(fd), flags); } -pub fn write(fd: i32, buf: &const u8, count: usize) -> usize { - arch.syscall3(arch.SYS_write, usize(fd), @ptrToInt(buf), count) +pub fn write(fd: i32, buf: [*]const u8, count: usize) usize { + return arch.syscall3(arch.SYS_write, @intCast(usize, fd), @ptrToInt(buf), count); } -pub fn pwrite(fd: i32, buf: &const u8, count: usize, offset: usize) -> usize { - arch.syscall4(arch.SYS_pwrite, usize(fd), @ptrToInt(buf), count, offset) +pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: usize) usize { + return arch.syscall4(arch.SYS_pwrite, @intCast(usize, fd), @ptrToInt(buf), count, offset); } -pub fn rename(old: &const u8, new: &const u8) -> usize { - arch.syscall2(arch.SYS_rename, @ptrToInt(old), @ptrToInt(new)) +pub fn rename(old: [*]const u8, new: [*]const u8) usize { + return arch.syscall2(arch.SYS_rename, @ptrToInt(old), @ptrToInt(new)); } -pub fn open(path: &const u8, flags: u32, perm: usize) -> usize { - arch.syscall3(arch.SYS_open, @ptrToInt(path), flags, perm) +pub fn open(path: [*]const u8, flags: u32, perm: usize) usize { + return arch.syscall3(arch.SYS_open, @ptrToInt(path), flags, perm); } -pub fn create(path: &const u8, perm: usize) -> usize { - arch.syscall2(arch.SYS_creat, @ptrToInt(path), perm) +pub fn create(path: [*]const u8, perm: usize) usize { + return arch.syscall2(arch.SYS_creat, @ptrToInt(path), perm); } -pub fn openat(dirfd: i32, path: &const u8, flags: usize, mode: usize) -> usize { - arch.syscall4(arch.SYS_openat, usize(dirfd), @ptrToInt(path), flags, mode) +pub fn openat(dirfd: i32, path: [*]const u8, flags: usize, mode: usize) usize { + return arch.syscall4(arch.SYS_openat, @intCast(usize, dirfd), @ptrToInt(path), flags, mode); } -pub fn close(fd: i32) -> usize { - arch.syscall1(arch.SYS_close, usize(fd)) +pub fn close(fd: i32) usize { + return arch.syscall1(arch.SYS_close, @intCast(usize, fd)); } -pub fn lseek(fd: i32, offset: isize, ref_pos: usize) -> usize { - arch.syscall3(arch.SYS_lseek, usize(fd), @bitCast(usize, offset), ref_pos) +pub fn lseek(fd: i32, offset: isize, ref_pos: usize) usize { + return arch.syscall3(arch.SYS_lseek, @intCast(usize, fd), @bitCast(usize, offset), ref_pos); } -pub fn exit(status: i32) -> noreturn { +pub fn exit(status: i32) noreturn { _ = arch.syscall1(arch.SYS_exit, @bitCast(usize, isize(status))); - unreachable + unreachable; } -pub fn getrandom(buf: &u8, count: usize, flags: u32) -> usize { - arch.syscall3(arch.SYS_getrandom, @ptrToInt(buf), count, usize(flags)) +pub fn getrandom(buf: &u8, count: usize, flags: u32) usize { + return arch.syscall3(arch.SYS_getrandom, @ptrToInt(buf), count, @bitCast(usize, flags)); } -pub fn kill(pid: i32, sig: i32) -> usize { - arch.syscall2(arch.SYS_kill, @bitCast(usize, isize(pid)), usize(sig)) +pub fn kill(pid: i32, sig: i32) usize { + return arch.syscall2(arch.SYS_kill, @bitCast(usize, @intCast(isize, pid)), @intCast(usize, sig)); } -pub fn unlink(path: &const u8) -> usize { - arch.syscall1(arch.SYS_unlink, @ptrToInt(path)) +pub fn unlink(path: [*]const u8) usize { + return arch.syscall1(arch.SYS_unlink, @ptrToInt(path)); } -pub fn waitpid(pid: i32, status: &i32, options: i32) -> usize { - arch.syscall4(arch.SYS_wait4, @bitCast(usize, isize(pid)), @ptrToInt(status), @bitCast(usize, isize(options)), 0) +pub fn waitpid(pid: i32, status: *i32, options: i32) usize { + return arch.syscall4(arch.SYS_wait4, @bitCast(usize, isize(pid)), @ptrToInt(status), @bitCast(usize, isize(options)), 0); } -pub fn nanosleep(req: &const timespec, rem: ?×pec) -> usize { - arch.syscall2(arch.SYS_nanosleep, @ptrToInt(req), @ptrToInt(rem)) +pub fn nanosleep(req: *const timespec, rem: ?*timespec) usize { + return arch.syscall2(arch.SYS_nanosleep, @ptrToInt(req), @ptrToInt(rem)); } -pub fn setuid(uid: u32) -> usize { - arch.syscall1(arch.SYS_setuid, uid) +pub fn setuid(uid: u32) usize { + return arch.syscall1(arch.SYS_setuid, uid); } -pub fn setgid(gid: u32) -> usize { - arch.syscall1(arch.SYS_setgid, gid) +pub fn setgid(gid: u32) usize { + return arch.syscall1(arch.SYS_setgid, gid); } -pub fn setreuid(ruid: u32, euid: u32) -> usize { - arch.syscall2(arch.SYS_setreuid, ruid, euid) +pub fn setreuid(ruid: u32, euid: u32) usize { + return arch.syscall2(arch.SYS_setreuid, ruid, euid); } -pub fn setregid(rgid: u32, egid: u32) -> usize { - arch.syscall2(arch.SYS_setregid, rgid, egid) +pub fn setregid(rgid: u32, egid: u32) usize { + return arch.syscall2(arch.SYS_setregid, rgid, egid); } -pub fn sigprocmask(flags: u32, noalias set: &const sigset_t, noalias oldset: ?&sigset_t) -> usize { - arch.syscall4(arch.SYS_rt_sigprocmask, flags, @ptrToInt(set), @ptrToInt(oldset), NSIG/8) +pub fn sigprocmask(flags: u32, noalias set: *const sigset_t, noalias oldset: ?*sigset_t) usize { + // TODO: Implement + return 0; } -pub fn sigaction(sig: u6, noalias act: &const Sigaction, noalias oact: ?&Sigaction) -> usize { - assert(sig >= 1); - assert(sig != SIGKILL); - assert(sig != SIGSTOP); - var ksa = k_sigaction { - .handler = act.handler, - .flags = act.flags | SA_RESTORER, - .mask = undefined, - .restorer = @ptrCast(extern fn(), arch.restore_rt), - }; - var ksa_old: k_sigaction = undefined; - @memcpy(@ptrCast(&u8, &ksa.mask), @ptrCast(&const u8, &act.mask), 8); - const result = arch.syscall4(arch.SYS_rt_sigaction, sig, @ptrToInt(&ksa), @ptrToInt(&ksa_old), @sizeOf(@typeOf(ksa.mask))); - const err = getErrno(result); - if (err != 0) { - return result; - } - if (oact) |old| { - old.handler = ksa_old.handler; - old.flags = @truncate(u32, ksa_old.flags); - @memcpy(@ptrCast(&u8, &old.mask), @ptrCast(&const u8, &ksa_old.mask), @sizeOf(@typeOf(ksa_old.mask))); - } +pub fn sigaction(sig: u6, noalias act: *const Sigaction, noalias oact: ?*Sigaction) usize { + // TODO: Implement return 0; } @@ -531,203 +524,49 @@ const sigset_t = [128 / @sizeOf(usize)]usize; const all_mask = []usize{@maxValue(usize)}; const app_mask = []usize{0xfffffffc7fffffff}; -const k_sigaction = extern struct { - handler: extern fn(i32), - flags: usize, - restorer: extern fn(), - mask: [2]u32, -}; - /// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall. pub const Sigaction = struct { - handler: extern fn(i32), + // TODO: Adjust to use freebsd struct layout + handler: extern fn (i32) void, mask: sigset_t, flags: u32, }; -pub const SIG_ERR = @intToPtr(extern fn(i32), @maxValue(usize)); -pub const SIG_DFL = @intToPtr(extern fn(i32), 0); -pub const SIG_IGN = @intToPtr(extern fn(i32), 1); +pub const SIG_ERR = @intToPtr(extern fn (i32) void, @maxValue(usize)); +pub const SIG_DFL = @intToPtr(extern fn (i32) void, 0); +pub const SIG_IGN = @intToPtr(extern fn (i32) void, 1); pub const empty_sigset = []usize{0} ** sigset_t.len; -pub fn raise(sig: i32) -> usize { +pub fn raise(sig: i32) usize { // TODO implement, see linux equivalent for what we want to try and do return 0; } -fn blockAllSignals(set: &sigset_t) { +fn blockAllSignals(set: *sigset_t) void { // TODO implement } -fn blockAppSignals(set: &sigset_t) { +fn blockAppSignals(set: *sigset_t) void { // TODO implement } -fn restoreSignals(set: &sigset_t) { +fn restoreSignals(set: *sigset_t) void { // TODO implement } -pub fn sigaddset(set: &sigset_t, sig: u6) { +pub fn sigaddset(set: *sigset_t, sig: u6) void { const s = sig - 1; (*set)[usize(s) / usize.bit_count] |= usize(1) << (s & (usize.bit_count - 1)); } -pub fn sigismember(set: &const sigset_t, sig: u6) -> bool { +pub fn sigismember(set: *const sigset_t, sig: u6) bool { const s = sig - 1; return ((*set)[usize(s) / usize.bit_count] & (usize(1) << (s & (usize.bit_count - 1)))) != 0; } - -pub const sa_family_t = u16; -pub const socklen_t = u32; -pub const in_addr = u32; -pub const in6_addr = [16]u8; - -pub const sockaddr = extern struct { - family: sa_family_t, - port: u16, - data: [12]u8, -}; - -pub const sockaddr_in = extern struct { - family: sa_family_t, - port: u16, - addr: in_addr, - zero: [8]u8, -}; - -pub const sockaddr_in6 = extern struct { - family: sa_family_t, - port: u16, - flowinfo: u32, - addr: in6_addr, - scope_id: u32, -}; - -pub const iovec = extern struct { - iov_base: &u8, - iov_len: usize, -}; - -// -//const IF_NAMESIZE = 16; -// -//export struct ifreq { -// ifrn_name: [IF_NAMESIZE]u8, -// union { -// ifru_addr: sockaddr, -// ifru_dstaddr: sockaddr, -// ifru_broadaddr: sockaddr, -// ifru_netmask: sockaddr, -// ifru_hwaddr: sockaddr, -// ifru_flags: i16, -// ifru_ivalue: i32, -// ifru_mtu: i32, -// ifru_map: ifmap, -// ifru_slave: [IF_NAMESIZE]u8, -// ifru_newname: [IF_NAMESIZE]u8, -// ifru_data: &u8, -// } ifr_ifru; -//} -// - -pub fn getsockname(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t) -> usize { - arch.syscall3(arch.SYS_getsockname, usize(fd), @ptrToInt(addr), @ptrToInt(len)) -} - -pub fn getpeername(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t) -> usize { - arch.syscall3(arch.SYS_getpeername, usize(fd), @ptrToInt(addr), @ptrToInt(len)) -} - -pub fn socket(domain: i32, socket_type: i32, protocol: i32) -> usize { - arch.syscall3(arch.SYS_socket, usize(domain), usize(socket_type), usize(protocol)) -} - -pub fn setsockopt(fd: i32, level: i32, optname: i32, optval: &const u8, optlen: socklen_t) -> usize { - arch.syscall5(arch.SYS_setsockopt, usize(fd), usize(level), usize(optname), usize(optval), @ptrToInt(optlen)) -} - -pub fn getsockopt(fd: i32, level: i32, optname: i32, noalias optval: &u8, noalias optlen: &socklen_t) -> usize { - arch.syscall5(arch.SYS_getsockopt, usize(fd), usize(level), usize(optname), @ptrToInt(optval), @ptrToInt(optlen)) -} - -pub fn sendmsg(fd: i32, msg: &const arch.msghdr, flags: u32) -> usize { - arch.syscall3(arch.SYS_sendmsg, usize(fd), @ptrToInt(msg), flags) -} - -pub fn connect(fd: i32, addr: &const sockaddr, len: socklen_t) -> usize { - arch.syscall3(arch.SYS_connect, usize(fd), @ptrToInt(addr), usize(len)) -} - -pub fn recvmsg(fd: i32, msg: &arch.msghdr, flags: u32) -> usize { - arch.syscall3(arch.SYS_recvmsg, usize(fd), @ptrToInt(msg), flags) -} - -pub fn recvfrom(fd: i32, noalias buf: &u8, len: usize, flags: u32, - noalias addr: ?&sockaddr, noalias alen: ?&socklen_t) -> usize -{ - arch.syscall6(arch.SYS_recvfrom, usize(fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen)) -} - -pub fn shutdown(fd: i32, how: i32) -> usize { - arch.syscall2(arch.SYS_shutdown, usize(fd), usize(how)) -} - -pub fn bind(fd: i32, addr: &const sockaddr, len: socklen_t) -> usize { - arch.syscall3(arch.SYS_bind, usize(fd), @ptrToInt(addr), usize(len)) -} - -pub fn listen(fd: i32, backlog: i32) -> usize { - arch.syscall2(arch.SYS_listen, usize(fd), usize(backlog)) -} - -pub fn sendto(fd: i32, buf: &const u8, len: usize, flags: u32, addr: ?&const sockaddr, alen: socklen_t) -> usize { - arch.syscall6(arch.SYS_sendto, usize(fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), usize(alen)) -} - -pub fn socketpair(domain: i32, socket_type: i32, protocol: i32, fd: [2]i32) -> usize { - arch.syscall4(arch.SYS_socketpair, usize(domain), usize(socket_type), usize(protocol), @ptrToInt(&fd[0])) -} - -pub fn accept(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t) -> usize { - accept4(fd, addr, len, 0) -} - -pub fn accept4(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t, flags: u32) -> usize { - arch.syscall4(arch.SYS_accept4, usize(fd), @ptrToInt(addr), @ptrToInt(len), flags) -} - -// error NameTooLong; -// error SystemResources; -// error Io; -// -// pub fn if_nametoindex(name: []u8) -> %u32 { -// var ifr: ifreq = undefined; -// -// if (name.len >= ifr.ifr_name.len) { -// return error.NameTooLong; -// } -// -// const socket_ret = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0); -// const socket_err = getErrno(socket_ret); -// if (socket_err > 0) { -// return error.SystemResources; -// } -// const socket_fd = i32(socket_ret); -// @memcpy(&ifr.ifr_name[0], &name[0], name.len); -// ifr.ifr_name[name.len] = 0; -// const ioctl_ret = ioctl(socket_fd, SIOCGIFINDEX, &ifr); -// close(socket_fd); -// const ioctl_err = getErrno(ioctl_ret); -// if (ioctl_err > 0) { -// return error.Io; -// } -// return ifr.ifr_ifindex; -// } - pub const Stat = arch.Stat; pub const timespec = arch.timespec; -pub fn fstat(fd: i32, stat_buf: &Stat) -> usize { - arch.syscall2(arch.SYS_fstat, usize(fd), @ptrToInt(stat_buf)) +pub fn fstat(fd: i32, stat_buf: *Stat) usize { + return arch.syscall2(arch.SYS_fstat, @intCast(usize, fd), @ptrToInt(stat_buf)); } diff --git a/std/os/freebsd_errno.zig b/std/os/freebsd_errno.zig index 132683de1d..0a0d825f5a 100644 --- a/std/os/freebsd_errno.zig +++ b/std/os/freebsd_errno.zig @@ -1,121 +1,121 @@ -pub const EPERM = 1; // Operation not permitted -pub const ENOENT = 2; // No such file or directory -pub const ESRCH = 3; // No such process -pub const EINTR = 4; // Interrupted system call -pub const EIO = 5; // Input/output error -pub const ENXIO = 6; // Device not configured -pub const E2BIG = 7; // Argument list too long -pub const ENOEXEC = 8; // Exec format error -pub const EBADF = 9; // Bad file descriptor -pub const ECHILD = 10; // No child processes -pub const EDEADLK = 11; // Resource deadlock avoided - // 11 was EAGAIN -pub const ENOMEM = 12; // Cannot allocate memory -pub const EACCES = 13; // Permission denied -pub const EFAULT = 14; // Bad address -pub const ENOTBLK = 15; // Block device required -pub const EBUSY = 16; // Device busy -pub const EEXIST = 17; // File exists -pub const EXDEV = 18; // Cross-device link -pub const ENODEV = 19; // Operation not supported by device -pub const ENOTDIR = 20; // Not a directory -pub const EISDIR = 21; // Is a directory -pub const EINVAL = 22; // Invalid argument -pub const ENFILE = 23; // Too many open files in system -pub const EMFILE = 24; // Too many open files -pub const ENOTTY = 25; // Inappropriate ioctl for device -pub const ETXTBSY = 26; // Text file busy -pub const EFBIG = 27; // File too large -pub const ENOSPC = 28; // No space left on device -pub const ESPIPE = 29; // Illegal seek -pub const EROFS = 30; // Read-only filesystem -pub const EMLINK = 31; // Too many links -pub const EPIPE = 32; // Broken pipe +pub const EPERM = 1; // Operation not permitted +pub const ENOENT = 2; // No such file or directory +pub const ESRCH = 3; // No such process +pub const EINTR = 4; // Interrupted system call +pub const EIO = 5; // Input/output error +pub const ENXIO = 6; // Device not configured +pub const E2BIG = 7; // Argument list too long +pub const ENOEXEC = 8; // Exec format error +pub const EBADF = 9; // Bad file descriptor +pub const ECHILD = 10; // No child processes +pub const EDEADLK = 11; // Resource deadlock avoided +// 11 was EAGAIN +pub const ENOMEM = 12; // Cannot allocate memory +pub const EACCES = 13; // Permission denied +pub const EFAULT = 14; // Bad address +pub const ENOTBLK = 15; // Block device required +pub const EBUSY = 16; // Device busy +pub const EEXIST = 17; // File exists +pub const EXDEV = 18; // Cross-device link +pub const ENODEV = 19; // Operation not supported by device +pub const ENOTDIR = 20; // Not a directory +pub const EISDIR = 21; // Is a directory +pub const EINVAL = 22; // Invalid argument +pub const ENFILE = 23; // Too many open files in system +pub const EMFILE = 24; // Too many open files +pub const ENOTTY = 25; // Inappropriate ioctl for device +pub const ETXTBSY = 26; // Text file busy +pub const EFBIG = 27; // File too large +pub const ENOSPC = 28; // No space left on device +pub const ESPIPE = 29; // Illegal seek +pub const EROFS = 30; // Read-only filesystem +pub const EMLINK = 31; // Too many links +pub const EPIPE = 32; // Broken pipe // math software -pub const EDOM = 33; // Numerical argument out of domain -pub const ERANGE = 34; // Result too large +pub const EDOM = 33; // Numerical argument out of domain +pub const ERANGE = 34; // Result too large // non-blocking and interrupt i/o -pub const EAGAIN = 35; // Resource temporarily unavailable -pub const EWOULDBLOCK = EAGAIN; // Operation would block -pub const EINPROGRESS = 36; // Operation now in progress -pub const EALREADY = 37; // Operation already in progress +pub const EAGAIN = 35; // Resource temporarily unavailable +pub const EWOULDBLOCK = EAGAIN; // Operation would block +pub const EINPROGRESS = 36; // Operation now in progress +pub const EALREADY = 37; // Operation already in progress // ipc/network software -- argument errors -pub const ENOTSOCK = 38; // Socket operation on non-socket -pub const EDESTADDRREQ = 39; // Destination address required -pub const EMSGSIZE = 40; // Message too long -pub const EPROTOTYPE = 41; // Protocol wrong type for socket -pub const ENOPROTOOPT = 42; // Protocol not available -pub const EPROTONOSUPPORT = 43; // Protocol not supported -pub const ESOCKTNOSUPPORT = 44; // Socket type not supported -pub const EOPNOTSUPP = 45; // Operation not supported -pub const ENOTSUP = EOPNOTSUPP; // Operation not supported -pub const EPFNOSUPPORT = 46; // Protocol family not supported -pub const EAFNOSUPPORT = 47; // Address family not supported by protocol family -pub const EADDRINUSE = 48; // Address already in use -pub const EADDRNOTAVAIL = 49; // Can't assign requested address +pub const ENOTSOCK = 38; // Socket operation on non-socket +pub const EDESTADDRREQ = 39; // Destination address required +pub const EMSGSIZE = 40; // Message too long +pub const EPROTOTYPE = 41; // Protocol wrong type for socket +pub const ENOPROTOOPT = 42; // Protocol not available +pub const EPROTONOSUPPORT = 43; // Protocol not supported +pub const ESOCKTNOSUPPORT = 44; // Socket type not supported +pub const EOPNOTSUPP = 45; // Operation not supported +pub const ENOTSUP = EOPNOTSUPP; // Operation not supported +pub const EPFNOSUPPORT = 46; // Protocol family not supported +pub const EAFNOSUPPORT = 47; // Address family not supported by protocol family +pub const EADDRINUSE = 48; // Address already in use +pub const EADDRNOTAVAIL = 49; // Can't assign requested address // ipc/network software -- operational errors -pub const ENETDOWN = 50; // Network is down -pub const ENETUNREACH = 51; // Network is unreachable -pub const ENETRESET = 52; // Network dropped connection on reset -pub const ECONNABORTED = 53; // Software caused connection abort -pub const ECONNRESET = 54; // Connection reset by peer -pub const ENOBUFS = 55; // No buffer space available -pub const EISCONN = 56; // Socket is already connected -pub const ENOTCONN = 57; // Socket is not connected -pub const ESHUTDOWN = 58; // Can't send after socket shutdown -pub const ETOOMANYREFS = 59; // Too many references: can't splice -pub const ETIMEDOUT = 60; // Operation timed out -pub const ECONNREFUSED = 61; // Connection refused +pub const ENETDOWN = 50; // Network is down +pub const ENETUNREACH = 51; // Network is unreachable +pub const ENETRESET = 52; // Network dropped connection on reset +pub const ECONNABORTED = 53; // Software caused connection abort +pub const ECONNRESET = 54; // Connection reset by peer +pub const ENOBUFS = 55; // No buffer space available +pub const EISCONN = 56; // Socket is already connected +pub const ENOTCONN = 57; // Socket is not connected +pub const ESHUTDOWN = 58; // Can't send after socket shutdown +pub const ETOOMANYREFS = 59; // Too many references: can't splice +pub const ETIMEDOUT = 60; // Operation timed out +pub const ECONNREFUSED = 61; // Connection refused -pub const ELOOP = 62; // Too many levels of symbolic links -pub const ENAMETOOLONG = 63; // File name too long +pub const ELOOP = 62; // Too many levels of symbolic links +pub const ENAMETOOLONG = 63; // File name too long // should be rearranged -pub const EHOSTDOWN = 64; // Host is down -pub const EHOSTUNREACH = 65; // No route to host -pub const ENOTEMPTY = 66; // Directory not empty +pub const EHOSTDOWN = 64; // Host is down +pub const EHOSTUNREACH = 65; // No route to host +pub const ENOTEMPTY = 66; // Directory not empty // quotas & mush -pub const EPROCLIM = 67; // Too many processes -pub const EUSERS = 68; // Too many users -pub const EDQUOT = 69; // Disc quota exceeded +pub const EPROCLIM = 67; // Too many processes +pub const EUSERS = 68; // Too many users +pub const EDQUOT = 69; // Disc quota exceeded // Network File System -pub const ESTALE = 70; // Stale NFS file handle -pub const EREMOTE = 71; // Too many levels of remote in path -pub const EBADRPC = 72; // RPC struct is bad -pub const ERPCMISMATCH = 73; // RPC version wrong -pub const EPROGUNAVAIL = 74; // RPC prog. not avail -pub const EPROGMISMATCH = 75; // Program version wrong -pub const EPROCUNAVAIL = 76; // Bad procedure for program +pub const ESTALE = 70; // Stale NFS file handle +pub const EREMOTE = 71; // Too many levels of remote in path +pub const EBADRPC = 72; // RPC struct is bad +pub const ERPCMISMATCH = 73; // RPC version wrong +pub const EPROGUNAVAIL = 74; // RPC prog. not avail +pub const EPROGMISMATCH = 75; // Program version wrong +pub const EPROCUNAVAIL = 76; // Bad procedure for program -pub const ENOLCK = 77; // No locks available -pub const ENOSYS = 78; // Function not implemented +pub const ENOLCK = 77; // No locks available +pub const ENOSYS = 78; // Function not implemented -pub const EFTYPE = 79; // Inappropriate file type or format -pub const EAUTH = 80; // Authentication error -pub const ENEEDAUTH = 81; // Need authenticator -pub const EIDRM = 82; // Identifier removed -pub const ENOMSG = 83; // No message of desired type -pub const EOVERFLOW = 84; // Value too large to be stored in data type -pub const ECANCELED = 85; // Operation canceled -pub const EILSEQ = 86; // Illegal byte sequence -pub const ENOATTR = 87; // Attribute not found +pub const EFTYPE = 79; // Inappropriate file type or format +pub const EAUTH = 80; // Authentication error +pub const ENEEDAUTH = 81; // Need authenticator +pub const EIDRM = 82; // Identifier removed +pub const ENOMSG = 83; // No message of desired type +pub const EOVERFLOW = 84; // Value too large to be stored in data type +pub const ECANCELED = 85; // Operation canceled +pub const EILSEQ = 86; // Illegal byte sequence +pub const ENOATTR = 87; // Attribute not found -pub const EDOOFUS = 88; // Programming error +pub const EDOOFUS = 88; // Programming error -pub const EBADMSG = 89; // Bad message -pub const EMULTIHOP = 90; // Multihop attempted -pub const ENOLINK = 91; // Link has been severed -pub const EPROTO = 92; // Protocol error +pub const EBADMSG = 89; // Bad message +pub const EMULTIHOP = 90; // Multihop attempted +pub const ENOLINK = 91; // Link has been severed +pub const EPROTO = 92; // Protocol error -pub const ENOTCAPABLE = 93; // Capabilities insufficient -pub const ECAPMODE = 94; // Not permitted in capability mode -pub const ENOTRECOVERABLE = 95; // State not recoverable -pub const EOWNERDEAD = 96; // Previous owner died +pub const ENOTCAPABLE = 93; // Capabilities insufficient +pub const ECAPMODE = 94; // Not permitted in capability mode +pub const ENOTRECOVERABLE = 95; // State not recoverable +pub const EOWNERDEAD = 96; // Previous owner died -pub const ELAST = 96; // Must be equal largest errno +pub const ELAST = 96; // Must be equal largest errno diff --git a/std/os/freebsd_x86_64.zig b/std/os/freebsd_x86_64.zig index ec3b93be14..09b4680329 100644 --- a/std/os/freebsd_x86_64.zig +++ b/std/os/freebsd_x86_64.zig @@ -1,4 +1,4 @@ -const freebsd = @import("freebsd.zig"); +const freebsd = @import("index.zig"); const socklen_t = freebsd.socklen_t; const iovec = freebsd.iovec; @@ -477,26 +477,26 @@ pub const SYS_mknodat = 559; pub const SYS_kevent = 560; pub const SYS_MAXSYSCALL = 561; -pub const O_CREAT = 0o100; -pub const O_EXCL = 0o200; -pub const O_NOCTTY = 0o400; -pub const O_TRUNC = 0o1000; -pub const O_APPEND = 0o2000; -pub const O_NONBLOCK = 0o4000; -pub const O_DSYNC = 0o10000; -pub const O_SYNC = 0o4010000; -pub const O_RSYNC = 0o4010000; +pub const O_CREAT = 0o100; +pub const O_EXCL = 0o200; +pub const O_NOCTTY = 0o400; +pub const O_TRUNC = 0o1000; +pub const O_APPEND = 0o2000; +pub const O_NONBLOCK = 0o4000; +pub const O_DSYNC = 0o10000; +pub const O_SYNC = 0o4010000; +pub const O_RSYNC = 0o4010000; pub const O_DIRECTORY = 0o200000; -pub const O_NOFOLLOW = 0o400000; -pub const O_CLOEXEC = 0o2000000; +pub const O_NOFOLLOW = 0o400000; +pub const O_CLOEXEC = 0o2000000; -pub const O_ASYNC = 0o20000; -pub const O_DIRECT = 0o40000; -pub const O_LARGEFILE = 0; -pub const O_NOATIME = 0o1000000; -pub const O_PATH = 0o10000000; +pub const O_ASYNC = 0o20000; +pub const O_DIRECT = 0o40000; +pub const O_LARGEFILE = 0; +pub const O_NOATIME = 0o1000000; +pub const O_PATH = 0o10000000; pub const O_TMPFILE = 0o20200000; -pub const O_NDELAY = O_NONBLOCK; +pub const O_NDELAY = O_NONBLOCK; pub const F_DUPFD = 0; pub const F_GETFD = 1; @@ -518,86 +518,99 @@ pub const F_GETOWN_EX = 16; pub const F_GETOWNER_UIDS = 17; -pub fn syscall0(number: usize) -> usize { - asm volatile ("syscall" +pub fn syscall0(number: usize) usize { + return asm volatile ("syscall" : [ret] "={rax}" (-> usize) : [number] "{rax}" (number) - : "rcx", "r11") + : "rcx", "r11" + ); } -pub fn syscall1(number: usize, arg1: usize) -> usize { - asm volatile ("syscall" +pub fn syscall1(number: usize, arg1: usize) usize { + return asm volatile ("syscall" : [ret] "={rax}" (-> usize) : [number] "{rax}" (number), - [arg1] "{rdi}" (arg1) - : "rcx", "r11") + [arg1] "{rdi}" (arg1) + : "rcx", "r11" + ); } -pub fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize { - asm volatile ("syscall" +pub fn syscall2(number: usize, arg1: usize, arg2: usize) usize { + return asm volatile ("syscall" : [ret] "={rax}" (-> usize) : [number] "{rax}" (number), - [arg1] "{rdi}" (arg1), - [arg2] "{rsi}" (arg2) - : "rcx", "r11") + [arg1] "{rdi}" (arg1), + [arg2] "{rsi}" (arg2) + : "rcx", "r11" + ); } -pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) -> usize { - asm volatile ("syscall" +pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize { + return asm volatile ("syscall" : [ret] "={rax}" (-> usize) : [number] "{rax}" (number), - [arg1] "{rdi}" (arg1), - [arg2] "{rsi}" (arg2), - [arg3] "{rdx}" (arg3) - : "rcx", "r11") + [arg1] "{rdi}" (arg1), + [arg2] "{rsi}" (arg2), + [arg3] "{rdx}" (arg3) + : "rcx", "r11" + ); } -pub fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) -> usize { - asm volatile ("syscall" +pub fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize { + return asm volatile ("syscall" : [ret] "={rax}" (-> usize) : [number] "{rax}" (number), - [arg1] "{rdi}" (arg1), - [arg2] "{rsi}" (arg2), - [arg3] "{rdx}" (arg3), - [arg4] "{r10}" (arg4) - : "rcx", "r11") + [arg1] "{rdi}" (arg1), + [arg2] "{rsi}" (arg2), + [arg3] "{rdx}" (arg3), + [arg4] "{r10}" (arg4) + : "rcx", "r11" + ); } -pub fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) -> usize { - asm volatile ("syscall" +pub fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize { + return asm volatile ("syscall" : [ret] "={rax}" (-> usize) : [number] "{rax}" (number), - [arg1] "{rdi}" (arg1), - [arg2] "{rsi}" (arg2), - [arg3] "{rdx}" (arg3), - [arg4] "{r10}" (arg4), - [arg5] "{r8}" (arg5) - : "rcx", "r11") + [arg1] "{rdi}" (arg1), + [arg2] "{rsi}" (arg2), + [arg3] "{rdx}" (arg3), + [arg4] "{r10}" (arg4), + [arg5] "{r8}" (arg5) + : "rcx", "r11" + ); } -pub fn syscall6(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, - arg5: usize, arg6: usize) -> usize -{ - asm volatile ("syscall" +pub fn syscall6( + number: usize, + arg1: usize, + arg2: usize, + arg3: usize, + arg4: usize, + arg5: usize, + arg6: usize, +) usize { + return asm volatile ("syscall" : [ret] "={rax}" (-> usize) : [number] "{rax}" (number), - [arg1] "{rdi}" (arg1), - [arg2] "{rsi}" (arg2), - [arg3] "{rdx}" (arg3), - [arg4] "{r10}" (arg4), - [arg5] "{r8}" (arg5), - [arg6] "{r9}" (arg6) - : "rcx", "r11") + [arg1] "{rdi}" (arg1), + [arg2] "{rsi}" (arg2), + [arg3] "{rdx}" (arg3), + [arg4] "{r10}" (arg4), + [arg5] "{r8}" (arg5), + [arg6] "{r9}" (arg6) + : "rcx", "r11" + ); } -pub nakedcc fn restore_rt() { +pub nakedcc fn restore_rt() void { asm volatile ("syscall" : : [number] "{rax}" (usize(SYS_rt_sigreturn)) - : "rcx", "r11") + : "rcx", "r11" + ); } - pub const msghdr = extern struct { msg_name: &u8, msg_namelen: socklen_t, diff --git a/std/os/index.zig b/std/os/index.zig index f332e8212a..ba3771c15e 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -24,7 +24,7 @@ test "std.os" { pub const windows = @import("windows/index.zig"); pub const darwin = @import("darwin.zig"); pub const linux = @import("linux/index.zig"); -pub const freebsd = @import("freebsd.zig"); +pub const freebsd = @import("freebsd/index.zig"); pub const zen = @import("zen.zig"); pub const posix = switch (builtin.os) { Os.linux => linux, -- cgit v1.2.3 From 7a3f0a55d9a481f260935f26426ee4508d44cb18 Mon Sep 17 00:00:00 2001 From: Greg V Date: Wed, 17 Oct 2018 18:01:00 +0300 Subject: Add freebsd to more things --- std/debug/index.zig | 2 ++ std/heap.zig | 6 +++--- std/os/file.zig | 6 +++--- std/os/index.zig | 6 +++--- std/os/path.zig | 11 ++++++++++- 5 files changed, 21 insertions(+), 10 deletions(-) (limited to 'std/os/index.zig') diff --git a/std/debug/index.zig b/std/debug/index.zig index e6d8fe3fc6..cabeba14f7 100644 --- a/std/debug/index.zig +++ b/std/debug/index.zig @@ -1078,6 +1078,8 @@ pub const DebugInfo = switch (builtin.os) { self.elf.close(); } }, + builtin.Os.freebsd => struct.{ + }, else => @compileError("Unsupported OS"), }; diff --git a/std/heap.zig b/std/heap.zig index 8a68a7b457..34addef094 100644 --- a/std/heap.zig +++ b/std/heap.zig @@ -69,7 +69,7 @@ pub const DirectAllocator = struct.{ const self = @fieldParentPtr(DirectAllocator, "allocator", allocator); switch (builtin.os) { - Os.linux, Os.macosx, Os.ios => { + Os.linux, Os.macosx, Os.ios, Os.freebsd => { const p = os.posix; const alloc_size = if (alignment <= os.page_size) n else n + alignment; const addr = p.mmap(null, alloc_size, p.PROT_READ | p.PROT_WRITE, p.MAP_PRIVATE | p.MAP_ANONYMOUS, -1, 0); @@ -120,7 +120,7 @@ pub const DirectAllocator = struct.{ const self = @fieldParentPtr(DirectAllocator, "allocator", allocator); switch (builtin.os) { - Os.linux, Os.macosx, Os.ios => { + Os.linux, Os.macosx, Os.ios, Os.freebsd => { if (new_size <= old_mem.len) { const base_addr = @ptrToInt(old_mem.ptr); const old_addr_end = base_addr + old_mem.len; @@ -165,7 +165,7 @@ pub const DirectAllocator = struct.{ const self = @fieldParentPtr(DirectAllocator, "allocator", allocator); switch (builtin.os) { - Os.linux, Os.macosx, Os.ios => { + Os.linux, Os.macosx, Os.ios, Os.freebsd => { _ = os.posix.munmap(@ptrToInt(bytes.ptr), bytes.len); }, Os.windows => { diff --git a/std/os/file.zig b/std/os/file.zig index 293d637d19..4c21cc9b5a 100644 --- a/std/os/file.zig +++ b/std/os/file.zig @@ -229,7 +229,7 @@ pub const File = struct.{ pub fn seekForward(self: File, amount: isize) !void { switch (builtin.os) { - Os.linux, Os.macosx, Os.ios => { + Os.linux, Os.macosx, Os.ios, Os.freebsd => { const result = posix.lseek(self.handle, amount, posix.SEEK_CUR); const err = posix.getErrno(result); if (err > 0) { @@ -260,7 +260,7 @@ pub const File = struct.{ pub fn seekTo(self: File, pos: usize) !void { switch (builtin.os) { - Os.linux, Os.macosx, Os.ios => { + Os.linux, Os.macosx, Os.ios, Os.freebsd => { const ipos = try math.cast(isize, pos); const result = posix.lseek(self.handle, ipos, posix.SEEK_SET); const err = posix.getErrno(result); @@ -294,7 +294,7 @@ pub const File = struct.{ pub fn getPos(self: File) !usize { switch (builtin.os) { - Os.linux, Os.macosx, Os.ios => { + Os.linux, Os.macosx, Os.ios, Os.freebsd => { const result = posix.lseek(self.handle, 0, posix.SEEK_CUR); const err = posix.getErrno(result); if (err > 0) { diff --git a/std/os/index.zig b/std/os/index.zig index ba3771c15e..16bc571a83 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -3,7 +3,7 @@ const builtin = @import("builtin"); const Os = builtin.Os; const is_windows = builtin.os == Os.windows; const is_posix = switch (builtin.os) { - builtin.Os.linux, builtin.Os.macosx => true, + builtin.Os.linux, builtin.Os.macosx, builtin.Os.freebsd => true, else => false, }; const os = @This(); @@ -42,7 +42,7 @@ pub const time = @import("time.zig"); pub const page_size = 4 * 1024; pub const MAX_PATH_BYTES = switch (builtin.os) { - Os.linux, Os.macosx, Os.ios => posix.PATH_MAX, + Os.linux, Os.macosx, Os.ios, Os.freebsd => posix.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. @@ -103,7 +103,7 @@ const math = std.math; /// library implementation. pub fn getRandomBytes(buf: []u8) !void { switch (builtin.os) { - Os.linux => while (true) { + Os.linux, Os.freebsd => while (true) { // TODO check libc version and potentially call c.getrandom. // See #397 const errno = posix.getErrno(posix.getrandom(buf.ptr, buf.len, 0)); diff --git a/std/os/path.zig b/std/os/path.zig index 8096cdd0d2..e0d8030bcc 100644 --- a/std/os/path.zig +++ b/std/os/path.zig @@ -1161,7 +1161,7 @@ pub fn realC(out_buffer: *[os.MAX_PATH_BYTES]u8, pathname: [*]const u8) RealErro const pathname_w = try windows_util.cStrToPrefixedFileW(pathname); return realW(out_buffer, pathname_w); }, - Os.macosx, Os.ios, Os.freebsd => { + Os.macosx, Os.ios => { // TODO instead of calling the libc function here, port the implementation to Zig const err = posix.getErrno(posix.realpath(pathname, out_buffer)); switch (err) { @@ -1188,6 +1188,15 @@ pub fn realC(out_buffer: *[os.MAX_PATH_BYTES]u8, pathname: [*]const u8) RealErro return os.readLinkC(out_buffer, proc_path.ptr); }, + Os.freebsd => { // XXX requires fdescfs + const fd = try os.posixOpenC(pathname, posix.O_PATH | posix.O_NONBLOCK | posix.O_CLOEXEC, 0); + defer os.close(fd); + + var buf: ["/dev/fd/-2147483648".len]u8 = undefined; + const proc_path = fmt.bufPrint(buf[0..], "/dev/fd/{}\x00", fd) catch unreachable; + + return os.readLinkC(out_buffer, proc_path.ptr); + }, else => @compileError("TODO implement os.path.real for " ++ @tagName(builtin.os)), } } -- cgit v1.2.3 From e5627f8e635c05a91edeb97b6d0e392d095ce39f Mon Sep 17 00:00:00 2001 From: Greg V Date: Wed, 17 Oct 2018 22:21:48 +0300 Subject: Support more of std on FreeBSD --- CMakeLists.txt | 1 + std/c/freebsd.zig | 36 ++++++++ std/c/index.zig | 1 + std/event/fs.zig | 32 ++++--- std/event/loop.zig | 27 +++--- std/os/freebsd/index.zig | 212 +++++++++++++++++++++++++++++++++++++++++++- std/os/get_app_data_dir.zig | 2 +- std/os/index.zig | 34 ++++--- 8 files changed, 308 insertions(+), 37 deletions(-) create mode 100644 std/c/freebsd.zig (limited to 'std/os/index.zig') diff --git a/CMakeLists.txt b/CMakeLists.txt index f10fc91b16..4ee9bcad1f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -444,6 +444,7 @@ set(ZIG_STD_FILES "buffer.zig" "build.zig" "c/darwin.zig" + "c/freebsd.zig" "c/index.zig" "c/linux.zig" "c/windows.zig" diff --git a/std/c/freebsd.zig b/std/c/freebsd.zig new file mode 100644 index 0000000000..6eb34929b5 --- /dev/null +++ b/std/c/freebsd.zig @@ -0,0 +1,36 @@ + +const timespec = @import("../os/freebsd/index.zig").timespec; + +extern "c" fn __error() *c_int; +pub const _errno = __error; + +pub extern "c" fn kqueue() c_int; +pub extern "c" fn kevent( + kq: c_int, + changelist: [*]const Kevent, + nchanges: c_int, + eventlist: [*]Kevent, + nevents: c_int, + timeout: ?*const timespec, +) c_int; +pub extern "c" fn sysctl(name: [*]c_int, namelen: c_uint, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int; +pub extern "c" fn sysctlbyname(name: [*]const u8, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int; +pub extern "c" fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usize) c_int; + +/// Renamed from `kevent` to `Kevent` to avoid conflict with function name. +pub const Kevent = extern struct.{ + ident: usize, + filter: i16, + flags: u16, + fflags: u32, + data: i64, + udata: usize, + // TODO ext +}; + + +pub const pthread_attr_t = extern struct.{ + __size: [56]u8, + __align: c_long, +}; + diff --git a/std/c/index.zig b/std/c/index.zig index 6b20d718ef..4aab39d931 100644 --- a/std/c/index.zig +++ b/std/c/index.zig @@ -5,6 +5,7 @@ pub use switch (builtin.os) { Os.linux => @import("linux.zig"), Os.windows => @import("windows.zig"), Os.macosx, Os.ios => @import("darwin.zig"), + Os.freebsd => @import("freebsd.zig"), else => empty_import, }; const empty_import = @import("../empty.zig"); diff --git a/std/event/fs.zig b/std/event/fs.zig index 56eee387b2..b20272dcb0 100644 --- a/std/event/fs.zig +++ b/std/event/fs.zig @@ -83,6 +83,7 @@ pub async fn pwritev(loop: *Loop, fd: os.FileHandle, data: []const []const u8, o switch (builtin.os) { builtin.Os.macosx, builtin.Os.linux, + builtin.Os.freebsd, => { const iovecs = try loop.allocator.alloc(os.posix.iovec_const, data.len); defer loop.allocator.free(iovecs); @@ -219,6 +220,7 @@ pub async fn preadv(loop: *Loop, fd: os.FileHandle, data: []const []u8, offset: switch (builtin.os) { builtin.Os.macosx, builtin.Os.linux, + builtin.Os.freebsd, => { const iovecs = try loop.allocator.alloc(os.posix.iovec, data.len); defer loop.allocator.free(iovecs); @@ -399,7 +401,7 @@ pub async fn openPosix( pub async fn openRead(loop: *Loop, path: []const u8) os.File.OpenError!os.FileHandle { switch (builtin.os) { - builtin.Os.macosx, builtin.Os.linux => { + builtin.Os.macosx, builtin.Os.linux, builtin.Os.freebsd => { const flags = posix.O_LARGEFILE | posix.O_RDONLY | posix.O_CLOEXEC; return await (async openPosix(loop, path, flags, os.File.default_mode) catch unreachable); }, @@ -427,6 +429,7 @@ pub async fn openWriteMode(loop: *Loop, path: []const u8, mode: os.File.Mode) os switch (builtin.os) { builtin.Os.macosx, builtin.Os.linux, + builtin.Os.freebsd, => { const flags = posix.O_LARGEFILE | posix.O_WRONLY | posix.O_CREAT | posix.O_CLOEXEC | posix.O_TRUNC; return await (async openPosix(loop, path, flags, os.File.default_mode) catch unreachable); @@ -449,7 +452,7 @@ pub async fn openReadWrite( mode: os.File.Mode, ) os.File.OpenError!os.FileHandle { switch (builtin.os) { - builtin.Os.macosx, builtin.Os.linux => { + builtin.Os.macosx, builtin.Os.linux, builtin.Os.freebsd => { const flags = posix.O_LARGEFILE | posix.O_RDWR | posix.O_CREAT | posix.O_CLOEXEC; return await (async openPosix(loop, path, flags, mode) catch unreachable); }, @@ -477,7 +480,7 @@ pub const CloseOperation = struct.{ os_data: OsData, const OsData = switch (builtin.os) { - builtin.Os.linux, builtin.Os.macosx => OsDataPosix, + builtin.Os.linux, builtin.Os.macosx, builtin.Os.freebsd => OsDataPosix, builtin.Os.windows => struct.{ handle: ?os.FileHandle, @@ -496,7 +499,7 @@ pub const CloseOperation = struct.{ self.* = CloseOperation.{ .loop = loop, .os_data = switch (builtin.os) { - builtin.Os.linux, builtin.Os.macosx => initOsDataPosix(self), + builtin.Os.linux, builtin.Os.macosx, builtin.Os.freebsd => initOsDataPosix(self), builtin.Os.windows => OsData.{ .handle = null }, else => @compileError("Unsupported OS"), }, @@ -525,6 +528,7 @@ pub const CloseOperation = struct.{ switch (builtin.os) { builtin.Os.linux, builtin.Os.macosx, + builtin.Os.freebsd, => { if (self.os_data.have_fd) { self.loop.posixFsRequest(&self.os_data.close_req_node); @@ -546,6 +550,7 @@ pub const CloseOperation = struct.{ switch (builtin.os) { builtin.Os.linux, builtin.Os.macosx, + builtin.Os.freebsd, => { self.os_data.close_req_node.data.msg.Close.fd = handle; self.os_data.have_fd = true; @@ -562,6 +567,7 @@ pub const CloseOperation = struct.{ switch (builtin.os) { builtin.Os.linux, builtin.Os.macosx, + builtin.Os.freebsd, => { self.os_data.have_fd = false; }, @@ -576,6 +582,7 @@ pub const CloseOperation = struct.{ switch (builtin.os) { builtin.Os.linux, builtin.Os.macosx, + builtin.Os.freebsd, => { assert(self.os_data.have_fd); return self.os_data.close_req_node.data.msg.Close.fd; @@ -599,6 +606,7 @@ pub async fn writeFileMode(loop: *Loop, path: []const u8, contents: []const u8, switch (builtin.os) { builtin.Os.linux, builtin.Os.macosx, + builtin.Os.freebsd, => return await (async writeFileModeThread(loop, path, contents, mode) catch unreachable), builtin.Os.windows => return await (async writeFileWindows(loop, path, contents) catch unreachable), else => @compileError("Unsupported OS"), @@ -704,7 +712,7 @@ pub fn Watch(comptime V: type) type { os_data: OsData, const OsData = switch (builtin.os) { - builtin.Os.macosx => struct.{ + builtin.Os.macosx, builtin.Os.freebsd => struct.{ file_table: FileTable, table_lock: event.Lock, @@ -793,7 +801,7 @@ pub fn Watch(comptime V: type) type { return self; }, - builtin.Os.macosx => { + builtin.Os.macosx, builtin.Os.freebsd => { const self = try loop.allocator.createOne(Self); errdefer loop.allocator.destroy(self); @@ -813,7 +821,7 @@ pub fn Watch(comptime V: type) type { /// All addFile calls and removeFile calls must have completed. pub fn destroy(self: *Self) void { switch (builtin.os) { - builtin.Os.macosx => { + builtin.Os.macosx, builtin.Os.freebsd => { // TODO we need to cancel the coroutines before destroying the lock self.os_data.table_lock.deinit(); var it = self.os_data.file_table.iterator(); @@ -855,14 +863,14 @@ pub fn Watch(comptime V: type) type { pub async fn addFile(self: *Self, file_path: []const u8, value: V) !?V { switch (builtin.os) { - builtin.Os.macosx => return await (async addFileMacosx(self, file_path, value) catch unreachable), + builtin.Os.macosx, builtin.Os.freebsd => return await (async addFileKEvent(self, file_path, value) catch unreachable), builtin.Os.linux => return await (async addFileLinux(self, file_path, value) catch unreachable), builtin.Os.windows => return await (async addFileWindows(self, file_path, value) catch unreachable), else => @compileError("Unsupported OS"), } } - async fn addFileMacosx(self: *Self, file_path: []const u8, value: V) !?V { + async fn addFileKEvent(self: *Self, file_path: []const u8, value: V) !?V { const resolved_path = try os.path.resolve(self.channel.loop.allocator, file_path); var resolved_path_consumed = false; defer if (!resolved_path_consumed) self.channel.loop.allocator.free(resolved_path); @@ -871,7 +879,11 @@ pub fn Watch(comptime V: type) type { var close_op_consumed = false; defer if (!close_op_consumed) close_op.finish(); - const flags = posix.O_SYMLINK | posix.O_EVTONLY; + + const flags = switch (builtin.os) { + builtin.Os.macosx => posix.O_SYMLINK | posix.O_EVTONLY, + else => 0, + }; const mode = 0; const fd = try await (async openPosix(self.channel.loop, resolved_path, flags, mode) catch unreachable); close_op.setHandle(fd); diff --git a/std/event/loop.zig b/std/event/loop.zig index 73d1d8975f..68c22f38b9 100644 --- a/std/event/loop.zig +++ b/std/event/loop.zig @@ -48,7 +48,7 @@ pub const Loop = struct.{ }; pub const EventFd = switch (builtin.os) { - builtin.Os.macosx => MacOsEventFd, + builtin.Os.macosx, builtin.Os.freebsd => KEventFd, builtin.Os.linux => struct.{ base: ResumeNode, epoll_op: u32, @@ -61,13 +61,13 @@ pub const Loop = struct.{ else => @compileError("unsupported OS"), }; - const MacOsEventFd = struct.{ + const KEventFd = struct.{ base: ResumeNode, kevent: posix.Kevent, }; pub const Basic = switch (builtin.os) { - builtin.Os.macosx => MacOsBasic, + builtin.Os.macosx, builtin.Os.freebsd => KEventBasic, builtin.Os.linux => struct.{ base: ResumeNode, }, @@ -77,7 +77,7 @@ pub const Loop = struct.{ else => @compileError("unsupported OS"), }; - const MacOsBasic = struct.{ + const KEventBasic = struct.{ base: ResumeNode, kev: posix.Kevent, }; @@ -213,7 +213,7 @@ pub const Loop = struct.{ self.extra_threads[extra_thread_index] = try os.spawnThread(self, workerRun); } }, - builtin.Os.macosx => { + builtin.Os.macosx, builtin.Os.freebsd => { self.os_data.kqfd = try os.bsdKQueue(); errdefer os.close(self.os_data.kqfd); @@ -368,7 +368,7 @@ pub const Loop = struct.{ os.close(self.os_data.epollfd); self.allocator.free(self.eventfd_resume_nodes); }, - builtin.Os.macosx => { + builtin.Os.macosx, builtin.Os.freebsd => { os.close(self.os_data.kqfd); os.close(self.os_data.fs_kqfd); }, @@ -483,7 +483,7 @@ pub const Loop = struct.{ const eventfd_node = &resume_stack_node.data; eventfd_node.base.handle = next_tick_node.data; switch (builtin.os) { - builtin.Os.macosx => { + builtin.Os.macosx, builtin.Os.freebsd => { const kevent_array = (*[1]posix.Kevent)(&eventfd_node.kevent); const empty_kevs = ([*]posix.Kevent)(undefined)[0..0]; _ = os.bsdKEvent(self.os_data.kqfd, kevent_array, empty_kevs, null) catch { @@ -545,6 +545,7 @@ pub const Loop = struct.{ switch (builtin.os) { builtin.Os.linux, builtin.Os.macosx, + builtin.Os.freebsd, => self.os_data.fs_thread.wait(), else => {}, } @@ -609,7 +610,7 @@ pub const Loop = struct.{ os.posixWrite(self.os_data.final_eventfd, wakeup_bytes) catch unreachable; return; }, - builtin.Os.macosx => { + builtin.Os.macosx, builtin.Os.freebsd => { self.posixFsRequest(&self.os_data.fs_end_request); const final_kevent = (*[1]posix.Kevent)(&self.os_data.final_kevent); const empty_kevs = ([*]posix.Kevent)(undefined)[0..0]; @@ -667,7 +668,7 @@ pub const Loop = struct.{ } } }, - builtin.Os.macosx => { + builtin.Os.macosx, builtin.Os.freebsd => { var eventlist: [1]posix.Kevent = undefined; const empty_kevs = ([*]posix.Kevent)(undefined)[0..0]; const count = os.bsdKEvent(self.os_data.kqfd, empty_kevs, eventlist[0..], null) catch unreachable; @@ -730,7 +731,7 @@ pub const Loop = struct.{ self.beginOneEvent(); // finished in posixFsRun after processing the msg self.os_data.fs_queue.put(request_node); switch (builtin.os) { - builtin.Os.macosx => { + builtin.Os.macosx, builtin.Os.freebsd => { const fs_kevs = (*[1]posix.Kevent)(&self.os_data.fs_kevent_wake); const empty_kevs = ([*]posix.Kevent)(undefined)[0..0]; _ = os.bsdKEvent(self.os_data.fs_kqfd, fs_kevs, empty_kevs, null) catch unreachable; @@ -800,7 +801,7 @@ pub const Loop = struct.{ else => unreachable, } }, - builtin.Os.macosx => { + builtin.Os.macosx, builtin.Os.freebsd => { const fs_kevs = (*[1]posix.Kevent)(&self.os_data.fs_kevent_wait); var out_kevs: [1]posix.Kevent = undefined; _ = os.bsdKEvent(self.os_data.fs_kqfd, fs_kevs, out_kevs[0..], null) catch unreachable; @@ -812,7 +813,7 @@ pub const Loop = struct.{ const OsData = switch (builtin.os) { builtin.Os.linux => LinuxOsData, - builtin.Os.macosx => MacOsData, + builtin.Os.macosx, builtin.Os.freebsd => KEventData, builtin.Os.windows => struct.{ io_port: windows.HANDLE, extra_thread_count: usize, @@ -820,7 +821,7 @@ pub const Loop = struct.{ else => struct.{}, }; - const MacOsData = struct.{ + const KEventData = struct.{ kqfd: i32, final_kevent: posix.Kevent, fs_kevent_wake: posix.Kevent, diff --git a/std/os/freebsd/index.zig b/std/os/freebsd/index.zig index 1df773b04b..1793379fb5 100644 --- a/std/os/freebsd/index.zig +++ b/std/os/freebsd/index.zig @@ -7,6 +7,10 @@ const arch = switch (builtin.arch) { pub use @import("syscall.zig"); pub use @import("errno.zig"); +const std = @import("../../index.zig"); +const c = std.c; +pub const Kevent = c.Kevent; + pub const PATH_MAX = 1024; pub const STDIN_FILENO = 0; @@ -293,6 +297,156 @@ pub const DT_LNK = 10; pub const DT_SOCK = 12; pub const DT_WHT = 14; +/// add event to kq (implies enable) +pub const EV_ADD = 0x0001; + +/// delete event from kq +pub const EV_DELETE = 0x0002; + +/// enable event +pub const EV_ENABLE = 0x0004; + +/// disable event (not reported) +pub const EV_DISABLE = 0x0008; + +/// only report one occurrence +pub const EV_ONESHOT = 0x0010; + +/// clear event state after reporting +pub const EV_CLEAR = 0x0020; + +/// force immediate event output +/// ... with or without EV_ERROR +/// ... use KEVENT_FLAG_ERROR_EVENTS +/// on syscalls supporting flags +pub const EV_RECEIPT = 0x0040; + +/// disable event after reporting +pub const EV_DISPATCH = 0x0080; + +pub const EVFILT_READ = -1; +pub const EVFILT_WRITE = -2; + +/// attached to aio requests +pub const EVFILT_AIO = -3; + +/// attached to vnodes +pub const EVFILT_VNODE = -4; + +/// attached to struct proc +pub const EVFILT_PROC = -5; + +/// attached to struct proc +pub const EVFILT_SIGNAL = -6; + +/// timers +pub const EVFILT_TIMER = -7; + +/// Process descriptors +pub const EVFILT_PROCDESC = -8; + +/// Filesystem events +pub const EVFILT_FS = -9; + +pub const EVFILT_LIO = -10; + +/// User events +pub const EVFILT_USER = -11; + +/// Sendfile events +pub const EVFILT_SENDFILE = -12; + +pub const EVFILT_EMPTY = -13; + +/// On input, NOTE_TRIGGER causes the event to be triggered for output. +pub const NOTE_TRIGGER = 0x01000000; + +/// ignore input fflags +pub const NOTE_FFNOP = 0x00000000; + +/// and fflags +pub const NOTE_FFAND = 0x40000000; + +/// or fflags +pub const NOTE_FFOR = 0x80000000; + +/// copy fflags +pub const NOTE_FFCOPY = 0xc0000000; + +/// mask for operations +pub const NOTE_FFCTRLMASK = 0xc0000000; +pub const NOTE_FFLAGSMASK = 0x00ffffff; + + +/// low water mark +pub const NOTE_LOWAT = 0x00000001; + +/// behave like poll() +pub const NOTE_FILE_POLL = 0x00000002; + +/// vnode was removed +pub const NOTE_DELETE = 0x00000001; + +/// data contents changed +pub const NOTE_WRITE = 0x00000002; + +/// size increased +pub const NOTE_EXTEND = 0x00000004; + +/// attributes changed +pub const NOTE_ATTRIB = 0x00000008; + +/// link count changed +pub const NOTE_LINK = 0x00000010; + +/// vnode was renamed +pub const NOTE_RENAME = 0x00000020; + +/// vnode access was revoked +pub const NOTE_REVOKE = 0x00000040; + +/// vnode was opened +pub const NOTE_OPEN = 0x00000080; + +/// file closed, fd did not allow write +pub const NOTE_CLOSE = 0x00000100; + +/// file closed, fd did allow write +pub const NOTE_CLOSE_WRITE = 0x00000200; + +/// file was read +pub const NOTE_READ = 0x00000400; + +/// process exited +pub const NOTE_EXIT = 0x80000000; + +/// process forked +pub const NOTE_FORK = 0x40000000; + +/// process exec'd +pub const NOTE_EXEC = 0x20000000; + +/// mask for signal & exit status +pub const NOTE_PDATAMASK = 0x000fffff; +pub const NOTE_PCTRLMASK = (~NOTE_PDATAMASK); + +/// data is seconds +pub const NOTE_SECONDS = 0x00000001; + +/// data is milliseconds +pub const NOTE_MSECONDS = 0x00000002; + +/// data is microseconds +pub const NOTE_USECONDS = 0x00000004; + +/// data is nanoseconds +pub const NOTE_NSECONDS = 0x00000008; + +/// timeout is absolute +pub const NOTE_ABSTIME = 0x00000010; + + + pub const TCGETS = 0x5401; pub const TCSETS = 0x5402; pub const TCSETSW = 0x5403; @@ -445,7 +599,11 @@ pub fn symlink(existing: [*]const u8, new: [*]const u8) usize { } pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: usize) usize { - return arch.syscall4(SYS_pread, usize(fd), @ptrToInt(buf), count, offset); + return arch.syscall4(SYS_pread, @intCast(usize, fd), @ptrToInt(buf), count, offset); +} + +pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: usize) usize { + return arch.syscall4(SYS_preadv, @intCast(usize, fd), @ptrToInt(iov), count, offset); } pub fn pipe(fd: *[2]i32) usize { @@ -464,6 +622,10 @@ pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: usize) usize { return arch.syscall4(SYS_pwrite, @intCast(usize, fd), @ptrToInt(buf), count, offset); } +pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: usize) usize { + return arch.syscall4(SYS_pwritev, @intCast(usize, fd), @ptrToInt(iov), count, offset); +} + pub fn rename(old: [*]const u8, new: [*]const u8) usize { return arch.syscall2(SYS_rename, @ptrToInt(old), @ptrToInt(new)); } @@ -590,3 +752,51 @@ pub const timespec = arch.timespec; pub fn fstat(fd: i32, stat_buf: *Stat) usize { return arch.syscall2(SYS_fstat, @intCast(usize, fd), @ptrToInt(stat_buf)); } + +pub const iovec = extern struct.{ + iov_base: [*]u8, + iov_len: usize, +}; + +pub const iovec_const = extern struct.{ + iov_base: [*]const u8, + iov_len: usize, +}; + +pub fn kqueue() usize { + return errnoWrap(c.kqueue()); +} + +pub fn kevent(kq: i32, changelist: []const Kevent, eventlist: []Kevent, timeout: ?*const timespec) usize { + return errnoWrap(c.kevent( + kq, + changelist.ptr, + @intCast(c_int, changelist.len), + eventlist.ptr, + @intCast(c_int, eventlist.len), + timeout, + )); +} + +pub fn sysctl(name: [*]c_int, namelen: c_uint, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) usize { + return errnoWrap(c.sysctl(name, namelen, oldp, oldlenp, newp, newlen)); +} + +pub fn sysctlbyname(name: [*]const u8, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) usize { + return errnoWrap(c.sysctlbyname(name, oldp, oldlenp, newp, newlen)); +} + +pub fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usize) usize { + return errnoWrap(c.sysctlnametomib(name, wibp, sizep)); +} + + + +/// Takes the return value from a syscall and formats it back in the way +/// that the kernel represents it to libc. Errno was a mistake, let's make +/// it go away forever. +fn errnoWrap(value: isize) usize { + return @bitCast(usize, if (value == -1) -isize(c._errno().*) else value); +} + + diff --git a/std/os/get_app_data_dir.zig b/std/os/get_app_data_dir.zig index 48826f5aed..513978fef6 100644 --- a/std/os/get_app_data_dir.zig +++ b/std/os/get_app_data_dir.zig @@ -43,7 +43,7 @@ pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataD }; return os.path.join(allocator, home_dir, "Library", "Application Support", appname); }, - builtin.Os.linux => { + builtin.Os.linux, builtin.Os.freebsd => { const home_dir = os.getEnvPosix("HOME") orelse { // TODO look in /etc/passwd return error.AppDataDirUnavailable; diff --git a/std/os/index.zig b/std/os/index.zig index 16bc571a83..36a7290d7e 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -421,7 +421,7 @@ pub fn posix_pwritev(fd: i32, iov: [*]const posix.iovec_const, count: usize, off } } }, - builtin.Os.linux => while (true) { + builtin.Os.linux, builtin.Os.freebsd => while (true) { const rc = posix.pwritev(fd, iov, count, offset); const err = posix.getErrno(rc); switch (err) { @@ -689,7 +689,7 @@ pub fn getBaseAddress() usize { }; return phdr - @sizeOf(ElfHeader); }, - builtin.Os.macosx => return @ptrToInt(&std.c._mh_execute_header), + builtin.Os.macosx, builtin.Os.freebsd => return @ptrToInt(&std.c._mh_execute_header), builtin.Os.windows => return @ptrToInt(windows.GetModuleHandleW(null)), else => @compileError("Unsupported OS"), } @@ -1307,7 +1307,7 @@ pub fn deleteDirC(dir_path: [*]const u8) DeleteDirError!void { const dir_path_w = try windows_util.cStrToPrefixedFileW(dir_path); return deleteDirW(&dir_path_w); }, - Os.linux, Os.macosx, Os.ios => { + Os.linux, Os.macosx, Os.ios, Os.freebsd => { const err = posix.getErrno(posix.rmdir(dir_path)); switch (err) { 0 => return, @@ -1350,7 +1350,7 @@ pub fn deleteDir(dir_path: []const u8) DeleteDirError!void { const dir_path_w = try windows_util.sliceToPrefixedFileW(dir_path); return deleteDirW(&dir_path_w); }, - Os.linux, Os.macosx, Os.ios => { + Os.linux, Os.macosx, Os.ios, Os.freebsd => { const dir_path_c = try toPosixPath(dir_path); return deleteDirC(&dir_path_c); }, @@ -1467,7 +1467,7 @@ pub const Dir = struct.{ allocator: *Allocator, pub const Handle = switch (builtin.os) { - Os.macosx, Os.ios => struct.{ + Os.macosx, Os.ios, Os.freebsd => struct.{ fd: i32, seek: i64, buf: []u8, @@ -1543,7 +1543,7 @@ pub const Dir = struct.{ .name_data = undefined, }; }, - Os.macosx, Os.ios => Handle.{ + Os.macosx, Os.ios, Os.freebsd => Handle.{ .fd = try posixOpen( dir_path, posix.O_RDONLY | posix.O_NONBLOCK | posix.O_DIRECTORY | posix.O_CLOEXEC, @@ -1574,7 +1574,7 @@ pub const Dir = struct.{ Os.windows => { _ = windows.FindClose(self.handle.handle); }, - Os.macosx, Os.ios, Os.linux => { + Os.macosx, Os.ios, Os.linux, Os.freebsd => { self.allocator.free(self.handle.buf); os.close(self.handle.fd); }, @@ -1589,6 +1589,7 @@ pub const Dir = struct.{ Os.linux => return self.nextLinux(), Os.macosx, Os.ios => return self.nextDarwin(), Os.windows => return self.nextWindows(), + Os.freebsd => return self.nextFreebsd(), else => @compileError("unimplemented"), } } @@ -1728,6 +1729,11 @@ pub const Dir = struct.{ }; } } + + fn nextFreebsd(self: *Dir) !?Entry { + self.handle.buf = try self.allocator.alloc(u8, page_size); + return null; // TODO + } }; pub fn changeCurDir(allocator: *Allocator, dir_path: []const u8) !void { @@ -2166,7 +2172,7 @@ pub fn unexpectedErrorWindows(err: windows.DWORD) UnexpectedError { pub fn openSelfExe() !os.File { switch (builtin.os) { Os.linux => return os.File.openReadC(c"/proc/self/exe"), - Os.macosx, Os.ios => { + Os.macosx, Os.ios, Os.freebsd => { var buf: [MAX_PATH_BYTES]u8 = undefined; const self_exe_path = try selfExePath(&buf); buf[self_exe_path.len] = 0; @@ -2183,7 +2189,7 @@ pub fn openSelfExe() !os.File { test "openSelfExe" { switch (builtin.os) { - Os.linux, Os.macosx, Os.ios, Os.windows => (try openSelfExe()).close(), + Os.linux, Os.macosx, Os.ios, Os.windows, Os.freebsd => (try openSelfExe()).close(), else => return error.SkipZigTest, // Unsupported OS. } } @@ -2214,6 +2220,7 @@ pub fn selfExePathW(out_buffer: *[windows_util.PATH_MAX_WIDE]u16) ![]u16 { pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) ![]u8 { switch (builtin.os) { Os.linux => return readLink(out_buffer, "/proc/self/exe"), + Os.freebsd => return readLink(out_buffer, "/proc/curproc/file"), Os.windows => { var utf16le_buf: [windows_util.PATH_MAX_WIDE]u16 = undefined; const utf16le_slice = try selfExePathW(&utf16le_buf); @@ -2252,7 +2259,7 @@ pub fn selfExeDirPath(out_buffer: *[MAX_PATH_BYTES]u8) ![]const u8 { // will not return null. return path.dirname(full_exe_path).?; }, - Os.windows, Os.macosx, Os.ios => { + Os.windows, Os.macosx, Os.ios, Os.freebsd => { const self_exe_path = try selfExePath(out_buffer); // Assume that the OS APIs return absolute paths, and therefore dirname // will not return null. @@ -3085,10 +3092,13 @@ pub const CpuCountError = error.{ pub fn cpuCount(fallback_allocator: *mem.Allocator) CpuCountError!usize { switch (builtin.os) { - builtin.Os.macosx => { + builtin.Os.macosx, builtin.Os.freebsd => { var count: c_int = undefined; var count_len: usize = @sizeOf(c_int); - const rc = posix.sysctlbyname(c"hw.logicalcpu", @ptrCast(*c_void, &count), &count_len, null, 0); + const rc = posix.sysctlbyname(switch (builtin.os) { + builtin.Os.macosx => c"hw.logicalcpu", + else => c"hw.ncpu", + }, @ptrCast(*c_void, &count), &count_len, null, 0); const err = posix.getErrno(rc); switch (err) { 0 => return @intCast(usize, count), -- cgit v1.2.3