}
+WasiDirectory :: struct {
+ dir_fd: FileDescriptor;
+ last_cookie: wasi.DirCookie;
+}
+
+DirectoryData :: ^WasiDirectory;
+
+__dir_open :: (path: str, dir: ^DirectoryData) -> bool {
+ dir_fd: FileDescriptor;
+ err := wasi.path_open(4, .SymLinkFollow, path, .Directory, ~~0xffffffff, ~~0xffffffff, .Sync, ^dir_fd);
+ if err != .Success {
+ return false;
+ }
+
+ d := new(WasiDirectory);
+ d.dir_fd = dir_fd;
+ d.last_cookie = 0;
+
+ *dir = d;
+ return true;
+}
+__dir_close :: (dir: DirectoryData) {
+ wasi.fd_close(dir.dir_fd);
+ cfree(dir);
+}
+
+__dir_read :: (dir: DirectoryData, out_entry: ^os.DirectoryEntry) -> bool {
+ buffer: [512] u8;
+ bufused: u32;
+
+ err := wasi.fd_readdir(dir.dir_fd, ~~buffer, 512, dir.last_cookie, ^bufused);
+ if err != .Success || bufused == 0 do return false;
+
+ dirent := cast(^wasi.DirEnt) buffer;
+ switch dirent.d_type {
+ case .Unknown do out_entry.type = .Unknown;
+ case .BlockDevice do out_entry.type = .Block;
+ case .CharDevice do out_entry.type = .Char;
+ case .Directory do out_entry.type = .Directory;
+ case .RegularFile do out_entry.type = .RegularFile;
+ case .SymLink do out_entry.type = .SymLink;
+ case #default do out_entry.type = .Other;
+ }
+
+ out_entry.identifier = ~~dirent.d_ino;
+ out_entry.name_length = dirent.d_namlen;
+ memory.set(~~^out_entry.name_data, 0, 256);
+ memory.copy(~~^out_entry.name_data, ~~(dirent + 1), math.min(dirent.d_namlen, sizeof typeof out_entry.name_data));
+
+ dir.last_cookie = dirent.d_next;
+ return true;
+}