authorgravatar for ypsvlq@gmail.comElaine Gibson <ypsvlq@gmail.com> 2026-04-14 19:00:57+01:00
committergravatar for ypsvlq@gmail.comElaine Gibson <ypsvlq@gmail.com> 2026-04-14 19:00:57+01:00
loge8a683a0f99e6a9294a95545368d956172c3dbd6
tree1ba3e37032a09849d8c27e68cddc01b211538552
parentc94ea1ea2da328ec7dcbd79f376d4283dddb79b7

std.Io.Threaded: implement dirReadHaiku


1 files changed, 113 insertions(+), 4 deletions(-)

lib/std/Io/Threaded.zig+113-4
......@@ -5791,10 +5791,119 @@ fn dirReadIllumos(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) D
57915791}
57925792
57935793fn dirReadHaiku(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.Reader.Error!usize {
5794 _ = userdata;
5795 _ = dr;
5796 _ = buffer;
5797 @panic("TODO implement dirReadHaiku");
5794 const t: *Threaded = @ptrCast(@alignCast(userdata));
5795 _ = t;
5796 var buffer_index: usize = 0;
5797 while (buffer.len - buffer_index != 0) {
5798 if (dr.end - dr.index == 0) {
5799 // Refill the buffer, unless we've already created references to
5800 // buffered data.
5801 if (buffer_index != 0) break;
5802 if (dr.state == .reset) {
5803 const syscall: Syscall = try .start();
5804 while (true) {
5805 const rc = posix.system._kern_rewind_dir(dr.dir.handle);
5806 switch (posix.errno(rc)) {
5807 .SUCCESS => {
5808 syscall.finish();
5809 break;
5810 },
5811 .INTR => {
5812 try syscall.checkCancel();
5813 continue;
5814 },
5815 else => |e| {
5816 syscall.finish();
5817 switch (e) {
5818 else => |err| return posix.unexpectedErrno(err),
5819 }
5820 },
5821 }
5822 }
5823 dr.state = .reading;
5824 }
5825 const syscall: Syscall = try .start();
5826 const n: usize = while (true) {
5827 const rc = posix.system._kern_read_dir(dr.dir.handle, dr.buffer.ptr, dr.buffer.len, @truncate(dr.buffer.len / @sizeOf(posix.system.DirEnt)));
5828 switch (posix.errno(rc)) {
5829 .SUCCESS => {
5830 syscall.finish();
5831 break @intCast(rc);
5832 },
5833 .INTR => {
5834 try syscall.checkCancel();
5835 continue;
5836 },
5837 else => |e| {
5838 syscall.finish();
5839 switch (e) {
5840 else => |err| return posix.unexpectedErrno(err),
5841 }
5842 },
5843 }
5844 };
5845 if (n == 0) {
5846 dr.state = .finished;
5847 return 0;
5848 }
5849 dr.index = 0;
5850 // _kern_read_dir returns entry count, but Dir.Reader is designed for byte count
5851 dr.end = 0;
5852 var i: usize = 0;
5853 while (i < n) : (i += 1) {
5854 const entry = @as(*align(1) posix.system.DirEnt, @ptrCast(&dr.buffer[dr.end]));
5855 dr.end += entry.reclen;
5856 }
5857 }
5858 const entry = @as(*align(1) posix.system.DirEnt, @ptrCast(&dr.buffer[dr.index]));
5859 const next_index = dr.index + entry.reclen;
5860 dr.index = next_index;
5861
5862 const name = std.mem.sliceTo(@as([*:0]u8, @ptrCast(&entry.name)), 0);
5863 if (std.mem.eql(u8, name, ".") or std.mem.eql(u8, name, "..") or entry.ino == 0) continue;
5864
5865 // haiku dirent doesn't expose type, so we have to call stat to get it.
5866 var stat: std.c.Stat = undefined;
5867 {
5868 const syscall: Syscall = try .start();
5869 while (true) {
5870 const rc = posix.system._kern_read_stat(dr.dir.handle, name, false, &stat, @sizeOf(std.c.Stat));
5871 switch (posix.errno(rc)) {
5872 .SUCCESS => {
5873 syscall.finish();
5874 break;
5875 },
5876 .INTR => {
5877 try syscall.checkCancel();
5878 continue;
5879 },
5880 else => |e| {
5881 syscall.finish();
5882 switch (e) {
5883 else => |err| return posix.unexpectedErrno(err),
5884 }
5885 },
5886 }
5887 }
5888 }
5889
5890 const entry_kind: File.Kind = switch (stat.mode & posix.S.IFMT) {
5891 posix.S.IFBLK => .block_device,
5892 posix.S.IFCHR => .character_device,
5893 posix.S.IFDIR => .directory,
5894 posix.S.IFIFO => .named_pipe,
5895 posix.S.IFLNK => .sym_link,
5896 posix.S.IFREG => .file,
5897 else => .unknown,
5898 };
5899 buffer[buffer_index] = .{
5900 .name = name,
5901 .kind = entry_kind,
5902 .inode = entry.ino,
5903 };
5904 buffer_index += 1;
5905 }
5906 return buffer_index;
57985907}
57995908
58005909fn dirReadWindows(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.Reader.Error!usize {