feature. See also
. The project being documented here (as the example) is the Zig library itself.
Dispatch.dirRead
fn dirRead(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.Reader.Error!usize
File
Code
fn dirRead(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.Reader.Error!usize {
const ev: *Evented = @ptrCast(@alignCast(userdata));
const Header = extern struct {
seek: i64,
};
const header: *Header = @ptrCast(dr.buffer.ptr);
const header_end: usize = @sizeOf(Header);
if (dr.index < header_end) {
dr.index = header_end;
dr.end = header_end;
header.* = .{ .seek = 0 };
}
var buffer_index: usize = 0;
while (buffer.len - buffer_index != 0) {
if (dr.end - dr.index == 0) {
// buffered data.
if (buffer_index != 0) break;
if (dr.state == .reset) {
ev.lseek(dr.dir.handle, 0, c.SEEK.SET) catch |err| switch (err) {
error.Unseekable => return error.Unexpected,
else => |e| return e,
};
dr.state = .reading;
}
const dents_buffer = dr.buffer[header_end..];
const n: usize = while (true) {
const rc = c.getdirentries(dr.dir.handle, dents_buffer.ptr, dents_buffer.len, &header.seek);
switch (c.errno(rc)) {
.SUCCESS => break @intCast(rc),
.INTR => {},
.BADF => |err| return errnoBug(err),
.FAULT => |err| return errnoBug(err),
.NOTDIR => |err| return errnoBug(err),
.INVAL => |err| return errnoBug(err),
else => |err| return unexpectedErrno(err),
}
};
if (n == 0) {
dr.state = .finished;
return 0;
}
dr.index = header_end;
dr.end = header_end + n;
}
const darwin_entry = @as(*align(1) c.dirent, @ptrCast(&dr.buffer[dr.index]));
const next_index = dr.index + darwin_entry.reclen;
dr.index = next_index;
const name = @as([*]u8, @ptrCast(&darwin_entry.name))[0..darwin_entry.namlen];
if (std.mem.eql(u8, name, ".") or std.mem.eql(u8, name, "..") or (darwin_entry.ino == 0))
continue;
const entry_kind: File.Kind = switch (darwin_entry.type) {
c.DT.BLK => .block_device,
c.DT.CHR => .character_device,
c.DT.DIR => .directory,
c.DT.FIFO => .named_pipe,
c.DT.LNK => .sym_link,
c.DT.REG => .file,
c.DT.SOCK => .unix_domain_socket,
c.DT.WHT => .whiteout,
else => .unknown,
};
buffer[buffer_index] = .{
.name = name,
.kind = entry_kind,
.inode = darwin_entry.ino,
};
buffer_index += 1;
}
return buffer_index;
}