From 5b436d2c5125b9cf9a08b3bff0dcb0248c4d1ec0 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 8 Dec 2025 23:03:34 -0800 Subject: [PATCH] build_runner compiling again --- lib/std/Io/Dir.zig | 81 ++++++++------------------ lib/std/Io/File.zig | 17 +----- lib/std/Io/File/Writer.zig | 25 ++++---- lib/std/Io/Threaded.zig | 116 +++++++++++++++++++------------------ lib/std/Io/net.zig | 4 +- lib/std/fs/test.zig | 12 ++-- src/Package/Fetch.zig | 4 +- 7 files changed, 111 insertions(+), 148 deletions(-) diff --git a/lib/std/Io/Dir.zig b/lib/std/Io/Dir.zig index 6c40e0217e6b6aed8646953653fb3e7c5fb11fa5..9c4a1f1df8d6ab47866e8e0a7e498d7bf3579739 100644 --- a/lib/std/Io/Dir.zig +++ b/lib/std/Io/Dir.zig @@ -198,7 +198,7 @@ pub const SelectiveWalker = struct { // likely just fail with the same error. var item = self.stack.pop().?; if (self.stack.items.len != 0) { - item.iter.dir.close(io); + item.iter.reader.dir.close(io); } return err; }) |entry| { @@ -211,7 +211,7 @@ pub const SelectiveWalker = struct { self.name_buffer.appendSliceAssumeCapacity(entry.name); self.name_buffer.appendAssumeCapacity(0); const walker_entry: Walker.Entry = .{ - .dir = top.iter.dir, + .dir = top.iter.reader.dir, .basename = self.name_buffer.items[dirname_len .. self.name_buffer.items.len - 1 :0], .path = self.name_buffer.items[0 .. self.name_buffer.items.len - 1 :0], .kind = entry.kind, @@ -220,7 +220,7 @@ pub const SelectiveWalker = struct { } else { var item = self.stack.pop().?; if (self.stack.items.len != 0) { - item.iter.dir.close(io); + item.iter.reader.dir.close(io); } } } @@ -260,7 +260,7 @@ pub const SelectiveWalker = struct { var item = self.stack.pop().?; if (self.stack.items.len != 0) { @branchHint(.likely); - item.iter.dir.close(io); + item.iter.reader.dir.close(io); } } }; @@ -741,7 +741,6 @@ pub const RealPathError = error{ FileNotFound, AccessDenied, PermissionDenied, - NameTooLong, NotSupported, NotDir, SymLinkLoop, @@ -757,9 +756,6 @@ pub const RealPathError = error{ DeviceBusy, SharingViolation, PipeBusy, - /// Windows: file paths provided by the user must be valid WTF-8. - /// https://wtf-8.codeberg.page/ - BadPathName, /// On Windows, `\\server` or `\\server\share` was not found. NetworkNotFound, PathAlreadyExists, @@ -772,7 +768,7 @@ pub const RealPathError = error{ /// On Windows, the volume does not contain a recognized file system. File /// system drivers might not be loaded, or the volume may be corrupt. UnrecognizedVolume, -} || Io.Cancelable || Io.UnexpectedError; +} || PathNameError || Io.Cancelable || Io.UnexpectedError; /// This function returns the canonicalized absolute pathname of `pathname` /// relative to this `Dir`. If `pathname` is absolute, ignores this `Dir` @@ -824,19 +820,12 @@ pub const DeleteFileError = error{ FileSystem, IsDir, SymLinkLoop, - NameTooLong, NotDir, SystemResources, ReadOnlyFileSystem, - /// WASI: file paths must be valid UTF-8. - /// Windows: file paths provided by the user must be valid WTF-8. - /// https://wtf-8.codeberg.page/ - /// Windows: file paths cannot contain these characters: - /// '/', '*', '?', '"', '<', '>', '|' - BadPathName, /// On Windows, `\\server` or `\\server\share` was not found. NetworkNotFound, -} || Io.Cancelable || Io.UnexpectedError; +} || PathNameError || Io.Cancelable || Io.UnexpectedError; /// Delete a file name and possibly the file it refers to, based on an open directory handle. /// @@ -864,17 +853,12 @@ pub const DeleteDirError = error{ FileBusy, FileSystem, SymLinkLoop, - NameTooLong, NotDir, SystemResources, ReadOnlyFileSystem, - /// WASI: file paths must be valid UTF-8. - /// Windows: file paths provided by the user must be valid WTF-8. - /// https://wtf-8.codeberg.page/ - BadPathName, /// On Windows, `\\server` or `\\server\share` was not found. NetworkNotFound, -} || Io.Cancelable || Io.UnexpectedError; +} || PathNameError || Io.Cancelable || Io.UnexpectedError; /// Returns `error.DirNotEmpty` if the directory is not empty. /// @@ -910,7 +894,6 @@ pub const RenameError = error{ IsDir, SymLinkLoop, LinkQuotaExceeded, - NameTooLong, FileNotFound, NotDir, SystemResources, @@ -918,10 +901,6 @@ pub const RenameError = error{ PathAlreadyExists, ReadOnlyFileSystem, RenameAcrossMountPoints, - /// WASI: file paths must be valid UTF-8. - /// Windows: file paths provided by the user must be valid WTF-8. - /// https://wtf-8.codeberg.page/ - BadPathName, NoDevice, SharingViolation, PipeBusy, @@ -933,7 +912,7 @@ pub const RenameError = error{ /// intercepts file system operations and makes them significantly slower /// in addition to possibly failing with this error code. AntivirusInterference, -} || Io.Cancelable || Io.UnexpectedError; +} || PathNameError || Io.Cancelable || Io.UnexpectedError; /// Change the name or location of a file or directory. /// @@ -985,12 +964,7 @@ pub const SymLinkError = error{ NoSpaceLeft, ReadOnlyFileSystem, NotDir, - NameTooLong, - /// WASI: file paths must be valid UTF-8. - /// Windows: file paths provided by the user must be valid WTF-8. - /// https://wtf-8.codeberg.page/ - BadPathName, -} || Io.Cancelable || Io.UnexpectedError; +} || PathNameError || Io.Cancelable || Io.UnexpectedError; /// Creates a symbolic link named `sym_link_path` which contains the string `target_path`. /// @@ -1075,15 +1049,10 @@ pub const ReadLinkError = error{ PermissionDenied, FileSystem, SymLinkLoop, - NameTooLong, FileNotFound, SystemResources, NotLink, NotDir, - /// WASI: file paths must be valid UTF-8. - /// Windows: file paths provided by the user must be valid WTF-8. - /// https://wtf-8.codeberg.page/ - BadPathName, /// Windows-only. This error may occur if the opened reparse point is /// of unsupported type. UnsupportedReparsePointType, @@ -1095,7 +1064,7 @@ pub const ReadLinkError = error{ /// intercepts file system operations and makes them significantly slower /// in addition to possibly failing with this error code. AntivirusInterference, -} || Io.Cancelable || Io.UnexpectedError; +} || PathNameError || Io.Cancelable || Io.UnexpectedError; /// Obtain target of a symbolic link. /// @@ -1183,7 +1152,6 @@ pub const DeleteTreeError = error{ FileTooBig, SymLinkLoop, ProcessFdQuotaExceeded, - NameTooLong, SystemFdQuotaExceeded, NoDevice, SystemResources, @@ -1194,15 +1162,9 @@ pub const DeleteTreeError = error{ /// One of the path components was not a directory. /// This error is unreachable if `sub_path` does not contain a path separator. NotDir, - /// WASI: file paths must be valid UTF-8. - /// Windows: file paths provided by the user must be valid WTF-8. - /// https://wtf-8.codeberg.page/ - /// On Windows, file paths cannot contain these characters: - /// '/', '*', '?', '"', '<', '>', '|' - BadPathName, /// On Windows, `\\server` or `\\server\share` was not found. NetworkNotFound, -} || Io.Cancelable || Io.UnexpectedError; +} || PathNameError || Io.Cancelable || Io.UnexpectedError; /// Whether `sub_path` describes a symlink, file, or directory, this function /// removes it. If it cannot be removed because it is a non-empty directory, @@ -1222,7 +1184,7 @@ pub fn deleteTree(dir: Dir, io: Io, sub_path: []const u8) DeleteTreeError!void { iter: Dir.Iterator, fn closeAll(inner_io: Io, items: []@This()) void { - for (items) |*item| item.iter.dir.close(inner_io); + for (items) |*item| item.iter.reader.dir.close(inner_io); } }; @@ -1243,7 +1205,7 @@ pub fn deleteTree(dir: Dir, io: Io, sub_path: []const u8) DeleteTreeError!void { handle_entry: while (true) { if (treat_as_dir) { if (stack.unusedCapacitySlice().len >= 1) { - var iterable_dir = top.iter.dir.openDir(io, entry.name, .{ + var iterable_dir = top.iter.reader.dir.openDir(io, entry.name, .{ .follow_symlinks = false, .iterate = true, }) catch |err| switch (err) { @@ -1273,16 +1235,16 @@ pub fn deleteTree(dir: Dir, io: Io, sub_path: []const u8) DeleteTreeError!void { }; stack.appendAssumeCapacity(.{ .name = entry.name, - .parent_dir = top.iter.dir, + .parent_dir = top.iter.reader.dir, .iter = iterable_dir.iterateAssumeFirstIteration(), }); continue :process_stack; } else { - try top.iter.dir.deleteTreeMinStackSizeWithKindHint(io, entry.name, entry.kind); + try top.iter.reader.dir.deleteTreeMinStackSizeWithKindHint(io, entry.name, entry.kind); break :handle_entry; } } else { - if (top.iter.dir.deleteFile(io, entry.name)) { + if (top.iter.reader.dir.deleteFile(io, entry.name)) { break :handle_entry; } else |err| switch (err) { error.FileNotFound => break :handle_entry, @@ -1305,6 +1267,7 @@ pub fn deleteTree(dir: Dir, io: Io, sub_path: []const u8) DeleteTreeError!void { error.FileBusy, error.BadPathName, error.NetworkNotFound, + error.Canceled, error.Unexpected, => |e| return e, } @@ -1314,7 +1277,7 @@ pub fn deleteTree(dir: Dir, io: Io, sub_path: []const u8) DeleteTreeError!void { // On Windows, we can't delete until the dir's handle has been closed, so // close it before we try to delete. - top.iter.dir.close(io); + top.iter.reader.dir.close(io); // In order to avoid double-closing the directory when cleaning up // the stack in the case of an error, we save the relevant portions and @@ -1324,7 +1287,7 @@ pub fn deleteTree(dir: Dir, io: Io, sub_path: []const u8) DeleteTreeError!void { stack.items.len -= 1; var need_to_retry: bool = false; - parent_dir.deleteDir(name) catch |err| switch (err) { + parent_dir.deleteDir(io, name) catch |err| switch (err) { error.FileNotFound => {}, error.DirNotEmpty => need_to_retry = true, else => |e| return e, @@ -1389,6 +1352,7 @@ pub fn deleteTree(dir: Dir, io: Io, sub_path: []const u8) DeleteTreeError!void { error.FileBusy, error.BadPathName, error.NetworkNotFound, + error.Canceled, error.Unexpected, => |e| return e, } @@ -1437,7 +1401,7 @@ fn deleteTreeMinStackSizeWithKindHint(parent: Dir, io: Io, sub_path: []const u8, scan_dir: while (true) { var dir_it = dir.iterateAssumeFirstIteration(); - dir_it: while (try dir_it.next()) |entry| { + dir_it: while (try dir_it.next(io)) |entry| { var treat_as_dir = entry.kind == .directory; handle_entry: while (true) { if (treat_as_dir) { @@ -1500,6 +1464,7 @@ fn deleteTreeMinStackSizeWithKindHint(parent: Dir, io: Io, sub_path: []const u8, error.FileBusy, error.BadPathName, error.NetworkNotFound, + error.Canceled, error.Unexpected, => |e| return e, } @@ -1727,7 +1692,7 @@ pub fn setOwner(dir: Dir, io: Io, owner: ?File.Uid, group: ?File.Gid) SetOwnerEr return io.vtable.dirSetOwner(io.userdata, dir, owner, group); } -pub const SetTimestampsError = File.SetTimestampsError; +pub const SetTimestampsError = File.SetTimestampsError || PathNameError; pub const SetTimestampsOptions = struct { follow_symlinks: bool = true, diff --git a/lib/std/Io/File.zig b/lib/std/Io/File.zig index ead129e3c50a24bf73fa322cd776ac3f605088ff..7718b56f8afab25c67b3f32fe55827b5fb05d1a1 100644 --- a/lib/std/Io/File.zig +++ b/lib/std/Io/File.zig @@ -284,7 +284,9 @@ pub fn isTty(file: File, io: Io) bool { return io.vtable.fileIsTty(io.userdata, file); } -pub const EnableAnsiEscapeCodesError = error{} || Io.Cancelable || Io.UnexpectedError; +pub const EnableAnsiEscapeCodesError = error{ + NotTerminalDevice, +} || Io.Cancelable || Io.UnexpectedError; pub fn enableAnsiEscapeCodes(file: File, io: Io) EnableAnsiEscapeCodesError!void { return io.vtable.fileEnableAnsiEscapeCodes(io.userdata, file); @@ -492,19 +494,6 @@ pub fn writePositional(file: File, io: Io, buffer: []const []const u8, offset: u return io.vtable.fileWritePositional(io.userdata, file, buffer, offset); } -pub const WriteFileStreamingError = error{ - /// `out_fd` is an unconnected socket, or out_fd closed its read end. - BrokenPipe, - /// Descriptor is not valid or locked, or an mmap(2)-like operation is not available for in_fd. - UnsupportedOperation, - /// Nonblocking I/O has been selected but the write would block. - WouldBlock, - /// Unspecified error while reading from in_fd. - InputOutput, - /// Insufficient kernel memory to read from in_fd. - SystemResources, -} || Io.Cancelable || Io.UnexpectedError; - pub const SeekError = error{ Unseekable, /// The file descriptor does not hold the required rights to seek on it. diff --git a/lib/std/Io/File/Writer.zig b/lib/std/Io/File/Writer.zig index cc971edbf44753edf9b081cbdbbcc002619e0e69..ec58824c06b062c64f4b588259f7d315bb728ea7 100644 --- a/lib/std/Io/File/Writer.zig +++ b/lib/std/Io/File/Writer.zig @@ -28,7 +28,9 @@ pub const Error = error{ /// File descriptor does not hold the required rights to write to it. AccessDenied, PermissionDenied, + /// File is an unconnected socket, or closed its read end. BrokenPipe, + /// Insufficient kernel memory to read from in_fd. SystemResources, NotOpenForWriting, /// The process cannot access the file because another process has locked @@ -39,20 +41,15 @@ pub const Error = error{ /// This error occurs when a device gets disconnected before or mid-flush /// while it's being written to - errno(6): No such device or address. NoDevice, + FileBusy, } || Io.Cancelable || Io.UnexpectedError; -pub const WriteFileError = error{ - /// `out_fd` is an unconnected socket, or out_fd closed its read end. - BrokenPipe, +pub const WriteFileError = Error || error{ /// Descriptor is not valid or locked, or an mmap(2)-like operation is not available for in_fd. - UnsupportedOperation, - /// Nonblocking I/O has been selected but the write would block. - WouldBlock, - /// Unspecified error while reading from in_fd. - InputOutput, - /// Insufficient kernel memory to read from in_fd. - SystemResources, -} || Io.Cancelable || Io.UnexpectedError; + Unimplemented, + EndOfStream, + ReadFailed, +}; pub const SeekError = Io.File.SeekError; @@ -175,6 +172,9 @@ fn sendFilePositional(w: *Writer, file_reader: *Io.File.Reader, limit: Io.Limit) w.err = error.Canceled; return error.WriteFailed; }, + error.EndOfStream => return error.EndOfStream, + error.Unimplemented => return error.Unimplemented, + error.ReadFailed => return error.ReadFailed, else => |e| { w.write_file_err = e; return error.WriteFailed; @@ -192,6 +192,9 @@ fn sendFileStreaming(w: *Writer, file_reader: *Io.File.Reader, limit: Io.Limit) w.err = error.Canceled; return error.WriteFailed; }, + error.EndOfStream => return error.EndOfStream, + error.Unimplemented => return error.Unimplemented, + error.ReadFailed => return error.ReadFailed, else => |e| { w.write_file_err = e; return error.WriteFailed; diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig index 459440f5a6da9b3a81b4ea3ffb90fb5de4d11c85..639e5cf6cd3cb6a49cead87895fc71501071c8c8 100644 --- a/lib/std/Io/Threaded.zig +++ b/lib/std/Io/Threaded.zig @@ -696,6 +696,7 @@ pub fn io(t: *Threaded) Io { .dirOpenFile = dirOpenFile, .dirOpenDir = dirOpenDir, .dirClose = dirClose, + .dirRead = dirRead, .dirRealPath = dirRealPath, .dirDeleteFile = dirDeleteFile, .dirDeleteDir = dirDeleteDir, @@ -822,6 +823,7 @@ pub fn ioBasic(t: *Threaded) Io { .dirOpenFile = dirOpenFile, .dirOpenDir = dirOpenDir, .dirClose = dirClose, + .dirRead = dirRead, .dirRealPath = dirRealPath, .dirDeleteFile = dirDeleteFile, .dirDeleteDir = dirDeleteDir, @@ -1621,7 +1623,7 @@ fn dirMakeOpenPathPosix( ) Dir.MakeOpenPathError!Dir { const t: *Threaded = @ptrCast(@alignCast(userdata)); const t_io = ioBasic(t); - return dirOpenDirPosix(t, dir, sub_path, permissions, options) catch |err| switch (err) { + return dirOpenDirPosix(t, dir, sub_path, options) catch |err| switch (err) { error.FileNotFound => { _ = try dir.makePathStatus(t_io, sub_path, permissions); return dirOpenDirPosix(t, dir, sub_path, options); @@ -2388,7 +2390,7 @@ fn dirCreateFilePosix( try current_thread.beginSyscall(); const fd: posix.fd_t = while (true) { - const rc = openat_sym(dir.handle, sub_path_posix, os_flags, flags.mode); + const rc = openat_sym(dir.handle, sub_path_posix, os_flags, flags.permissions.toMode()); switch (posix.errno(rc)) { .SUCCESS => { current_thread.endSyscall(); @@ -3256,6 +3258,14 @@ fn dirClose(userdata: ?*anyopaque, dirs: []const Dir) void { for (dirs) |dir| posix.close(dir.handle); } +fn dirRead(userdata: ?*anyopaque, dir_reader: *Dir.Reader, buffer: []Dir.Entry) Dir.Reader.Error!usize { + const t: *Threaded = @ptrCast(@alignCast(userdata)); + _ = t; + _ = dir_reader; + _ = buffer; + @panic("TODO"); +} + const dirRealPath = switch (native_os) { .windows => dirRealPathWindows, else => dirRealPathPosix, @@ -3412,7 +3422,6 @@ fn dirRealPathPosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, out_b switch (e) { .ACCES => return error.AccessDenied, .FAULT => |err| return errnoBug(err), - .INVAL => return error.NotLink, .IO => return error.FileSystem, .LOOP => return error.SymLinkLoop, .NAMETOOLONG => return error.NameTooLong, @@ -4562,7 +4571,7 @@ fn fileSyncPosix(userdata: ?*anyopaque, file: File) File.SyncError!void { const current_thread = Thread.getCurrent(t); try current_thread.beginSyscall(); while (true) { - switch (posix.system.fsync(file.handle)) { + switch (posix.errno(posix.system.fsync(file.handle))) { .SUCCESS => return current_thread.endSyscall(), .CANCELED => return current_thread.endSyscallCanceled(), .INTR => { @@ -4640,7 +4649,7 @@ fn isTty(current_thread: *Thread, file: File) Io.Cancelable!bool { const linux = std.os.linux; try current_thread.beginSyscall(); while (true) { - var wsz: linux.winsize = undefined; + var wsz: posix.winsize = undefined; const fd: usize = @bitCast(@as(isize, file.handle)); const rc = linux.syscall3(.ioctl, fd, linux.T.IOCGWINSZ, @intFromPtr(&wsz)); switch (linux.errno(rc)) { @@ -4948,7 +4957,7 @@ fn dirSetTimestamps( last_accessed: Io.Timestamp, last_modified: Io.Timestamp, options: Dir.SetTimestampsOptions, -) File.SetTimestampsError!void { +) Dir.SetTimestampsError!void { const t: *Threaded = @ptrCast(@alignCast(userdata)); const current_thread = Thread.getCurrent(t); @@ -4961,8 +4970,8 @@ fn dirSetTimestamps( } const times: [2]posix.timespec = .{ - timestampToPosix(last_accessed), - timestampToPosix(last_modified), + timestampToPosix(last_accessed.nanoseconds), + timestampToPosix(last_modified.nanoseconds), }; const flags: u32 = if (!options.follow_symlinks) posix.AT.SYMLINK_NOFOLLOW else 0; @@ -5000,7 +5009,7 @@ fn dirSetTimestampsNow( dir: Dir, sub_path: []const u8, options: Dir.SetTimestampsOptions, -) File.SetTimestampsError!void { +) Dir.SetTimestampsError!void { const t: *Threaded = @ptrCast(@alignCast(userdata)); const current_thread = Thread.getCurrent(t); @@ -5068,8 +5077,8 @@ fn fileSetTimestamps( } const times: [2]posix.timespec = .{ - timestampToPosix(last_accessed), - timestampToPosix(last_modified), + timestampToPosix(last_accessed.nanoseconds), + timestampToPosix(last_modified.nanoseconds), }; if (native_os == .wasi and !builtin.link_libc) { @@ -5226,7 +5235,7 @@ fn fileLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockError!v } } - const operation = switch (lock) { + const operation: i32 = switch (lock) { .none => posix.LOCK.UN, .shared => posix.LOCK.SH, .exclusive => posix.LOCK.EX, @@ -5288,7 +5297,7 @@ fn fileTryLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockErro } } - const operation = switch (lock) { + const operation: i32 = switch (lock) { .none => posix.LOCK.UN, .shared => posix.LOCK.SH | posix.LOCK.NB, .exclusive => posix.LOCK.EX | posix.LOCK.NB, @@ -5346,27 +5355,16 @@ fn fileUnlock(userdata: ?*anyopaque, file: File) void { return; } - try current_thread.beginSyscall(); while (true) { switch (posix.errno(posix.system.flock(file.handle, posix.LOCK.UN))) { - .SUCCESS => return current_thread.endSyscall(), - .CANCELED => return current_thread.endSyscallCanceled(), - .INTR => { - try current_thread.checkCancel(); - continue; - }, - else => |e| { - current_thread.endSyscall(); - if (is_debug) switch (e) { - .AGAIN => unreachable, // unlocking can't block - .BADF => unreachable, // File descriptor used after closed. - .INVAL => unreachable, // invalid parameters - .NOLCK => unreachable, // Resource deallocation. - .OPNOTSUPP => unreachable, // We already got the lock. - else => unreachable, // Resource deallocation must succeed. - }; - return; - }, + .SUCCESS => return, + .CANCELED, .INTR => continue, + .AGAIN => return assert(!is_debug), // unlocking can't block + .BADF => return assert(!is_debug), // File descriptor used after closed. + .INVAL => return assert(!is_debug), // invalid parameters + .NOLCK => return assert(!is_debug), // Resource deallocation. + .OPNOTSUPP => return assert(!is_debug), // We already got the lock. + else => return assert(!is_debug), // Resource deallocation must succeed. } } } @@ -5424,7 +5422,7 @@ fn fileDowngradeLock(userdata: ?*anyopaque, file: File) File.DowngradeLockError! switch (posix.errno(posix.system.flock(file.handle, operation))) { .SUCCESS => { current_thread.endSyscall(); - return true; + return; }, .CANCELED => return current_thread.endSyscallCanceled(), .INTR => { @@ -6255,8 +6253,9 @@ fn fileWritePositional( .NOSPC => return error.NoSpaceLeft, .PERM => return error.PermissionDenied, .PIPE => return error.BrokenPipe, - .CONNRESET => return error.ConnectionResetByPeer, + .CONNRESET => |err| return errnoBug(err), // Not a socket handle. .BUSY => return error.DeviceBusy, + .TXTBSY => return error.FileBusy, .NXIO => return error.Unseekable, .SPIPE => return error.Unseekable, .OVERFLOW => return error.Unseekable, @@ -6373,7 +6372,7 @@ fn fileWriteStreaming( .NOSPC => return error.NoSpaceLeft, .PERM => return error.PermissionDenied, .PIPE => return error.BrokenPipe, - .CONNRESET => return error.ConnectionResetByPeer, + .CONNRESET => |err| return errnoBug(err), // Not a socket handle. .BUSY => return error.DeviceBusy, else => |err| return posix.unexpectedErrno(err), } @@ -6388,12 +6387,12 @@ fn fileWriteFileStreaming( header: []const u8, file_reader: *File.Reader, limit: Io.Limit, -) File.WriteFileStreamingError!usize { +) File.Writer.WriteFileError!usize { const t: *Threaded = @ptrCast(@alignCast(userdata)); const reader_buffered = file_reader.interface.buffered(); if (reader_buffered.len >= @intFromEnum(limit)) { const n = try fileWriteStreaming(t, file, header, &.{limit.slice(reader_buffered)}, 1); - file_reader.seekBy(n -| header.len) catch return error.ReadFailed; + file_reader.interface.toss(n -| header.len); return n; } const file_limit = @intFromEnum(limit) - reader_buffered.len; @@ -6404,7 +6403,7 @@ fn fileWriteFileStreaming( if (size - file_reader.pos == 0) { if (reader_buffered.len != 0) { const n = try fileWriteStreaming(t, file, header, &.{limit.slice(reader_buffered)}, 1); - file_reader.seekBy(n -| header.len) catch return error.ReadFailed; + file_reader.interface.toss(n -| header.len); return n; } else { return error.EndOfStream; @@ -6495,7 +6494,7 @@ fn fileWriteFileStreaming( return error.EndOfStream; } const ubytes: usize = @intCast(sbytes); - file_reader.seekBy(ubytes -| header.len) catch return error.ReadFailed; + file_reader.interface.toss(ubytes -| header.len); return ubytes; } @@ -6581,7 +6580,7 @@ fn fileWriteFileStreaming( return error.EndOfStream; } const u_len: usize = @bitCast(len); - file_reader.seekBy(u_len -| header.len) catch return error.ReadFailed; + file_reader.interface.toss(u_len -| header.len); return u_len; } @@ -6591,7 +6590,7 @@ fn fileWriteFileStreaming( // Linux sendfile does not support headers. if (header.len != 0 or reader_buffered.len != 0) { const n = try fileWriteStreaming(t, file, header, &.{limit.slice(reader_buffered)}, 1); - file_reader.seekBy(n -| header.len) catch return error.ReadFailed; + file_reader.interface.toss(n -| header.len); return n; } const max_count = 0x7ffff000; // Avoid EINVAL. @@ -6671,7 +6670,7 @@ fn fileWriteFileStreaming( if (@atomicLoad(UseCopyFileRange, &t.use_copy_file_range, .monotonic) == .disabled) break :cfr; if (header.len != 0 or reader_buffered.len != 0) { const n = try fileWriteStreaming(t, file, header, &.{limit.slice(reader_buffered)}, 1); - file_reader.seekBy(n -| header.len) catch return error.ReadFailed; + file_reader.interface.toss(n -| header.len); return n; } var off_in: i64 = undefined; @@ -6682,7 +6681,7 @@ fn fileWriteFileStreaming( break :p &off_in; }, .streaming => null, - .failure => return error.WriteFailed, + .failure => return error.ReadFailed, }; const current_thread = Thread.getCurrent(t); const n: usize = switch (native_os) { @@ -6712,13 +6711,16 @@ fn fileWriteFileStreaming( assert(error.Unexpected == switch (e) { .FBIG => return error.FileTooBig, .IO => return error.InputOutput, - .ISDIR => return error.IsDir, .NOMEM => return error.SystemResources, .NOSPC => return error.NoSpaceLeft, - .OVERFLOW => return error.Overflow, + .OVERFLOW => |err| errnoBug(err), // We avoid passing too large a count. .PERM => return error.PermissionDenied, - .TXTBSY => return error.SwapFile, - .XDEV => return error.NotSameFileSystem, + .BUSY => return error.DeviceBusy, + .TXTBSY => return error.FileBusy, + // copy_file_range can still work but not on + // this pair of file descriptors. + .XDEV => return error.Unimplemented, + .ISDIR => |err| errnoBug(err), .BADF => |err| errnoBug(err), else => |err| posix.unexpectedErrno(err), }); @@ -6791,7 +6793,7 @@ fn netWriteFile( _ = header; _ = file_reader; _ = limit; - return error.Unimplemented; // TODO + @panic("TODO"); } fn netWriteFileUnavailable( @@ -6822,7 +6824,7 @@ fn fileWriteFilePositional( const reader_buffered = file_reader.interface.buffered(); if (reader_buffered.len >= @intFromEnum(limit)) { const n = try fileWritePositional(t, file, header, &.{limit.slice(reader_buffered)}, 1, offset); - file_reader.seekBy(n -| header.len) catch return error.ReadFailed; + file_reader.interface.toss(n -| header.len); return n; } const out_fd = file.handle; @@ -6832,7 +6834,7 @@ fn fileWriteFilePositional( if (size - file_reader.pos == 0) { if (reader_buffered.len != 0) { const n = try fileWritePositional(t, file, header, &.{limit.slice(reader_buffered)}, 1, offset); - file_reader.seekBy(n -| header.len) catch return error.ReadFailed; + file_reader.interface.toss(n -| header.len); return n; } else { return error.EndOfStream; @@ -6844,7 +6846,7 @@ fn fileWriteFilePositional( if (@atomicLoad(UseCopyFileRange, &t.use_copy_file_range, .monotonic) == .disabled) break :cfr; if (header.len != 0 or reader_buffered.len != 0) { const n = try fileWritePositional(t, file, header, &.{limit.slice(reader_buffered)}, 1, offset); - file_reader.seekBy(n -| header.len) catch return error.ReadFailed; + file_reader.interface.toss(n -| header.len); return n; } var off_in: i64 = undefined; @@ -6855,7 +6857,7 @@ fn fileWriteFilePositional( break :p &off_in; }, .streaming => null, - .failure => return error.WriteFailed, + .failure => return error.ReadFailed, }; var off_out: i64 = @intCast(offset); const current_thread = Thread.getCurrent(t); @@ -6886,15 +6888,17 @@ fn fileWriteFilePositional( assert(error.Unexpected == switch (e) { .FBIG => return error.FileTooBig, .IO => return error.InputOutput, - .ISDIR => return error.IsDir, .NOMEM => return error.SystemResources, .NOSPC => return error.NoSpaceLeft, .OVERFLOW => return error.Unseekable, .NXIO => return error.Unseekable, .SPIPE => return error.Unseekable, .PERM => return error.PermissionDenied, - .TXTBSY => return error.SwapFile, - .XDEV => return error.NotSameFileSystem, + .TXTBSY => return error.FileBusy, + // copy_file_range can still work but not on + // this pair of file descriptors. + .XDEV => return error.Unimplemented, + .ISDIR => |err| errnoBug(err), .BADF => |err| errnoBug(err), else => |err| posix.unexpectedErrno(err), }); @@ -6962,7 +6966,7 @@ fn fileWriteFilePositional( const size = file_reader.getSize() catch break :fcf; if (header.len != 0 or reader_buffered.len != 0) { const n = try fileWritePositional(t, file, header, &.{limit.slice(reader_buffered)}, 1, offset); - file_reader.seekBy(n -| header.len) catch return error.ReadFailed; + file_reader.interface.toss(n -| header.len); return n; } const current_thread = Thread.getCurrent(t); diff --git a/lib/std/Io/net.zig b/lib/std/Io/net.zig index 8b8728b6f107cab5dc98d56e336abb9504431716..8b1523fbd3068410cff2e0be4dff83cae0de6f82 100644 --- a/lib/std/Io/net.zig +++ b/lib/std/Io/net.zig @@ -1290,7 +1290,9 @@ pub const Stream = struct { SocketNotBound, } || Io.UnexpectedError || Io.Cancelable; - pub const WriteFileError = error{} || Io.Cancelable || Io.UnexpectedError; + pub const WriteFileError = error{ + NetworkDown, + } || Io.Cancelable || Io.UnexpectedError; pub fn init(stream: Stream, io: Io, buffer: []u8) Writer { return .{ diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index da0a0cff79fd9e6c38bdd6d4d392465e39864662..3a4b551ae8dfbe9b518a28bd85ae6f061810fcbe 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -844,7 +844,7 @@ test "directory operations on files" { try testing.expectError(error.PathAlreadyExists, ctx.dir.makeDir(io, test_file_name, .default_dir)); try testing.expectError(error.NotDir, ctx.dir.openDir(io, test_file_name, .{})); - try testing.expectError(error.NotDir, ctx.dir.deleteDir(test_file_name)); + try testing.expectError(error.NotDir, ctx.dir.deleteDir(io, test_file_name)); if (ctx.path_type == .absolute and comptime PathType.absolute.isSupported(builtin.os)) { try testing.expectError(error.PathAlreadyExists, fs.makeDirAbsolute(test_file_name)); @@ -934,16 +934,16 @@ test "deleteDir" { const test_file_path = try ctx.transformPath("test_dir" ++ fs.path.sep_str ++ "test_file"); // deleting a non-existent directory - try testing.expectError(error.FileNotFound, ctx.dir.deleteDir(test_dir_path)); + try testing.expectError(error.FileNotFound, ctx.dir.deleteDir(io, test_dir_path)); // deleting a non-empty directory try ctx.dir.makeDir(io, test_dir_path, .default_dir); try ctx.dir.writeFile(io, .{ .sub_path = test_file_path, .data = "" }); - try testing.expectError(error.DirNotEmpty, ctx.dir.deleteDir(test_dir_path)); + try testing.expectError(error.DirNotEmpty, ctx.dir.deleteDir(io, test_dir_path)); // deleting an empty directory try ctx.dir.deleteFile(io, test_file_path); - try ctx.dir.deleteDir(test_dir_path); + try ctx.dir.deleteDir(io, test_dir_path); } }.impl); } @@ -2062,7 +2062,7 @@ test "'.' and '..' in Io.Dir functions" { const prev_status = try dir.updateFile(io, file_path, dir, update_path, .{}); try testing.expectEqual(Io.Dir.PrevStatus.stale, prev_status); - try ctx.dir.deleteDir(subdir_path); + try ctx.dir.deleteDir(io, subdir_path); } }.impl); } @@ -2174,7 +2174,7 @@ test "invalid UTF-8/WTF-8 paths" { try testing.expectError(expected_err, ctx.dir.deleteFile(invalid_path)); - try testing.expectError(expected_err, ctx.dir.deleteDir(invalid_path)); + try testing.expectError(expected_err, ctx.dir.deleteDir(io, invalid_path)); try testing.expectError(expected_err, ctx.dir.rename(invalid_path, ctx.dir, invalid_path, io)); diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig index e9753734e91c70b66507decd8006b95609efae30..137d7635e7001d45692ac2d7112b2abb2a4a3da4 100644 --- a/src/Package/Fetch.zig +++ b/src/Package/Fetch.zig @@ -578,7 +578,7 @@ fn runResource( }; // Remove temporary directory root if not already renamed to global cache. if (!std.mem.eql(u8, package_sub_path, tmp_dir_sub_path)) { - cache_root.handle.deleteDir(tmp_dir_sub_path) catch {}; + cache_root.handle.deleteDir(io, tmp_dir_sub_path) catch {}; } // Validate the computed hash against the expected hash. If invalid, this @@ -1593,7 +1593,7 @@ fn computeHash(f: *Fetch, pkg_path: Cache.Path, filter: Filter) RunError!Compute var i: usize = 0; while (i < sus_dirs.count()) : (i += 1) { const sus_dir = sus_dirs.keys()[i]; - root_dir.deleteDir(sus_dir) catch |err| switch (err) { + root_dir.deleteDir(io, sus_dir) catch |err| switch (err) { error.DirNotEmpty => continue, error.FileNotFound => continue, else => |e| { -- 2.54.0