authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-28 06:33:30-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-29 06:20:52-07:00
logb39f3d294da3ce9075bbc08651965615839219f2
tree89096136184f6d491bba689ba559541a8750745b
parent4114392369c28a2455a508e4da67d945ebad2b44

std.Io.Threaded: implement dirMakeOpenPath for WASI

and fix error code when file operation occurs on director handle

5 files changed, 40 insertions(+), 37 deletions(-)

lib/std/Io.zig+1-1
......@@ -684,7 +684,7 @@ pub const VTable = struct {
684684 fileWriteStreaming: *const fn (?*anyopaque, File, buffer: [][]const u8) File.WriteStreamingError!usize,
685685 fileWritePositional: *const fn (?*anyopaque, File, buffer: [][]const u8, offset: u64) File.WritePositionalError!usize,
686686 /// Returns 0 on end of stream.
687 fileReadStreaming: *const fn (?*anyopaque, File, data: [][]u8) File.ReadStreamingError!usize,
687 fileReadStreaming: *const fn (?*anyopaque, File, data: [][]u8) File.Reader.Error!usize,
688688 /// Returns 0 on end of stream.
689689 fileReadPositional: *const fn (?*anyopaque, File, data: [][]u8, offset: u64) File.ReadPositionalError!usize,
690690 fileSeekBy: *const fn (?*anyopaque, File, relative_offset: i64) File.SeekError!void,
lib/std/Io/File.zig+24-24
......@@ -213,29 +213,7 @@ pub fn openSelfExe(io: Io, flags: OpenFlags) OpenSelfExeError!File {
213213 return io.vtable.openSelfExe(io.userdata, flags);
214214}
215215
216pub const ReadStreamingError = error{
217 InputOutput,
218 SystemResources,
219 IsDir,
220 BrokenPipe,
221 ConnectionResetByPeer,
222 Timeout,
223 NotOpenForReading,
224 SocketUnconnected,
225 /// This error occurs when no global event loop is configured,
226 /// and reading from the file descriptor would block.
227 WouldBlock,
228 /// In WASI, this error occurs when the file descriptor does
229 /// not hold the required rights to read from it.
230 AccessDenied,
231 /// This error occurs in Linux if the process to be read from
232 /// no longer exists.
233 ProcessNotFound,
234 /// Unable to read file due to lock.
235 LockViolation,
236} || Io.Cancelable || Io.UnexpectedError;
237
238pub const ReadPositionalError = ReadStreamingError || error{Unseekable};
216pub const ReadPositionalError = Reader.Error || error{Unseekable};
239217
240218pub fn readPositional(file: File, io: Io, buffer: []u8, offset: u64) ReadPositionalError!usize {
241219 return io.vtable.fileReadPositional(io.userdata, file, buffer, offset);
......@@ -301,7 +279,29 @@ pub const Reader = struct {
301279 seek_err: ?Reader.SeekError = null,
302280 interface: Io.Reader,
303281
304 pub const Error = std.posix.ReadError || Io.Cancelable;
282 pub const Error = error{
283 InputOutput,
284 SystemResources,
285 IsDir,
286 BrokenPipe,
287 ConnectionResetByPeer,
288 Timeout,
289 /// In WASI, EBADF is mapped to this error because it is returned when
290 /// trying to read a directory file descriptor as if it were a file.
291 NotOpenForReading,
292 SocketUnconnected,
293 /// This error occurs when no global event loop is configured,
294 /// and reading from the file descriptor would block.
295 WouldBlock,
296 /// In WASI, this error occurs when the file descriptor does
297 /// not hold the required rights to read from it.
298 AccessDenied,
299 /// This error occurs in Linux if the process to be read from
300 /// no longer exists.
301 ProcessNotFound,
302 /// Unable to read file due to lock.
303 LockViolation,
304 } || Io.Cancelable || Io.UnexpectedError;
305305
306306 pub const SizeError = std.os.windows.GetFileSizeError || StatError || error{
307307 /// Occurs if, for example, the file handle is a network socket and therefore does not have a size.
lib/std/Io/Kqueue.zig+1-1
......@@ -1226,7 +1226,7 @@ fn fileWritePositional(userdata: ?*anyopaque, file: File, buffer: [][]const u8,
12261226 _ = offset;
12271227 @panic("TODO");
12281228}
1229fn fileReadStreaming(userdata: ?*anyopaque, file: File, data: [][]u8) File.ReadStreamingError!usize {
1229fn fileReadStreaming(userdata: ?*anyopaque, file: File, data: [][]u8) File.Reader.Error!usize {
12301230 const k: *Kqueue = @ptrCast(@alignCast(userdata));
12311231 _ = k;
12321232 _ = file;
lib/std/Io/Threaded.zig+13-10
......@@ -1219,14 +1219,17 @@ fn dirMakeOpenPathWasi(
12191219 userdata: ?*anyopaque,
12201220 dir: Io.Dir,
12211221 sub_path: []const u8,
1222 mode: Io.Dir.OpenOptions,
1222 options: Io.Dir.OpenOptions,
12231223) Io.Dir.MakeOpenPathError!Io.Dir {
12241224 const t: *Threaded = @ptrCast(@alignCast(userdata));
1225 _ = t;
1226 _ = dir;
1227 _ = sub_path;
1228 _ = mode;
1229 @panic("TODO implement dirMakeOpenPathWasi");
1225 const t_io = ioBasic(t);
1226 return dirOpenDirWasi(t, dir, sub_path, options) catch |err| switch (err) {
1227 error.FileNotFound => {
1228 try dir.makePath(t_io, sub_path);
1229 return dirOpenDirWasi(t, dir, sub_path, options);
1230 },
1231 else => |e| return e,
1232 };
12301233}
12311234
12321235fn dirStat(userdata: ?*anyopaque, dir: Io.Dir) Io.Dir.StatError!Io.Dir.Stat {
......@@ -2498,7 +2501,7 @@ const fileReadStreaming = switch (native_os) {
24982501 else => fileReadStreamingPosix,
24992502};
25002503
2501fn fileReadStreamingPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File.ReadStreamingError!usize {
2504fn fileReadStreamingPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File.Reader.Error!usize {
25022505 const t: *Threaded = @ptrCast(@alignCast(userdata));
25032506
25042507 var iovecs_buffer: [max_iovecs_len]posix.iovec = undefined;
......@@ -2523,7 +2526,7 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io
25232526
25242527 .INVAL => |err| return errnoBug(err),
25252528 .FAULT => |err| return errnoBug(err),
2526 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
2529 .BADF => return error.NotOpenForReading, // File operation on directory.
25272530 .IO => return error.InputOutput,
25282531 .ISDIR => return error.IsDir,
25292532 .NOBUFS => return error.SystemResources,
......@@ -2561,7 +2564,7 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io
25612564 }
25622565}
25632566
2564fn fileReadStreamingWindows(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File.ReadStreamingError!usize {
2567fn fileReadStreamingWindows(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File.Reader.Error!usize {
25652568 const t: *Threaded = @ptrCast(@alignCast(userdata));
25662569
25672570 const DWORD = windows.DWORD;
......@@ -2617,7 +2620,7 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8, o
26172620 .INVAL => |err| return errnoBug(err),
26182621 .FAULT => |err| return errnoBug(err),
26192622 .AGAIN => |err| return errnoBug(err),
2620 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
2623 .BADF => return error.NotOpenForReading, // File operation on directory.
26212624 .IO => return error.InputOutput,
26222625 .ISDIR => return error.IsDir,
26232626 .NOBUFS => return error.SystemResources,
lib/std/posix.zig+1-1
......@@ -814,7 +814,7 @@ pub fn exit(status: u8) noreturn {
814814 system.exit(status);
815815}
816816
817pub const ReadError = std.Io.File.ReadStreamingError;
817pub const ReadError = std.Io.File.Reader.Error;
818818
819819/// Returns the number of bytes that were read, which can be less than
820820/// buf.len. If 0 bytes were read, that means EOF.