diff options
Diffstat (limited to 'std/os')
| -rw-r--r-- | std/os/freebsd/index.zig | 212 | ||||
| -rw-r--r-- | std/os/get_app_data_dir.zig | 2 | ||||
| -rw-r--r-- | std/os/index.zig | 34 |
3 files changed, 234 insertions, 14 deletions
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), |
