| author | |
| committer | |
| log | 89412fda775aecdedf4047355f2c45b48334a285 |
| tree | 1aa3818600ec8bdead689f0a60bf507b4c259370 |
| parent | 69b54b0cd12fb90f8ff101bc66e433a81d4b8409 |
7 files changed, 202 insertions(+), 156 deletions(-)
lib/std/Io/File.zig+11-83| ... | ... | @@ -47,90 +47,14 @@ pub const Stat = struct { |
| 47 | 47 | kind: Kind, |
| 48 | 48 | |
| 49 | 49 | /// Last access time in nanoseconds, relative to UTC 1970-01-01. |
| 50 | /// TODO change this to Io.Timestamp except don't waste storage on clock | |
| 50 | 51 | atime: i128, |
| 51 | 52 | /// Last modification time in nanoseconds, relative to UTC 1970-01-01. |
| 53 | /// TODO change this to Io.Timestamp except don't waste storage on clock | |
| 52 | 54 | mtime: i128, |
| 53 | 55 | /// Last status/metadata change time in nanoseconds, relative to UTC 1970-01-01. |
| 56 | /// TODO change this to Io.Timestamp except don't waste storage on clock | |
| 54 | 57 | ctime: i128, |
| 55 | ||
| 56 | pub fn fromPosix(st: std.posix.Stat) Stat { | |
| 57 | const atime = st.atime(); | |
| 58 | const mtime = st.mtime(); | |
| 59 | const ctime = st.ctime(); | |
| 60 | return .{ | |
| 61 | .inode = st.ino, | |
| 62 | .size = @bitCast(st.size), | |
| 63 | .mode = st.mode, | |
| 64 | .kind = k: { | |
| 65 | const m = st.mode & std.posix.S.IFMT; | |
| 66 | switch (m) { | |
| 67 | std.posix.S.IFBLK => break :k .block_device, | |
| 68 | std.posix.S.IFCHR => break :k .character_device, | |
| 69 | std.posix.S.IFDIR => break :k .directory, | |
| 70 | std.posix.S.IFIFO => break :k .named_pipe, | |
| 71 | std.posix.S.IFLNK => break :k .sym_link, | |
| 72 | std.posix.S.IFREG => break :k .file, | |
| 73 | std.posix.S.IFSOCK => break :k .unix_domain_socket, | |
| 74 | else => {}, | |
| 75 | } | |
| 76 | if (builtin.os.tag == .illumos) switch (m) { | |
| 77 | std.posix.S.IFDOOR => break :k .door, | |
| 78 | std.posix.S.IFPORT => break :k .event_port, | |
| 79 | else => {}, | |
| 80 | }; | |
| 81 | ||
| 82 | break :k .unknown; | |
| 83 | }, | |
| 84 | .atime = @as(i128, atime.sec) * std.time.ns_per_s + atime.nsec, | |
| 85 | .mtime = @as(i128, mtime.sec) * std.time.ns_per_s + mtime.nsec, | |
| 86 | .ctime = @as(i128, ctime.sec) * std.time.ns_per_s + ctime.nsec, | |
| 87 | }; | |
| 88 | } | |
| 89 | ||
| 90 | pub fn fromLinux(stx: std.os.linux.Statx) Stat { | |
| 91 | const atime = stx.atime; | |
| 92 | const mtime = stx.mtime; | |
| 93 | const ctime = stx.ctime; | |
| 94 | ||
| 95 | return .{ | |
| 96 | .inode = stx.ino, | |
| 97 | .size = stx.size, | |
| 98 | .mode = stx.mode, | |
| 99 | .kind = switch (stx.mode & std.os.linux.S.IFMT) { | |
| 100 | std.os.linux.S.IFDIR => .directory, | |
| 101 | std.os.linux.S.IFCHR => .character_device, | |
| 102 | std.os.linux.S.IFBLK => .block_device, | |
| 103 | std.os.linux.S.IFREG => .file, | |
| 104 | std.os.linux.S.IFIFO => .named_pipe, | |
| 105 | std.os.linux.S.IFLNK => .sym_link, | |
| 106 | std.os.linux.S.IFSOCK => .unix_domain_socket, | |
| 107 | else => .unknown, | |
| 108 | }, | |
| 109 | .atime = @as(i128, atime.sec) * std.time.ns_per_s + atime.nsec, | |
| 110 | .mtime = @as(i128, mtime.sec) * std.time.ns_per_s + mtime.nsec, | |
| 111 | .ctime = @as(i128, ctime.sec) * std.time.ns_per_s + ctime.nsec, | |
| 112 | }; | |
| 113 | } | |
| 114 | ||
| 115 | pub fn fromWasi(st: std.os.wasi.filestat_t) Stat { | |
| 116 | return .{ | |
| 117 | .inode = st.ino, | |
| 118 | .size = @bitCast(st.size), | |
| 119 | .mode = 0, | |
| 120 | .kind = switch (st.filetype) { | |
| 121 | .BLOCK_DEVICE => .block_device, | |
| 122 | .CHARACTER_DEVICE => .character_device, | |
| 123 | .DIRECTORY => .directory, | |
| 124 | .SYMBOLIC_LINK => .sym_link, | |
| 125 | .REGULAR_FILE => .file, | |
| 126 | .SOCKET_STREAM, .SOCKET_DGRAM => .unix_domain_socket, | |
| 127 | else => .unknown, | |
| 128 | }, | |
| 129 | .atime = st.atim, | |
| 130 | .mtime = st.mtim, | |
| 131 | .ctime = st.ctim, | |
| 132 | }; | |
| 133 | } | |
| 134 | 58 | }; |
| 135 | 59 | |
| 136 | 60 | pub fn stdout() File { |
| ... | ... | @@ -145,13 +69,17 @@ pub fn stdin() File { |
| 145 | 69 | return .{ .handle = if (is_windows) std.os.windows.peb().ProcessParameters.hStdInput else std.posix.STDIN_FILENO }; |
| 146 | 70 | } |
| 147 | 71 | |
| 148 | pub const StatError = std.posix.FStatError || Io.Cancelable; | |
| 72 | pub const StatError = error{ | |
| 73 | SystemResources, | |
| 74 | /// In WASI, this error may occur when the file descriptor does | |
| 75 | /// not hold the required rights to get its filestat information. | |
| 76 | AccessDenied, | |
| 77 | PermissionDenied, | |
| 78 | } || Io.Cancelable || Io.UnexpectedError; | |
| 149 | 79 | |
| 150 | 80 | /// Returns `Stat` containing basic information about the `File`. |
| 151 | 81 | pub fn stat(file: File, io: Io) StatError!Stat { |
| 152 | _ = file; | |
| 153 | _ = io; | |
| 154 | @panic("TODO"); | |
| 82 | return io.vtable.fileStat(io.userdata, file); | |
| 155 | 83 | } |
| 156 | 84 | |
| 157 | 85 | pub const OpenFlags = std.fs.File.OpenFlags; |
lib/std/Io/Threaded.zig+152-3| ... | ... | @@ -163,7 +163,12 @@ pub fn io(pool: *Pool) Io { |
| 163 | 163 | .dirMake = dirMake, |
| 164 | 164 | .dirStat = dirStat, |
| 165 | 165 | .dirStatPath = dirStatPath, |
| 166 | .fileStat = fileStat, | |
| 166 | .fileStat = switch (builtin.os.tag) { | |
| 167 | .linux => fileStatLinux, | |
| 168 | .windows => fileStatWindows, | |
| 169 | .wasi => fileStatWasi, | |
| 170 | else => fileStatPosix, | |
| 171 | }, | |
| 167 | 172 | .createFile = createFile, |
| 168 | 173 | .fileOpen = fileOpen, |
| 169 | 174 | .fileClose = fileClose, |
| ... | ... | @@ -781,14 +786,80 @@ fn dirStatPath(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8) Io.Dir. |
| 781 | 786 | @panic("TODO"); |
| 782 | 787 | } |
| 783 | 788 | |
| 784 | fn fileStat(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat { | |
| 789 | fn fileStatPosix(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat { | |
| 785 | 790 | const pool: *Pool = @ptrCast(@alignCast(userdata)); |
| 786 | try pool.checkCancel(); | |
| 791 | const fstat_sym = if (posix.lfs64_abi) posix.system.fstat64 else posix.system.fstat; | |
| 792 | while (true) { | |
| 793 | try pool.checkCancel(); | |
| 794 | var stat = std.mem.zeroes(posix.Stat); | |
| 795 | switch (posix.errno(fstat_sym(file.handle, &stat))) { | |
| 796 | .SUCCESS => return statFromPosix(&stat), | |
| 797 | .INTR => continue, | |
| 798 | .INVAL => |err| return errnoBug(err), | |
| 799 | .BADF => |err| return errnoBug(err), | |
| 800 | .NOMEM => return error.SystemResources, | |
| 801 | .ACCES => return error.AccessDenied, | |
| 802 | else => |err| return posix.unexpectedErrno(err), | |
| 803 | } | |
| 804 | } | |
| 805 | } | |
| 806 | ||
| 807 | fn fileStatLinux(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat { | |
| 808 | const pool: *Pool = @ptrCast(@alignCast(userdata)); | |
| 809 | const linux = std.os.linux; | |
| 810 | while (true) { | |
| 811 | try pool.checkCancel(); | |
| 812 | var statx = std.mem.zeroes(linux.Statx); | |
| 813 | const rc = linux.statx( | |
| 814 | file.handle, | |
| 815 | "", | |
| 816 | linux.AT.EMPTY_PATH, | |
| 817 | linux.STATX_TYPE | linux.STATX_MODE | linux.STATX_ATIME | linux.STATX_MTIME | linux.STATX_CTIME, | |
| 818 | &statx, | |
| 819 | ); | |
| 820 | switch (linux.E.init(rc)) { | |
| 821 | .SUCCESS => return statFromLinux(&statx), | |
| 822 | .INTR => continue, | |
| 823 | .ACCES => |err| return errnoBug(err), | |
| 824 | .BADF => |err| return errnoBug(err), | |
| 825 | .FAULT => |err| return errnoBug(err), | |
| 826 | .INVAL => |err| return errnoBug(err), | |
| 827 | .LOOP => |err| return errnoBug(err), | |
| 828 | .NAMETOOLONG => |err| return errnoBug(err), | |
| 829 | .NOENT => |err| return errnoBug(err), | |
| 830 | .NOMEM => return error.SystemResources, | |
| 831 | .NOTDIR => |err| return errnoBug(err), | |
| 832 | else => |err| return posix.unexpectedErrno(err), | |
| 833 | } | |
| 834 | } | |
| 835 | } | |
| 787 | 836 | |
| 837 | fn fileStatWindows(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat { | |
| 838 | const pool: *Pool = @ptrCast(@alignCast(userdata)); | |
| 839 | try pool.checkCancel(); | |
| 788 | 840 | _ = file; |
| 789 | 841 | @panic("TODO"); |
| 790 | 842 | } |
| 791 | 843 | |
| 844 | fn fileStatWasi(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat { | |
| 845 | if (builtin.link_libc) return fileStatPosix(userdata, file); | |
| 846 | const pool: *Pool = @ptrCast(@alignCast(userdata)); | |
| 847 | while (true) { | |
| 848 | try pool.checkCancel(); | |
| 849 | var stat: std.os.wasi.filestat_t = undefined; | |
| 850 | switch (std.os.wasi.fd_filestat_get(file.handle, &stat)) { | |
| 851 | .SUCCESS => return statFromWasi(&stat), | |
| 852 | .INTR => continue, | |
| 853 | .INVAL => |err| return errnoBug(err), | |
| 854 | .BADF => |err| return errnoBug(err), | |
| 855 | .NOMEM => return error.SystemResources, | |
| 856 | .ACCES => return error.AccessDenied, | |
| 857 | .NOTCAPABLE => return error.AccessDenied, | |
| 858 | else => |err| return posix.unexpectedErrno(err), | |
| 859 | } | |
| 860 | } | |
| 861 | } | |
| 862 | ||
| 792 | 863 | fn createFile( |
| 793 | 864 | userdata: ?*anyopaque, |
| 794 | 865 | dir: Io.Dir, |
| ... | ... | @@ -2114,3 +2185,81 @@ fn clockToWasi(clock: Io.Timestamp.Clock) std.os.wasi.clockid_t { |
| 2114 | 2185 | .cpu_thread => .THREAD_CPUTIME_ID, |
| 2115 | 2186 | }; |
| 2116 | 2187 | } |
| 2188 | ||
| 2189 | fn statFromLinux(stx: *const std.os.linux.Statx) Io.File.Stat { | |
| 2190 | const atime = stx.atime; | |
| 2191 | const mtime = stx.mtime; | |
| 2192 | const ctime = stx.ctime; | |
| 2193 | return .{ | |
| 2194 | .inode = stx.ino, | |
| 2195 | .size = stx.size, | |
| 2196 | .mode = stx.mode, | |
| 2197 | .kind = switch (stx.mode & std.os.linux.S.IFMT) { | |
| 2198 | std.os.linux.S.IFDIR => .directory, | |
| 2199 | std.os.linux.S.IFCHR => .character_device, | |
| 2200 | std.os.linux.S.IFBLK => .block_device, | |
| 2201 | std.os.linux.S.IFREG => .file, | |
| 2202 | std.os.linux.S.IFIFO => .named_pipe, | |
| 2203 | std.os.linux.S.IFLNK => .sym_link, | |
| 2204 | std.os.linux.S.IFSOCK => .unix_domain_socket, | |
| 2205 | else => .unknown, | |
| 2206 | }, | |
| 2207 | .atime = @as(i128, atime.sec) * std.time.ns_per_s + atime.nsec, | |
| 2208 | .mtime = @as(i128, mtime.sec) * std.time.ns_per_s + mtime.nsec, | |
| 2209 | .ctime = @as(i128, ctime.sec) * std.time.ns_per_s + ctime.nsec, | |
| 2210 | }; | |
| 2211 | } | |
| 2212 | ||
| 2213 | fn statFromPosix(st: *const std.posix.Stat) Io.File.Stat { | |
| 2214 | const atime = st.atime(); | |
| 2215 | const mtime = st.mtime(); | |
| 2216 | const ctime = st.ctime(); | |
| 2217 | return .{ | |
| 2218 | .inode = st.ino, | |
| 2219 | .size = @bitCast(st.size), | |
| 2220 | .mode = st.mode, | |
| 2221 | .kind = k: { | |
| 2222 | const m = st.mode & std.posix.S.IFMT; | |
| 2223 | switch (m) { | |
| 2224 | std.posix.S.IFBLK => break :k .block_device, | |
| 2225 | std.posix.S.IFCHR => break :k .character_device, | |
| 2226 | std.posix.S.IFDIR => break :k .directory, | |
| 2227 | std.posix.S.IFIFO => break :k .named_pipe, | |
| 2228 | std.posix.S.IFLNK => break :k .sym_link, | |
| 2229 | std.posix.S.IFREG => break :k .file, | |
| 2230 | std.posix.S.IFSOCK => break :k .unix_domain_socket, | |
| 2231 | else => {}, | |
| 2232 | } | |
| 2233 | if (builtin.os.tag == .illumos) switch (m) { | |
| 2234 | std.posix.S.IFDOOR => break :k .door, | |
| 2235 | std.posix.S.IFPORT => break :k .event_port, | |
| 2236 | else => {}, | |
| 2237 | }; | |
| 2238 | ||
| 2239 | break :k .unknown; | |
| 2240 | }, | |
| 2241 | .atime = @as(i128, atime.sec) * std.time.ns_per_s + atime.nsec, | |
| 2242 | .mtime = @as(i128, mtime.sec) * std.time.ns_per_s + mtime.nsec, | |
| 2243 | .ctime = @as(i128, ctime.sec) * std.time.ns_per_s + ctime.nsec, | |
| 2244 | }; | |
| 2245 | } | |
| 2246 | ||
| 2247 | fn statFromWasi(st: *const std.os.wasi.filestat_t) Io.File.Stat { | |
| 2248 | return .{ | |
| 2249 | .inode = st.ino, | |
| 2250 | .size = @bitCast(st.size), | |
| 2251 | .mode = 0, | |
| 2252 | .kind = switch (st.filetype) { | |
| 2253 | .BLOCK_DEVICE => .block_device, | |
| 2254 | .CHARACTER_DEVICE => .character_device, | |
| 2255 | .DIRECTORY => .directory, | |
| 2256 | .SYMBOLIC_LINK => .sym_link, | |
| 2257 | .REGULAR_FILE => .file, | |
| 2258 | .SOCKET_STREAM, .SOCKET_DGRAM => .unix_domain_socket, | |
| 2259 | else => .unknown, | |
| 2260 | }, | |
| 2261 | .atime = st.atim, | |
| 2262 | .mtime = st.mtim, | |
| 2263 | .ctime = st.ctim, | |
| 2264 | }; | |
| 2265 | } |
lib/std/debug.zig+3-1| ... | ... | @@ -82,6 +82,7 @@ pub const SelfInfoError = error{ |
| 82 | 82 | /// The required debug info could not be read from disk due to some IO error. |
| 83 | 83 | ReadFailed, |
| 84 | 84 | OutOfMemory, |
| 85 | Canceled, | |
| 85 | 86 | Unexpected, |
| 86 | 87 | }; |
| 87 | 88 | |
| ... | ... | @@ -691,6 +692,7 @@ pub noinline fn writeCurrentStackTrace(options: StackUnwindOptions, writer: *Wri |
| 691 | 692 | error.UnsupportedDebugInfo => "unwind info unsupported", |
| 692 | 693 | error.ReadFailed => "filesystem error", |
| 693 | 694 | error.OutOfMemory => "out of memory", |
| 695 | error.Canceled => "operation canceled", | |
| 694 | 696 | error.Unexpected => "unexpected error", |
| 695 | 697 | }; |
| 696 | 698 | if (it.stratOk(options.allow_unsafe_unwind)) { |
| ... | ... | @@ -1079,7 +1081,7 @@ fn printSourceAtAddress(gpa: Allocator, debug_info: *SelfInfo, writer: *Writer, |
| 1079 | 1081 | error.UnsupportedDebugInfo, |
| 1080 | 1082 | error.InvalidDebugInfo, |
| 1081 | 1083 | => .unknown, |
| 1082 | error.ReadFailed, error.Unexpected => s: { | |
| 1084 | error.ReadFailed, error.Unexpected, error.Canceled => s: { | |
| 1083 | 1085 | tty_config.setColor(writer, .dim) catch {}; |
| 1084 | 1086 | try writer.print("Failed to read debug info from filesystem, trace may be incomplete\n\n", .{}); |
| 1085 | 1087 | tty_config.setColor(writer, .reset) catch {}; |
lib/std/debug/ElfFile.zig+2-1| ... | ... | @@ -108,6 +108,7 @@ pub const LoadError = error{ |
| 108 | 108 | LockedMemoryLimitExceeded, |
| 109 | 109 | ProcessFdQuotaExceeded, |
| 110 | 110 | SystemFdQuotaExceeded, |
| 111 | Canceled, | |
| 111 | 112 | Unexpected, |
| 112 | 113 | }; |
| 113 | 114 | |
| ... | ... | @@ -408,7 +409,7 @@ fn loadInner( |
| 408 | 409 | arena: Allocator, |
| 409 | 410 | elf_file: std.fs.File, |
| 410 | 411 | opt_crc: ?u32, |
| 411 | ) (LoadError || error{CrcMismatch})!LoadInnerResult { | |
| 412 | ) (LoadError || error{ CrcMismatch, Canceled })!LoadInnerResult { | |
| 412 | 413 | const mapped_mem: []align(std.heap.page_size_min) const u8 = mapped: { |
| 413 | 414 | const file_len = std.math.cast( |
| 414 | 415 | usize, |
lib/std/debug/SelfInfo/Elf.zig+1| ... | ... | @@ -336,6 +336,7 @@ const Module = struct { |
| 336 | 336 | var elf_file = load_result catch |err| switch (err) { |
| 337 | 337 | error.OutOfMemory, |
| 338 | 338 | error.Unexpected, |
| 339 | error.Canceled, | |
| 339 | 340 | => |e| return e, |
| 340 | 341 | |
| 341 | 342 | error.Overflow, |
lib/std/fs/File.zig+32-60| ... | ... | @@ -1,10 +1,12 @@ |
| 1 | const File = @This(); | |
| 2 | ||
| 1 | 3 | const builtin = @import("builtin"); |
| 2 | const Os = std.builtin.Os; | |
| 3 | 4 | const native_os = builtin.os.tag; |
| 4 | 5 | const is_windows = native_os == .windows; |
| 5 | 6 | |
| 6 | const File = @This(); | |
| 7 | 7 | const std = @import("../std.zig"); |
| 8 | const Io = std.Io; | |
| 9 | const Os = std.builtin.Os; | |
| 8 | 10 | const Allocator = std.mem.Allocator; |
| 9 | 11 | const posix = std.posix; |
| 10 | 12 | const math = std.math; |
| ... | ... | @@ -17,12 +19,12 @@ const Alignment = std.mem.Alignment; |
| 17 | 19 | /// The OS-specific file descriptor or file handle. |
| 18 | 20 | handle: Handle, |
| 19 | 21 | |
| 20 | pub const Handle = std.Io.File.Handle; | |
| 21 | pub const Mode = std.Io.File.Mode; | |
| 22 | pub const INode = std.Io.File.INode; | |
| 22 | pub const Handle = Io.File.Handle; | |
| 23 | pub const Mode = Io.File.Mode; | |
| 24 | pub const INode = Io.File.INode; | |
| 23 | 25 | pub const Uid = posix.uid_t; |
| 24 | 26 | pub const Gid = posix.gid_t; |
| 25 | pub const Kind = std.Io.File.Kind; | |
| 27 | pub const Kind = Io.File.Kind; | |
| 26 | 28 | |
| 27 | 29 | /// This is the default mode given to POSIX operating systems for creating |
| 28 | 30 | /// files. `0o666` is "-rw-rw-rw-" which is counter-intuitive at first, |
| ... | ... | @@ -386,7 +388,7 @@ pub fn mode(self: File) ModeError!Mode { |
| 386 | 388 | return (try self.stat()).mode; |
| 387 | 389 | } |
| 388 | 390 | |
| 389 | pub const Stat = std.Io.File.Stat; | |
| 391 | pub const Stat = Io.File.Stat; | |
| 390 | 392 | |
| 391 | 393 | pub const StatError = posix.FStatError; |
| 392 | 394 | |
| ... | ... | @@ -436,39 +438,9 @@ pub fn stat(self: File) StatError!Stat { |
| 436 | 438 | }; |
| 437 | 439 | } |
| 438 | 440 | |
| 439 | if (builtin.os.tag == .wasi and !builtin.link_libc) { | |
| 440 | const st = try std.os.fstat_wasi(self.handle); | |
| 441 | return Stat.fromWasi(st); | |
| 442 | } | |
| 443 | ||
| 444 | if (builtin.os.tag == .linux) { | |
| 445 | var stx = std.mem.zeroes(linux.Statx); | |
| 446 | ||
| 447 | const rc = linux.statx( | |
| 448 | self.handle, | |
| 449 | "", | |
| 450 | linux.AT.EMPTY_PATH, | |
| 451 | linux.STATX_TYPE | linux.STATX_MODE | linux.STATX_ATIME | linux.STATX_MTIME | linux.STATX_CTIME, | |
| 452 | &stx, | |
| 453 | ); | |
| 454 | ||
| 455 | return switch (linux.E.init(rc)) { | |
| 456 | .SUCCESS => Stat.fromLinux(stx), | |
| 457 | .ACCES => unreachable, | |
| 458 | .BADF => unreachable, | |
| 459 | .FAULT => unreachable, | |
| 460 | .INVAL => unreachable, | |
| 461 | .LOOP => unreachable, | |
| 462 | .NAMETOOLONG => unreachable, | |
| 463 | .NOENT => unreachable, | |
| 464 | .NOMEM => error.SystemResources, | |
| 465 | .NOTDIR => unreachable, | |
| 466 | else => |err| posix.unexpectedErrno(err), | |
| 467 | }; | |
| 468 | } | |
| 469 | ||
| 470 | const st = try posix.fstat(self.handle); | |
| 471 | return Stat.fromPosix(st); | |
| 441 | var threaded: Io.Threaded = .init_single_threaded; | |
| 442 | const io = threaded.io(); | |
| 443 | return Io.File.stat(.{ .handle = self.handle }, io); | |
| 472 | 444 | } |
| 473 | 445 | |
| 474 | 446 | pub const ChmodError = posix.FChmodError; |
| ... | ... | @@ -785,8 +757,8 @@ pub fn pwritev(self: File, iovecs: []posix.iovec_const, offset: u64) PWriteError |
| 785 | 757 | return posix.pwritev(self.handle, iovecs, offset); |
| 786 | 758 | } |
| 787 | 759 | |
| 788 | /// Deprecated in favor of `std.Io.File.Reader`. | |
| 789 | pub const Reader = std.Io.File.Reader; | |
| 760 | /// Deprecated in favor of `Io.File.Reader`. | |
| 761 | pub const Reader = Io.File.Reader; | |
| 790 | 762 | |
| 791 | 763 | pub const Writer = struct { |
| 792 | 764 | file: File, |
| ... | ... | @@ -799,7 +771,7 @@ pub const Writer = struct { |
| 799 | 771 | copy_file_range_err: ?CopyFileRangeError = null, |
| 800 | 772 | fcopyfile_err: ?FcopyfileError = null, |
| 801 | 773 | seek_err: ?Writer.SeekError = null, |
| 802 | interface: std.Io.Writer, | |
| 774 | interface: Io.Writer, | |
| 803 | 775 | |
| 804 | 776 | pub const Mode = Reader.Mode; |
| 805 | 777 | |
| ... | ... | @@ -845,13 +817,13 @@ pub const Writer = struct { |
| 845 | 817 | }; |
| 846 | 818 | } |
| 847 | 819 | |
| 848 | pub fn initInterface(buffer: []u8) std.Io.Writer { | |
| 820 | pub fn initInterface(buffer: []u8) Io.Writer { | |
| 849 | 821 | return .{ |
| 850 | 822 | .vtable = &.{ |
| 851 | 823 | .drain = drain, |
| 852 | 824 | .sendFile = switch (builtin.zig_backend) { |
| 853 | 825 | else => sendFile, |
| 854 | .stage2_aarch64 => std.Io.Writer.unimplementedSendFile, | |
| 826 | .stage2_aarch64 => Io.Writer.unimplementedSendFile, | |
| 855 | 827 | }, |
| 856 | 828 | }, |
| 857 | 829 | .buffer = buffer, |
| ... | ... | @@ -859,7 +831,7 @@ pub const Writer = struct { |
| 859 | 831 | } |
| 860 | 832 | |
| 861 | 833 | /// TODO when this logic moves from fs.File to Io.File the io parameter should be deleted |
| 862 | pub fn moveToReader(w: *Writer, io: std.Io) Reader { | |
| 834 | pub fn moveToReader(w: *Writer, io: Io) Reader { | |
| 863 | 835 | defer w.* = undefined; |
| 864 | 836 | return .{ |
| 865 | 837 | .io = io, |
| ... | ... | @@ -871,7 +843,7 @@ pub const Writer = struct { |
| 871 | 843 | }; |
| 872 | 844 | } |
| 873 | 845 | |
| 874 | pub fn drain(io_w: *std.Io.Writer, data: []const []const u8, splat: usize) std.Io.Writer.Error!usize { | |
| 846 | pub fn drain(io_w: *Io.Writer, data: []const []const u8, splat: usize) Io.Writer.Error!usize { | |
| 875 | 847 | const w: *Writer = @alignCast(@fieldParentPtr("interface", io_w)); |
| 876 | 848 | const handle = w.file.handle; |
| 877 | 849 | const buffered = io_w.buffered(); |
| ... | ... | @@ -1021,10 +993,10 @@ pub const Writer = struct { |
| 1021 | 993 | } |
| 1022 | 994 | |
| 1023 | 995 | pub fn sendFile( |
| 1024 | io_w: *std.Io.Writer, | |
| 1025 | file_reader: *std.Io.File.Reader, | |
| 1026 | limit: std.Io.Limit, | |
| 1027 | ) std.Io.Writer.FileError!usize { | |
| 996 | io_w: *Io.Writer, | |
| 997 | file_reader: *Io.File.Reader, | |
| 998 | limit: Io.Limit, | |
| 999 | ) Io.Writer.FileError!usize { | |
| 1028 | 1000 | const reader_buffered = file_reader.interface.buffered(); |
| 1029 | 1001 | if (reader_buffered.len >= @intFromEnum(limit)) |
| 1030 | 1002 | return sendFileBuffered(io_w, file_reader, limit.slice(reader_buffered)); |
| ... | ... | @@ -1288,16 +1260,16 @@ pub const Writer = struct { |
| 1288 | 1260 | } |
| 1289 | 1261 | |
| 1290 | 1262 | fn sendFileBuffered( |
| 1291 | io_w: *std.Io.Writer, | |
| 1292 | file_reader: *std.Io.File.Reader, | |
| 1263 | io_w: *Io.Writer, | |
| 1264 | file_reader: *Io.File.Reader, | |
| 1293 | 1265 | reader_buffered: []const u8, |
| 1294 | ) std.Io.Writer.FileError!usize { | |
| 1266 | ) Io.Writer.FileError!usize { | |
| 1295 | 1267 | const n = try drain(io_w, &.{reader_buffered}, 1); |
| 1296 | 1268 | file_reader.seekBy(@intCast(n)) catch return error.ReadFailed; |
| 1297 | 1269 | return n; |
| 1298 | 1270 | } |
| 1299 | 1271 | |
| 1300 | pub fn seekTo(w: *Writer, offset: u64) (Writer.SeekError || std.Io.Writer.Error)!void { | |
| 1272 | pub fn seekTo(w: *Writer, offset: u64) (Writer.SeekError || Io.Writer.Error)!void { | |
| 1301 | 1273 | try w.interface.flush(); |
| 1302 | 1274 | try seekToUnbuffered(w, offset); |
| 1303 | 1275 | } |
| ... | ... | @@ -1321,7 +1293,7 @@ pub const Writer = struct { |
| 1321 | 1293 | } |
| 1322 | 1294 | } |
| 1323 | 1295 | |
| 1324 | pub const EndError = SetEndPosError || std.Io.Writer.Error; | |
| 1296 | pub const EndError = SetEndPosError || Io.Writer.Error; | |
| 1325 | 1297 | |
| 1326 | 1298 | /// Flushes any buffered data and sets the end position of the file. |
| 1327 | 1299 | /// |
| ... | ... | @@ -1352,14 +1324,14 @@ pub const Writer = struct { |
| 1352 | 1324 | /// |
| 1353 | 1325 | /// Positional is more threadsafe, since the global seek position is not |
| 1354 | 1326 | /// affected. |
| 1355 | pub fn reader(file: File, io: std.Io, buffer: []u8) Reader { | |
| 1327 | pub fn reader(file: File, io: Io, buffer: []u8) Reader { | |
| 1356 | 1328 | return .init(.{ .handle = file.handle }, io, buffer); |
| 1357 | 1329 | } |
| 1358 | 1330 | |
| 1359 | 1331 | /// Positional is more threadsafe, since the global seek position is not |
| 1360 | 1332 | /// affected, but when such syscalls are not available, preemptively |
| 1361 | 1333 | /// initializing in streaming mode skips a failed syscall. |
| 1362 | pub fn readerStreaming(file: File, io: std.Io, buffer: []u8) Reader { | |
| 1334 | pub fn readerStreaming(file: File, io: Io, buffer: []u8) Reader { | |
| 1363 | 1335 | return .initStreaming(.{ .handle = file.handle }, io, buffer); |
| 1364 | 1336 | } |
| 1365 | 1337 | |
| ... | ... | @@ -1541,10 +1513,10 @@ pub fn downgradeLock(file: File) LockError!void { |
| 1541 | 1513 | } |
| 1542 | 1514 | } |
| 1543 | 1515 | |
| 1544 | pub fn adaptToNewApi(file: File) std.Io.File { | |
| 1516 | pub fn adaptToNewApi(file: File) Io.File { | |
| 1545 | 1517 | return .{ .handle = file.handle }; |
| 1546 | 1518 | } |
| 1547 | 1519 | |
| 1548 | pub fn adaptFromNewApi(file: std.Io.File) File { | |
| 1520 | pub fn adaptFromNewApi(file: Io.File) File { | |
| 1549 | 1521 | return .{ .handle = file.handle }; |
| 1550 | 1522 | } |
lib/std/posix.zig+1-8| ... | ... | @@ -4458,14 +4458,7 @@ pub fn wait4(pid: pid_t, flags: u32, ru: ?*rusage) WaitPidResult { |
| 4458 | 4458 | } |
| 4459 | 4459 | } |
| 4460 | 4460 | |
| 4461 | pub const FStatError = error{ | |
| 4462 | SystemResources, | |
| 4463 | ||
| 4464 | /// In WASI, this error may occur when the file descriptor does | |
| 4465 | /// not hold the required rights to get its filestat information. | |
| 4466 | AccessDenied, | |
| 4467 | PermissionDenied, | |
| 4468 | } || UnexpectedError; | |
| 4461 | pub const FStatError = std.Io.File.StatError; | |
| 4469 | 4462 | |
| 4470 | 4463 | /// Return information about a file descriptor. |
| 4471 | 4464 | pub fn fstat(fd: fd_t) FStatError!Stat { |