Support more of std on FreeBSD
parent
831bb66895
commit
e5627f8e63
|
@ -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"
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
|
|
Loading…
Reference in New Issue