diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2018-12-29 12:49:23 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-12-29 12:49:23 -0500 |
| commit | d8b6fa9134e247658bb98155ba2e4243cd335b1b (patch) | |
| tree | 55887d1fb589b00a6ec4ed9d51bc38b9821f4699 /std/os/index.zig | |
| parent | c464ecf3bf6d764ad06a20f10efc386e26fb7fa2 (diff) | |
| parent | 2e08bd6be4a3b472fcaa69f0cb7683b269cdacdd (diff) | |
| download | zig-d8b6fa9134e247658bb98155ba2e4243cd335b1b.tar.gz zig-d8b6fa9134e247658bb98155ba2e4243cd335b1b.zip | |
Merge pull request #1859 from mgxm/fbsd2
Progress towards tier 1 support for FreeBSD x86_64
Diffstat (limited to 'std/os/index.zig')
| -rw-r--r-- | std/os/index.zig | 72 |
1 files changed, 67 insertions, 5 deletions
diff --git a/std/os/index.zig b/std/os/index.zig index bb2eb76265..78d543583d 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -107,7 +107,7 @@ const math = std.math; /// library implementation. pub fn getRandomBytes(buf: []u8) !void { switch (builtin.os) { - Os.linux, Os.freebsd => while (true) { + Os.linux => while (true) { // TODO check libc version and potentially call c.getrandom. // See #397 const errno = posix.getErrno(posix.getrandom(buf.ptr, buf.len, 0)); @@ -120,7 +120,7 @@ pub fn getRandomBytes(buf: []u8) !void { else => return unexpectedErrorPosix(errno), } }, - Os.macosx, Os.ios => return getRandomBytesDevURandom(buf), + Os.macosx, Os.ios, Os.freebsd => return getRandomBytesDevURandom(buf), Os.windows => { // Call RtlGenRandom() instead of CryptGetRandom() on Windows // https://github.com/rust-lang-nursery/rand/issues/111 @@ -1766,8 +1766,57 @@ pub const Dir = struct { } fn nextFreebsd(self: *Dir) !?Entry { - //self.handle.buf = try self.allocator.alloc(u8, page_size); - @compileError("TODO implement dirs for FreeBSD"); + start_over: while (true) { + if (self.handle.index >= self.handle.end_index) { + if (self.handle.buf.len == 0) { + self.handle.buf = try self.allocator.alloc(u8, page_size); + } + + while (true) { + const result = posix.getdirentries(self.handle.fd, self.handle.buf.ptr, self.handle.buf.len, &self.handle.seek); + const err = posix.getErrno(result); + if (err > 0) { + switch (err) { + posix.EBADF, posix.EFAULT, posix.ENOTDIR => unreachable, + posix.EINVAL => { + self.handle.buf = try self.allocator.realloc(u8, self.handle.buf, self.handle.buf.len * 2); + continue; + }, + else => return unexpectedErrorPosix(err), + } + } + if (result == 0) return null; + self.handle.index = 0; + self.handle.end_index = result; + break; + } + } + const freebsd_entry = @ptrCast(*align(1) posix.dirent, &self.handle.buf[self.handle.index]); + const next_index = self.handle.index + freebsd_entry.d_reclen; + self.handle.index = next_index; + + const name = @ptrCast([*]u8, &freebsd_entry.d_name)[0..freebsd_entry.d_namlen]; + + if (mem.eql(u8, name, ".") or mem.eql(u8, name, "..")) { + continue :start_over; + } + + const entry_kind = switch (freebsd_entry.d_type) { + posix.DT_BLK => Entry.Kind.BlockDevice, + posix.DT_CHR => Entry.Kind.CharacterDevice, + posix.DT_DIR => Entry.Kind.Directory, + posix.DT_FIFO => Entry.Kind.NamedPipe, + posix.DT_LNK => Entry.Kind.SymLink, + posix.DT_REG => Entry.Kind.File, + posix.DT_SOCK => Entry.Kind.UnixDomainSocket, + posix.DT_WHT => Entry.Kind.Whiteout, + else => Entry.Kind.Unknown, + }; + return Entry{ + .name = name, + .kind = entry_kind, + }; + } } }; @@ -2255,7 +2304,20 @@ pub fn selfExePathW(out_buffer: *[windows_util.PATH_MAX_WIDE]u16) ![]u16 { pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) ![]u8 { switch (builtin.os) { Os.linux => return readLink(out_buffer, "/proc/self/exe"), - Os.freebsd => return readLink(out_buffer, "/proc/curproc/file"), + Os.freebsd => { + var mib = [4]c_int{ posix.CTL_KERN, posix.KERN_PROC, posix.KERN_PROC_PATHNAME, -1}; + var out_len: usize = out_buffer.len; + const err = posix.getErrno(posix.sysctl(&mib, 4, out_buffer, &out_len, null, 0)); + + if (err == 0 ) return mem.toSlice(u8, out_buffer); + + return switch (err) { + posix.EFAULT => error.BadAdress, + posix.EPERM => error.PermissionDenied, + else => unexpectedErrorPosix(err), + }; + + }, Os.windows => { var utf16le_buf: [windows_util.PATH_MAX_WIDE]u16 = undefined; const utf16le_slice = try selfExePathW(&utf16le_buf); |
