| author | |
| committer | |
| log | e5627f8e635c05a91edeb97b6d0e392d095ce39f |
| tree | 8c7bb5ffc769367faecc7535b95b51d18b042cde |
| parent | 831bb668955fa9d332f7beb1ea11f1c8028e5235 |
8 files changed, 308 insertions(+), 37 deletions(-)
CMakeLists.txt+1| ... | ... | @@ -444,6 +444,7 @@ set(ZIG_STD_FILES |
| 444 | 444 | "buffer.zig" |
| 445 | 445 | "build.zig" |
| 446 | 446 | "c/darwin.zig" |
| 447 | "c/freebsd.zig" | |
| 447 | 448 | "c/index.zig" |
| 448 | 449 | "c/linux.zig" |
| 449 | 450 | "c/windows.zig" |
std/c/freebsd.zig created+36| ... | ... | @@ -0,0 +1,36 @@ |
| 1 | ||
| 2 | const timespec = @import("../os/freebsd/index.zig").timespec; | |
| 3 | ||
| 4 | extern "c" fn __error() *c_int; | |
| 5 | pub const _errno = __error; | |
| 6 | ||
| 7 | pub extern "c" fn kqueue() c_int; | |
| 8 | pub 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; | |
| 16 | pub extern "c" fn sysctl(name: [*]c_int, namelen: c_uint, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int; | |
| 17 | pub extern "c" fn sysctlbyname(name: [*]const u8, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int; | |
| 18 | pub 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. | |
| 21 | pub 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 | ||
| 32 | pub 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 | 5 | Os.linux => @import("linux.zig"), |
| 6 | 6 | Os.windows => @import("windows.zig"), |
| 7 | 7 | Os.macosx, Os.ios => @import("darwin.zig"), |
| 8 | Os.freebsd => @import("freebsd.zig"), | |
| 8 | 9 | else => empty_import, |
| 9 | 10 | }; |
| 10 | 11 | const 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 | 83 | switch (builtin.os) { |
| 84 | 84 | builtin.Os.macosx, |
| 85 | 85 | builtin.Os.linux, |
| 86 | builtin.Os.freebsd, | |
| 86 | 87 | => { |
| 87 | 88 | const iovecs = try loop.allocator.alloc(os.posix.iovec_const, data.len); |
| 88 | 89 | defer loop.allocator.free(iovecs); |
| ... | ... | @@ -219,6 +220,7 @@ pub async fn preadv(loop: *Loop, fd: os.FileHandle, data: []const []u8, offset: |
| 219 | 220 | switch (builtin.os) { |
| 220 | 221 | builtin.Os.macosx, |
| 221 | 222 | builtin.Os.linux, |
| 223 | builtin.Os.freebsd, | |
| 222 | 224 | => { |
| 223 | 225 | const iovecs = try loop.allocator.alloc(os.posix.iovec, data.len); |
| 224 | 226 | defer loop.allocator.free(iovecs); |
| ... | ... | @@ -399,7 +401,7 @@ pub async fn openPosix( |
| 399 | 401 | |
| 400 | 402 | pub async fn openRead(loop: *Loop, path: []const u8) os.File.OpenError!os.FileHandle { |
| 401 | 403 | switch (builtin.os) { |
| 402 | builtin.Os.macosx, builtin.Os.linux => { | |
| 404 | builtin.Os.macosx, builtin.Os.linux, builtin.Os.freebsd => { | |
| 403 | 405 | const flags = posix.O_LARGEFILE | posix.O_RDONLY | posix.O_CLOEXEC; |
| 404 | 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 | 429 | switch (builtin.os) { |
| 428 | 430 | builtin.Os.macosx, |
| 429 | 431 | builtin.Os.linux, |
| 432 | builtin.Os.freebsd, | |
| 430 | 433 | => { |
| 431 | 434 | const flags = posix.O_LARGEFILE | posix.O_WRONLY | posix.O_CREAT | posix.O_CLOEXEC | posix.O_TRUNC; |
| 432 | 435 | return await (async openPosix(loop, path, flags, os.File.default_mode) catch unreachable); |
| ... | ... | @@ -449,7 +452,7 @@ pub async fn openReadWrite( |
| 449 | 452 | mode: os.File.Mode, |
| 450 | 453 | ) os.File.OpenError!os.FileHandle { |
| 451 | 454 | switch (builtin.os) { |
| 452 | builtin.Os.macosx, builtin.Os.linux => { | |
| 455 | builtin.Os.macosx, builtin.Os.linux, builtin.Os.freebsd => { | |
| 453 | 456 | const flags = posix.O_LARGEFILE | posix.O_RDWR | posix.O_CREAT | posix.O_CLOEXEC; |
| 454 | 457 | return await (async openPosix(loop, path, flags, mode) catch unreachable); |
| 455 | 458 | }, |
| ... | ... | @@ -477,7 +480,7 @@ pub const CloseOperation = struct.{ |
| 477 | 480 | os_data: OsData, |
| 478 | 481 | |
| 479 | 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, | |
| 481 | 484 | |
| 482 | 485 | builtin.Os.windows => struct.{ |
| 483 | 486 | handle: ?os.FileHandle, |
| ... | ... | @@ -496,7 +499,7 @@ pub const CloseOperation = struct.{ |
| 496 | 499 | self.* = CloseOperation.{ |
| 497 | 500 | .loop = loop, |
| 498 | 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 | 503 | builtin.Os.windows => OsData.{ .handle = null }, |
| 501 | 504 | else => @compileError("Unsupported OS"), |
| 502 | 505 | }, |
| ... | ... | @@ -525,6 +528,7 @@ pub const CloseOperation = struct.{ |
| 525 | 528 | switch (builtin.os) { |
| 526 | 529 | builtin.Os.linux, |
| 527 | 530 | builtin.Os.macosx, |
| 531 | builtin.Os.freebsd, | |
| 528 | 532 | => { |
| 529 | 533 | if (self.os_data.have_fd) { |
| 530 | 534 | self.loop.posixFsRequest(&self.os_data.close_req_node); |
| ... | ... | @@ -546,6 +550,7 @@ pub const CloseOperation = struct.{ |
| 546 | 550 | switch (builtin.os) { |
| 547 | 551 | builtin.Os.linux, |
| 548 | 552 | builtin.Os.macosx, |
| 553 | builtin.Os.freebsd, | |
| 549 | 554 | => { |
| 550 | 555 | self.os_data.close_req_node.data.msg.Close.fd = handle; |
| 551 | 556 | self.os_data.have_fd = true; |
| ... | ... | @@ -562,6 +567,7 @@ pub const CloseOperation = struct.{ |
| 562 | 567 | switch (builtin.os) { |
| 563 | 568 | builtin.Os.linux, |
| 564 | 569 | builtin.Os.macosx, |
| 570 | builtin.Os.freebsd, | |
| 565 | 571 | => { |
| 566 | 572 | self.os_data.have_fd = false; |
| 567 | 573 | }, |
| ... | ... | @@ -576,6 +582,7 @@ pub const CloseOperation = struct.{ |
| 576 | 582 | switch (builtin.os) { |
| 577 | 583 | builtin.Os.linux, |
| 578 | 584 | builtin.Os.macosx, |
| 585 | builtin.Os.freebsd, | |
| 579 | 586 | => { |
| 580 | 587 | assert(self.os_data.have_fd); |
| 581 | 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 | 606 | switch (builtin.os) { |
| 600 | 607 | builtin.Os.linux, |
| 601 | 608 | builtin.Os.macosx, |
| 609 | builtin.Os.freebsd, | |
| 602 | 610 | => return await (async writeFileModeThread(loop, path, contents, mode) catch unreachable), |
| 603 | 611 | builtin.Os.windows => return await (async writeFileWindows(loop, path, contents) catch unreachable), |
| 604 | 612 | else => @compileError("Unsupported OS"), |
| ... | ... | @@ -704,7 +712,7 @@ pub fn Watch(comptime V: type) type { |
| 704 | 712 | os_data: OsData, |
| 705 | 713 | |
| 706 | 714 | const OsData = switch (builtin.os) { |
| 707 | builtin.Os.macosx => struct.{ | |
| 715 | builtin.Os.macosx, builtin.Os.freebsd => struct.{ | |
| 708 | 716 | file_table: FileTable, |
| 709 | 717 | table_lock: event.Lock, |
| 710 | 718 | |
| ... | ... | @@ -793,7 +801,7 @@ pub fn Watch(comptime V: type) type { |
| 793 | 801 | return self; |
| 794 | 802 | }, |
| 795 | 803 | |
| 796 | builtin.Os.macosx => { | |
| 804 | builtin.Os.macosx, builtin.Os.freebsd => { | |
| 797 | 805 | const self = try loop.allocator.createOne(Self); |
| 798 | 806 | errdefer loop.allocator.destroy(self); |
| 799 | 807 | |
| ... | ... | @@ -813,7 +821,7 @@ pub fn Watch(comptime V: type) type { |
| 813 | 821 | /// All addFile calls and removeFile calls must have completed. |
| 814 | 822 | pub fn destroy(self: *Self) void { |
| 815 | 823 | switch (builtin.os) { |
| 816 | builtin.Os.macosx => { | |
| 824 | builtin.Os.macosx, builtin.Os.freebsd => { | |
| 817 | 825 | // TODO we need to cancel the coroutines before destroying the lock |
| 818 | 826 | self.os_data.table_lock.deinit(); |
| 819 | 827 | var it = self.os_data.file_table.iterator(); |
| ... | ... | @@ -855,14 +863,14 @@ pub fn Watch(comptime V: type) type { |
| 855 | 863 | |
| 856 | 864 | pub async fn addFile(self: *Self, file_path: []const u8, value: V) !?V { |
| 857 | 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 | 867 | builtin.Os.linux => return await (async addFileLinux(self, file_path, value) catch unreachable), |
| 860 | 868 | builtin.Os.windows => return await (async addFileWindows(self, file_path, value) catch unreachable), |
| 861 | 869 | else => @compileError("Unsupported OS"), |
| 862 | 870 | } |
| 863 | 871 | } |
| 864 | 872 | |
| 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 | 874 | const resolved_path = try os.path.resolve(self.channel.loop.allocator, file_path); |
| 867 | 875 | var resolved_path_consumed = false; |
| 868 | 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 | 879 | var close_op_consumed = false; |
| 872 | 880 | defer if (!close_op_consumed) close_op.finish(); |
| 873 | 881 | |
| 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 | 887 | const mode = 0; |
| 876 | 888 | const fd = try await (async openPosix(self.channel.loop, resolved_path, flags, mode) catch unreachable); |
| 877 | 889 | close_op.setHandle(fd); |
std/event/loop.zig+14-13| ... | ... | @@ -48,7 +48,7 @@ pub const Loop = struct.{ |
| 48 | 48 | }; |
| 49 | 49 | |
| 50 | 50 | pub const EventFd = switch (builtin.os) { |
| 51 | builtin.Os.macosx => MacOsEventFd, | |
| 51 | builtin.Os.macosx, builtin.Os.freebsd => KEventFd, | |
| 52 | 52 | builtin.Os.linux => struct.{ |
| 53 | 53 | base: ResumeNode, |
| 54 | 54 | epoll_op: u32, |
| ... | ... | @@ -61,13 +61,13 @@ pub const Loop = struct.{ |
| 61 | 61 | else => @compileError("unsupported OS"), |
| 62 | 62 | }; |
| 63 | 63 | |
| 64 | const MacOsEventFd = struct.{ | |
| 64 | const KEventFd = struct.{ | |
| 65 | 65 | base: ResumeNode, |
| 66 | 66 | kevent: posix.Kevent, |
| 67 | 67 | }; |
| 68 | 68 | |
| 69 | 69 | pub const Basic = switch (builtin.os) { |
| 70 | builtin.Os.macosx => MacOsBasic, | |
| 70 | builtin.Os.macosx, builtin.Os.freebsd => KEventBasic, | |
| 71 | 71 | builtin.Os.linux => struct.{ |
| 72 | 72 | base: ResumeNode, |
| 73 | 73 | }, |
| ... | ... | @@ -77,7 +77,7 @@ pub const Loop = struct.{ |
| 77 | 77 | else => @compileError("unsupported OS"), |
| 78 | 78 | }; |
| 79 | 79 | |
| 80 | const MacOsBasic = struct.{ | |
| 80 | const KEventBasic = struct.{ | |
| 81 | 81 | base: ResumeNode, |
| 82 | 82 | kev: posix.Kevent, |
| 83 | 83 | }; |
| ... | ... | @@ -213,7 +213,7 @@ pub const Loop = struct.{ |
| 213 | 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 | 217 | self.os_data.kqfd = try os.bsdKQueue(); |
| 218 | 218 | errdefer os.close(self.os_data.kqfd); |
| 219 | 219 | |
| ... | ... | @@ -368,7 +368,7 @@ pub const Loop = struct.{ |
| 368 | 368 | os.close(self.os_data.epollfd); |
| 369 | 369 | self.allocator.free(self.eventfd_resume_nodes); |
| 370 | 370 | }, |
| 371 | builtin.Os.macosx => { | |
| 371 | builtin.Os.macosx, builtin.Os.freebsd => { | |
| 372 | 372 | os.close(self.os_data.kqfd); |
| 373 | 373 | os.close(self.os_data.fs_kqfd); |
| 374 | 374 | }, |
| ... | ... | @@ -483,7 +483,7 @@ pub const Loop = struct.{ |
| 483 | 483 | const eventfd_node = &resume_stack_node.data; |
| 484 | 484 | eventfd_node.base.handle = next_tick_node.data; |
| 485 | 485 | switch (builtin.os) { |
| 486 | builtin.Os.macosx => { | |
| 486 | builtin.Os.macosx, builtin.Os.freebsd => { | |
| 487 | 487 | const kevent_array = (*[1]posix.Kevent)(&eventfd_node.kevent); |
| 488 | 488 | const empty_kevs = ([*]posix.Kevent)(undefined)[0..0]; |
| 489 | 489 | _ = os.bsdKEvent(self.os_data.kqfd, kevent_array, empty_kevs, null) catch { |
| ... | ... | @@ -545,6 +545,7 @@ pub const Loop = struct.{ |
| 545 | 545 | switch (builtin.os) { |
| 546 | 546 | builtin.Os.linux, |
| 547 | 547 | builtin.Os.macosx, |
| 548 | builtin.Os.freebsd, | |
| 548 | 549 | => self.os_data.fs_thread.wait(), |
| 549 | 550 | else => {}, |
| 550 | 551 | } |
| ... | ... | @@ -609,7 +610,7 @@ pub const Loop = struct.{ |
| 609 | 610 | os.posixWrite(self.os_data.final_eventfd, wakeup_bytes) catch unreachable; |
| 610 | 611 | return; |
| 611 | 612 | }, |
| 612 | builtin.Os.macosx => { | |
| 613 | builtin.Os.macosx, builtin.Os.freebsd => { | |
| 613 | 614 | self.posixFsRequest(&self.os_data.fs_end_request); |
| 614 | 615 | const final_kevent = (*[1]posix.Kevent)(&self.os_data.final_kevent); |
| 615 | 616 | const empty_kevs = ([*]posix.Kevent)(undefined)[0..0]; |
| ... | ... | @@ -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 | 672 | var eventlist: [1]posix.Kevent = undefined; |
| 672 | 673 | const empty_kevs = ([*]posix.Kevent)(undefined)[0..0]; |
| 673 | 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 | 731 | self.beginOneEvent(); // finished in posixFsRun after processing the msg |
| 731 | 732 | self.os_data.fs_queue.put(request_node); |
| 732 | 733 | switch (builtin.os) { |
| 733 | builtin.Os.macosx => { | |
| 734 | builtin.Os.macosx, builtin.Os.freebsd => { | |
| 734 | 735 | const fs_kevs = (*[1]posix.Kevent)(&self.os_data.fs_kevent_wake); |
| 735 | 736 | const empty_kevs = ([*]posix.Kevent)(undefined)[0..0]; |
| 736 | 737 | _ = os.bsdKEvent(self.os_data.fs_kqfd, fs_kevs, empty_kevs, null) catch unreachable; |
| ... | ... | @@ -800,7 +801,7 @@ pub const Loop = struct.{ |
| 800 | 801 | else => unreachable, |
| 801 | 802 | } |
| 802 | 803 | }, |
| 803 | builtin.Os.macosx => { | |
| 804 | builtin.Os.macosx, builtin.Os.freebsd => { | |
| 804 | 805 | const fs_kevs = (*[1]posix.Kevent)(&self.os_data.fs_kevent_wait); |
| 805 | 806 | var out_kevs: [1]posix.Kevent = undefined; |
| 806 | 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 | 813 | |
| 813 | 814 | const OsData = switch (builtin.os) { |
| 814 | 815 | builtin.Os.linux => LinuxOsData, |
| 815 | builtin.Os.macosx => MacOsData, | |
| 816 | builtin.Os.macosx, builtin.Os.freebsd => KEventData, | |
| 816 | 817 | builtin.Os.windows => struct.{ |
| 817 | 818 | io_port: windows.HANDLE, |
| 818 | 819 | extra_thread_count: usize, |
| ... | ... | @@ -820,7 +821,7 @@ pub const Loop = struct.{ |
| 820 | 821 | else => struct.{}, |
| 821 | 822 | }; |
| 822 | 823 | |
| 823 | const MacOsData = struct.{ | |
| 824 | const KEventData = struct.{ | |
| 824 | 825 | kqfd: i32, |
| 825 | 826 | final_kevent: posix.Kevent, |
| 826 | 827 | fs_kevent_wake: posix.Kevent, |
std/os/freebsd/index.zig+211-1| ... | ... | @@ -7,6 +7,10 @@ const arch = switch (builtin.arch) { |
| 7 | 7 | pub use @import("syscall.zig"); |
| 8 | 8 | pub use @import("errno.zig"); |
| 9 | 9 | |
| 10 | const std = @import("../../index.zig"); | |
| 11 | const c = std.c; | |
| 12 | pub const Kevent = c.Kevent; | |
| 13 | ||
| 10 | 14 | pub const PATH_MAX = 1024; |
| 11 | 15 | |
| 12 | 16 | pub const STDIN_FILENO = 0; |
| ... | ... | @@ -293,6 +297,156 @@ pub const DT_LNK = 10; |
| 293 | 297 | pub const DT_SOCK = 12; |
| 294 | 298 | pub const DT_WHT = 14; |
| 295 | 299 | |
| 300 | /// add event to kq (implies enable) | |
| 301 | pub const EV_ADD = 0x0001; | |
| 302 | ||
| 303 | /// delete event from kq | |
| 304 | pub const EV_DELETE = 0x0002; | |
| 305 | ||
| 306 | /// enable event | |
| 307 | pub const EV_ENABLE = 0x0004; | |
| 308 | ||
| 309 | /// disable event (not reported) | |
| 310 | pub const EV_DISABLE = 0x0008; | |
| 311 | ||
| 312 | /// only report one occurrence | |
| 313 | pub const EV_ONESHOT = 0x0010; | |
| 314 | ||
| 315 | /// clear event state after reporting | |
| 316 | pub 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 | |
| 322 | pub const EV_RECEIPT = 0x0040; | |
| 323 | ||
| 324 | /// disable event after reporting | |
| 325 | pub const EV_DISPATCH = 0x0080; | |
| 326 | ||
| 327 | pub const EVFILT_READ = -1; | |
| 328 | pub const EVFILT_WRITE = -2; | |
| 329 | ||
| 330 | /// attached to aio requests | |
| 331 | pub const EVFILT_AIO = -3; | |
| 332 | ||
| 333 | /// attached to vnodes | |
| 334 | pub const EVFILT_VNODE = -4; | |
| 335 | ||
| 336 | /// attached to struct proc | |
| 337 | pub const EVFILT_PROC = -5; | |
| 338 | ||
| 339 | /// attached to struct proc | |
| 340 | pub const EVFILT_SIGNAL = -6; | |
| 341 | ||
| 342 | /// timers | |
| 343 | pub const EVFILT_TIMER = -7; | |
| 344 | ||
| 345 | /// Process descriptors | |
| 346 | pub const EVFILT_PROCDESC = -8; | |
| 347 | ||
| 348 | /// Filesystem events | |
| 349 | pub const EVFILT_FS = -9; | |
| 350 | ||
| 351 | pub const EVFILT_LIO = -10; | |
| 352 | ||
| 353 | /// User events | |
| 354 | pub const EVFILT_USER = -11; | |
| 355 | ||
| 356 | /// Sendfile events | |
| 357 | pub const EVFILT_SENDFILE = -12; | |
| 358 | ||
| 359 | pub const EVFILT_EMPTY = -13; | |
| 360 | ||
| 361 | /// On input, NOTE_TRIGGER causes the event to be triggered for output. | |
| 362 | pub const NOTE_TRIGGER = 0x01000000; | |
| 363 | ||
| 364 | /// ignore input fflags | |
| 365 | pub const NOTE_FFNOP = 0x00000000; | |
| 366 | ||
| 367 | /// and fflags | |
| 368 | pub const NOTE_FFAND = 0x40000000; | |
| 369 | ||
| 370 | /// or fflags | |
| 371 | pub const NOTE_FFOR = 0x80000000; | |
| 372 | ||
| 373 | /// copy fflags | |
| 374 | pub const NOTE_FFCOPY = 0xc0000000; | |
| 375 | ||
| 376 | /// mask for operations | |
| 377 | pub const NOTE_FFCTRLMASK = 0xc0000000; | |
| 378 | pub const NOTE_FFLAGSMASK = 0x00ffffff; | |
| 379 | ||
| 380 | ||
| 381 | /// low water mark | |
| 382 | pub const NOTE_LOWAT = 0x00000001; | |
| 383 | ||
| 384 | /// behave like poll() | |
| 385 | pub const NOTE_FILE_POLL = 0x00000002; | |
| 386 | ||
| 387 | /// vnode was removed | |
| 388 | pub const NOTE_DELETE = 0x00000001; | |
| 389 | ||
| 390 | /// data contents changed | |
| 391 | pub const NOTE_WRITE = 0x00000002; | |
| 392 | ||
| 393 | /// size increased | |
| 394 | pub const NOTE_EXTEND = 0x00000004; | |
| 395 | ||
| 396 | /// attributes changed | |
| 397 | pub const NOTE_ATTRIB = 0x00000008; | |
| 398 | ||
| 399 | /// link count changed | |
| 400 | pub const NOTE_LINK = 0x00000010; | |
| 401 | ||
| 402 | /// vnode was renamed | |
| 403 | pub const NOTE_RENAME = 0x00000020; | |
| 404 | ||
| 405 | /// vnode access was revoked | |
| 406 | pub const NOTE_REVOKE = 0x00000040; | |
| 407 | ||
| 408 | /// vnode was opened | |
| 409 | pub const NOTE_OPEN = 0x00000080; | |
| 410 | ||
| 411 | /// file closed, fd did not allow write | |
| 412 | pub const NOTE_CLOSE = 0x00000100; | |
| 413 | ||
| 414 | /// file closed, fd did allow write | |
| 415 | pub const NOTE_CLOSE_WRITE = 0x00000200; | |
| 416 | ||
| 417 | /// file was read | |
| 418 | pub const NOTE_READ = 0x00000400; | |
| 419 | ||
| 420 | /// process exited | |
| 421 | pub const NOTE_EXIT = 0x80000000; | |
| 422 | ||
| 423 | /// process forked | |
| 424 | pub const NOTE_FORK = 0x40000000; | |
| 425 | ||
| 426 | /// process exec'd | |
| 427 | pub const NOTE_EXEC = 0x20000000; | |
| 428 | ||
| 429 | /// mask for signal & exit status | |
| 430 | pub const NOTE_PDATAMASK = 0x000fffff; | |
| 431 | pub const NOTE_PCTRLMASK = (~NOTE_PDATAMASK); | |
| 432 | ||
| 433 | /// data is seconds | |
| 434 | pub const NOTE_SECONDS = 0x00000001; | |
| 435 | ||
| 436 | /// data is milliseconds | |
| 437 | pub const NOTE_MSECONDS = 0x00000002; | |
| 438 | ||
| 439 | /// data is microseconds | |
| 440 | pub const NOTE_USECONDS = 0x00000004; | |
| 441 | ||
| 442 | /// data is nanoseconds | |
| 443 | pub const NOTE_NSECONDS = 0x00000008; | |
| 444 | ||
| 445 | /// timeout is absolute | |
| 446 | pub const NOTE_ABSTIME = 0x00000010; | |
| 447 | ||
| 448 | ||
| 449 | ||
| 296 | 450 | pub const TCGETS = 0x5401; |
| 297 | 451 | pub const TCSETS = 0x5402; |
| 298 | 452 | pub const TCSETSW = 0x5403; |
| ... | ... | @@ -445,7 +599,11 @@ pub fn symlink(existing: [*]const u8, new: [*]const u8) usize { |
| 445 | 599 | } |
| 446 | 600 | |
| 447 | 601 | pub 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 | ||
| 605 | pub 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 | } |
| 450 | 608 | |
| 451 | 609 | pub fn pipe(fd: *[2]i32) usize { |
| ... | ... | @@ -464,6 +622,10 @@ pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: usize) usize { |
| 464 | 622 | return arch.syscall4(SYS_pwrite, @intCast(usize, fd), @ptrToInt(buf), count, offset); |
| 465 | 623 | } |
| 466 | 624 | |
| 625 | pub 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 | ||
| 467 | 629 | pub fn rename(old: [*]const u8, new: [*]const u8) usize { |
| 468 | 630 | return arch.syscall2(SYS_rename, @ptrToInt(old), @ptrToInt(new)); |
| 469 | 631 | } |
| ... | ... | @@ -590,3 +752,51 @@ pub const timespec = arch.timespec; |
| 590 | 752 | pub fn fstat(fd: i32, stat_buf: *Stat) usize { |
| 591 | 753 | return arch.syscall2(SYS_fstat, @intCast(usize, fd), @ptrToInt(stat_buf)); |
| 592 | 754 | } |
| 755 | ||
| 756 | pub const iovec = extern struct.{ | |
| 757 | iov_base: [*]u8, | |
| 758 | iov_len: usize, | |
| 759 | }; | |
| 760 | ||
| 761 | pub const iovec_const = extern struct.{ | |
| 762 | iov_base: [*]const u8, | |
| 763 | iov_len: usize, | |
| 764 | }; | |
| 765 | ||
| 766 | pub fn kqueue() usize { | |
| 767 | return errnoWrap(c.kqueue()); | |
| 768 | } | |
| 769 | ||
| 770 | pub 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 | ||
| 781 | pub 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 | ||
| 785 | pub 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 | ||
| 789 | pub 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. | |
| 798 | fn 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 | 43 | }; |
| 44 | 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 | 47 | const home_dir = os.getEnvPosix("HOME") orelse { |
| 48 | 48 | // TODO look in /etc/passwd |
| 49 | 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 | 421 | } |
| 422 | 422 | } |
| 423 | 423 | }, |
| 424 | builtin.Os.linux => while (true) { | |
| 424 | builtin.Os.linux, builtin.Os.freebsd => while (true) { | |
| 425 | 425 | const rc = posix.pwritev(fd, iov, count, offset); |
| 426 | 426 | const err = posix.getErrno(rc); |
| 427 | 427 | switch (err) { |
| ... | ... | @@ -689,7 +689,7 @@ pub fn getBaseAddress() usize { |
| 689 | 689 | }; |
| 690 | 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 | 693 | builtin.Os.windows => return @ptrToInt(windows.GetModuleHandleW(null)), |
| 694 | 694 | else => @compileError("Unsupported OS"), |
| 695 | 695 | } |
| ... | ... | @@ -1307,7 +1307,7 @@ pub fn deleteDirC(dir_path: [*]const u8) DeleteDirError!void { |
| 1307 | 1307 | const dir_path_w = try windows_util.cStrToPrefixedFileW(dir_path); |
| 1308 | 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 | 1311 | const err = posix.getErrno(posix.rmdir(dir_path)); |
| 1312 | 1312 | switch (err) { |
| 1313 | 1313 | 0 => return, |
| ... | ... | @@ -1350,7 +1350,7 @@ pub fn deleteDir(dir_path: []const u8) DeleteDirError!void { |
| 1350 | 1350 | const dir_path_w = try windows_util.sliceToPrefixedFileW(dir_path); |
| 1351 | 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 | 1354 | const dir_path_c = try toPosixPath(dir_path); |
| 1355 | 1355 | return deleteDirC(&dir_path_c); |
| 1356 | 1356 | }, |
| ... | ... | @@ -1467,7 +1467,7 @@ pub const Dir = struct.{ |
| 1467 | 1467 | allocator: *Allocator, |
| 1468 | 1468 | |
| 1469 | 1469 | pub const Handle = switch (builtin.os) { |
| 1470 | Os.macosx, Os.ios => struct.{ | |
| 1470 | Os.macosx, Os.ios, Os.freebsd => struct.{ | |
| 1471 | 1471 | fd: i32, |
| 1472 | 1472 | seek: i64, |
| 1473 | 1473 | buf: []u8, |
| ... | ... | @@ -1543,7 +1543,7 @@ pub const Dir = struct.{ |
| 1543 | 1543 | .name_data = undefined, |
| 1544 | 1544 | }; |
| 1545 | 1545 | }, |
| 1546 | Os.macosx, Os.ios => Handle.{ | |
| 1546 | Os.macosx, Os.ios, Os.freebsd => Handle.{ | |
| 1547 | 1547 | .fd = try posixOpen( |
| 1548 | 1548 | dir_path, |
| 1549 | 1549 | posix.O_RDONLY | posix.O_NONBLOCK | posix.O_DIRECTORY | posix.O_CLOEXEC, |
| ... | ... | @@ -1574,7 +1574,7 @@ pub const Dir = struct.{ |
| 1574 | 1574 | Os.windows => { |
| 1575 | 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 | 1578 | self.allocator.free(self.handle.buf); |
| 1579 | 1579 | os.close(self.handle.fd); |
| 1580 | 1580 | }, |
| ... | ... | @@ -1589,6 +1589,7 @@ pub const Dir = struct.{ |
| 1589 | 1589 | Os.linux => return self.nextLinux(), |
| 1590 | 1590 | Os.macosx, Os.ios => return self.nextDarwin(), |
| 1591 | 1591 | Os.windows => return self.nextWindows(), |
| 1592 | Os.freebsd => return self.nextFreebsd(), | |
| 1592 | 1593 | else => @compileError("unimplemented"), |
| 1593 | 1594 | } |
| 1594 | 1595 | } |
| ... | ... | @@ -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 | }; |
| 1732 | 1738 | |
| 1733 | 1739 | pub fn changeCurDir(allocator: *Allocator, dir_path: []const u8) !void { |
| ... | ... | @@ -2166,7 +2172,7 @@ pub fn unexpectedErrorWindows(err: windows.DWORD) UnexpectedError { |
| 2166 | 2172 | pub fn openSelfExe() !os.File { |
| 2167 | 2173 | switch (builtin.os) { |
| 2168 | 2174 | Os.linux => return os.File.openReadC(c"/proc/self/exe"), |
| 2169 | Os.macosx, Os.ios => { | |
| 2175 | Os.macosx, Os.ios, Os.freebsd => { | |
| 2170 | 2176 | var buf: [MAX_PATH_BYTES]u8 = undefined; |
| 2171 | 2177 | const self_exe_path = try selfExePath(&buf); |
| 2172 | 2178 | buf[self_exe_path.len] = 0; |
| ... | ... | @@ -2183,7 +2189,7 @@ pub fn openSelfExe() !os.File { |
| 2183 | 2189 | |
| 2184 | 2190 | test "openSelfExe" { |
| 2185 | 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 | 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 | 2220 | pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) ![]u8 { |
| 2215 | 2221 | switch (builtin.os) { |
| 2216 | 2222 | Os.linux => return readLink(out_buffer, "/proc/self/exe"), |
| 2223 | Os.freebsd => return readLink(out_buffer, "/proc/curproc/file"), | |
| 2217 | 2224 | Os.windows => { |
| 2218 | 2225 | var utf16le_buf: [windows_util.PATH_MAX_WIDE]u16 = undefined; |
| 2219 | 2226 | const utf16le_slice = try selfExePathW(&utf16le_buf); |
| ... | ... | @@ -2252,7 +2259,7 @@ pub fn selfExeDirPath(out_buffer: *[MAX_PATH_BYTES]u8) ![]const u8 { |
| 2252 | 2259 | // will not return null. |
| 2253 | 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 | 2263 | const self_exe_path = try selfExePath(out_buffer); |
| 2257 | 2264 | // Assume that the OS APIs return absolute paths, and therefore dirname |
| 2258 | 2265 | // will not return null. |
| ... | ... | @@ -3085,10 +3092,13 @@ pub const CpuCountError = error.{ |
| 3085 | 3092 | |
| 3086 | 3093 | pub fn cpuCount(fallback_allocator: *mem.Allocator) CpuCountError!usize { |
| 3087 | 3094 | switch (builtin.os) { |
| 3088 | builtin.Os.macosx => { | |
| 3095 | builtin.Os.macosx, builtin.Os.freebsd => { | |
| 3089 | 3096 | var count: c_int = undefined; |
| 3090 | 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 | 3102 | const err = posix.getErrno(rc); |
| 3093 | 3103 | switch (err) { |
| 3094 | 3104 | 0 => return @intCast(usize, count), |