Function nextLinux [src]

Implementation of next that can return error.DirNotFound if the directory being iterated was deleted during iteration (this error is Linux specific).

Prototype

pub fn nextLinux(self: *Self) ErrorLinux!?Entry

Parameters

self: *Self

Possible Errors

AccessDenied IteratorError
DirNotFound
InvalidUtf8 IteratorError

WASI-only. The path of an entry could not be encoded as valid UTF-8. WASI is unable to handle paths that cannot be encoded as well-formed UTF-8. https://github.com/WebAssembly/wasi-filesystem/issues/17#issuecomment-1430639353

SystemResources IteratorError
Unexpected UnexpectedError

The Operating System returned an undocumented error code.

This error is in theory not possible, but it would be better to handle this error than to invoke undefined behavior.

When this error code is observed, it usually means the Zig Standard Library needs a small patch to add the error code to the error set for the respective function.

Source

pub fn nextLinux(self: *Self) ErrorLinux!?Entry { start_over: while (true) { if (self.index >= self.end_index) { if (self.first_iter) { posix.lseek_SET(self.dir.fd, 0) catch unreachable; // EBADF here likely means that the Dir was not opened with iteration permissions self.first_iter = false; } const rc = linux.getdents64(self.dir.fd, &self.buf, self.buf.len); switch (linux.E.init(rc)) { .SUCCESS => {}, .BADF => unreachable, // Dir is invalid or was opened without iteration ability .FAULT => unreachable, .NOTDIR => unreachable, .NOENT => return error.DirNotFound, // The directory being iterated was deleted during iteration. .INVAL => return error.Unexpected, // Linux may in some cases return EINVAL when reading /proc/$PID/net. .ACCES => return error.AccessDenied, // Do not have permission to iterate this directory. else => |err| return posix.unexpectedErrno(err), } if (rc == 0) return null; self.index = 0; self.end_index = rc; } const linux_entry = @as(*align(1) linux.dirent64, @ptrCast(&self.buf[self.index])); const next_index = self.index + linux_entry.reclen; self.index = next_index; const name = mem.sliceTo(@as([*:0]u8, @ptrCast(&linux_entry.name)), 0); // skip . and .. entries if (mem.eql(u8, name, ".") or mem.eql(u8, name, "..")) { continue :start_over; } const entry_kind: Entry.Kind = switch (linux_entry.type) { linux.DT.BLK => .block_device, linux.DT.CHR => .character_device, linux.DT.DIR => .directory, linux.DT.FIFO => .named_pipe, linux.DT.LNK => .sym_link, linux.DT.REG => .file, linux.DT.SOCK => .unix_domain_socket, else => .unknown, }; return Entry{ .name = name, .kind = entry_kind, }; } }