aboutsummaryrefslogtreecommitdiff
path: root/std/os
diff options
context:
space:
mode:
Diffstat (limited to 'std/os')
-rw-r--r--std/os/freebsd/index.zig212
-rw-r--r--std/os/get_app_data_dir.zig2
-rw-r--r--std/os/index.zig34
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),