authorgravatar for greg@unrelenting.technologyGreg V <greg@unrelenting.technology> 2018-10-17 22:21:48+03:00
committergravatar for greg@unrelenting.technologyGreg V <greg@unrelenting.technology> 2018-10-20 15:21:35+03:00
loge5627f8e635c05a91edeb97b6d0e392d095ce39f
tree8c7bb5ffc769367faecc7535b95b51d18b042cde
parent831bb668955fa9d332f7beb1ea11f1c8028e5235

Support more of std on FreeBSD


8 files changed, 308 insertions(+), 37 deletions(-)

CMakeLists.txt+1
...@@ -444,6 +444,7 @@ set(ZIG_STD_FILES...@@ -444,6 +444,7 @@ set(ZIG_STD_FILES
444 "buffer.zig"444 "buffer.zig"
445 "build.zig"445 "build.zig"
446 "c/darwin.zig"446 "c/darwin.zig"
447 "c/freebsd.zig"
447 "c/index.zig"448 "c/index.zig"
448 "c/linux.zig"449 "c/linux.zig"
449 "c/windows.zig"450 "c/windows.zig"
std/c/freebsd.zig created+36
...@@ -0,0 +1,36 @@
1
2const timespec = @import("../os/freebsd/index.zig").timespec;
3
4extern "c" fn __error() *c_int;
5pub const _errno = __error;
6
7pub extern "c" fn kqueue() c_int;
8pub extern "c" fn kevent(
9 kq: c_int,
10 changelist: [*]const Kevent,
11 nchanges: c_int,
12 eventlist: [*]Kevent,
13 nevents: c_int,
14 timeout: ?*const timespec,
15) c_int;
16pub extern "c" fn sysctl(name: [*]c_int, namelen: c_uint, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int;
17pub extern "c" fn sysctlbyname(name: [*]const u8, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int;
18pub extern "c" fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usize) c_int;
19
20/// Renamed from `kevent` to `Kevent` to avoid conflict with function name.
21pub const Kevent = extern struct.{
22 ident: usize,
23 filter: i16,
24 flags: u16,
25 fflags: u32,
26 data: i64,
27 udata: usize,
28 // TODO ext
29};
30
31
32pub const pthread_attr_t = extern struct.{
33 __size: [56]u8,
34 __align: c_long,
35};
36
std/c/index.zig+1
...@@ -5,6 +5,7 @@ pub use switch (builtin.os) {...@@ -5,6 +5,7 @@ pub use switch (builtin.os) {
5 Os.linux => @import("linux.zig"),5 Os.linux => @import("linux.zig"),
6 Os.windows => @import("windows.zig"),6 Os.windows => @import("windows.zig"),
7 Os.macosx, Os.ios => @import("darwin.zig"),7 Os.macosx, Os.ios => @import("darwin.zig"),
8 Os.freebsd => @import("freebsd.zig"),
8 else => empty_import,9 else => empty_import,
9};10};
10const empty_import = @import("../empty.zig");11const empty_import = @import("../empty.zig");
std/event/fs.zig+22-10
...@@ -83,6 +83,7 @@ pub async fn pwritev(loop: *Loop, fd: os.FileHandle, data: []const []const u8, o...@@ -83,6 +83,7 @@ pub async fn pwritev(loop: *Loop, fd: os.FileHandle, data: []const []const u8, o
83 switch (builtin.os) {83 switch (builtin.os) {
84 builtin.Os.macosx,84 builtin.Os.macosx,
85 builtin.Os.linux,85 builtin.Os.linux,
86 builtin.Os.freebsd,
86 => {87 => {
87 const iovecs = try loop.allocator.alloc(os.posix.iovec_const, data.len);88 const iovecs = try loop.allocator.alloc(os.posix.iovec_const, data.len);
88 defer loop.allocator.free(iovecs);89 defer loop.allocator.free(iovecs);
...@@ -219,6 +220,7 @@ pub async fn preadv(loop: *Loop, fd: os.FileHandle, data: []const []u8, offset:...@@ -219,6 +220,7 @@ pub async fn preadv(loop: *Loop, fd: os.FileHandle, data: []const []u8, offset:
219 switch (builtin.os) {220 switch (builtin.os) {
220 builtin.Os.macosx,221 builtin.Os.macosx,
221 builtin.Os.linux,222 builtin.Os.linux,
223 builtin.Os.freebsd,
222 => {224 => {
223 const iovecs = try loop.allocator.alloc(os.posix.iovec, data.len);225 const iovecs = try loop.allocator.alloc(os.posix.iovec, data.len);
224 defer loop.allocator.free(iovecs);226 defer loop.allocator.free(iovecs);
...@@ -399,7 +401,7 @@ pub async fn openPosix(...@@ -399,7 +401,7 @@ pub async fn openPosix(
399401
400pub async fn openRead(loop: *Loop, path: []const u8) os.File.OpenError!os.FileHandle {402pub async fn openRead(loop: *Loop, path: []const u8) os.File.OpenError!os.FileHandle {
401 switch (builtin.os) {403 switch (builtin.os) {
402 builtin.Os.macosx, builtin.Os.linux => {404 builtin.Os.macosx, builtin.Os.linux, builtin.Os.freebsd => {
403 const flags = posix.O_LARGEFILE | posix.O_RDONLY | posix.O_CLOEXEC;405 const flags = posix.O_LARGEFILE | posix.O_RDONLY | posix.O_CLOEXEC;
404 return await (async openPosix(loop, path, flags, os.File.default_mode) catch unreachable);406 return await (async openPosix(loop, path, flags, os.File.default_mode) catch unreachable);
405 },407 },
...@@ -427,6 +429,7 @@ pub async fn openWriteMode(loop: *Loop, path: []const u8, mode: os.File.Mode) os...@@ -427,6 +429,7 @@ pub async fn openWriteMode(loop: *Loop, path: []const u8, mode: os.File.Mode) os
427 switch (builtin.os) {429 switch (builtin.os) {
428 builtin.Os.macosx,430 builtin.Os.macosx,
429 builtin.Os.linux,431 builtin.Os.linux,
432 builtin.Os.freebsd,
430 => {433 => {
431 const flags = posix.O_LARGEFILE | posix.O_WRONLY | posix.O_CREAT | posix.O_CLOEXEC | posix.O_TRUNC;434 const flags = posix.O_LARGEFILE | posix.O_WRONLY | posix.O_CREAT | posix.O_CLOEXEC | posix.O_TRUNC;
432 return await (async openPosix(loop, path, flags, os.File.default_mode) catch unreachable);435 return await (async openPosix(loop, path, flags, os.File.default_mode) catch unreachable);
...@@ -449,7 +452,7 @@ pub async fn openReadWrite(...@@ -449,7 +452,7 @@ pub async fn openReadWrite(
449 mode: os.File.Mode,452 mode: os.File.Mode,
450) os.File.OpenError!os.FileHandle {453) os.File.OpenError!os.FileHandle {
451 switch (builtin.os) {454 switch (builtin.os) {
452 builtin.Os.macosx, builtin.Os.linux => {455 builtin.Os.macosx, builtin.Os.linux, builtin.Os.freebsd => {
453 const flags = posix.O_LARGEFILE | posix.O_RDWR | posix.O_CREAT | posix.O_CLOEXEC;456 const flags = posix.O_LARGEFILE | posix.O_RDWR | posix.O_CREAT | posix.O_CLOEXEC;
454 return await (async openPosix(loop, path, flags, mode) catch unreachable);457 return await (async openPosix(loop, path, flags, mode) catch unreachable);
455 },458 },
...@@ -477,7 +480,7 @@ pub const CloseOperation = struct.{...@@ -477,7 +480,7 @@ pub const CloseOperation = struct.{
477 os_data: OsData,480 os_data: OsData,
478481
479 const OsData = switch (builtin.os) {482 const OsData = switch (builtin.os) {
480 builtin.Os.linux, builtin.Os.macosx => OsDataPosix,483 builtin.Os.linux, builtin.Os.macosx, builtin.Os.freebsd => OsDataPosix,
481484
482 builtin.Os.windows => struct.{485 builtin.Os.windows => struct.{
483 handle: ?os.FileHandle,486 handle: ?os.FileHandle,
...@@ -496,7 +499,7 @@ pub const CloseOperation = struct.{...@@ -496,7 +499,7 @@ pub const CloseOperation = struct.{
496 self.* = CloseOperation.{499 self.* = CloseOperation.{
497 .loop = loop,500 .loop = loop,
498 .os_data = switch (builtin.os) {501 .os_data = switch (builtin.os) {
499 builtin.Os.linux, builtin.Os.macosx => initOsDataPosix(self),502 builtin.Os.linux, builtin.Os.macosx, builtin.Os.freebsd => initOsDataPosix(self),
500 builtin.Os.windows => OsData.{ .handle = null },503 builtin.Os.windows => OsData.{ .handle = null },
501 else => @compileError("Unsupported OS"),504 else => @compileError("Unsupported OS"),
502 },505 },
...@@ -525,6 +528,7 @@ pub const CloseOperation = struct.{...@@ -525,6 +528,7 @@ pub const CloseOperation = struct.{
525 switch (builtin.os) {528 switch (builtin.os) {
526 builtin.Os.linux,529 builtin.Os.linux,
527 builtin.Os.macosx,530 builtin.Os.macosx,
531 builtin.Os.freebsd,
528 => {532 => {
529 if (self.os_data.have_fd) {533 if (self.os_data.have_fd) {
530 self.loop.posixFsRequest(&self.os_data.close_req_node);534 self.loop.posixFsRequest(&self.os_data.close_req_node);
...@@ -546,6 +550,7 @@ pub const CloseOperation = struct.{...@@ -546,6 +550,7 @@ pub const CloseOperation = struct.{
546 switch (builtin.os) {550 switch (builtin.os) {
547 builtin.Os.linux,551 builtin.Os.linux,
548 builtin.Os.macosx,552 builtin.Os.macosx,
553 builtin.Os.freebsd,
549 => {554 => {
550 self.os_data.close_req_node.data.msg.Close.fd = handle;555 self.os_data.close_req_node.data.msg.Close.fd = handle;
551 self.os_data.have_fd = true;556 self.os_data.have_fd = true;
...@@ -562,6 +567,7 @@ pub const CloseOperation = struct.{...@@ -562,6 +567,7 @@ pub const CloseOperation = struct.{
562 switch (builtin.os) {567 switch (builtin.os) {
563 builtin.Os.linux,568 builtin.Os.linux,
564 builtin.Os.macosx,569 builtin.Os.macosx,
570 builtin.Os.freebsd,
565 => {571 => {
566 self.os_data.have_fd = false;572 self.os_data.have_fd = false;
567 },573 },
...@@ -576,6 +582,7 @@ pub const CloseOperation = struct.{...@@ -576,6 +582,7 @@ pub const CloseOperation = struct.{
576 switch (builtin.os) {582 switch (builtin.os) {
577 builtin.Os.linux,583 builtin.Os.linux,
578 builtin.Os.macosx,584 builtin.Os.macosx,
585 builtin.Os.freebsd,
579 => {586 => {
580 assert(self.os_data.have_fd);587 assert(self.os_data.have_fd);
581 return self.os_data.close_req_node.data.msg.Close.fd;588 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,...@@ -599,6 +606,7 @@ pub async fn writeFileMode(loop: *Loop, path: []const u8, contents: []const u8,
599 switch (builtin.os) {606 switch (builtin.os) {
600 builtin.Os.linux,607 builtin.Os.linux,
601 builtin.Os.macosx,608 builtin.Os.macosx,
609 builtin.Os.freebsd,
602 => return await (async writeFileModeThread(loop, path, contents, mode) catch unreachable),610 => return await (async writeFileModeThread(loop, path, contents, mode) catch unreachable),
603 builtin.Os.windows => return await (async writeFileWindows(loop, path, contents) catch unreachable),611 builtin.Os.windows => return await (async writeFileWindows(loop, path, contents) catch unreachable),
604 else => @compileError("Unsupported OS"),612 else => @compileError("Unsupported OS"),
...@@ -704,7 +712,7 @@ pub fn Watch(comptime V: type) type {...@@ -704,7 +712,7 @@ pub fn Watch(comptime V: type) type {
704 os_data: OsData,712 os_data: OsData,
705713
706 const OsData = switch (builtin.os) {714 const OsData = switch (builtin.os) {
707 builtin.Os.macosx => struct.{715 builtin.Os.macosx, builtin.Os.freebsd => struct.{
708 file_table: FileTable,716 file_table: FileTable,
709 table_lock: event.Lock,717 table_lock: event.Lock,
710718
...@@ -793,7 +801,7 @@ pub fn Watch(comptime V: type) type {...@@ -793,7 +801,7 @@ pub fn Watch(comptime V: type) type {
793 return self;801 return self;
794 },802 },
795803
796 builtin.Os.macosx => {804 builtin.Os.macosx, builtin.Os.freebsd => {
797 const self = try loop.allocator.createOne(Self);805 const self = try loop.allocator.createOne(Self);
798 errdefer loop.allocator.destroy(self);806 errdefer loop.allocator.destroy(self);
799807
...@@ -813,7 +821,7 @@ pub fn Watch(comptime V: type) type {...@@ -813,7 +821,7 @@ pub fn Watch(comptime V: type) type {
813 /// All addFile calls and removeFile calls must have completed.821 /// All addFile calls and removeFile calls must have completed.
814 pub fn destroy(self: *Self) void {822 pub fn destroy(self: *Self) void {
815 switch (builtin.os) {823 switch (builtin.os) {
816 builtin.Os.macosx => {824 builtin.Os.macosx, builtin.Os.freebsd => {
817 // TODO we need to cancel the coroutines before destroying the lock825 // TODO we need to cancel the coroutines before destroying the lock
818 self.os_data.table_lock.deinit();826 self.os_data.table_lock.deinit();
819 var it = self.os_data.file_table.iterator();827 var it = self.os_data.file_table.iterator();
...@@ -855,14 +863,14 @@ pub fn Watch(comptime V: type) type {...@@ -855,14 +863,14 @@ pub fn Watch(comptime V: type) type {
855863
856 pub async fn addFile(self: *Self, file_path: []const u8, value: V) !?V {864 pub async fn addFile(self: *Self, file_path: []const u8, value: V) !?V {
857 switch (builtin.os) {865 switch (builtin.os) {
858 builtin.Os.macosx => return await (async addFileMacosx(self, file_path, value) catch unreachable),866 builtin.Os.macosx, builtin.Os.freebsd => return await (async addFileKEvent(self, file_path, value) catch unreachable),
859 builtin.Os.linux => return await (async addFileLinux(self, file_path, value) catch unreachable),867 builtin.Os.linux => return await (async addFileLinux(self, file_path, value) catch unreachable),
860 builtin.Os.windows => return await (async addFileWindows(self, file_path, value) catch unreachable),868 builtin.Os.windows => return await (async addFileWindows(self, file_path, value) catch unreachable),
861 else => @compileError("Unsupported OS"),869 else => @compileError("Unsupported OS"),
862 }870 }
863 }871 }
864872
865 async fn addFileMacosx(self: *Self, file_path: []const u8, value: V) !?V {873 async fn addFileKEvent(self: *Self, file_path: []const u8, value: V) !?V {
866 const resolved_path = try os.path.resolve(self.channel.loop.allocator, file_path);874 const resolved_path = try os.path.resolve(self.channel.loop.allocator, file_path);
867 var resolved_path_consumed = false;875 var resolved_path_consumed = false;
868 defer if (!resolved_path_consumed) self.channel.loop.allocator.free(resolved_path);876 defer if (!resolved_path_consumed) self.channel.loop.allocator.free(resolved_path);
...@@ -871,7 +879,11 @@ pub fn Watch(comptime V: type) type {...@@ -871,7 +879,11 @@ pub fn Watch(comptime V: type) type {
871 var close_op_consumed = false;879 var close_op_consumed = false;
872 defer if (!close_op_consumed) close_op.finish();880 defer if (!close_op_consumed) close_op.finish();
873881
874 const flags = posix.O_SYMLINK | posix.O_EVTONLY;882
883 const flags = switch (builtin.os) {
884 builtin.Os.macosx => posix.O_SYMLINK | posix.O_EVTONLY,
885 else => 0,
886 };
875 const mode = 0;887 const mode = 0;
876 const fd = try await (async openPosix(self.channel.loop, resolved_path, flags, mode) catch unreachable);888 const fd = try await (async openPosix(self.channel.loop, resolved_path, flags, mode) catch unreachable);
877 close_op.setHandle(fd);889 close_op.setHandle(fd);
std/event/loop.zig+14-13
...@@ -48,7 +48,7 @@ pub const Loop = struct.{...@@ -48,7 +48,7 @@ pub const Loop = struct.{
48 };48 };
4949
50 pub const EventFd = switch (builtin.os) {50 pub const EventFd = switch (builtin.os) {
51 builtin.Os.macosx => MacOsEventFd,51 builtin.Os.macosx, builtin.Os.freebsd => KEventFd,
52 builtin.Os.linux => struct.{52 builtin.Os.linux => struct.{
53 base: ResumeNode,53 base: ResumeNode,
54 epoll_op: u32,54 epoll_op: u32,
...@@ -61,13 +61,13 @@ pub const Loop = struct.{...@@ -61,13 +61,13 @@ pub const Loop = struct.{
61 else => @compileError("unsupported OS"),61 else => @compileError("unsupported OS"),
62 };62 };
6363
64 const MacOsEventFd = struct.{64 const KEventFd = struct.{
65 base: ResumeNode,65 base: ResumeNode,
66 kevent: posix.Kevent,66 kevent: posix.Kevent,
67 };67 };
6868
69 pub const Basic = switch (builtin.os) {69 pub const Basic = switch (builtin.os) {
70 builtin.Os.macosx => MacOsBasic,70 builtin.Os.macosx, builtin.Os.freebsd => KEventBasic,
71 builtin.Os.linux => struct.{71 builtin.Os.linux => struct.{
72 base: ResumeNode,72 base: ResumeNode,
73 },73 },
...@@ -77,7 +77,7 @@ pub const Loop = struct.{...@@ -77,7 +77,7 @@ pub const Loop = struct.{
77 else => @compileError("unsupported OS"),77 else => @compileError("unsupported OS"),
78 };78 };
7979
80 const MacOsBasic = struct.{80 const KEventBasic = struct.{
81 base: ResumeNode,81 base: ResumeNode,
82 kev: posix.Kevent,82 kev: posix.Kevent,
83 };83 };
...@@ -213,7 +213,7 @@ pub const Loop = struct.{...@@ -213,7 +213,7 @@ pub const Loop = struct.{
213 self.extra_threads[extra_thread_index] = try os.spawnThread(self, workerRun);213 self.extra_threads[extra_thread_index] = try os.spawnThread(self, workerRun);
214 }214 }
215 },215 },
216 builtin.Os.macosx => {216 builtin.Os.macosx, builtin.Os.freebsd => {
217 self.os_data.kqfd = try os.bsdKQueue();217 self.os_data.kqfd = try os.bsdKQueue();
218 errdefer os.close(self.os_data.kqfd);218 errdefer os.close(self.os_data.kqfd);
219219
...@@ -368,7 +368,7 @@ pub const Loop = struct.{...@@ -368,7 +368,7 @@ pub const Loop = struct.{
368 os.close(self.os_data.epollfd);368 os.close(self.os_data.epollfd);
369 self.allocator.free(self.eventfd_resume_nodes);369 self.allocator.free(self.eventfd_resume_nodes);
370 },370 },
371 builtin.Os.macosx => {371 builtin.Os.macosx, builtin.Os.freebsd => {
372 os.close(self.os_data.kqfd);372 os.close(self.os_data.kqfd);
373 os.close(self.os_data.fs_kqfd);373 os.close(self.os_data.fs_kqfd);
374 },374 },
...@@ -483,7 +483,7 @@ pub const Loop = struct.{...@@ -483,7 +483,7 @@ pub const Loop = struct.{
483 const eventfd_node = &resume_stack_node.data;483 const eventfd_node = &resume_stack_node.data;
484 eventfd_node.base.handle = next_tick_node.data;484 eventfd_node.base.handle = next_tick_node.data;
485 switch (builtin.os) {485 switch (builtin.os) {
486 builtin.Os.macosx => {486 builtin.Os.macosx, builtin.Os.freebsd => {
487 const kevent_array = (*[1]posix.Kevent)(&eventfd_node.kevent);487 const kevent_array = (*[1]posix.Kevent)(&eventfd_node.kevent);
488 const empty_kevs = ([*]posix.Kevent)(undefined)[0..0];488 const empty_kevs = ([*]posix.Kevent)(undefined)[0..0];
489 _ = os.bsdKEvent(self.os_data.kqfd, kevent_array, empty_kevs, null) catch {489 _ = os.bsdKEvent(self.os_data.kqfd, kevent_array, empty_kevs, null) catch {
...@@ -545,6 +545,7 @@ pub const Loop = struct.{...@@ -545,6 +545,7 @@ pub const Loop = struct.{
545 switch (builtin.os) {545 switch (builtin.os) {
546 builtin.Os.linux,546 builtin.Os.linux,
547 builtin.Os.macosx,547 builtin.Os.macosx,
548 builtin.Os.freebsd,
548 => self.os_data.fs_thread.wait(),549 => self.os_data.fs_thread.wait(),
549 else => {},550 else => {},
550 }551 }
...@@ -609,7 +610,7 @@ pub const Loop = struct.{...@@ -609,7 +610,7 @@ pub const Loop = struct.{
609 os.posixWrite(self.os_data.final_eventfd, wakeup_bytes) catch unreachable;610 os.posixWrite(self.os_data.final_eventfd, wakeup_bytes) catch unreachable;
610 return;611 return;
611 },612 },
612 builtin.Os.macosx => {613 builtin.Os.macosx, builtin.Os.freebsd => {
613 self.posixFsRequest(&self.os_data.fs_end_request);614 self.posixFsRequest(&self.os_data.fs_end_request);
614 const final_kevent = (*[1]posix.Kevent)(&self.os_data.final_kevent);615 const final_kevent = (*[1]posix.Kevent)(&self.os_data.final_kevent);
615 const empty_kevs = ([*]posix.Kevent)(undefined)[0..0];616 const empty_kevs = ([*]posix.Kevent)(undefined)[0..0];
...@@ -667,7 +668,7 @@ pub const Loop = struct.{...@@ -667,7 +668,7 @@ pub const Loop = struct.{
667 }668 }
668 }669 }
669 },670 },
670 builtin.Os.macosx => {671 builtin.Os.macosx, builtin.Os.freebsd => {
671 var eventlist: [1]posix.Kevent = undefined;672 var eventlist: [1]posix.Kevent = undefined;
672 const empty_kevs = ([*]posix.Kevent)(undefined)[0..0];673 const empty_kevs = ([*]posix.Kevent)(undefined)[0..0];
673 const count = os.bsdKEvent(self.os_data.kqfd, empty_kevs, eventlist[0..], null) catch unreachable;674 const count = os.bsdKEvent(self.os_data.kqfd, empty_kevs, eventlist[0..], null) catch unreachable;
...@@ -730,7 +731,7 @@ pub const Loop = struct.{...@@ -730,7 +731,7 @@ pub const Loop = struct.{
730 self.beginOneEvent(); // finished in posixFsRun after processing the msg731 self.beginOneEvent(); // finished in posixFsRun after processing the msg
731 self.os_data.fs_queue.put(request_node);732 self.os_data.fs_queue.put(request_node);
732 switch (builtin.os) {733 switch (builtin.os) {
733 builtin.Os.macosx => {734 builtin.Os.macosx, builtin.Os.freebsd => {
734 const fs_kevs = (*[1]posix.Kevent)(&self.os_data.fs_kevent_wake);735 const fs_kevs = (*[1]posix.Kevent)(&self.os_data.fs_kevent_wake);
735 const empty_kevs = ([*]posix.Kevent)(undefined)[0..0];736 const empty_kevs = ([*]posix.Kevent)(undefined)[0..0];
736 _ = os.bsdKEvent(self.os_data.fs_kqfd, fs_kevs, empty_kevs, null) catch unreachable;737 _ = os.bsdKEvent(self.os_data.fs_kqfd, fs_kevs, empty_kevs, null) catch unreachable;
...@@ -800,7 +801,7 @@ pub const Loop = struct.{...@@ -800,7 +801,7 @@ pub const Loop = struct.{
800 else => unreachable,801 else => unreachable,
801 }802 }
802 },803 },
803 builtin.Os.macosx => {804 builtin.Os.macosx, builtin.Os.freebsd => {
804 const fs_kevs = (*[1]posix.Kevent)(&self.os_data.fs_kevent_wait);805 const fs_kevs = (*[1]posix.Kevent)(&self.os_data.fs_kevent_wait);
805 var out_kevs: [1]posix.Kevent = undefined;806 var out_kevs: [1]posix.Kevent = undefined;
806 _ = os.bsdKEvent(self.os_data.fs_kqfd, fs_kevs, out_kevs[0..], null) catch unreachable;807 _ = os.bsdKEvent(self.os_data.fs_kqfd, fs_kevs, out_kevs[0..], null) catch unreachable;
...@@ -812,7 +813,7 @@ pub const Loop = struct.{...@@ -812,7 +813,7 @@ pub const Loop = struct.{
812813
813 const OsData = switch (builtin.os) {814 const OsData = switch (builtin.os) {
814 builtin.Os.linux => LinuxOsData,815 builtin.Os.linux => LinuxOsData,
815 builtin.Os.macosx => MacOsData,816 builtin.Os.macosx, builtin.Os.freebsd => KEventData,
816 builtin.Os.windows => struct.{817 builtin.Os.windows => struct.{
817 io_port: windows.HANDLE,818 io_port: windows.HANDLE,
818 extra_thread_count: usize,819 extra_thread_count: usize,
...@@ -820,7 +821,7 @@ pub const Loop = struct.{...@@ -820,7 +821,7 @@ pub const Loop = struct.{
820 else => struct.{},821 else => struct.{},
821 };822 };
822823
823 const MacOsData = struct.{824 const KEventData = struct.{
824 kqfd: i32,825 kqfd: i32,
825 final_kevent: posix.Kevent,826 final_kevent: posix.Kevent,
826 fs_kevent_wake: posix.Kevent,827 fs_kevent_wake: posix.Kevent,
std/os/freebsd/index.zig+211-1
...@@ -7,6 +7,10 @@ const arch = switch (builtin.arch) {...@@ -7,6 +7,10 @@ const arch = switch (builtin.arch) {
7pub use @import("syscall.zig");7pub use @import("syscall.zig");
8pub use @import("errno.zig");8pub use @import("errno.zig");
99
10const std = @import("../../index.zig");
11const c = std.c;
12pub const Kevent = c.Kevent;
13
10pub const PATH_MAX = 1024;14pub const PATH_MAX = 1024;
1115
12pub const STDIN_FILENO = 0;16pub const STDIN_FILENO = 0;
...@@ -293,6 +297,156 @@ pub const DT_LNK = 10;...@@ -293,6 +297,156 @@ pub const DT_LNK = 10;
293pub const DT_SOCK = 12;297pub const DT_SOCK = 12;
294pub const DT_WHT = 14;298pub const DT_WHT = 14;
295299
300/// add event to kq (implies enable)
301pub const EV_ADD = 0x0001;
302
303/// delete event from kq
304pub const EV_DELETE = 0x0002;
305
306/// enable event
307pub const EV_ENABLE = 0x0004;
308
309/// disable event (not reported)
310pub const EV_DISABLE = 0x0008;
311
312/// only report one occurrence
313pub const EV_ONESHOT = 0x0010;
314
315/// clear event state after reporting
316pub const EV_CLEAR = 0x0020;
317
318/// force immediate event output
319/// ... with or without EV_ERROR
320/// ... use KEVENT_FLAG_ERROR_EVENTS
321/// on syscalls supporting flags
322pub const EV_RECEIPT = 0x0040;
323
324/// disable event after reporting
325pub const EV_DISPATCH = 0x0080;
326
327pub const EVFILT_READ = -1;
328pub const EVFILT_WRITE = -2;
329
330/// attached to aio requests
331pub const EVFILT_AIO = -3;
332
333/// attached to vnodes
334pub const EVFILT_VNODE = -4;
335
336/// attached to struct proc
337pub const EVFILT_PROC = -5;
338
339/// attached to struct proc
340pub const EVFILT_SIGNAL = -6;
341
342/// timers
343pub const EVFILT_TIMER = -7;
344
345/// Process descriptors
346pub const EVFILT_PROCDESC = -8;
347
348/// Filesystem events
349pub const EVFILT_FS = -9;
350
351pub const EVFILT_LIO = -10;
352
353/// User events
354pub const EVFILT_USER = -11;
355
356/// Sendfile events
357pub const EVFILT_SENDFILE = -12;
358
359pub const EVFILT_EMPTY = -13;
360
361/// On input, NOTE_TRIGGER causes the event to be triggered for output.
362pub const NOTE_TRIGGER = 0x01000000;
363
364/// ignore input fflags
365pub const NOTE_FFNOP = 0x00000000;
366
367/// and fflags
368pub const NOTE_FFAND = 0x40000000;
369
370/// or fflags
371pub const NOTE_FFOR = 0x80000000;
372
373/// copy fflags
374pub const NOTE_FFCOPY = 0xc0000000;
375
376/// mask for operations
377pub const NOTE_FFCTRLMASK = 0xc0000000;
378pub const NOTE_FFLAGSMASK = 0x00ffffff;
379
380
381/// low water mark
382pub const NOTE_LOWAT = 0x00000001;
383
384/// behave like poll()
385pub const NOTE_FILE_POLL = 0x00000002;
386
387/// vnode was removed
388pub const NOTE_DELETE = 0x00000001;
389
390/// data contents changed
391pub const NOTE_WRITE = 0x00000002;
392
393/// size increased
394pub const NOTE_EXTEND = 0x00000004;
395
396/// attributes changed
397pub const NOTE_ATTRIB = 0x00000008;
398
399/// link count changed
400pub const NOTE_LINK = 0x00000010;
401
402/// vnode was renamed
403pub const NOTE_RENAME = 0x00000020;
404
405/// vnode access was revoked
406pub const NOTE_REVOKE = 0x00000040;
407
408/// vnode was opened
409pub const NOTE_OPEN = 0x00000080;
410
411/// file closed, fd did not allow write
412pub const NOTE_CLOSE = 0x00000100;
413
414/// file closed, fd did allow write
415pub const NOTE_CLOSE_WRITE = 0x00000200;
416
417/// file was read
418pub const NOTE_READ = 0x00000400;
419
420/// process exited
421pub const NOTE_EXIT = 0x80000000;
422
423/// process forked
424pub const NOTE_FORK = 0x40000000;
425
426/// process exec'd
427pub const NOTE_EXEC = 0x20000000;
428
429/// mask for signal & exit status
430pub const NOTE_PDATAMASK = 0x000fffff;
431pub const NOTE_PCTRLMASK = (~NOTE_PDATAMASK);
432
433/// data is seconds
434pub const NOTE_SECONDS = 0x00000001;
435
436/// data is milliseconds
437pub const NOTE_MSECONDS = 0x00000002;
438
439/// data is microseconds
440pub const NOTE_USECONDS = 0x00000004;
441
442/// data is nanoseconds
443pub const NOTE_NSECONDS = 0x00000008;
444
445/// timeout is absolute
446pub const NOTE_ABSTIME = 0x00000010;
447
448
449
296pub const TCGETS = 0x5401;450pub const TCGETS = 0x5401;
297pub const TCSETS = 0x5402;451pub const TCSETS = 0x5402;
298pub const TCSETSW = 0x5403;452pub const TCSETSW = 0x5403;
...@@ -445,7 +599,11 @@ pub fn symlink(existing: [*]const u8, new: [*]const u8) usize {...@@ -445,7 +599,11 @@ pub fn symlink(existing: [*]const u8, new: [*]const u8) usize {
445}599}
446600
447pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: usize) usize {601pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: usize) usize {
448 return arch.syscall4(SYS_pread, usize(fd), @ptrToInt(buf), count, offset);602 return arch.syscall4(SYS_pread, @intCast(usize, fd), @ptrToInt(buf), count, offset);
603}
604
605pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: usize) usize {
606 return arch.syscall4(SYS_preadv, @intCast(usize, fd), @ptrToInt(iov), count, offset);
449}607}
450608
451pub fn pipe(fd: *[2]i32) usize {609pub fn pipe(fd: *[2]i32) usize {
...@@ -464,6 +622,10 @@ pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: usize) usize {...@@ -464,6 +622,10 @@ pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: usize) usize {
464 return arch.syscall4(SYS_pwrite, @intCast(usize, fd), @ptrToInt(buf), count, offset);622 return arch.syscall4(SYS_pwrite, @intCast(usize, fd), @ptrToInt(buf), count, offset);
465}623}
466624
625pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: usize) usize {
626 return arch.syscall4(SYS_pwritev, @intCast(usize, fd), @ptrToInt(iov), count, offset);
627}
628
467pub fn rename(old: [*]const u8, new: [*]const u8) usize {629pub fn rename(old: [*]const u8, new: [*]const u8) usize {
468 return arch.syscall2(SYS_rename, @ptrToInt(old), @ptrToInt(new));630 return arch.syscall2(SYS_rename, @ptrToInt(old), @ptrToInt(new));
469}631}
...@@ -590,3 +752,51 @@ pub const timespec = arch.timespec;...@@ -590,3 +752,51 @@ pub const timespec = arch.timespec;
590pub fn fstat(fd: i32, stat_buf: *Stat) usize {752pub fn fstat(fd: i32, stat_buf: *Stat) usize {
591 return arch.syscall2(SYS_fstat, @intCast(usize, fd), @ptrToInt(stat_buf));753 return arch.syscall2(SYS_fstat, @intCast(usize, fd), @ptrToInt(stat_buf));
592}754}
755
756pub const iovec = extern struct.{
757 iov_base: [*]u8,
758 iov_len: usize,
759};
760
761pub const iovec_const = extern struct.{
762 iov_base: [*]const u8,
763 iov_len: usize,
764};
765
766pub fn kqueue() usize {
767 return errnoWrap(c.kqueue());
768}
769
770pub fn kevent(kq: i32, changelist: []const Kevent, eventlist: []Kevent, timeout: ?*const timespec) usize {
771 return errnoWrap(c.kevent(
772 kq,
773 changelist.ptr,
774 @intCast(c_int, changelist.len),
775 eventlist.ptr,
776 @intCast(c_int, eventlist.len),
777 timeout,
778 ));
779}
780
781pub fn sysctl(name: [*]c_int, namelen: c_uint, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) usize {
782 return errnoWrap(c.sysctl(name, namelen, oldp, oldlenp, newp, newlen));
783}
784
785pub fn sysctlbyname(name: [*]const u8, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) usize {
786 return errnoWrap(c.sysctlbyname(name, oldp, oldlenp, newp, newlen));
787}
788
789pub fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usize) usize {
790 return errnoWrap(c.sysctlnametomib(name, wibp, sizep));
791}
792
793
794
795/// Takes the return value from a syscall and formats it back in the way
796/// that the kernel represents it to libc. Errno was a mistake, let's make
797/// it go away forever.
798fn errnoWrap(value: isize) usize {
799 return @bitCast(usize, if (value == -1) -isize(c._errno().*) else value);
800}
801
802
std/os/get_app_data_dir.zig+1-1
...@@ -43,7 +43,7 @@ pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataD...@@ -43,7 +43,7 @@ pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataD
43 };43 };
44 return os.path.join(allocator, home_dir, "Library", "Application Support", appname);44 return os.path.join(allocator, home_dir, "Library", "Application Support", appname);
45 },45 },
46 builtin.Os.linux => {46 builtin.Os.linux, builtin.Os.freebsd => {
47 const home_dir = os.getEnvPosix("HOME") orelse {47 const home_dir = os.getEnvPosix("HOME") orelse {
48 // TODO look in /etc/passwd48 // TODO look in /etc/passwd
49 return error.AppDataDirUnavailable;49 return error.AppDataDirUnavailable;
std/os/index.zig+22-12
...@@ -421,7 +421,7 @@ pub fn posix_pwritev(fd: i32, iov: [*]const posix.iovec_const, count: usize, off...@@ -421,7 +421,7 @@ pub fn posix_pwritev(fd: i32, iov: [*]const posix.iovec_const, count: usize, off
421 }421 }
422 }422 }
423 },423 },
424 builtin.Os.linux => while (true) {424 builtin.Os.linux, builtin.Os.freebsd => while (true) {
425 const rc = posix.pwritev(fd, iov, count, offset);425 const rc = posix.pwritev(fd, iov, count, offset);
426 const err = posix.getErrno(rc);426 const err = posix.getErrno(rc);
427 switch (err) {427 switch (err) {
...@@ -689,7 +689,7 @@ pub fn getBaseAddress() usize {...@@ -689,7 +689,7 @@ pub fn getBaseAddress() usize {
689 };689 };
690 return phdr - @sizeOf(ElfHeader);690 return phdr - @sizeOf(ElfHeader);
691 },691 },
692 builtin.Os.macosx => return @ptrToInt(&std.c._mh_execute_header),692 builtin.Os.macosx, builtin.Os.freebsd => return @ptrToInt(&std.c._mh_execute_header),
693 builtin.Os.windows => return @ptrToInt(windows.GetModuleHandleW(null)),693 builtin.Os.windows => return @ptrToInt(windows.GetModuleHandleW(null)),
694 else => @compileError("Unsupported OS"),694 else => @compileError("Unsupported OS"),
695 }695 }
...@@ -1307,7 +1307,7 @@ pub fn deleteDirC(dir_path: [*]const u8) DeleteDirError!void {...@@ -1307,7 +1307,7 @@ pub fn deleteDirC(dir_path: [*]const u8) DeleteDirError!void {
1307 const dir_path_w = try windows_util.cStrToPrefixedFileW(dir_path);1307 const dir_path_w = try windows_util.cStrToPrefixedFileW(dir_path);
1308 return deleteDirW(&dir_path_w);1308 return deleteDirW(&dir_path_w);
1309 },1309 },
1310 Os.linux, Os.macosx, Os.ios => {1310 Os.linux, Os.macosx, Os.ios, Os.freebsd => {
1311 const err = posix.getErrno(posix.rmdir(dir_path));1311 const err = posix.getErrno(posix.rmdir(dir_path));
1312 switch (err) {1312 switch (err) {
1313 0 => return,1313 0 => return,
...@@ -1350,7 +1350,7 @@ pub fn deleteDir(dir_path: []const u8) DeleteDirError!void {...@@ -1350,7 +1350,7 @@ pub fn deleteDir(dir_path: []const u8) DeleteDirError!void {
1350 const dir_path_w = try windows_util.sliceToPrefixedFileW(dir_path);1350 const dir_path_w = try windows_util.sliceToPrefixedFileW(dir_path);
1351 return deleteDirW(&dir_path_w);1351 return deleteDirW(&dir_path_w);
1352 },1352 },
1353 Os.linux, Os.macosx, Os.ios => {1353 Os.linux, Os.macosx, Os.ios, Os.freebsd => {
1354 const dir_path_c = try toPosixPath(dir_path);1354 const dir_path_c = try toPosixPath(dir_path);
1355 return deleteDirC(&dir_path_c);1355 return deleteDirC(&dir_path_c);
1356 },1356 },
...@@ -1467,7 +1467,7 @@ pub const Dir = struct.{...@@ -1467,7 +1467,7 @@ pub const Dir = struct.{
1467 allocator: *Allocator,1467 allocator: *Allocator,
14681468
1469 pub const Handle = switch (builtin.os) {1469 pub const Handle = switch (builtin.os) {
1470 Os.macosx, Os.ios => struct.{1470 Os.macosx, Os.ios, Os.freebsd => struct.{
1471 fd: i32,1471 fd: i32,
1472 seek: i64,1472 seek: i64,
1473 buf: []u8,1473 buf: []u8,
...@@ -1543,7 +1543,7 @@ pub const Dir = struct.{...@@ -1543,7 +1543,7 @@ pub const Dir = struct.{
1543 .name_data = undefined,1543 .name_data = undefined,
1544 };1544 };
1545 },1545 },
1546 Os.macosx, Os.ios => Handle.{1546 Os.macosx, Os.ios, Os.freebsd => Handle.{
1547 .fd = try posixOpen(1547 .fd = try posixOpen(
1548 dir_path,1548 dir_path,
1549 posix.O_RDONLY | posix.O_NONBLOCK | posix.O_DIRECTORY | posix.O_CLOEXEC,1549 posix.O_RDONLY | posix.O_NONBLOCK | posix.O_DIRECTORY | posix.O_CLOEXEC,
...@@ -1574,7 +1574,7 @@ pub const Dir = struct.{...@@ -1574,7 +1574,7 @@ pub const Dir = struct.{
1574 Os.windows => {1574 Os.windows => {
1575 _ = windows.FindClose(self.handle.handle);1575 _ = windows.FindClose(self.handle.handle);
1576 },1576 },
1577 Os.macosx, Os.ios, Os.linux => {1577 Os.macosx, Os.ios, Os.linux, Os.freebsd => {
1578 self.allocator.free(self.handle.buf);1578 self.allocator.free(self.handle.buf);
1579 os.close(self.handle.fd);1579 os.close(self.handle.fd);
1580 },1580 },
...@@ -1589,6 +1589,7 @@ pub const Dir = struct.{...@@ -1589,6 +1589,7 @@ pub const Dir = struct.{
1589 Os.linux => return self.nextLinux(),1589 Os.linux => return self.nextLinux(),
1590 Os.macosx, Os.ios => return self.nextDarwin(),1590 Os.macosx, Os.ios => return self.nextDarwin(),
1591 Os.windows => return self.nextWindows(),1591 Os.windows => return self.nextWindows(),
1592 Os.freebsd => return self.nextFreebsd(),
1592 else => @compileError("unimplemented"),1593 else => @compileError("unimplemented"),
1593 }1594 }
1594 }1595 }
...@@ -1728,6 +1729,11 @@ pub const Dir = struct.{...@@ -1728,6 +1729,11 @@ pub const Dir = struct.{
1728 };1729 };
1729 }1730 }
1730 }1731 }
1732
1733 fn nextFreebsd(self: *Dir) !?Entry {
1734 self.handle.buf = try self.allocator.alloc(u8, page_size);
1735 return null; // TODO
1736 }
1731};1737};
17321738
1733pub fn changeCurDir(allocator: *Allocator, dir_path: []const u8) !void {1739pub fn changeCurDir(allocator: *Allocator, dir_path: []const u8) !void {
...@@ -2166,7 +2172,7 @@ pub fn unexpectedErrorWindows(err: windows.DWORD) UnexpectedError {...@@ -2166,7 +2172,7 @@ pub fn unexpectedErrorWindows(err: windows.DWORD) UnexpectedError {
2166pub fn openSelfExe() !os.File {2172pub fn openSelfExe() !os.File {
2167 switch (builtin.os) {2173 switch (builtin.os) {
2168 Os.linux => return os.File.openReadC(c"/proc/self/exe"),2174 Os.linux => return os.File.openReadC(c"/proc/self/exe"),
2169 Os.macosx, Os.ios => {2175 Os.macosx, Os.ios, Os.freebsd => {
2170 var buf: [MAX_PATH_BYTES]u8 = undefined;2176 var buf: [MAX_PATH_BYTES]u8 = undefined;
2171 const self_exe_path = try selfExePath(&buf);2177 const self_exe_path = try selfExePath(&buf);
2172 buf[self_exe_path.len] = 0;2178 buf[self_exe_path.len] = 0;
...@@ -2183,7 +2189,7 @@ pub fn openSelfExe() !os.File {...@@ -2183,7 +2189,7 @@ pub fn openSelfExe() !os.File {
21832189
2184test "openSelfExe" {2190test "openSelfExe" {
2185 switch (builtin.os) {2191 switch (builtin.os) {
2186 Os.linux, Os.macosx, Os.ios, Os.windows => (try openSelfExe()).close(),2192 Os.linux, Os.macosx, Os.ios, Os.windows, Os.freebsd => (try openSelfExe()).close(),
2187 else => return error.SkipZigTest, // Unsupported OS.2193 else => return error.SkipZigTest, // Unsupported OS.
2188 }2194 }
2189}2195}
...@@ -2214,6 +2220,7 @@ pub fn selfExePathW(out_buffer: *[windows_util.PATH_MAX_WIDE]u16) ![]u16 {...@@ -2214,6 +2220,7 @@ pub fn selfExePathW(out_buffer: *[windows_util.PATH_MAX_WIDE]u16) ![]u16 {
2214pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) ![]u8 {2220pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) ![]u8 {
2215 switch (builtin.os) {2221 switch (builtin.os) {
2216 Os.linux => return readLink(out_buffer, "/proc/self/exe"),2222 Os.linux => return readLink(out_buffer, "/proc/self/exe"),
2223 Os.freebsd => return readLink(out_buffer, "/proc/curproc/file"),
2217 Os.windows => {2224 Os.windows => {
2218 var utf16le_buf: [windows_util.PATH_MAX_WIDE]u16 = undefined;2225 var utf16le_buf: [windows_util.PATH_MAX_WIDE]u16 = undefined;
2219 const utf16le_slice = try selfExePathW(&utf16le_buf);2226 const utf16le_slice = try selfExePathW(&utf16le_buf);
...@@ -2252,7 +2259,7 @@ pub fn selfExeDirPath(out_buffer: *[MAX_PATH_BYTES]u8) ![]const u8 {...@@ -2252,7 +2259,7 @@ pub fn selfExeDirPath(out_buffer: *[MAX_PATH_BYTES]u8) ![]const u8 {
2252 // will not return null.2259 // will not return null.
2253 return path.dirname(full_exe_path).?;2260 return path.dirname(full_exe_path).?;
2254 },2261 },
2255 Os.windows, Os.macosx, Os.ios => {2262 Os.windows, Os.macosx, Os.ios, Os.freebsd => {
2256 const self_exe_path = try selfExePath(out_buffer);2263 const self_exe_path = try selfExePath(out_buffer);
2257 // Assume that the OS APIs return absolute paths, and therefore dirname2264 // Assume that the OS APIs return absolute paths, and therefore dirname
2258 // will not return null.2265 // will not return null.
...@@ -3085,10 +3092,13 @@ pub const CpuCountError = error.{...@@ -3085,10 +3092,13 @@ pub const CpuCountError = error.{
30853092
3086pub fn cpuCount(fallback_allocator: *mem.Allocator) CpuCountError!usize {3093pub fn cpuCount(fallback_allocator: *mem.Allocator) CpuCountError!usize {
3087 switch (builtin.os) {3094 switch (builtin.os) {
3088 builtin.Os.macosx => {3095 builtin.Os.macosx, builtin.Os.freebsd => {
3089 var count: c_int = undefined;3096 var count: c_int = undefined;
3090 var count_len: usize = @sizeOf(c_int);3097 var count_len: usize = @sizeOf(c_int);
3091 const rc = posix.sysctlbyname(c"hw.logicalcpu", @ptrCast(*c_void, &count), &count_len, null, 0);3098 const rc = posix.sysctlbyname(switch (builtin.os) {
3099 builtin.Os.macosx => c"hw.logicalcpu",
3100 else => c"hw.ncpu",
3101 }, @ptrCast(*c_void, &count), &count_len, null, 0);
3092 const err = posix.getErrno(rc);3102 const err = posix.getErrno(rc);
3093 switch (err) {3103 switch (err) {
3094 0 => return @intCast(usize, count),3104 0 => return @intCast(usize, count),