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
444444 "buffer.zig"
445445 "build.zig"
446446 "c/darwin.zig"
447 "c/freebsd.zig"
447448 "c/index.zig"
448449 "c/linux.zig"
449450 "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) {
55 Os.linux => @import("linux.zig"),
66 Os.windows => @import("windows.zig"),
77 Os.macosx, Os.ios => @import("darwin.zig"),
8 Os.freebsd => @import("freebsd.zig"),
89 else => empty_import,
910};
1011const 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
8383 switch (builtin.os) {
8484 builtin.Os.macosx,
8585 builtin.Os.linux,
86 builtin.Os.freebsd,
8687 => {
8788 const iovecs = try loop.allocator.alloc(os.posix.iovec_const, data.len);
8889 defer loop.allocator.free(iovecs);
......@@ -219,6 +220,7 @@ pub async fn preadv(loop: *Loop, fd: os.FileHandle, data: []const []u8, offset:
219220 switch (builtin.os) {
220221 builtin.Os.macosx,
221222 builtin.Os.linux,
223 builtin.Os.freebsd,
222224 => {
223225 const iovecs = try loop.allocator.alloc(os.posix.iovec, data.len);
224226 defer loop.allocator.free(iovecs);
......@@ -399,7 +401,7 @@ pub async fn openPosix(
399401
400402pub async fn openRead(loop: *Loop, path: []const u8) os.File.OpenError!os.FileHandle {
401403 switch (builtin.os) {
402 builtin.Os.macosx, builtin.Os.linux => {
404 builtin.Os.macosx, builtin.Os.linux, builtin.Os.freebsd => {
403405 const flags = posix.O_LARGEFILE | posix.O_RDONLY | posix.O_CLOEXEC;
404406 return await (async openPosix(loop, path, flags, os.File.default_mode) catch unreachable);
405407 },
......@@ -427,6 +429,7 @@ pub async fn openWriteMode(loop: *Loop, path: []const u8, mode: os.File.Mode) os
427429 switch (builtin.os) {
428430 builtin.Os.macosx,
429431 builtin.Os.linux,
432 builtin.Os.freebsd,
430433 => {
431434 const flags = posix.O_LARGEFILE | posix.O_WRONLY | posix.O_CREAT | posix.O_CLOEXEC | posix.O_TRUNC;
432435 return await (async openPosix(loop, path, flags, os.File.default_mode) catch unreachable);
......@@ -449,7 +452,7 @@ pub async fn openReadWrite(
449452 mode: os.File.Mode,
450453) os.File.OpenError!os.FileHandle {
451454 switch (builtin.os) {
452 builtin.Os.macosx, builtin.Os.linux => {
455 builtin.Os.macosx, builtin.Os.linux, builtin.Os.freebsd => {
453456 const flags = posix.O_LARGEFILE | posix.O_RDWR | posix.O_CREAT | posix.O_CLOEXEC;
454457 return await (async openPosix(loop, path, flags, mode) catch unreachable);
455458 },
......@@ -477,7 +480,7 @@ pub const CloseOperation = struct.{
477480 os_data: OsData,
478481
479482 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
482485 builtin.Os.windows => struct.{
483486 handle: ?os.FileHandle,
......@@ -496,7 +499,7 @@ pub const CloseOperation = struct.{
496499 self.* = CloseOperation.{
497500 .loop = loop,
498501 .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),
500503 builtin.Os.windows => OsData.{ .handle = null },
501504 else => @compileError("Unsupported OS"),
502505 },
......@@ -525,6 +528,7 @@ pub const CloseOperation = struct.{
525528 switch (builtin.os) {
526529 builtin.Os.linux,
527530 builtin.Os.macosx,
531 builtin.Os.freebsd,
528532 => {
529533 if (self.os_data.have_fd) {
530534 self.loop.posixFsRequest(&self.os_data.close_req_node);
......@@ -546,6 +550,7 @@ pub const CloseOperation = struct.{
546550 switch (builtin.os) {
547551 builtin.Os.linux,
548552 builtin.Os.macosx,
553 builtin.Os.freebsd,
549554 => {
550555 self.os_data.close_req_node.data.msg.Close.fd = handle;
551556 self.os_data.have_fd = true;
......@@ -562,6 +567,7 @@ pub const CloseOperation = struct.{
562567 switch (builtin.os) {
563568 builtin.Os.linux,
564569 builtin.Os.macosx,
570 builtin.Os.freebsd,
565571 => {
566572 self.os_data.have_fd = false;
567573 },
......@@ -576,6 +582,7 @@ pub const CloseOperation = struct.{
576582 switch (builtin.os) {
577583 builtin.Os.linux,
578584 builtin.Os.macosx,
585 builtin.Os.freebsd,
579586 => {
580587 assert(self.os_data.have_fd);
581588 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,
599606 switch (builtin.os) {
600607 builtin.Os.linux,
601608 builtin.Os.macosx,
609 builtin.Os.freebsd,
602610 => return await (async writeFileModeThread(loop, path, contents, mode) catch unreachable),
603611 builtin.Os.windows => return await (async writeFileWindows(loop, path, contents) catch unreachable),
604612 else => @compileError("Unsupported OS"),
......@@ -704,7 +712,7 @@ pub fn Watch(comptime V: type) type {
704712 os_data: OsData,
705713
706714 const OsData = switch (builtin.os) {
707 builtin.Os.macosx => struct.{
715 builtin.Os.macosx, builtin.Os.freebsd => struct.{
708716 file_table: FileTable,
709717 table_lock: event.Lock,
710718
......@@ -793,7 +801,7 @@ pub fn Watch(comptime V: type) type {
793801 return self;
794802 },
795803
796 builtin.Os.macosx => {
804 builtin.Os.macosx, builtin.Os.freebsd => {
797805 const self = try loop.allocator.createOne(Self);
798806 errdefer loop.allocator.destroy(self);
799807
......@@ -813,7 +821,7 @@ pub fn Watch(comptime V: type) type {
813821 /// All addFile calls and removeFile calls must have completed.
814822 pub fn destroy(self: *Self) void {
815823 switch (builtin.os) {
816 builtin.Os.macosx => {
824 builtin.Os.macosx, builtin.Os.freebsd => {
817825 // TODO we need to cancel the coroutines before destroying the lock
818826 self.os_data.table_lock.deinit();
819827 var it = self.os_data.file_table.iterator();
......@@ -855,14 +863,14 @@ pub fn Watch(comptime V: type) type {
855863
856864 pub async fn addFile(self: *Self, file_path: []const u8, value: V) !?V {
857865 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),
859867 builtin.Os.linux => return await (async addFileLinux(self, file_path, value) catch unreachable),
860868 builtin.Os.windows => return await (async addFileWindows(self, file_path, value) catch unreachable),
861869 else => @compileError("Unsupported OS"),
862870 }
863871 }
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 {
866874 const resolved_path = try os.path.resolve(self.channel.loop.allocator, file_path);
867875 var resolved_path_consumed = false;
868876 defer if (!resolved_path_consumed) self.channel.loop.allocator.free(resolved_path);
......@@ -871,7 +879,11 @@ pub fn Watch(comptime V: type) type {
871879 var close_op_consumed = false;
872880 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 };
875887 const mode = 0;
876888 const fd = try await (async openPosix(self.channel.loop, resolved_path, flags, mode) catch unreachable);
877889 close_op.setHandle(fd);
std/event/loop.zig+14-13
......@@ -48,7 +48,7 @@ pub const Loop = struct.{
4848 };
4949
5050 pub const EventFd = switch (builtin.os) {
51 builtin.Os.macosx => MacOsEventFd,
51 builtin.Os.macosx, builtin.Os.freebsd => KEventFd,
5252 builtin.Os.linux => struct.{
5353 base: ResumeNode,
5454 epoll_op: u32,
......@@ -61,13 +61,13 @@ pub const Loop = struct.{
6161 else => @compileError("unsupported OS"),
6262 };
6363
64 const MacOsEventFd = struct.{
64 const KEventFd = struct.{
6565 base: ResumeNode,
6666 kevent: posix.Kevent,
6767 };
6868
6969 pub const Basic = switch (builtin.os) {
70 builtin.Os.macosx => MacOsBasic,
70 builtin.Os.macosx, builtin.Os.freebsd => KEventBasic,
7171 builtin.Os.linux => struct.{
7272 base: ResumeNode,
7373 },
......@@ -77,7 +77,7 @@ pub const Loop = struct.{
7777 else => @compileError("unsupported OS"),
7878 };
7979
80 const MacOsBasic = struct.{
80 const KEventBasic = struct.{
8181 base: ResumeNode,
8282 kev: posix.Kevent,
8383 };
......@@ -213,7 +213,7 @@ pub const Loop = struct.{
213213 self.extra_threads[extra_thread_index] = try os.spawnThread(self, workerRun);
214214 }
215215 },
216 builtin.Os.macosx => {
216 builtin.Os.macosx, builtin.Os.freebsd => {
217217 self.os_data.kqfd = try os.bsdKQueue();
218218 errdefer os.close(self.os_data.kqfd);
219219
......@@ -368,7 +368,7 @@ pub const Loop = struct.{
368368 os.close(self.os_data.epollfd);
369369 self.allocator.free(self.eventfd_resume_nodes);
370370 },
371 builtin.Os.macosx => {
371 builtin.Os.macosx, builtin.Os.freebsd => {
372372 os.close(self.os_data.kqfd);
373373 os.close(self.os_data.fs_kqfd);
374374 },
......@@ -483,7 +483,7 @@ pub const Loop = struct.{
483483 const eventfd_node = &resume_stack_node.data;
484484 eventfd_node.base.handle = next_tick_node.data;
485485 switch (builtin.os) {
486 builtin.Os.macosx => {
486 builtin.Os.macosx, builtin.Os.freebsd => {
487487 const kevent_array = (*[1]posix.Kevent)(&eventfd_node.kevent);
488488 const empty_kevs = ([*]posix.Kevent)(undefined)[0..0];
489489 _ = os.bsdKEvent(self.os_data.kqfd, kevent_array, empty_kevs, null) catch {
......@@ -545,6 +545,7 @@ pub const Loop = struct.{
545545 switch (builtin.os) {
546546 builtin.Os.linux,
547547 builtin.Os.macosx,
548 builtin.Os.freebsd,
548549 => self.os_data.fs_thread.wait(),
549550 else => {},
550551 }
......@@ -609,7 +610,7 @@ pub const Loop = struct.{
609610 os.posixWrite(self.os_data.final_eventfd, wakeup_bytes) catch unreachable;
610611 return;
611612 },
612 builtin.Os.macosx => {
613 builtin.Os.macosx, builtin.Os.freebsd => {
613614 self.posixFsRequest(&self.os_data.fs_end_request);
614615 const final_kevent = (*[1]posix.Kevent)(&self.os_data.final_kevent);
615616 const empty_kevs = ([*]posix.Kevent)(undefined)[0..0];
......@@ -667,7 +668,7 @@ pub const Loop = struct.{
667668 }
668669 }
669670 },
670 builtin.Os.macosx => {
671 builtin.Os.macosx, builtin.Os.freebsd => {
671672 var eventlist: [1]posix.Kevent = undefined;
672673 const empty_kevs = ([*]posix.Kevent)(undefined)[0..0];
673674 const count = os.bsdKEvent(self.os_data.kqfd, empty_kevs, eventlist[0..], null) catch unreachable;
......@@ -730,7 +731,7 @@ pub const Loop = struct.{
730731 self.beginOneEvent(); // finished in posixFsRun after processing the msg
731732 self.os_data.fs_queue.put(request_node);
732733 switch (builtin.os) {
733 builtin.Os.macosx => {
734 builtin.Os.macosx, builtin.Os.freebsd => {
734735 const fs_kevs = (*[1]posix.Kevent)(&self.os_data.fs_kevent_wake);
735736 const empty_kevs = ([*]posix.Kevent)(undefined)[0..0];
736737 _ = os.bsdKEvent(self.os_data.fs_kqfd, fs_kevs, empty_kevs, null) catch unreachable;
......@@ -800,7 +801,7 @@ pub const Loop = struct.{
800801 else => unreachable,
801802 }
802803 },
803 builtin.Os.macosx => {
804 builtin.Os.macosx, builtin.Os.freebsd => {
804805 const fs_kevs = (*[1]posix.Kevent)(&self.os_data.fs_kevent_wait);
805806 var out_kevs: [1]posix.Kevent = undefined;
806807 _ = os.bsdKEvent(self.os_data.fs_kqfd, fs_kevs, out_kevs[0..], null) catch unreachable;
......@@ -812,7 +813,7 @@ pub const Loop = struct.{
812813
813814 const OsData = switch (builtin.os) {
814815 builtin.Os.linux => LinuxOsData,
815 builtin.Os.macosx => MacOsData,
816 builtin.Os.macosx, builtin.Os.freebsd => KEventData,
816817 builtin.Os.windows => struct.{
817818 io_port: windows.HANDLE,
818819 extra_thread_count: usize,
......@@ -820,7 +821,7 @@ pub const Loop = struct.{
820821 else => struct.{},
821822 };
822823
823 const MacOsData = struct.{
824 const KEventData = struct.{
824825 kqfd: i32,
825826 final_kevent: posix.Kevent,
826827 fs_kevent_wake: posix.Kevent,
std/os/freebsd/index.zig+211-1
......@@ -7,6 +7,10 @@ const arch = switch (builtin.arch) {
77pub use @import("syscall.zig");
88pub use @import("errno.zig");
99
10const std = @import("../../index.zig");
11const c = std.c;
12pub const Kevent = c.Kevent;
13
1014pub const PATH_MAX = 1024;
1115
1216pub const STDIN_FILENO = 0;
......@@ -293,6 +297,156 @@ pub const DT_LNK = 10;
293297pub const DT_SOCK = 12;
294298pub 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
296450pub const TCGETS = 0x5401;
297451pub const TCSETS = 0x5402;
298452pub const TCSETSW = 0x5403;
......@@ -445,7 +599,11 @@ pub fn symlink(existing: [*]const u8, new: [*]const u8) usize {
445599}
446600
447601pub 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);
449607}
450608
451609pub fn pipe(fd: *[2]i32) usize {
......@@ -464,6 +622,10 @@ pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: usize) usize {
464622 return arch.syscall4(SYS_pwrite, @intCast(usize, fd), @ptrToInt(buf), count, offset);
465623}
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
467629pub fn rename(old: [*]const u8, new: [*]const u8) usize {
468630 return arch.syscall2(SYS_rename, @ptrToInt(old), @ptrToInt(new));
469631}
......@@ -590,3 +752,51 @@ pub const timespec = arch.timespec;
590752pub fn fstat(fd: i32, stat_buf: *Stat) usize {
591753 return arch.syscall2(SYS_fstat, @intCast(usize, fd), @ptrToInt(stat_buf));
592754}
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
4343 };
4444 return os.path.join(allocator, home_dir, "Library", "Application Support", appname);
4545 },
46 builtin.Os.linux => {
46 builtin.Os.linux, builtin.Os.freebsd => {
4747 const home_dir = os.getEnvPosix("HOME") orelse {
4848 // TODO look in /etc/passwd
4949 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
421421 }
422422 }
423423 },
424 builtin.Os.linux => while (true) {
424 builtin.Os.linux, builtin.Os.freebsd => while (true) {
425425 const rc = posix.pwritev(fd, iov, count, offset);
426426 const err = posix.getErrno(rc);
427427 switch (err) {
......@@ -689,7 +689,7 @@ pub fn getBaseAddress() usize {
689689 };
690690 return phdr - @sizeOf(ElfHeader);
691691 },
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),
693693 builtin.Os.windows => return @ptrToInt(windows.GetModuleHandleW(null)),
694694 else => @compileError("Unsupported OS"),
695695 }
......@@ -1307,7 +1307,7 @@ pub fn deleteDirC(dir_path: [*]const u8) DeleteDirError!void {
13071307 const dir_path_w = try windows_util.cStrToPrefixedFileW(dir_path);
13081308 return deleteDirW(&dir_path_w);
13091309 },
1310 Os.linux, Os.macosx, Os.ios => {
1310 Os.linux, Os.macosx, Os.ios, Os.freebsd => {
13111311 const err = posix.getErrno(posix.rmdir(dir_path));
13121312 switch (err) {
13131313 0 => return,
......@@ -1350,7 +1350,7 @@ pub fn deleteDir(dir_path: []const u8) DeleteDirError!void {
13501350 const dir_path_w = try windows_util.sliceToPrefixedFileW(dir_path);
13511351 return deleteDirW(&dir_path_w);
13521352 },
1353 Os.linux, Os.macosx, Os.ios => {
1353 Os.linux, Os.macosx, Os.ios, Os.freebsd => {
13541354 const dir_path_c = try toPosixPath(dir_path);
13551355 return deleteDirC(&dir_path_c);
13561356 },
......@@ -1467,7 +1467,7 @@ pub const Dir = struct.{
14671467 allocator: *Allocator,
14681468
14691469 pub const Handle = switch (builtin.os) {
1470 Os.macosx, Os.ios => struct.{
1470 Os.macosx, Os.ios, Os.freebsd => struct.{
14711471 fd: i32,
14721472 seek: i64,
14731473 buf: []u8,
......@@ -1543,7 +1543,7 @@ pub const Dir = struct.{
15431543 .name_data = undefined,
15441544 };
15451545 },
1546 Os.macosx, Os.ios => Handle.{
1546 Os.macosx, Os.ios, Os.freebsd => Handle.{
15471547 .fd = try posixOpen(
15481548 dir_path,
15491549 posix.O_RDONLY | posix.O_NONBLOCK | posix.O_DIRECTORY | posix.O_CLOEXEC,
......@@ -1574,7 +1574,7 @@ pub const Dir = struct.{
15741574 Os.windows => {
15751575 _ = windows.FindClose(self.handle.handle);
15761576 },
1577 Os.macosx, Os.ios, Os.linux => {
1577 Os.macosx, Os.ios, Os.linux, Os.freebsd => {
15781578 self.allocator.free(self.handle.buf);
15791579 os.close(self.handle.fd);
15801580 },
......@@ -1589,6 +1589,7 @@ pub const Dir = struct.{
15891589 Os.linux => return self.nextLinux(),
15901590 Os.macosx, Os.ios => return self.nextDarwin(),
15911591 Os.windows => return self.nextWindows(),
1592 Os.freebsd => return self.nextFreebsd(),
15921593 else => @compileError("unimplemented"),
15931594 }
15941595 }
......@@ -1728,6 +1729,11 @@ pub const Dir = struct.{
17281729 };
17291730 }
17301731 }
1732
1733 fn nextFreebsd(self: *Dir) !?Entry {
1734 self.handle.buf = try self.allocator.alloc(u8, page_size);
1735 return null; // TODO
1736 }
17311737};
17321738
17331739pub fn changeCurDir(allocator: *Allocator, dir_path: []const u8) !void {
......@@ -2166,7 +2172,7 @@ pub fn unexpectedErrorWindows(err: windows.DWORD) UnexpectedError {
21662172pub fn openSelfExe() !os.File {
21672173 switch (builtin.os) {
21682174 Os.linux => return os.File.openReadC(c"/proc/self/exe"),
2169 Os.macosx, Os.ios => {
2175 Os.macosx, Os.ios, Os.freebsd => {
21702176 var buf: [MAX_PATH_BYTES]u8 = undefined;
21712177 const self_exe_path = try selfExePath(&buf);
21722178 buf[self_exe_path.len] = 0;
......@@ -2183,7 +2189,7 @@ pub fn openSelfExe() !os.File {
21832189
21842190test "openSelfExe" {
21852191 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(),
21872193 else => return error.SkipZigTest, // Unsupported OS.
21882194 }
21892195}
......@@ -2214,6 +2220,7 @@ pub fn selfExePathW(out_buffer: *[windows_util.PATH_MAX_WIDE]u16) ![]u16 {
22142220pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) ![]u8 {
22152221 switch (builtin.os) {
22162222 Os.linux => return readLink(out_buffer, "/proc/self/exe"),
2223 Os.freebsd => return readLink(out_buffer, "/proc/curproc/file"),
22172224 Os.windows => {
22182225 var utf16le_buf: [windows_util.PATH_MAX_WIDE]u16 = undefined;
22192226 const utf16le_slice = try selfExePathW(&utf16le_buf);
......@@ -2252,7 +2259,7 @@ pub fn selfExeDirPath(out_buffer: *[MAX_PATH_BYTES]u8) ![]const u8 {
22522259 // will not return null.
22532260 return path.dirname(full_exe_path).?;
22542261 },
2255 Os.windows, Os.macosx, Os.ios => {
2262 Os.windows, Os.macosx, Os.ios, Os.freebsd => {
22562263 const self_exe_path = try selfExePath(out_buffer);
22572264 // Assume that the OS APIs return absolute paths, and therefore dirname
22582265 // will not return null.
......@@ -3085,10 +3092,13 @@ pub const CpuCountError = error.{
30853092
30863093pub fn cpuCount(fallback_allocator: *mem.Allocator) CpuCountError!usize {
30873094 switch (builtin.os) {
3088 builtin.Os.macosx => {
3095 builtin.Os.macosx, builtin.Os.freebsd => {
30893096 var count: c_int = undefined;
30903097 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);
30923102 const err = posix.getErrno(rc);
30933103 switch (err) {
30943104 0 => return @intCast(usize, count),