authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-16 17:05:35-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-29 06:20:50-07:00
log3bf0ce65a514e6f86241364c4a11089e32b3ba57
tree17a43899fa0f1df18087a0af5d717e7f8b3034d1
parent7b1502f327f580254f5699754ec21521eac10cc7

fix miscellaneous compilation errors

- ILSEQ -> error.BadPathName - implement dirStatPath for WASI

11 files changed, 114 insertions(+), 224 deletions(-)

lib/compiler/aro/aro/Compilation.zig+2-1
...@@ -171,10 +171,11 @@ pub fn init(gpa: Allocator, arena: Allocator, io: Io, diagnostics: *Diagnostics,...@@ -171,10 +171,11 @@ pub fn init(gpa: Allocator, arena: Allocator, io: Io, diagnostics: *Diagnostics,
171171
172/// Initialize Compilation with default environment,172/// Initialize Compilation with default environment,
173/// pragma handlers and emulation mode set to target.173/// pragma handlers and emulation mode set to target.
174pub fn initDefault(gpa: Allocator, arena: Allocator, diagnostics: *Diagnostics, cwd: std.fs.Dir) !Compilation {174pub fn initDefault(gpa: Allocator, arena: Allocator, io: Io, diagnostics: *Diagnostics, cwd: std.fs.Dir) !Compilation {
175 var comp: Compilation = .{175 var comp: Compilation = .{
176 .gpa = gpa,176 .gpa = gpa,
177 .arena = arena,177 .arena = arena,
178 .io = io,
178 .diagnostics = diagnostics,179 .diagnostics = diagnostics,
179 .environment = try Environment.loadAll(gpa),180 .environment = try Environment.loadAll(gpa),
180 .cwd = cwd,181 .cwd = cwd,
lib/std/Io/Threaded.zig+37-1
...@@ -174,7 +174,7 @@ pub fn io(t: *Threaded) Io {...@@ -174,7 +174,7 @@ pub fn io(t: *Threaded) Io {
174 .dirStatPath = switch (builtin.os.tag) {174 .dirStatPath = switch (builtin.os.tag) {
175 .linux => dirStatPathLinux,175 .linux => dirStatPathLinux,
176 .windows => @panic("TODO"),176 .windows => @panic("TODO"),
177 .wasi => @panic("TODO"),177 .wasi => dirStatPathWasi,
178 else => dirStatPathPosix,178 else => dirStatPathPosix,
179 },179 },
180 .fileStat = switch (builtin.os.tag) {180 .fileStat = switch (builtin.os.tag) {
...@@ -984,6 +984,42 @@ fn dirStatPathPosix(...@@ -984,6 +984,42 @@ fn dirStatPathPosix(
984 }984 }
985}985}
986986
987fn dirStatPathWasi(
988 userdata: ?*anyopaque,
989 dir: Io.Dir,
990 sub_path: []const u8,
991 options: Io.Dir.StatPathOptions,
992) Io.Dir.StatPathError!Io.File.Stat {
993 if (builtin.link_libc) return dirStatPathPosix(userdata, dir, sub_path, options);
994 const t: *Threaded = @ptrCast(@alignCast(userdata));
995 const dir_fd = dir.handle;
996 const wasi = std.os.wasi;
997 const flags: wasi.lookupflags_t = .{
998 .SYMLINK_FOLLOW = @intFromBool(options.follow_symlinks),
999 };
1000 var stat: wasi.filestat_t = undefined;
1001 while (true) {
1002 try t.checkCancel();
1003 switch (wasi.path_filestat_get(dir_fd, flags, sub_path.ptr, sub_path.len, &stat)) {
1004 .SUCCESS => return statFromWasi(stat),
1005 .INTR => continue,
1006 .CANCELED => return error.Canceled,
1007
1008 .INVAL => |err| errnoBug(err),
1009 .BADF => |err| errnoBug(err), // Always a race condition.
1010 .NOMEM => return error.SystemResources,
1011 .ACCES => return error.AccessDenied,
1012 .FAULT => |err| errnoBug(err),
1013 .NAMETOOLONG => return error.NameTooLong,
1014 .NOENT => return error.FileNotFound,
1015 .NOTDIR => return error.FileNotFound,
1016 .NOTCAPABLE => return error.AccessDenied,
1017 .ILSEQ => return error.BadPathName,
1018 else => |err| return posix.unexpectedErrno(err),
1019 }
1020 }
1021}
1022
987fn fileStatPosix(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat {1023fn fileStatPosix(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat {
988 const t: *Threaded = @ptrCast(@alignCast(userdata));1024 const t: *Threaded = @ptrCast(@alignCast(userdata));
9891025
lib/std/fs/Dir.zig-4
...@@ -2500,10 +2500,6 @@ pub fn statFile(self: Dir, sub_path: []const u8) StatFileError!Stat {...@@ -2500,10 +2500,6 @@ pub fn statFile(self: Dir, sub_path: []const u8) StatFileError!Stat {
2500 defer file.close();2500 defer file.close();
2501 return file.stat();2501 return file.stat();
2502 }2502 }
2503 if (native_os == .wasi and !builtin.link_libc) {
2504 const st = try std.os.fstatat_wasi(self.fd, sub_path, .{ .SYMLINK_FOLLOW = true });
2505 return Stat.fromWasi(st);
2506 }
2507 var threaded: Io.Threaded = .init_single_threaded;2503 var threaded: Io.Threaded = .init_single_threaded;
2508 const io = threaded.io();2504 const io = threaded.io();
2509 return Io.Dir.statPath(.{ .handle = self.fd }, io, sub_path, .{});2505 return Io.Dir.statPath(.{ .handle = self.fd }, io, sub_path, .{});
lib/std/fs/test.zig-22
...@@ -2031,37 +2031,28 @@ test "invalid UTF-8/WTF-8 paths" {...@@ -2031,37 +2031,28 @@ test "invalid UTF-8/WTF-8 paths" {
2031 const invalid_path = try ctx.transformPath("\xFF");2031 const invalid_path = try ctx.transformPath("\xFF");
20322032
2033 try testing.expectError(expected_err, ctx.dir.openFile(invalid_path, .{}));2033 try testing.expectError(expected_err, ctx.dir.openFile(invalid_path, .{}));
2034 try testing.expectError(expected_err, ctx.dir.openFileZ(invalid_path, .{}));
20352034
2036 try testing.expectError(expected_err, ctx.dir.createFile(invalid_path, .{}));2035 try testing.expectError(expected_err, ctx.dir.createFile(invalid_path, .{}));
2037 try testing.expectError(expected_err, ctx.dir.createFileZ(invalid_path, .{}));
20382036
2039 try testing.expectError(expected_err, ctx.dir.makeDir(invalid_path));2037 try testing.expectError(expected_err, ctx.dir.makeDir(invalid_path));
2040 try testing.expectError(expected_err, ctx.dir.makeDirZ(invalid_path));
20412038
2042 try testing.expectError(expected_err, ctx.dir.makePath(invalid_path));2039 try testing.expectError(expected_err, ctx.dir.makePath(invalid_path));
2043 try testing.expectError(expected_err, ctx.dir.makeOpenPath(invalid_path, .{}));2040 try testing.expectError(expected_err, ctx.dir.makeOpenPath(invalid_path, .{}));
20442041
2045 try testing.expectError(expected_err, ctx.dir.openDir(invalid_path, .{}));2042 try testing.expectError(expected_err, ctx.dir.openDir(invalid_path, .{}));
2046 try testing.expectError(expected_err, ctx.dir.openDirZ(invalid_path, .{}));
20472043
2048 try testing.expectError(expected_err, ctx.dir.deleteFile(invalid_path));2044 try testing.expectError(expected_err, ctx.dir.deleteFile(invalid_path));
2049 try testing.expectError(expected_err, ctx.dir.deleteFileZ(invalid_path));
20502045
2051 try testing.expectError(expected_err, ctx.dir.deleteDir(invalid_path));2046 try testing.expectError(expected_err, ctx.dir.deleteDir(invalid_path));
2052 try testing.expectError(expected_err, ctx.dir.deleteDirZ(invalid_path));
20532047
2054 try testing.expectError(expected_err, ctx.dir.rename(invalid_path, invalid_path));2048 try testing.expectError(expected_err, ctx.dir.rename(invalid_path, invalid_path));
2055 try testing.expectError(expected_err, ctx.dir.renameZ(invalid_path, invalid_path));
20562049
2057 try testing.expectError(expected_err, ctx.dir.symLink(invalid_path, invalid_path, .{}));2050 try testing.expectError(expected_err, ctx.dir.symLink(invalid_path, invalid_path, .{}));
2058 try testing.expectError(expected_err, ctx.dir.symLinkZ(invalid_path, invalid_path, .{}));
2059 if (native_os == .wasi) {2051 if (native_os == .wasi) {
2060 try testing.expectError(expected_err, ctx.dir.symLinkWasi(invalid_path, invalid_path, .{}));2052 try testing.expectError(expected_err, ctx.dir.symLinkWasi(invalid_path, invalid_path, .{}));
2061 }2053 }
20622054
2063 try testing.expectError(expected_err, ctx.dir.readLink(invalid_path, &[_]u8{}));2055 try testing.expectError(expected_err, ctx.dir.readLink(invalid_path, &[_]u8{}));
2064 try testing.expectError(expected_err, ctx.dir.readLinkZ(invalid_path, &[_]u8{}));
2065 if (native_os == .wasi) {2056 if (native_os == .wasi) {
2066 try testing.expectError(expected_err, ctx.dir.readLinkWasi(invalid_path, &[_]u8{}));2057 try testing.expectError(expected_err, ctx.dir.readLinkWasi(invalid_path, &[_]u8{}));
2067 }2058 }
...@@ -2075,7 +2066,6 @@ test "invalid UTF-8/WTF-8 paths" {...@@ -2075,7 +2066,6 @@ test "invalid UTF-8/WTF-8 paths" {
2075 try testing.expectError(expected_err, ctx.dir.writeFile(.{ .sub_path = invalid_path, .data = "" }));2066 try testing.expectError(expected_err, ctx.dir.writeFile(.{ .sub_path = invalid_path, .data = "" }));
20762067
2077 try testing.expectError(expected_err, ctx.dir.access(invalid_path, .{}));2068 try testing.expectError(expected_err, ctx.dir.access(invalid_path, .{}));
2078 try testing.expectError(expected_err, ctx.dir.accessZ(invalid_path, .{}));
20792069
2080 var dir = ctx.dir.adaptToNewApi();2070 var dir = ctx.dir.adaptToNewApi();
2081 try testing.expectError(expected_err, dir.updateFile(io, invalid_path, dir, invalid_path, .{}));2071 try testing.expectError(expected_err, dir.updateFile(io, invalid_path, dir, invalid_path, .{}));
...@@ -2085,37 +2075,25 @@ test "invalid UTF-8/WTF-8 paths" {...@@ -2085,37 +2075,25 @@ test "invalid UTF-8/WTF-8 paths" {
20852075
2086 if (native_os != .wasi) {2076 if (native_os != .wasi) {
2087 try testing.expectError(expected_err, ctx.dir.realpath(invalid_path, &[_]u8{}));2077 try testing.expectError(expected_err, ctx.dir.realpath(invalid_path, &[_]u8{}));
2088 try testing.expectError(expected_err, ctx.dir.realpathZ(invalid_path, &[_]u8{}));
2089 try testing.expectError(expected_err, ctx.dir.realpathAlloc(testing.allocator, invalid_path));2078 try testing.expectError(expected_err, ctx.dir.realpathAlloc(testing.allocator, invalid_path));
2090 }2079 }
20912080
2092 try testing.expectError(expected_err, fs.rename(ctx.dir, invalid_path, ctx.dir, invalid_path));2081 try testing.expectError(expected_err, fs.rename(ctx.dir, invalid_path, ctx.dir, invalid_path));
2093 try testing.expectError(expected_err, fs.renameZ(ctx.dir, invalid_path, ctx.dir, invalid_path));
20942082
2095 if (native_os != .wasi and ctx.path_type != .relative) {2083 if (native_os != .wasi and ctx.path_type != .relative) {
2096 try testing.expectError(expected_err, fs.copyFileAbsolute(invalid_path, invalid_path, .{}));2084 try testing.expectError(expected_err, fs.copyFileAbsolute(invalid_path, invalid_path, .{}));
2097 try testing.expectError(expected_err, fs.makeDirAbsolute(invalid_path));2085 try testing.expectError(expected_err, fs.makeDirAbsolute(invalid_path));
2098 try testing.expectError(expected_err, fs.makeDirAbsoluteZ(invalid_path));
2099 try testing.expectError(expected_err, fs.deleteDirAbsolute(invalid_path));2086 try testing.expectError(expected_err, fs.deleteDirAbsolute(invalid_path));
2100 try testing.expectError(expected_err, fs.deleteDirAbsoluteZ(invalid_path));
2101 try testing.expectError(expected_err, fs.renameAbsolute(invalid_path, invalid_path));2087 try testing.expectError(expected_err, fs.renameAbsolute(invalid_path, invalid_path));
2102 try testing.expectError(expected_err, fs.renameAbsoluteZ(invalid_path, invalid_path));
2103 try testing.expectError(expected_err, fs.openDirAbsolute(invalid_path, .{}));2088 try testing.expectError(expected_err, fs.openDirAbsolute(invalid_path, .{}));
2104 try testing.expectError(expected_err, fs.openDirAbsoluteZ(invalid_path, .{}));
2105 try testing.expectError(expected_err, fs.openFileAbsolute(invalid_path, .{}));2089 try testing.expectError(expected_err, fs.openFileAbsolute(invalid_path, .{}));
2106 try testing.expectError(expected_err, fs.openFileAbsoluteZ(invalid_path, .{}));
2107 try testing.expectError(expected_err, fs.accessAbsolute(invalid_path, .{}));2090 try testing.expectError(expected_err, fs.accessAbsolute(invalid_path, .{}));
2108 try testing.expectError(expected_err, fs.accessAbsoluteZ(invalid_path, .{}));
2109 try testing.expectError(expected_err, fs.createFileAbsolute(invalid_path, .{}));2091 try testing.expectError(expected_err, fs.createFileAbsolute(invalid_path, .{}));
2110 try testing.expectError(expected_err, fs.createFileAbsoluteZ(invalid_path, .{}));
2111 try testing.expectError(expected_err, fs.deleteFileAbsolute(invalid_path));2092 try testing.expectError(expected_err, fs.deleteFileAbsolute(invalid_path));
2112 try testing.expectError(expected_err, fs.deleteFileAbsoluteZ(invalid_path));
2113 try testing.expectError(expected_err, fs.deleteTreeAbsolute(invalid_path));2093 try testing.expectError(expected_err, fs.deleteTreeAbsolute(invalid_path));
2114 var readlink_buf: [fs.max_path_bytes]u8 = undefined;2094 var readlink_buf: [fs.max_path_bytes]u8 = undefined;
2115 try testing.expectError(expected_err, fs.readLinkAbsolute(invalid_path, &readlink_buf));2095 try testing.expectError(expected_err, fs.readLinkAbsolute(invalid_path, &readlink_buf));
2116 try testing.expectError(expected_err, fs.readLinkAbsoluteZ(invalid_path, &readlink_buf));
2117 try testing.expectError(expected_err, fs.symLinkAbsolute(invalid_path, invalid_path, .{}));2096 try testing.expectError(expected_err, fs.symLinkAbsolute(invalid_path, invalid_path, .{}));
2118 try testing.expectError(expected_err, fs.symLinkAbsoluteZ(invalid_path, invalid_path, .{}));
2119 try testing.expectError(expected_err, fs.realpathAlloc(testing.allocator, invalid_path));2097 try testing.expectError(expected_err, fs.realpathAlloc(testing.allocator, invalid_path));
2120 }2098 }
2121 }2099 }
lib/std/os.zig-30
...@@ -201,36 +201,6 @@ pub fn getFdPath(fd: std.posix.fd_t, out_buffer: *[max_path_bytes]u8) std.posix....@@ -201,36 +201,6 @@ pub fn getFdPath(fd: std.posix.fd_t, out_buffer: *[max_path_bytes]u8) std.posix.
201 }201 }
202}202}
203203
204pub const FstatatError = error{
205 SystemResources,
206 AccessDenied,
207 NameTooLong,
208 FileNotFound,
209 InvalidUtf8,
210 Unexpected,
211};
212
213/// WASI-only. Same as `fstatat` but targeting WASI.
214/// `pathname` should be encoded as valid UTF-8.
215/// See also `fstatat`.
216pub fn fstatat_wasi(dirfd: posix.fd_t, pathname: []const u8, flags: wasi.lookupflags_t) FstatatError!wasi.filestat_t {
217 var stat: wasi.filestat_t = undefined;
218 switch (wasi.path_filestat_get(dirfd, flags, pathname.ptr, pathname.len, &stat)) {
219 .SUCCESS => return stat,
220 .INVAL => unreachable,
221 .BADF => unreachable, // Always a race condition.
222 .NOMEM => return error.SystemResources,
223 .ACCES => return error.AccessDenied,
224 .FAULT => unreachable,
225 .NAMETOOLONG => return error.NameTooLong,
226 .NOENT => return error.FileNotFound,
227 .NOTDIR => return error.FileNotFound,
228 .NOTCAPABLE => return error.AccessDenied,
229 .ILSEQ => return error.InvalidUtf8,
230 else => |err| return posix.unexpectedErrno(err),
231 }
232}
233
234pub fn fstat_wasi(fd: posix.fd_t) posix.FStatError!wasi.filestat_t {204pub fn fstat_wasi(fd: posix.fd_t) posix.FStatError!wasi.filestat_t {
235 var stat: wasi.filestat_t = undefined;205 var stat: wasi.filestat_t = undefined;
236 switch (wasi.fd_filestat_get(fd, &stat)) {206 switch (wasi.fd_filestat_get(fd, &stat)) {
lib/std/os/windows.zig+4-4
...@@ -146,7 +146,7 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN...@@ -146,7 +146,7 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN
146 // call has failed. There is not really a sane way to handle146 // call has failed. There is not really a sane way to handle
147 // this other than retrying the creation after the OS finishes147 // this other than retrying the creation after the OS finishes
148 // the deletion.148 // the deletion.
149 std.Thread.sleep(std.time.ns_per_ms);149 kernel32.Sleep(1);
150 continue;150 continue;
151 },151 },
152 .VIRUS_INFECTED, .VIRUS_DELETED => return error.AntivirusInterference,152 .VIRUS_INFECTED, .VIRUS_DELETED => return error.AntivirusInterference,
...@@ -604,7 +604,7 @@ pub const ReadFileError = error{...@@ -604,7 +604,7 @@ pub const ReadFileError = error{
604 BrokenPipe,604 BrokenPipe,
605 /// The specified network name is no longer available.605 /// The specified network name is no longer available.
606 ConnectionResetByPeer,606 ConnectionResetByPeer,
607 OperationAborted,607 Canceled,
608 /// Unable to read file due to lock.608 /// Unable to read file due to lock.
609 LockViolation,609 LockViolation,
610 /// Known to be possible when:610 /// Known to be possible when:
...@@ -654,7 +654,7 @@ pub fn ReadFile(in_hFile: HANDLE, buffer: []u8, offset: ?u64) ReadFileError!usiz...@@ -654,7 +654,7 @@ pub fn ReadFile(in_hFile: HANDLE, buffer: []u8, offset: ?u64) ReadFileError!usiz
654654
655pub const WriteFileError = error{655pub const WriteFileError = error{
656 SystemResources,656 SystemResources,
657 OperationAborted,657 Canceled,
658 BrokenPipe,658 BrokenPipe,
659 NotOpenForWriting,659 NotOpenForWriting,
660 /// The process cannot access the file because another process has locked660 /// The process cannot access the file because another process has locked
...@@ -694,7 +694,7 @@ pub fn WriteFile(...@@ -694,7 +694,7 @@ pub fn WriteFile(
694 switch (GetLastError()) {694 switch (GetLastError()) {
695 .INVALID_USER_BUFFER => return error.SystemResources,695 .INVALID_USER_BUFFER => return error.SystemResources,
696 .NOT_ENOUGH_MEMORY => return error.SystemResources,696 .NOT_ENOUGH_MEMORY => return error.SystemResources,
697 .OPERATION_ABORTED => return error.OperationAborted,697 .OPERATION_ABORTED => return error.Canceled,
698 .NOT_ENOUGH_QUOTA => return error.SystemResources,698 .NOT_ENOUGH_QUOTA => return error.SystemResources,
699 .IO_PENDING => unreachable,699 .IO_PENDING => unreachable,
700 .NO_DATA => return error.BrokenPipe,700 .NO_DATA => return error.BrokenPipe,
lib/std/posix.zig+31-99
...@@ -821,9 +821,6 @@ pub const ReadError = std.Io.File.ReadStreamingError;...@@ -821,9 +821,6 @@ pub const ReadError = std.Io.File.ReadStreamingError;
821/// The corresponding POSIX limit is `maxInt(isize)`.821/// The corresponding POSIX limit is `maxInt(isize)`.
822pub fn read(fd: fd_t, buf: []u8) ReadError!usize {822pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
823 if (buf.len == 0) return 0;823 if (buf.len == 0) return 0;
824 if (native_os == .windows) {
825 return windows.ReadFile(fd, buf, null);
826 }
827 if (native_os == .wasi and !builtin.link_libc) {824 if (native_os == .wasi and !builtin.link_libc) {
828 const iovs = [1]iovec{iovec{825 const iovs = [1]iovec{iovec{
829 .base = buf.ptr,826 .base = buf.ptr,
...@@ -1181,7 +1178,7 @@ pub const WriteError = error{...@@ -1181,7 +1178,7 @@ pub const WriteError = error{
1181 PermissionDenied,1178 PermissionDenied,
1182 BrokenPipe,1179 BrokenPipe,
1183 SystemResources,1180 SystemResources,
1184 OperationAborted,1181 Canceled,
1185 NotOpenForWriting,1182 NotOpenForWriting,
11861183
1187 /// The process cannot access the file because another process has locked1184 /// The process cannot access the file because another process has locked
...@@ -1597,10 +1594,7 @@ pub fn openZ(file_path: [*:0]const u8, flags: O, perm: mode_t) OpenError!fd_t {...@@ -1597,10 +1594,7 @@ pub fn openZ(file_path: [*:0]const u8, flags: O, perm: mode_t) OpenError!fd_t {
1597 .PERM => return error.PermissionDenied,1594 .PERM => return error.PermissionDenied,
1598 .EXIST => return error.PathAlreadyExists,1595 .EXIST => return error.PathAlreadyExists,
1599 .BUSY => return error.DeviceBusy,1596 .BUSY => return error.DeviceBusy,
1600 .ILSEQ => |err| if (native_os == .wasi)1597 .ILSEQ => return error.BadPathName,
1601 return error.InvalidUtf8
1602 else
1603 return unexpectedErrno(err),
1604 else => |err| return unexpectedErrno(err),1598 else => |err| return unexpectedErrno(err),
1605 }1599 }
1606 }1600 }
...@@ -1678,7 +1672,7 @@ pub fn openatWasi(...@@ -1678,7 +1672,7 @@ pub fn openatWasi(
1678 .EXIST => return error.PathAlreadyExists,1672 .EXIST => return error.PathAlreadyExists,
1679 .BUSY => return error.DeviceBusy,1673 .BUSY => return error.DeviceBusy,
1680 .NOTCAPABLE => return error.AccessDenied,1674 .NOTCAPABLE => return error.AccessDenied,
1681 .ILSEQ => return error.InvalidUtf8,1675 .ILSEQ => return error.BadPathName,
1682 else => |err| return unexpectedErrno(err),1676 else => |err| return unexpectedErrno(err),
1683 }1677 }
1684 }1678 }
...@@ -1773,10 +1767,7 @@ pub fn openatZ(dir_fd: fd_t, file_path: [*:0]const u8, flags: O, mode: mode_t) O...@@ -1773,10 +1767,7 @@ pub fn openatZ(dir_fd: fd_t, file_path: [*:0]const u8, flags: O, mode: mode_t) O
1773 .AGAIN => return error.WouldBlock,1767 .AGAIN => return error.WouldBlock,
1774 .TXTBSY => return error.FileBusy,1768 .TXTBSY => return error.FileBusy,
1775 .NXIO => return error.NoDevice,1769 .NXIO => return error.NoDevice,
1776 .ILSEQ => |err| if (native_os == .wasi)1770 .ILSEQ => return error.BadPathName,
1777 return error.InvalidUtf8
1778 else
1779 return unexpectedErrno(err),
1780 else => |err| return unexpectedErrno(err),1771 else => |err| return unexpectedErrno(err),
1781 }1772 }
1782 }1773 }
...@@ -2084,10 +2075,7 @@ pub fn symlinkZ(target_path: [*:0]const u8, sym_link_path: [*:0]const u8) SymLin...@@ -2084,10 +2075,7 @@ pub fn symlinkZ(target_path: [*:0]const u8, sym_link_path: [*:0]const u8) SymLin
2084 .NOMEM => return error.SystemResources,2075 .NOMEM => return error.SystemResources,
2085 .NOSPC => return error.NoSpaceLeft,2076 .NOSPC => return error.NoSpaceLeft,
2086 .ROFS => return error.ReadOnlyFileSystem,2077 .ROFS => return error.ReadOnlyFileSystem,
2087 .ILSEQ => |err| if (native_os == .wasi)2078 .ILSEQ => return error.BadPathName,
2088 return error.InvalidUtf8
2089 else
2090 return unexpectedErrno(err),
2091 else => |err| return unexpectedErrno(err),2079 else => |err| return unexpectedErrno(err),
2092 }2080 }
2093}2081}
...@@ -2133,7 +2121,7 @@ pub fn symlinkatWasi(target_path: []const u8, newdirfd: fd_t, sym_link_path: []c...@@ -2133,7 +2121,7 @@ pub fn symlinkatWasi(target_path: []const u8, newdirfd: fd_t, sym_link_path: []c
2133 .NOSPC => return error.NoSpaceLeft,2121 .NOSPC => return error.NoSpaceLeft,
2134 .ROFS => return error.ReadOnlyFileSystem,2122 .ROFS => return error.ReadOnlyFileSystem,
2135 .NOTCAPABLE => return error.AccessDenied,2123 .NOTCAPABLE => return error.AccessDenied,
2136 .ILSEQ => return error.InvalidUtf8,2124 .ILSEQ => return error.BadPathName,
2137 else => |err| return unexpectedErrno(err),2125 else => |err| return unexpectedErrno(err),
2138 }2126 }
2139}2127}
...@@ -2162,10 +2150,7 @@ pub fn symlinkatZ(target_path: [*:0]const u8, newdirfd: fd_t, sym_link_path: [*:...@@ -2162,10 +2150,7 @@ pub fn symlinkatZ(target_path: [*:0]const u8, newdirfd: fd_t, sym_link_path: [*:
2162 .NOMEM => return error.SystemResources,2150 .NOMEM => return error.SystemResources,
2163 .NOSPC => return error.NoSpaceLeft,2151 .NOSPC => return error.NoSpaceLeft,
2164 .ROFS => return error.ReadOnlyFileSystem,2152 .ROFS => return error.ReadOnlyFileSystem,
2165 .ILSEQ => |err| if (native_os == .wasi)2153 .ILSEQ => return error.BadPathName,
2166 return error.InvalidUtf8
2167 else
2168 return unexpectedErrno(err),
2169 else => |err| return unexpectedErrno(err),2154 else => |err| return unexpectedErrno(err),
2170 }2155 }
2171}2156}
...@@ -2184,9 +2169,7 @@ pub const LinkError = UnexpectedError || error{...@@ -2184,9 +2169,7 @@ pub const LinkError = UnexpectedError || error{
2184 NoSpaceLeft,2169 NoSpaceLeft,
2185 ReadOnlyFileSystem,2170 ReadOnlyFileSystem,
2186 NotSameFileSystem,2171 NotSameFileSystem,
21872172 BadPathName,
2188 /// WASI-only; file paths must be valid UTF-8.
2189 InvalidUtf8,
2190};2173};
21912174
2192/// On WASI, both paths should be encoded as valid UTF-8.2175/// On WASI, both paths should be encoded as valid UTF-8.
...@@ -2212,10 +2195,7 @@ pub fn linkZ(oldpath: [*:0]const u8, newpath: [*:0]const u8) LinkError!void {...@@ -2212,10 +2195,7 @@ pub fn linkZ(oldpath: [*:0]const u8, newpath: [*:0]const u8) LinkError!void {
2212 .ROFS => return error.ReadOnlyFileSystem,2195 .ROFS => return error.ReadOnlyFileSystem,
2213 .XDEV => return error.NotSameFileSystem,2196 .XDEV => return error.NotSameFileSystem,
2214 .INVAL => unreachable,2197 .INVAL => unreachable,
2215 .ILSEQ => |err| if (native_os == .wasi)2198 .ILSEQ => return error.BadPathName,
2216 return error.InvalidUtf8
2217 else
2218 return unexpectedErrno(err),
2219 else => |err| return unexpectedErrno(err),2199 else => |err| return unexpectedErrno(err),
2220 }2200 }
2221}2201}
...@@ -2266,10 +2246,7 @@ pub fn linkatZ(...@@ -2266,10 +2246,7 @@ pub fn linkatZ(
2266 .ROFS => return error.ReadOnlyFileSystem,2246 .ROFS => return error.ReadOnlyFileSystem,
2267 .XDEV => return error.NotSameFileSystem,2247 .XDEV => return error.NotSameFileSystem,
2268 .INVAL => unreachable,2248 .INVAL => unreachable,
2269 .ILSEQ => |err| if (native_os == .wasi)2249 .ILSEQ => return error.BadPathName,
2270 return error.InvalidUtf8
2271 else
2272 return unexpectedErrno(err),
2273 else => |err| return unexpectedErrno(err),2250 else => |err| return unexpectedErrno(err),
2274 }2251 }
2275}2252}
...@@ -2315,7 +2292,7 @@ pub fn linkat(...@@ -2315,7 +2292,7 @@ pub fn linkat(
2315 .ROFS => return error.ReadOnlyFileSystem,2292 .ROFS => return error.ReadOnlyFileSystem,
2316 .XDEV => return error.NotSameFileSystem,2293 .XDEV => return error.NotSameFileSystem,
2317 .INVAL => unreachable,2294 .INVAL => unreachable,
2318 .ILSEQ => return error.InvalidUtf8,2295 .ILSEQ => return error.BadPathName,
2319 else => |err| return unexpectedErrno(err),2296 else => |err| return unexpectedErrno(err),
2320 }2297 }
2321 }2298 }
...@@ -2398,10 +2375,7 @@ pub fn unlinkZ(file_path: [*:0]const u8) UnlinkError!void {...@@ -2398,10 +2375,7 @@ pub fn unlinkZ(file_path: [*:0]const u8) UnlinkError!void {
2398 .NOTDIR => return error.NotDir,2375 .NOTDIR => return error.NotDir,
2399 .NOMEM => return error.SystemResources,2376 .NOMEM => return error.SystemResources,
2400 .ROFS => return error.ReadOnlyFileSystem,2377 .ROFS => return error.ReadOnlyFileSystem,
2401 .ILSEQ => |err| if (native_os == .wasi)2378 .ILSEQ => return error.BadPathName,
2402 return error.InvalidUtf8
2403 else
2404 return unexpectedErrno(err),
2405 else => |err| return unexpectedErrno(err),2379 else => |err| return unexpectedErrno(err),
2406 }2380 }
2407}2381}
...@@ -2460,7 +2434,7 @@ pub fn unlinkatWasi(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatErro...@@ -2460,7 +2434,7 @@ pub fn unlinkatWasi(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatErro
2460 .ROFS => return error.ReadOnlyFileSystem,2434 .ROFS => return error.ReadOnlyFileSystem,
2461 .NOTEMPTY => return error.DirNotEmpty,2435 .NOTEMPTY => return error.DirNotEmpty,
2462 .NOTCAPABLE => return error.AccessDenied,2436 .NOTCAPABLE => return error.AccessDenied,
2463 .ILSEQ => return error.InvalidUtf8,2437 .ILSEQ => return error.BadPathName,
24642438
2465 .INVAL => unreachable, // invalid flags, or pathname has . as last component2439 .INVAL => unreachable, // invalid flags, or pathname has . as last component
2466 .BADF => unreachable, // always a race condition2440 .BADF => unreachable, // always a race condition
...@@ -2493,10 +2467,7 @@ pub fn unlinkatZ(dirfd: fd_t, file_path_c: [*:0]const u8, flags: u32) UnlinkatEr...@@ -2493,10 +2467,7 @@ pub fn unlinkatZ(dirfd: fd_t, file_path_c: [*:0]const u8, flags: u32) UnlinkatEr
2493 .ROFS => return error.ReadOnlyFileSystem,2467 .ROFS => return error.ReadOnlyFileSystem,
2494 .EXIST => return error.DirNotEmpty,2468 .EXIST => return error.DirNotEmpty,
2495 .NOTEMPTY => return error.DirNotEmpty,2469 .NOTEMPTY => return error.DirNotEmpty,
2496 .ILSEQ => |err| if (native_os == .wasi)2470 .ILSEQ => return error.BadPathName,
2497 return error.InvalidUtf8
2498 else
2499 return unexpectedErrno(err),
25002471
2501 .INVAL => unreachable, // invalid flags, or pathname has . as last component2472 .INVAL => unreachable, // invalid flags, or pathname has . as last component
2502 .BADF => unreachable, // always a race condition2473 .BADF => unreachable, // always a race condition
...@@ -2598,10 +2569,7 @@ pub fn renameZ(old_path: [*:0]const u8, new_path: [*:0]const u8) RenameError!voi...@@ -2598,10 +2569,7 @@ pub fn renameZ(old_path: [*:0]const u8, new_path: [*:0]const u8) RenameError!voi
2598 .NOTEMPTY => return error.PathAlreadyExists,2569 .NOTEMPTY => return error.PathAlreadyExists,
2599 .ROFS => return error.ReadOnlyFileSystem,2570 .ROFS => return error.ReadOnlyFileSystem,
2600 .XDEV => return error.RenameAcrossMountPoints,2571 .XDEV => return error.RenameAcrossMountPoints,
2601 .ILSEQ => |err| if (native_os == .wasi)2572 .ILSEQ => return error.BadPathName,
2602 return error.InvalidUtf8
2603 else
2604 return unexpectedErrno(err),
2605 else => |err| return unexpectedErrno(err),2573 else => |err| return unexpectedErrno(err),
2606 }2574 }
2607}2575}
...@@ -2662,7 +2630,7 @@ fn renameatWasi(old: RelativePathWasi, new: RelativePathWasi) RenameError!void {...@@ -2662,7 +2630,7 @@ fn renameatWasi(old: RelativePathWasi, new: RelativePathWasi) RenameError!void {
2662 .ROFS => return error.ReadOnlyFileSystem,2630 .ROFS => return error.ReadOnlyFileSystem,
2663 .XDEV => return error.RenameAcrossMountPoints,2631 .XDEV => return error.RenameAcrossMountPoints,
2664 .NOTCAPABLE => return error.AccessDenied,2632 .NOTCAPABLE => return error.AccessDenied,
2665 .ILSEQ => return error.InvalidUtf8,2633 .ILSEQ => return error.BadPathName,
2666 else => |err| return unexpectedErrno(err),2634 else => |err| return unexpectedErrno(err),
2667 }2635 }
2668}2636}
...@@ -2713,10 +2681,7 @@ pub fn renameatZ(...@@ -2713,10 +2681,7 @@ pub fn renameatZ(
2713 .NOTEMPTY => return error.PathAlreadyExists,2681 .NOTEMPTY => return error.PathAlreadyExists,
2714 .ROFS => return error.ReadOnlyFileSystem,2682 .ROFS => return error.ReadOnlyFileSystem,
2715 .XDEV => return error.RenameAcrossMountPoints,2683 .XDEV => return error.RenameAcrossMountPoints,
2716 .ILSEQ => |err| if (native_os == .wasi)2684 .ILSEQ => return error.BadPathName,
2717 return error.InvalidUtf8
2718 else
2719 return unexpectedErrno(err),
2720 else => |err| return unexpectedErrno(err),2685 else => |err| return unexpectedErrno(err),
2721 }2686 }
2722}2687}
...@@ -2870,7 +2835,7 @@ pub fn mkdiratWasi(dir_fd: fd_t, sub_dir_path: []const u8, mode: mode_t) MakeDir...@@ -2870,7 +2835,7 @@ pub fn mkdiratWasi(dir_fd: fd_t, sub_dir_path: []const u8, mode: mode_t) MakeDir
2870 .NOTDIR => return error.NotDir,2835 .NOTDIR => return error.NotDir,
2871 .ROFS => return error.ReadOnlyFileSystem,2836 .ROFS => return error.ReadOnlyFileSystem,
2872 .NOTCAPABLE => return error.AccessDenied,2837 .NOTCAPABLE => return error.AccessDenied,
2873 .ILSEQ => return error.InvalidUtf8,2838 .ILSEQ => return error.BadPathName,
2874 else => |err| return unexpectedErrno(err),2839 else => |err| return unexpectedErrno(err),
2875 }2840 }
2876}2841}
...@@ -2901,10 +2866,7 @@ pub fn mkdiratZ(dir_fd: fd_t, sub_dir_path: [*:0]const u8, mode: mode_t) MakeDir...@@ -2901,10 +2866,7 @@ pub fn mkdiratZ(dir_fd: fd_t, sub_dir_path: [*:0]const u8, mode: mode_t) MakeDir
2901 .ROFS => return error.ReadOnlyFileSystem,2866 .ROFS => return error.ReadOnlyFileSystem,
2902 // dragonfly: when dir_fd is unlinked from filesystem2867 // dragonfly: when dir_fd is unlinked from filesystem
2903 .NOTCONN => return error.FileNotFound,2868 .NOTCONN => return error.FileNotFound,
2904 .ILSEQ => |err| if (native_os == .wasi)2869 .ILSEQ => return error.BadPathName,
2905 return error.InvalidUtf8
2906 else
2907 return unexpectedErrno(err),
2908 else => |err| return unexpectedErrno(err),2870 else => |err| return unexpectedErrno(err),
2909 }2871 }
2910}2872}
...@@ -2973,10 +2935,7 @@ pub fn mkdirZ(dir_path: [*:0]const u8, mode: mode_t) MakeDirError!void {...@@ -2973,10 +2935,7 @@ pub fn mkdirZ(dir_path: [*:0]const u8, mode: mode_t) MakeDirError!void {
2973 .NOSPC => return error.NoSpaceLeft,2935 .NOSPC => return error.NoSpaceLeft,
2974 .NOTDIR => return error.NotDir,2936 .NOTDIR => return error.NotDir,
2975 .ROFS => return error.ReadOnlyFileSystem,2937 .ROFS => return error.ReadOnlyFileSystem,
2976 .ILSEQ => |err| if (native_os == .wasi)2938 .ILSEQ => return error.BadPathName,
2977 return error.InvalidUtf8
2978 else
2979 return unexpectedErrno(err),
2980 else => |err| return unexpectedErrno(err),2939 else => |err| return unexpectedErrno(err),
2981 }2940 }
2982}2941}
...@@ -3067,10 +3026,7 @@ pub fn rmdirZ(dir_path: [*:0]const u8) DeleteDirError!void {...@@ -3067,10 +3026,7 @@ pub fn rmdirZ(dir_path: [*:0]const u8) DeleteDirError!void {
3067 .EXIST => return error.DirNotEmpty,3026 .EXIST => return error.DirNotEmpty,
3068 .NOTEMPTY => return error.DirNotEmpty,3027 .NOTEMPTY => return error.DirNotEmpty,
3069 .ROFS => return error.ReadOnlyFileSystem,3028 .ROFS => return error.ReadOnlyFileSystem,
3070 .ILSEQ => |err| if (native_os == .wasi)3029 .ILSEQ => return error.BadPathName,
3071 return error.InvalidUtf8
3072 else
3073 return unexpectedErrno(err),
3074 else => |err| return unexpectedErrno(err),3030 else => |err| return unexpectedErrno(err),
3075 }3031 }
3076}3032}
...@@ -3145,10 +3101,7 @@ pub fn chdirZ(dir_path: [*:0]const u8) ChangeCurDirError!void {...@@ -3145,10 +3101,7 @@ pub fn chdirZ(dir_path: [*:0]const u8) ChangeCurDirError!void {
3145 .NOENT => return error.FileNotFound,3101 .NOENT => return error.FileNotFound,
3146 .NOMEM => return error.SystemResources,3102 .NOMEM => return error.SystemResources,
3147 .NOTDIR => return error.NotDir,3103 .NOTDIR => return error.NotDir,
3148 .ILSEQ => |err| if (native_os == .wasi)3104 .ILSEQ => return error.BadPathName,
3149 return error.InvalidUtf8
3150 else
3151 return unexpectedErrno(err),
3152 else => |err| return unexpectedErrno(err),3105 else => |err| return unexpectedErrno(err),
3153 }3106 }
3154}3107}
...@@ -3254,10 +3207,7 @@ pub fn readlinkZ(file_path: [*:0]const u8, out_buffer: []u8) ReadLinkError![]u8...@@ -3254,10 +3207,7 @@ pub fn readlinkZ(file_path: [*:0]const u8, out_buffer: []u8) ReadLinkError![]u8
3254 .NOENT => return error.FileNotFound,3207 .NOENT => return error.FileNotFound,
3255 .NOMEM => return error.SystemResources,3208 .NOMEM => return error.SystemResources,
3256 .NOTDIR => return error.NotDir,3209 .NOTDIR => return error.NotDir,
3257 .ILSEQ => |err| if (native_os == .wasi)3210 .ILSEQ => return error.BadPathName,
3258 return error.InvalidUtf8
3259 else
3260 return unexpectedErrno(err),
3261 else => |err| return unexpectedErrno(err),3211 else => |err| return unexpectedErrno(err),
3262 }3212 }
3263}3213}
...@@ -3299,7 +3249,7 @@ pub fn readlinkatWasi(dirfd: fd_t, file_path: []const u8, out_buffer: []u8) Read...@@ -3299,7 +3249,7 @@ pub fn readlinkatWasi(dirfd: fd_t, file_path: []const u8, out_buffer: []u8) Read
3299 .NOMEM => return error.SystemResources,3249 .NOMEM => return error.SystemResources,
3300 .NOTDIR => return error.NotDir,3250 .NOTDIR => return error.NotDir,
3301 .NOTCAPABLE => return error.AccessDenied,3251 .NOTCAPABLE => return error.AccessDenied,
3302 .ILSEQ => return error.InvalidUtf8,3252 .ILSEQ => return error.BadPathName,
3303 else => |err| return unexpectedErrno(err),3253 else => |err| return unexpectedErrno(err),
3304 }3254 }
3305}3255}
...@@ -3332,10 +3282,7 @@ pub fn readlinkatZ(dirfd: fd_t, file_path: [*:0]const u8, out_buffer: []u8) Read...@@ -3332,10 +3282,7 @@ pub fn readlinkatZ(dirfd: fd_t, file_path: [*:0]const u8, out_buffer: []u8) Read
3332 .NOENT => return error.FileNotFound,3282 .NOENT => return error.FileNotFound,
3333 .NOMEM => return error.SystemResources,3283 .NOMEM => return error.SystemResources,
3334 .NOTDIR => return error.NotDir,3284 .NOTDIR => return error.NotDir,
3335 .ILSEQ => |err| if (native_os == .wasi)3285 .ILSEQ => return error.BadPathName,
3336 return error.InvalidUtf8
3337 else
3338 return unexpectedErrno(err),
3339 else => |err| return unexpectedErrno(err),3286 else => |err| return unexpectedErrno(err),
3340 }3287 }
3341}3288}
...@@ -4421,13 +4368,10 @@ pub const FStatAtError = FStatError || error{...@@ -4421,13 +4368,10 @@ pub const FStatAtError = FStatError || error{
4421/// which is relative to `dirfd` handle.4368/// which is relative to `dirfd` handle.
4422/// On WASI, `pathname` should be encoded as valid UTF-8.4369/// On WASI, `pathname` should be encoded as valid UTF-8.
4423/// On other platforms, `pathname` is an opaque sequence of bytes with no particular encoding.4370/// On other platforms, `pathname` is an opaque sequence of bytes with no particular encoding.
4424/// See also `fstatatZ` and `std.os.fstatat_wasi`.4371/// See also `fstatatZ`.
4425pub fn fstatat(dirfd: fd_t, pathname: []const u8, flags: u32) FStatAtError!Stat {4372pub fn fstatat(dirfd: fd_t, pathname: []const u8, flags: u32) FStatAtError!Stat {
4426 if (native_os == .wasi and !builtin.link_libc) {4373 if (native_os == .wasi and !builtin.link_libc) {
4427 const filestat = try std.os.fstatat_wasi(dirfd, pathname, .{4374 @compileError("use std.Io instead");
4428 .SYMLINK_FOLLOW = (flags & AT.SYMLINK_NOFOLLOW) == 0,
4429 });
4430 return Stat.fromFilestat(filestat);
4431 } else if (native_os == .windows) {4375 } else if (native_os == .windows) {
4432 @compileError("fstatat is not yet implemented on Windows");4376 @compileError("fstatat is not yet implemented on Windows");
4433 } else {4377 } else {
...@@ -4440,10 +4384,7 @@ pub fn fstatat(dirfd: fd_t, pathname: []const u8, flags: u32) FStatAtError!Stat...@@ -4440,10 +4384,7 @@ pub fn fstatat(dirfd: fd_t, pathname: []const u8, flags: u32) FStatAtError!Stat
4440/// See also `fstatat`.4384/// See also `fstatat`.
4441pub fn fstatatZ(dirfd: fd_t, pathname: [*:0]const u8, flags: u32) FStatAtError!Stat {4385pub fn fstatatZ(dirfd: fd_t, pathname: [*:0]const u8, flags: u32) FStatAtError!Stat {
4442 if (native_os == .wasi and !builtin.link_libc) {4386 if (native_os == .wasi and !builtin.link_libc) {
4443 const filestat = try std.os.fstatat_wasi(dirfd, mem.sliceTo(pathname, 0), .{4387 @compileError("use std.Io instead");
4444 .SYMLINK_FOLLOW = (flags & AT.SYMLINK_NOFOLLOW) == 0,
4445 });
4446 return Stat.fromFilestat(filestat);
4447 }4388 }
44484389
4449 const fstatat_sym = if (lfs64_abi) system.fstatat64 else system.fstatat;4390 const fstatat_sym = if (lfs64_abi) system.fstatat64 else system.fstatat;
...@@ -4460,10 +4401,7 @@ pub fn fstatatZ(dirfd: fd_t, pathname: [*:0]const u8, flags: u32) FStatAtError!S...@@ -4460,10 +4401,7 @@ pub fn fstatatZ(dirfd: fd_t, pathname: [*:0]const u8, flags: u32) FStatAtError!S
4460 .LOOP => return error.SymLinkLoop,4401 .LOOP => return error.SymLinkLoop,
4461 .NOENT => return error.FileNotFound,4402 .NOENT => return error.FileNotFound,
4462 .NOTDIR => return error.FileNotFound,4403 .NOTDIR => return error.FileNotFound,
4463 .ILSEQ => |err| if (native_os == .wasi)4404 .ILSEQ => return error.BadPathName,
4464 return error.InvalidUtf8
4465 else
4466 return unexpectedErrno(err),
4467 else => |err| return unexpectedErrno(err),4405 else => |err| return unexpectedErrno(err),
4468 }4406 }
4469}4407}
...@@ -4991,10 +4929,7 @@ pub fn accessZ(path: [*:0]const u8, mode: u32) AccessError!void {...@@ -4991,10 +4929,7 @@ pub fn accessZ(path: [*:0]const u8, mode: u32) AccessError!void {
4991 .FAULT => unreachable,4929 .FAULT => unreachable,
4992 .IO => return error.InputOutput,4930 .IO => return error.InputOutput,
4993 .NOMEM => return error.SystemResources,4931 .NOMEM => return error.SystemResources,
4994 .ILSEQ => |err| if (native_os == .wasi)4932 .ILSEQ => return error.BadPathName,
4995 return error.InvalidUtf8
4996 else
4997 return unexpectedErrno(err),
4998 else => |err| return unexpectedErrno(err),4933 else => |err| return unexpectedErrno(err),
4999 }4934 }
5000}4935}
...@@ -5072,10 +5007,7 @@ pub fn faccessatZ(dirfd: fd_t, path: [*:0]const u8, mode: u32, flags: u32) Acces...@@ -5072,10 +5007,7 @@ pub fn faccessatZ(dirfd: fd_t, path: [*:0]const u8, mode: u32, flags: u32) Acces
5072 .FAULT => unreachable,5007 .FAULT => unreachable,
5073 .IO => return error.InputOutput,5008 .IO => return error.InputOutput,
5074 .NOMEM => return error.SystemResources,5009 .NOMEM => return error.SystemResources,
5075 .ILSEQ => |err| if (native_os == .wasi)5010 .ILSEQ => return error.BadPathName,
5076 return error.InvalidUtf8
5077 else
5078 return unexpectedErrno(err),
5079 else => |err| return unexpectedErrno(err),5011 else => |err| return unexpectedErrno(err),
5080 }5012 }
5081}5013}
lib/std/posix/test.zig-43
...@@ -226,49 +226,6 @@ test "linkat with different directories" {...@@ -226,49 +226,6 @@ test "linkat with different directories" {
226 }226 }
227}227}
228228
229test "fstatat" {
230 if ((builtin.cpu.arch == .riscv32 or builtin.cpu.arch.isLoongArch()) and builtin.os.tag == .linux and !builtin.link_libc) return error.SkipZigTest; // No `fstatat()`.
231 // enable when `fstat` and `fstatat` are implemented on Windows
232 if (native_os == .windows) return error.SkipZigTest;
233
234 var tmp = tmpDir(.{});
235 defer tmp.cleanup();
236
237 // create dummy file
238 const contents = "nonsense";
239 try tmp.dir.writeFile(.{ .sub_path = "file.txt", .data = contents });
240
241 // fetch file's info on the opened fd directly
242 const file = try tmp.dir.openFile("file.txt", .{});
243 const stat = try posix.fstat(file.handle);
244 defer file.close();
245
246 // now repeat but using `fstatat` instead
247 const statat = try posix.fstatat(tmp.dir.fd, "file.txt", posix.AT.SYMLINK_NOFOLLOW);
248
249 try expectEqual(stat.dev, statat.dev);
250 try expectEqual(stat.ino, statat.ino);
251 try expectEqual(stat.nlink, statat.nlink);
252 try expectEqual(stat.mode, statat.mode);
253 try expectEqual(stat.uid, statat.uid);
254 try expectEqual(stat.gid, statat.gid);
255 try expectEqual(stat.rdev, statat.rdev);
256 try expectEqual(stat.size, statat.size);
257 try expectEqual(stat.blksize, statat.blksize);
258
259 // The stat.blocks/statat.blocks count is managed by the filesystem and may
260 // change if the file is stored in a journal or "inline".
261 // try expectEqual(stat.blocks, statat.blocks);
262
263 // s390x-linux does not have nanosecond precision for fstat(), but it does for
264 // fstatat(). As a result, comparing the timestamps isn't worth the effort
265 if (!(builtin.cpu.arch == .s390x and builtin.os.tag == .linux)) {
266 try expectEqual(stat.atime(), statat.atime());
267 try expectEqual(stat.mtime(), statat.mtime());
268 try expectEqual(stat.ctime(), statat.ctime());
269 }
270}
271
272test "readlinkat" {229test "readlinkat" {
273 var tmp = tmpDir(.{});230 var tmp = tmpDir(.{});
274 defer tmp.cleanup();231 defer tmp.cleanup();
test/src/convert-stack-trace.zig+7-1
...@@ -32,6 +32,12 @@ pub fn main() !void {...@@ -32,6 +32,12 @@ pub fn main() !void {
32 const args = try std.process.argsAlloc(arena);32 const args = try std.process.argsAlloc(arena);
33 if (args.len != 2) std.process.fatal("usage: convert-stack-trace path/to/test/output", .{});33 if (args.len != 2) std.process.fatal("usage: convert-stack-trace path/to/test/output", .{});
3434
35 const gpa = arena;
36
37 var threaded: std.Io.Threaded = .init(gpa);
38 defer threaded.deinit();
39 const io = threaded.io();
40
35 var read_buf: [1024]u8 = undefined;41 var read_buf: [1024]u8 = undefined;
36 var write_buf: [1024]u8 = undefined;42 var write_buf: [1024]u8 = undefined;
3743
...@@ -40,7 +46,7 @@ pub fn main() !void {...@@ -40,7 +46,7 @@ pub fn main() !void {
4046
41 const out_file: std.fs.File = .stdout();47 const out_file: std.fs.File = .stdout();
4248
43 var in_fr = in_file.reader(&read_buf);49 var in_fr = in_file.reader(io, &read_buf);
44 var out_fw = out_file.writer(&write_buf);50 var out_fw = out_file.writer(&write_buf);
4551
46 const w = &out_fw.interface;52 const w = &out_fw.interface;
tools/docgen.zig+7-1
...@@ -36,6 +36,12 @@ pub fn main() !void {...@@ -36,6 +36,12 @@ pub fn main() !void {
36 var args_it = try process.argsWithAllocator(arena);36 var args_it = try process.argsWithAllocator(arena);
37 if (!args_it.skip()) @panic("expected self arg");37 if (!args_it.skip()) @panic("expected self arg");
3838
39 const gpa = arena;
40
41 var threaded: std.Io.Threaded = .init(gpa);
42 defer threaded.deinit();
43 const io = threaded.io();
44
39 var opt_code_dir: ?[]const u8 = null;45 var opt_code_dir: ?[]const u8 = null;
40 var opt_input: ?[]const u8 = null;46 var opt_input: ?[]const u8 = null;
41 var opt_output: ?[]const u8 = null;47 var opt_output: ?[]const u8 = null;
...@@ -77,7 +83,7 @@ pub fn main() !void {...@@ -77,7 +83,7 @@ pub fn main() !void {
77 var code_dir = try fs.cwd().openDir(code_dir_path, .{});83 var code_dir = try fs.cwd().openDir(code_dir_path, .{});
78 defer code_dir.close();84 defer code_dir.close();
7985
80 var in_file_reader = in_file.reader(&.{});86 var in_file_reader = in_file.reader(io, &.{});
81 const input_file_bytes = try in_file_reader.interface.allocRemaining(arena, .limited(max_doc_file_size));87 const input_file_bytes = try in_file_reader.interface.allocRemaining(arena, .limited(max_doc_file_size));
8288
83 var tokenizer = Tokenizer.init(input_path, input_file_bytes);89 var tokenizer = Tokenizer.init(input_path, input_file_bytes);
tools/doctest.zig+26-18
...@@ -1,5 +1,8 @@...@@ -1,5 +1,8 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
2
2const std = @import("std");3const std = @import("std");
4const Io = std.Io;
5const Writer = std.Io.Writer;
3const fatal = std.process.fatal;6const fatal = std.process.fatal;
4const mem = std.mem;7const mem = std.mem;
5const fs = std.fs;8const fs = std.fs;
...@@ -7,7 +10,6 @@ const process = std.process;...@@ -7,7 +10,6 @@ const process = std.process;
7const Allocator = std.mem.Allocator;10const Allocator = std.mem.Allocator;
8const testing = std.testing;11const testing = std.testing;
9const getExternalExecutor = std.zig.system.getExternalExecutor;12const getExternalExecutor = std.zig.system.getExternalExecutor;
10const Writer = std.Io.Writer;
1113
12const max_doc_file_size = 10 * 1024 * 1024;14const max_doc_file_size = 10 * 1024 * 1024;
1315
...@@ -36,6 +38,12 @@ pub fn main() !void {...@@ -36,6 +38,12 @@ pub fn main() !void {
36 var args_it = try process.argsWithAllocator(arena);38 var args_it = try process.argsWithAllocator(arena);
37 if (!args_it.skip()) fatal("missing argv[0]", .{});39 if (!args_it.skip()) fatal("missing argv[0]", .{});
3840
41 const gpa = arena;
42
43 var threaded: std.Io.Threaded = .init(gpa);
44 defer threaded.deinit();
45 const io = threaded.io();
46
39 var opt_input: ?[]const u8 = null;47 var opt_input: ?[]const u8 = null;
40 var opt_output: ?[]const u8 = null;48 var opt_output: ?[]const u8 = null;
41 var opt_zig: ?[]const u8 = null;49 var opt_zig: ?[]const u8 = null;
...@@ -93,6 +101,7 @@ pub fn main() !void {...@@ -93,6 +101,7 @@ pub fn main() !void {
93 try printSourceBlock(arena, out, source, fs.path.basename(input_path));101 try printSourceBlock(arena, out, source, fs.path.basename(input_path));
94 try printOutput(102 try printOutput(
95 arena,103 arena,
104 io,
96 out,105 out,
97 code,106 code,
98 tmp_dir_path,107 tmp_dir_path,
...@@ -109,6 +118,7 @@ pub fn main() !void {...@@ -109,6 +118,7 @@ pub fn main() !void {
109118
110fn printOutput(119fn printOutput(
111 arena: Allocator,120 arena: Allocator,
121 io: Io,
112 out: *Writer,122 out: *Writer,
113 code: Code,123 code: Code,
114 /// Relative to this process' cwd.124 /// Relative to this process' cwd.
...@@ -123,11 +133,11 @@ fn printOutput(...@@ -123,11 +133,11 @@ fn printOutput(
123 var env_map = try process.getEnvMap(arena);133 var env_map = try process.getEnvMap(arena);
124 try env_map.put("CLICOLOR_FORCE", "1");134 try env_map.put("CLICOLOR_FORCE", "1");
125135
126 const host = try std.zig.system.resolveTargetQuery(.{});136 const host = try std.zig.system.resolveTargetQuery(io, .{});
127 const obj_ext = builtin.object_format.fileExt(builtin.cpu.arch);137 const obj_ext = builtin.object_format.fileExt(builtin.cpu.arch);
128 const print = std.debug.print;138 const print = std.debug.print;
129139
130 var shell_buffer: std.Io.Writer.Allocating = .init(arena);140 var shell_buffer: Writer.Allocating = .init(arena);
131 defer shell_buffer.deinit();141 defer shell_buffer.deinit();
132 const shell_out = &shell_buffer.writer;142 const shell_out = &shell_buffer.writer;
133143
...@@ -238,7 +248,7 @@ fn printOutput(...@@ -238,7 +248,7 @@ fn printOutput(
238 const target_query = try std.Target.Query.parse(.{248 const target_query = try std.Target.Query.parse(.{
239 .arch_os_abi = code.target_str orelse "native",249 .arch_os_abi = code.target_str orelse "native",
240 });250 });
241 const target = try std.zig.system.resolveTargetQuery(target_query);251 const target = try std.zig.system.resolveTargetQuery(io, target_query);
242252
243 const path_to_exe = try std.fmt.allocPrint(arena, "./{s}{s}", .{253 const path_to_exe = try std.fmt.allocPrint(arena, "./{s}{s}", .{
244 code_name, target.exeFileExt(),254 code_name, target.exeFileExt(),
...@@ -316,9 +326,7 @@ fn printOutput(...@@ -316,9 +326,7 @@ fn printOutput(
316 const target_query = try std.Target.Query.parse(.{326 const target_query = try std.Target.Query.parse(.{
317 .arch_os_abi = triple,327 .arch_os_abi = triple,
318 });328 });
319 const target = try std.zig.system.resolveTargetQuery(329 const target = try std.zig.system.resolveTargetQuery(io, target_query);
320 target_query,
321 );
322 switch (getExternalExecutor(&host, &target, .{330 switch (getExternalExecutor(&host, &target, .{
323 .link_libc = code.link_libc,331 .link_libc = code.link_libc,
324 })) {332 })) {
...@@ -1397,7 +1405,7 @@ test "printShell" {...@@ -1397,7 +1405,7 @@ test "printShell" {
1397 \\</samp></pre></figure>1405 \\</samp></pre></figure>
1398 ;1406 ;
13991407
1400 var buffer: std.Io.Writer.Allocating = .init(test_allocator);1408 var buffer: Writer.Allocating = .init(test_allocator);
1401 defer buffer.deinit();1409 defer buffer.deinit();
14021410
1403 try printShell(&buffer.writer, shell_out, false);1411 try printShell(&buffer.writer, shell_out, false);
...@@ -1414,7 +1422,7 @@ test "printShell" {...@@ -1414,7 +1422,7 @@ test "printShell" {
1414 \\</samp></pre></figure>1422 \\</samp></pre></figure>
1415 ;1423 ;
14161424
1417 var buffer: std.Io.Writer.Allocating = .init(test_allocator);1425 var buffer: Writer.Allocating = .init(test_allocator);
1418 defer buffer.deinit();1426 defer buffer.deinit();
14191427
1420 try printShell(&buffer.writer, shell_out, false);1428 try printShell(&buffer.writer, shell_out, false);
...@@ -1428,7 +1436,7 @@ test "printShell" {...@@ -1428,7 +1436,7 @@ test "printShell" {
1428 \\</samp></pre></figure>1436 \\</samp></pre></figure>
1429 ;1437 ;
14301438
1431 var buffer: std.Io.Writer.Allocating = .init(test_allocator);1439 var buffer: Writer.Allocating = .init(test_allocator);
1432 defer buffer.deinit();1440 defer buffer.deinit();
14331441
1434 try printShell(&buffer.writer, shell_out, false);1442 try printShell(&buffer.writer, shell_out, false);
...@@ -1447,7 +1455,7 @@ test "printShell" {...@@ -1447,7 +1455,7 @@ test "printShell" {
1447 \\</samp></pre></figure>1455 \\</samp></pre></figure>
1448 ;1456 ;
14491457
1450 var buffer: std.Io.Writer.Allocating = .init(test_allocator);1458 var buffer: Writer.Allocating = .init(test_allocator);
1451 defer buffer.deinit();1459 defer buffer.deinit();
14521460
1453 try printShell(&buffer.writer, shell_out, false);1461 try printShell(&buffer.writer, shell_out, false);
...@@ -1468,7 +1476,7 @@ test "printShell" {...@@ -1468,7 +1476,7 @@ test "printShell" {
1468 \\</samp></pre></figure>1476 \\</samp></pre></figure>
1469 ;1477 ;
14701478
1471 var buffer: std.Io.Writer.Allocating = .init(test_allocator);1479 var buffer: Writer.Allocating = .init(test_allocator);
1472 defer buffer.deinit();1480 defer buffer.deinit();
14731481
1474 try printShell(&buffer.writer, shell_out, false);1482 try printShell(&buffer.writer, shell_out, false);
...@@ -1487,7 +1495,7 @@ test "printShell" {...@@ -1487,7 +1495,7 @@ test "printShell" {
1487 \\</samp></pre></figure>1495 \\</samp></pre></figure>
1488 ;1496 ;
14891497
1490 var buffer: std.Io.Writer.Allocating = .init(test_allocator);1498 var buffer: Writer.Allocating = .init(test_allocator);
1491 defer buffer.deinit();1499 defer buffer.deinit();
14921500
1493 try printShell(&buffer.writer, shell_out, false);1501 try printShell(&buffer.writer, shell_out, false);
...@@ -1510,7 +1518,7 @@ test "printShell" {...@@ -1510,7 +1518,7 @@ test "printShell" {
1510 \\</samp></pre></figure>1518 \\</samp></pre></figure>
1511 ;1519 ;
15121520
1513 var buffer: std.Io.Writer.Allocating = .init(test_allocator);1521 var buffer: Writer.Allocating = .init(test_allocator);
1514 defer buffer.deinit();1522 defer buffer.deinit();
15151523
1516 try printShell(&buffer.writer, shell_out, false);1524 try printShell(&buffer.writer, shell_out, false);
...@@ -1532,7 +1540,7 @@ test "printShell" {...@@ -1532,7 +1540,7 @@ test "printShell" {
1532 \\</samp></pre></figure>1540 \\</samp></pre></figure>
1533 ;1541 ;
15341542
1535 var buffer: std.Io.Writer.Allocating = .init(test_allocator);1543 var buffer: Writer.Allocating = .init(test_allocator);
1536 defer buffer.deinit();1544 defer buffer.deinit();
15371545
1538 try printShell(&buffer.writer, shell_out, false);1546 try printShell(&buffer.writer, shell_out, false);
...@@ -1549,7 +1557,7 @@ test "printShell" {...@@ -1549,7 +1557,7 @@ test "printShell" {
1549 \\</samp></pre></figure>1557 \\</samp></pre></figure>
1550 ;1558 ;
15511559
1552 var buffer: std.Io.Writer.Allocating = .init(test_allocator);1560 var buffer: Writer.Allocating = .init(test_allocator);
1553 defer buffer.deinit();1561 defer buffer.deinit();
15541562
1555 try printShell(&buffer.writer, shell_out, false);1563 try printShell(&buffer.writer, shell_out, false);
...@@ -1568,7 +1576,7 @@ test "printShell" {...@@ -1568,7 +1576,7 @@ test "printShell" {
1568 \\</samp></pre></figure>1576 \\</samp></pre></figure>
1569 ;1577 ;
15701578
1571 var buffer: std.Io.Writer.Allocating = .init(test_allocator);1579 var buffer: Writer.Allocating = .init(test_allocator);
1572 defer buffer.deinit();1580 defer buffer.deinit();
15731581
1574 try printShell(&buffer.writer, shell_out, false);1582 try printShell(&buffer.writer, shell_out, false);
...@@ -1583,7 +1591,7 @@ test "printShell" {...@@ -1583,7 +1591,7 @@ test "printShell" {
1583 \\</samp></pre></figure>1591 \\</samp></pre></figure>
1584 ;1592 ;
15851593
1586 var buffer: std.Io.Writer.Allocating = .init(test_allocator);1594 var buffer: Writer.Allocating = .init(test_allocator);
1587 defer buffer.deinit();1595 defer buffer.deinit();
15881596
1589 try printShell(&buffer.writer, shell_out, false);1597 try printShell(&buffer.writer, shell_out, false);