authorgravatar for i@mgxm.meMarcio Giaxa <i@mgxm.me> 2018-12-17 22:06:28-02:00
committergravatar for i@mgxm.meMarcio Giaxa <i@mgxm.me> 2018-12-19 18:41:59-02:00
log5ea37f6e8c9226ec02fbc95cc5c6d06a8e9ee6f7
tree2022cdb14f206ce6ad8a89960dc175d166affbad
parent666b153144eeb160c5b2279d406f8e0b23613857

freebsd: add getdirentries


3 files changed, 68 insertions(+), 2 deletions(-)

std/c/freebsd.zig+12
...@@ -13,6 +13,7 @@ pub extern "c" fn kevent(...@@ -13,6 +13,7 @@ pub extern "c" fn kevent(
13pub extern "c" fn sysctl(name: [*]c_int, namelen: c_uint, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int;13pub extern "c" fn sysctl(name: [*]c_int, namelen: c_uint, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int;
14pub extern "c" fn sysctlbyname(name: [*]const u8, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int;14pub extern "c" fn sysctlbyname(name: [*]const u8, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int;
15pub extern "c" fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usize) c_int;15pub extern "c" fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usize) c_int;
16pub extern "c" fn getdirentries(fd: c_int, buf_ptr: [*]u8, nbytes: usize, basep: *i64) usize;
1617
17/// Renamed from `kevent` to `Kevent` to avoid conflict with function name.18/// Renamed from `kevent` to `Kevent` to avoid conflict with function name.
18pub const Kevent = extern struct {19pub const Kevent = extern struct {
...@@ -66,3 +67,14 @@ pub const timespec = extern struct {...@@ -66,3 +67,14 @@ pub const timespec = extern struct {
66 tv_sec: isize,67 tv_sec: isize,
67 tv_nsec: isize,68 tv_nsec: isize,
68};69};
70
71pub const dirent = extern struct {
72 d_fileno: usize,
73 d_off: i64,
74 d_reclen: u64,
75 d_type: u8,
76 d_pad0: u8,
77 d_namlen: u16,
78 d_pad1: u16,
79 d_name: [256]u8,
80};
std/os/freebsd/index.zig+5
...@@ -562,6 +562,10 @@ pub fn getdents(fd: i32, dirp: [*]u8, count: usize) usize {...@@ -562,6 +562,10 @@ pub fn getdents(fd: i32, dirp: [*]u8, count: usize) usize {
562 return arch.syscall3(SYS_getdents, @bitCast(usize, isize(fd)), @ptrToInt(dirp), count);562 return arch.syscall3(SYS_getdents, @bitCast(usize, isize(fd)), @ptrToInt(dirp), count);
563}563}
564564
565pub fn getdirentries(fd: i32, buf_ptr: [*]u8, buf_len: usize, basep: *i64) usize {
566 return errnoWrap(@bitCast(isize, c.getdirentries(fd, buf_ptr, buf_len, basep)));
567}
568
565pub fn isatty(fd: i32) bool {569pub fn isatty(fd: i32) bool {
566 var wsz: winsize = undefined;570 var wsz: winsize = undefined;
567 return arch.syscall3(SYS_ioctl, @bitCast(usize, isize(fd)), TIOCGWINSZ, @ptrToInt(&wsz)) == 0;571 return arch.syscall3(SYS_ioctl, @bitCast(usize, isize(fd)), TIOCGWINSZ, @ptrToInt(&wsz)) == 0;
...@@ -743,6 +747,7 @@ pub fn raise(sig: i32) usize {...@@ -743,6 +747,7 @@ pub fn raise(sig: i32) usize {
743}747}
744748
745pub const Stat = c.Stat;749pub const Stat = c.Stat;
750pub const dirent = c.dirent;
746pub const timespec = c.timespec;751pub const timespec = c.timespec;
747752
748pub fn fstat(fd: i32, stat_buf: *Stat) usize {753pub fn fstat(fd: i32, stat_buf: *Stat) usize {
std/os/index.zig+51-2
...@@ -1753,8 +1753,57 @@ pub const Dir = struct {...@@ -1753,8 +1753,57 @@ pub const Dir = struct {
1753 }1753 }
17541754
1755 fn nextFreebsd(self: *Dir) !?Entry {1755 fn nextFreebsd(self: *Dir) !?Entry {
1756 //self.handle.buf = try self.allocator.alloc(u8, page_size);1756 start_over: while (true) {
1757 @compileError("TODO implement dirs for FreeBSD");1757 if (self.handle.index >= self.handle.end_index) {
1758 if (self.handle.buf.len == 0) {
1759 self.handle.buf = try self.allocator.alloc(u8, page_size);
1760 }
1761
1762 while (true) {
1763 const result = posix.getdirentries(self.handle.fd, self.handle.buf.ptr, self.handle.buf.len, &self.handle.seek);
1764 const err = posix.getErrno(result);
1765 if (err > 0) {
1766 switch (err) {
1767 posix.EBADF, posix.EFAULT, posix.ENOTDIR => unreachable,
1768 posix.EINVAL => {
1769 self.handle.buf = try self.allocator.realloc(u8, self.handle.buf, self.handle.buf.len * 2);
1770 continue;
1771 },
1772 else => return unexpectedErrorPosix(err),
1773 }
1774 }
1775 if (result == 0) return null;
1776 self.handle.index = 0;
1777 self.handle.end_index = result;
1778 break;
1779 }
1780 }
1781 const freebsd_entry = @ptrCast(*align(1) posix.dirent, &self.handle.buf[self.handle.index]);
1782 const next_index = self.handle.index + freebsd_entry.d_reclen;
1783 self.handle.index = next_index;
1784
1785 const name = @ptrCast([*]u8, &freebsd_entry.d_name)[0..freebsd_entry.d_namlen];
1786
1787 if (mem.eql(u8, name, ".") or mem.eql(u8, name, "..")) {
1788 continue :start_over;
1789 }
1790
1791 const entry_kind = switch (freebsd_entry.d_type) {
1792 posix.DT_BLK => Entry.Kind.BlockDevice,
1793 posix.DT_CHR => Entry.Kind.CharacterDevice,
1794 posix.DT_DIR => Entry.Kind.Directory,
1795 posix.DT_FIFO => Entry.Kind.NamedPipe,
1796 posix.DT_LNK => Entry.Kind.SymLink,
1797 posix.DT_REG => Entry.Kind.File,
1798 posix.DT_SOCK => Entry.Kind.UnixDomainSocket,
1799 posix.DT_WHT => Entry.Kind.Whiteout,
1800 else => Entry.Kind.Unknown,
1801 };
1802 return Entry{
1803 .name = name,
1804 .kind = entry_kind,
1805 };
1806 }
1758 }1807 }
1759};1808};
17601809