| author | |
| committer | |
| log | 81e7e9fdbbb822c413649479dd572ffcd244543a |
| tree | bb0b3a9262df12afd28a46fd7326dffe0b2d452b |
| parent | da6b959f647f62aeaf96f380ad2828c16142f23f |
5 files changed, 129 insertions(+), 82 deletions(-)
lib/std/Io.zig+1| ... | @@ -666,6 +666,7 @@ pub const VTable = struct { | ... | @@ -666,6 +666,7 @@ pub const VTable = struct { |
| 666 | dirAccess: *const fn (?*anyopaque, Dir, sub_path: []const u8, Dir.AccessOptions) Dir.AccessError!void, | 666 | dirAccess: *const fn (?*anyopaque, Dir, sub_path: []const u8, Dir.AccessOptions) Dir.AccessError!void, |
| 667 | dirCreateFile: *const fn (?*anyopaque, Dir, sub_path: []const u8, File.CreateFlags) File.OpenError!File, | 667 | dirCreateFile: *const fn (?*anyopaque, Dir, sub_path: []const u8, File.CreateFlags) File.OpenError!File, |
| 668 | dirOpenFile: *const fn (?*anyopaque, Dir, sub_path: []const u8, File.OpenFlags) File.OpenError!File, | 668 | dirOpenFile: *const fn (?*anyopaque, Dir, sub_path: []const u8, File.OpenFlags) File.OpenError!File, |
| 669 | dirOpenDir: *const fn (?*anyopaque, Dir, sub_path: []const u8, Dir.OpenOptions) Dir.OpenError!Dir, | ||
| 669 | fileStat: *const fn (?*anyopaque, File) File.StatError!File.Stat, | 670 | fileStat: *const fn (?*anyopaque, File) File.StatError!File.Stat, |
| 670 | fileClose: *const fn (?*anyopaque, File) void, | 671 | fileClose: *const fn (?*anyopaque, File) void, |
| 671 | fileWriteStreaming: *const fn (?*anyopaque, File, buffer: [][]const u8) File.WriteStreamingError!usize, | 672 | fileWriteStreaming: *const fn (?*anyopaque, File, buffer: [][]const u8) File.WriteStreamingError!usize, |
lib/std/Io/Dir.zig+24| ... | @@ -69,6 +69,30 @@ pub const OpenError = error{ | ... | @@ -69,6 +69,30 @@ pub const OpenError = error{ |
| 69 | NetworkNotFound, | 69 | NetworkNotFound, |
| 70 | } || PathNameError || Io.Cancelable || Io.UnexpectedError; | 70 | } || PathNameError || Io.Cancelable || Io.UnexpectedError; |
| 71 | 71 | ||
| 72 | pub const OpenOptions = struct { | ||
| 73 | /// `true` means the opened directory can be used as the `Dir` parameter | ||
| 74 | /// for functions which operate based on an open directory handle. When `false`, | ||
| 75 | /// such operations are Illegal Behavior. | ||
| 76 | access_sub_paths: bool = true, | ||
| 77 | /// `true` means the opened directory can be scanned for the files and sub-directories | ||
| 78 | /// of the result. It means the `iterate` function can be called. | ||
| 79 | iterate: bool = false, | ||
| 80 | /// `false` means it won't dereference the symlinks. | ||
| 81 | follow_symlinks: bool = true, | ||
| 82 | }; | ||
| 83 | |||
| 84 | /// Opens a directory at the given path. The directory is a system resource that remains | ||
| 85 | /// open until `close` is called on the result. | ||
| 86 | /// | ||
| 87 | /// The directory cannot be iterated unless the `iterate` option is set to `true`. | ||
| 88 | /// | ||
| 89 | /// On Windows, `sub_path` should be encoded as [WTF-8](https://wtf-8.codeberg.page/). | ||
| 90 | /// On WASI, `sub_path` should be encoded as valid UTF-8. | ||
| 91 | /// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding. | ||
| 92 | pub fn openDir(dir: Dir, io: Io, sub_path: []const u8, options: OpenOptions) OpenError!Dir { | ||
| 93 | return io.vtable.dirOpenDir(io.userdata, dir, sub_path, options); | ||
| 94 | } | ||
| 95 | |||
| 72 | pub fn openFile(dir: Dir, io: Io, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File { | 96 | pub fn openFile(dir: Dir, io: Io, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File { |
| 73 | return io.vtable.dirOpenFile(io.userdata, dir, sub_path, flags); | 97 | return io.vtable.dirOpenFile(io.userdata, dir, sub_path, flags); |
| 74 | } | 98 | } |
lib/std/Io/Threaded.zig+86-1| ... | @@ -198,6 +198,11 @@ pub fn io(t: *Threaded) Io { | ... | @@ -198,6 +198,11 @@ pub fn io(t: *Threaded) Io { |
| 198 | .wasi => dirOpenFileWasi, | 198 | .wasi => dirOpenFileWasi, |
| 199 | else => dirOpenFilePosix, | 199 | else => dirOpenFilePosix, |
| 200 | }, | 200 | }, |
| 201 | .dirOpenDir = switch (builtin.os.tag) { | ||
| 202 | .windows => @panic("TODO"), | ||
| 203 | .wasi => dirOpenDirWasi, | ||
| 204 | else => dirOpenDirPosix, | ||
| 205 | }, | ||
| 201 | .fileClose = fileClose, | 206 | .fileClose = fileClose, |
| 202 | .fileWriteStreaming = fileWriteStreaming, | 207 | .fileWriteStreaming = fileWriteStreaming, |
| 203 | .fileWritePositional = fileWritePositional, | 208 | .fileWritePositional = fileWritePositional, |
| ... | @@ -1429,7 +1434,6 @@ fn dirCreateFileWasi( | ... | @@ -1429,7 +1434,6 @@ fn dirCreateFileWasi( |
| 1429 | .CANCELED => return error.Canceled, | 1434 | .CANCELED => return error.Canceled, |
| 1430 | 1435 | ||
| 1431 | .FAULT => |err| return errnoBug(err), | 1436 | .FAULT => |err| return errnoBug(err), |
| 1432 | // Provides INVAL with a linux host on a bad path name, but NOENT on Windows | ||
| 1433 | .INVAL => return error.BadPathName, | 1437 | .INVAL => return error.BadPathName, |
| 1434 | .BADF => |err| return errnoBug(err), // File descriptor used after closed. | 1438 | .BADF => |err| return errnoBug(err), // File descriptor used after closed. |
| 1435 | .ACCES => return error.AccessDenied, | 1439 | .ACCES => return error.AccessDenied, |
| ... | @@ -1656,6 +1660,87 @@ fn dirOpenFileWasi( | ... | @@ -1656,6 +1660,87 @@ fn dirOpenFileWasi( |
| 1656 | } | 1660 | } |
| 1657 | } | 1661 | } |
| 1658 | 1662 | ||
| 1663 | fn dirOpenDirPosix( | ||
| 1664 | userdata: ?*anyopaque, | ||
| 1665 | dir: Io.Dir, | ||
| 1666 | sub_path: []const u8, | ||
| 1667 | options: Io.Dir.OpenOptions, | ||
| 1668 | ) Io.Dir.OpenError!Io.Dir { | ||
| 1669 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | ||
| 1670 | |||
| 1671 | _ = t; | ||
| 1672 | _ = dir; | ||
| 1673 | _ = sub_path; | ||
| 1674 | _ = options; | ||
| 1675 | @panic("TODO"); | ||
| 1676 | } | ||
| 1677 | |||
| 1678 | fn dirOpenDirWasi( | ||
| 1679 | userdata: ?*anyopaque, | ||
| 1680 | dir: Io.Dir, | ||
| 1681 | sub_path: []const u8, | ||
| 1682 | options: Io.Dir.OpenOptions, | ||
| 1683 | ) Io.Dir.OpenError!Io.Dir { | ||
| 1684 | if (builtin.link_libc) return dirOpenDirPosix(userdata, dir, sub_path, options); | ||
| 1685 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | ||
| 1686 | const wasi = std.os.wasi; | ||
| 1687 | |||
| 1688 | var base: std.os.wasi.rights_t = .{ | ||
| 1689 | .FD_FILESTAT_GET = true, | ||
| 1690 | .FD_FDSTAT_SET_FLAGS = true, | ||
| 1691 | .FD_FILESTAT_SET_TIMES = true, | ||
| 1692 | }; | ||
| 1693 | if (options.access_sub_paths) { | ||
| 1694 | base.FD_READDIR = true; | ||
| 1695 | base.PATH_CREATE_DIRECTORY = true; | ||
| 1696 | base.PATH_CREATE_FILE = true; | ||
| 1697 | base.PATH_LINK_SOURCE = true; | ||
| 1698 | base.PATH_LINK_TARGET = true; | ||
| 1699 | base.PATH_OPEN = true; | ||
| 1700 | base.PATH_READLINK = true; | ||
| 1701 | base.PATH_RENAME_SOURCE = true; | ||
| 1702 | base.PATH_RENAME_TARGET = true; | ||
| 1703 | base.PATH_FILESTAT_GET = true; | ||
| 1704 | base.PATH_FILESTAT_SET_SIZE = true; | ||
| 1705 | base.PATH_FILESTAT_SET_TIMES = true; | ||
| 1706 | base.PATH_SYMLINK = true; | ||
| 1707 | base.PATH_REMOVE_DIRECTORY = true; | ||
| 1708 | base.PATH_UNLINK_FILE = true; | ||
| 1709 | } | ||
| 1710 | |||
| 1711 | const lookup_flags: wasi.lookupflags_t = .{ .SYMLINK_FOLLOW = options.follow_symlinks }; | ||
| 1712 | const oflags: wasi.oflags_t = .{ .DIRECTORY = true }; | ||
| 1713 | const fdflags: wasi.fdflags_t = .{}; | ||
| 1714 | var fd: posix.fd_t = undefined; | ||
| 1715 | |||
| 1716 | while (true) { | ||
| 1717 | try t.checkCancel(); | ||
| 1718 | switch (wasi.path_open(dir.handle, lookup_flags, sub_path.ptr, sub_path.len, oflags, base, base, fdflags, &fd)) { | ||
| 1719 | .SUCCESS => return .{ .handle = fd }, | ||
| 1720 | .INTR => continue, | ||
| 1721 | .CANCELED => return error.Canceled, | ||
| 1722 | |||
| 1723 | .FAULT => |err| return errnoBug(err), | ||
| 1724 | .INVAL => return error.BadPathName, | ||
| 1725 | .BADF => |err| return errnoBug(err), // File descriptor used after closed. | ||
| 1726 | .ACCES => return error.AccessDenied, | ||
| 1727 | .LOOP => return error.SymLinkLoop, | ||
| 1728 | .MFILE => return error.ProcessFdQuotaExceeded, | ||
| 1729 | .NAMETOOLONG => return error.NameTooLong, | ||
| 1730 | .NFILE => return error.SystemFdQuotaExceeded, | ||
| 1731 | .NODEV => return error.NoDevice, | ||
| 1732 | .NOENT => return error.FileNotFound, | ||
| 1733 | .NOMEM => return error.SystemResources, | ||
| 1734 | .NOTDIR => return error.NotDir, | ||
| 1735 | .PERM => return error.PermissionDenied, | ||
| 1736 | .BUSY => return error.DeviceBusy, | ||
| 1737 | .NOTCAPABLE => return error.AccessDenied, | ||
| 1738 | .ILSEQ => return error.BadPathName, | ||
| 1739 | else => |err| return posix.unexpectedErrno(err), | ||
| 1740 | } | ||
| 1741 | } | ||
| 1742 | } | ||
| 1743 | |||
| 1659 | fn fileClose(userdata: ?*anyopaque, file: Io.File) void { | 1744 | fn fileClose(userdata: ?*anyopaque, file: Io.File) void { |
| 1660 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 1745 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 1661 | _ = t; | 1746 | _ = t; |
lib/std/fs/Dir.zig+13-76| ... | @@ -1235,28 +1235,10 @@ pub fn setAsCwd(self: Dir) !void { | ... | @@ -1235,28 +1235,10 @@ pub fn setAsCwd(self: Dir) !void { |
| 1235 | try posix.fchdir(self.fd); | 1235 | try posix.fchdir(self.fd); |
| 1236 | } | 1236 | } |
| 1237 | 1237 | ||
| 1238 | pub const OpenOptions = struct { | 1238 | /// Deprecated in favor of `Io.Dir.OpenOptions`. |
| 1239 | /// `true` means the opened directory can be used as the `Dir` parameter | 1239 | pub const OpenOptions = Io.Dir.OpenOptions; |
| 1240 | /// for functions which operate based on an open directory handle. When `false`, | ||
| 1241 | /// such operations are Illegal Behavior. | ||
| 1242 | access_sub_paths: bool = true, | ||
| 1243 | |||
| 1244 | /// `true` means the opened directory can be scanned for the files and sub-directories | ||
| 1245 | /// of the result. It means the `iterate` function can be called. | ||
| 1246 | iterate: bool = false, | ||
| 1247 | |||
| 1248 | /// `true` means it won't dereference the symlinks. | ||
| 1249 | no_follow: bool = false, | ||
| 1250 | }; | ||
| 1251 | 1240 | ||
| 1252 | /// Opens a directory at the given path. The directory is a system resource that remains | 1241 | /// Deprecated in favor of `Io.Dir.openDir`. |
| 1253 | /// open until `close` is called on the result. | ||
| 1254 | /// The directory cannot be iterated unless the `iterate` option is set to `true`. | ||
| 1255 | /// | ||
| 1256 | /// On Windows, `sub_path` should be encoded as [WTF-8](https://wtf-8.codeberg.page/). | ||
| 1257 | /// On WASI, `sub_path` should be encoded as valid UTF-8. | ||
| 1258 | /// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding. | ||
| 1259 | /// Asserts that the path parameter has no null bytes. | ||
| 1260 | pub fn openDir(self: Dir, sub_path: []const u8, args: OpenOptions) OpenError!Dir { | 1242 | pub fn openDir(self: Dir, sub_path: []const u8, args: OpenOptions) OpenError!Dir { |
| 1261 | switch (native_os) { | 1243 | switch (native_os) { |
| 1262 | .windows => { | 1244 | .windows => { |
| ... | @@ -1264,54 +1246,9 @@ pub fn openDir(self: Dir, sub_path: []const u8, args: OpenOptions) OpenError!Dir | ... | @@ -1264,54 +1246,9 @@ pub fn openDir(self: Dir, sub_path: []const u8, args: OpenOptions) OpenError!Dir |
| 1264 | return self.openDirW(sub_path_w.span().ptr, args); | 1246 | return self.openDirW(sub_path_w.span().ptr, args); |
| 1265 | }, | 1247 | }, |
| 1266 | .wasi => if (!builtin.link_libc) { | 1248 | .wasi => if (!builtin.link_libc) { |
| 1267 | var base: std.os.wasi.rights_t = .{ | 1249 | var threaded: Io.Threaded = .init_single_threaded; |
| 1268 | .FD_FILESTAT_GET = true, | 1250 | const io = threaded.io(); |
| 1269 | .FD_FDSTAT_SET_FLAGS = true, | 1251 | return .adaptFromNewApi(try Io.Dir.openDir(.{ .handle = self.fd }, io, sub_path, args)); |
| 1270 | .FD_FILESTAT_SET_TIMES = true, | ||
| 1271 | }; | ||
| 1272 | if (args.access_sub_paths) { | ||
| 1273 | base.FD_READDIR = true; | ||
| 1274 | base.PATH_CREATE_DIRECTORY = true; | ||
| 1275 | base.PATH_CREATE_FILE = true; | ||
| 1276 | base.PATH_LINK_SOURCE = true; | ||
| 1277 | base.PATH_LINK_TARGET = true; | ||
| 1278 | base.PATH_OPEN = true; | ||
| 1279 | base.PATH_READLINK = true; | ||
| 1280 | base.PATH_RENAME_SOURCE = true; | ||
| 1281 | base.PATH_RENAME_TARGET = true; | ||
| 1282 | base.PATH_FILESTAT_GET = true; | ||
| 1283 | base.PATH_FILESTAT_SET_SIZE = true; | ||
| 1284 | base.PATH_FILESTAT_SET_TIMES = true; | ||
| 1285 | base.PATH_SYMLINK = true; | ||
| 1286 | base.PATH_REMOVE_DIRECTORY = true; | ||
| 1287 | base.PATH_UNLINK_FILE = true; | ||
| 1288 | } | ||
| 1289 | |||
| 1290 | const result = posix.openatWasi( | ||
| 1291 | self.fd, | ||
| 1292 | sub_path, | ||
| 1293 | .{ .SYMLINK_FOLLOW = !args.no_follow }, | ||
| 1294 | .{ .DIRECTORY = true }, | ||
| 1295 | .{}, | ||
| 1296 | base, | ||
| 1297 | base, | ||
| 1298 | ); | ||
| 1299 | const fd = result catch |err| switch (err) { | ||
| 1300 | error.FileTooBig => unreachable, // can't happen for directories | ||
| 1301 | error.IsDir => unreachable, // we're setting DIRECTORY | ||
| 1302 | error.NoSpaceLeft => unreachable, // not setting CREAT | ||
| 1303 | error.PathAlreadyExists => unreachable, // not setting CREAT | ||
| 1304 | error.FileLocksNotSupported => unreachable, // locking folders is not supported | ||
| 1305 | error.WouldBlock => unreachable, // can't happen for directories | ||
| 1306 | error.FileBusy => unreachable, // can't happen for directories | ||
| 1307 | error.SharingViolation => unreachable, | ||
| 1308 | error.PipeBusy => unreachable, | ||
| 1309 | error.ProcessNotFound => unreachable, | ||
| 1310 | error.AntivirusInterference => unreachable, | ||
| 1311 | |||
| 1312 | else => |e| return e, | ||
| 1313 | }; | ||
| 1314 | return .{ .fd = fd }; | ||
| 1315 | }, | 1252 | }, |
| 1316 | else => {}, | 1253 | else => {}, |
| 1317 | } | 1254 | } |
| ... | @@ -1358,12 +1295,12 @@ pub fn openDirZ(self: Dir, sub_path_c: [*:0]const u8, args: OpenOptions) OpenErr | ... | @@ -1358,12 +1295,12 @@ pub fn openDirZ(self: Dir, sub_path_c: [*:0]const u8, args: OpenOptions) OpenErr |
| 1358 | var symlink_flags: posix.O = switch (native_os) { | 1295 | var symlink_flags: posix.O = switch (native_os) { |
| 1359 | .wasi => .{ | 1296 | .wasi => .{ |
| 1360 | .read = true, | 1297 | .read = true, |
| 1361 | .NOFOLLOW = args.no_follow, | 1298 | .NOFOLLOW = !args.follow_symlinks, |
| 1362 | .DIRECTORY = true, | 1299 | .DIRECTORY = true, |
| 1363 | }, | 1300 | }, |
| 1364 | else => .{ | 1301 | else => .{ |
| 1365 | .ACCMODE = .RDONLY, | 1302 | .ACCMODE = .RDONLY, |
| 1366 | .NOFOLLOW = args.no_follow, | 1303 | .NOFOLLOW = !args.follow_symlinks, |
| 1367 | .DIRECTORY = true, | 1304 | .DIRECTORY = true, |
| 1368 | .CLOEXEC = true, | 1305 | .CLOEXEC = true, |
| 1369 | }, | 1306 | }, |
| ... | @@ -1384,7 +1321,7 @@ pub fn openDirW(self: Dir, sub_path_w: [*:0]const u16, args: OpenOptions) OpenEr | ... | @@ -1384,7 +1321,7 @@ pub fn openDirW(self: Dir, sub_path_w: [*:0]const u16, args: OpenOptions) OpenEr |
| 1384 | w.SYNCHRONIZE | w.FILE_TRAVERSE; | 1321 | w.SYNCHRONIZE | w.FILE_TRAVERSE; |
| 1385 | const flags: u32 = if (args.iterate) base_flags | w.FILE_LIST_DIRECTORY else base_flags; | 1322 | const flags: u32 = if (args.iterate) base_flags | w.FILE_LIST_DIRECTORY else base_flags; |
| 1386 | const dir = self.makeOpenDirAccessMaskW(sub_path_w, flags, .{ | 1323 | const dir = self.makeOpenDirAccessMaskW(sub_path_w, flags, .{ |
| 1387 | .no_follow = args.no_follow, | 1324 | .no_follow = !args.follow_symlinks, |
| 1388 | .create_disposition = w.FILE_OPEN, | 1325 | .create_disposition = w.FILE_OPEN, |
| 1389 | }) catch |err| switch (err) { | 1326 | }) catch |err| switch (err) { |
| 1390 | error.ReadOnlyFileSystem => unreachable, | 1327 | error.ReadOnlyFileSystem => unreachable, |
| ... | @@ -1923,7 +1860,7 @@ pub fn deleteTree(self: Dir, sub_path: []const u8) DeleteTreeError!void { | ... | @@ -1923,7 +1860,7 @@ pub fn deleteTree(self: Dir, sub_path: []const u8) DeleteTreeError!void { |
| 1923 | if (treat_as_dir) { | 1860 | if (treat_as_dir) { |
| 1924 | if (stack.unusedCapacitySlice().len >= 1) { | 1861 | if (stack.unusedCapacitySlice().len >= 1) { |
| 1925 | var iterable_dir = top.iter.dir.openDir(entry.name, .{ | 1862 | var iterable_dir = top.iter.dir.openDir(entry.name, .{ |
| 1926 | .no_follow = true, | 1863 | .follow_symlinks = false, |
| 1927 | .iterate = true, | 1864 | .iterate = true, |
| 1928 | }) catch |err| switch (err) { | 1865 | }) catch |err| switch (err) { |
| 1929 | error.NotDir => { | 1866 | error.NotDir => { |
| ... | @@ -2019,7 +1956,7 @@ pub fn deleteTree(self: Dir, sub_path: []const u8) DeleteTreeError!void { | ... | @@ -2019,7 +1956,7 @@ pub fn deleteTree(self: Dir, sub_path: []const u8) DeleteTreeError!void { |
| 2019 | handle_entry: while (true) { | 1956 | handle_entry: while (true) { |
| 2020 | if (treat_as_dir) { | 1957 | if (treat_as_dir) { |
| 2021 | break :iterable_dir parent_dir.openDir(name, .{ | 1958 | break :iterable_dir parent_dir.openDir(name, .{ |
| 2022 | .no_follow = true, | 1959 | .follow_symlinks = false, |
| 2023 | .iterate = true, | 1960 | .iterate = true, |
| 2024 | }) catch |err| switch (err) { | 1961 | }) catch |err| switch (err) { |
| 2025 | error.NotDir => { | 1962 | error.NotDir => { |
| ... | @@ -2125,7 +2062,7 @@ fn deleteTreeMinStackSizeWithKindHint(self: Dir, sub_path: []const u8, kind_hint | ... | @@ -2125,7 +2062,7 @@ fn deleteTreeMinStackSizeWithKindHint(self: Dir, sub_path: []const u8, kind_hint |
| 2125 | handle_entry: while (true) { | 2062 | handle_entry: while (true) { |
| 2126 | if (treat_as_dir) { | 2063 | if (treat_as_dir) { |
| 2127 | const new_dir = dir.openDir(entry.name, .{ | 2064 | const new_dir = dir.openDir(entry.name, .{ |
| 2128 | .no_follow = true, | 2065 | .follow_symlinks = false, |
| 2129 | .iterate = true, | 2066 | .iterate = true, |
| 2130 | }) catch |err| switch (err) { | 2067 | }) catch |err| switch (err) { |
| 2131 | error.NotDir => { | 2068 | error.NotDir => { |
| ... | @@ -2224,7 +2161,7 @@ fn deleteTreeOpenInitialSubpath(self: Dir, sub_path: []const u8, kind_hint: File | ... | @@ -2224,7 +2161,7 @@ fn deleteTreeOpenInitialSubpath(self: Dir, sub_path: []const u8, kind_hint: File |
| 2224 | handle_entry: while (true) { | 2161 | handle_entry: while (true) { |
| 2225 | if (treat_as_dir) { | 2162 | if (treat_as_dir) { |
| 2226 | break :iterable_dir self.openDir(sub_path, .{ | 2163 | break :iterable_dir self.openDir(sub_path, .{ |
| 2227 | .no_follow = true, | 2164 | .follow_symlinks = false, |
| 2228 | .iterate = true, | 2165 | .iterate = true, |
| 2229 | }) catch |err| switch (err) { | 2166 | }) catch |err| switch (err) { |
| 2230 | error.NotDir => { | 2167 | error.NotDir => { |
lib/std/tar.zig+5-5| ... | @@ -977,7 +977,7 @@ test pipeToFileSystem { | ... | @@ -977,7 +977,7 @@ test pipeToFileSystem { |
| 977 | const data = @embedFile("tar/testdata/example.tar"); | 977 | const data = @embedFile("tar/testdata/example.tar"); |
| 978 | var reader: std.Io.Reader = .fixed(data); | 978 | var reader: std.Io.Reader = .fixed(data); |
| 979 | 979 | ||
| 980 | var tmp = testing.tmpDir(.{ .no_follow = true }); | 980 | var tmp = testing.tmpDir(.{ .follow_symlinks = false }); |
| 981 | defer tmp.cleanup(); | 981 | defer tmp.cleanup(); |
| 982 | const dir = tmp.dir; | 982 | const dir = tmp.dir; |
| 983 | 983 | ||
| ... | @@ -1010,7 +1010,7 @@ test "pipeToFileSystem root_dir" { | ... | @@ -1010,7 +1010,7 @@ test "pipeToFileSystem root_dir" { |
| 1010 | 1010 | ||
| 1011 | // with strip_components = 1 | 1011 | // with strip_components = 1 |
| 1012 | { | 1012 | { |
| 1013 | var tmp = testing.tmpDir(.{ .no_follow = true }); | 1013 | var tmp = testing.tmpDir(.{ .follow_symlinks = false }); |
| 1014 | defer tmp.cleanup(); | 1014 | defer tmp.cleanup(); |
| 1015 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; | 1015 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; |
| 1016 | defer diagnostics.deinit(); | 1016 | defer diagnostics.deinit(); |
| ... | @@ -1032,7 +1032,7 @@ test "pipeToFileSystem root_dir" { | ... | @@ -1032,7 +1032,7 @@ test "pipeToFileSystem root_dir" { |
| 1032 | // with strip_components = 0 | 1032 | // with strip_components = 0 |
| 1033 | { | 1033 | { |
| 1034 | reader = .fixed(data); | 1034 | reader = .fixed(data); |
| 1035 | var tmp = testing.tmpDir(.{ .no_follow = true }); | 1035 | var tmp = testing.tmpDir(.{ .follow_symlinks = false }); |
| 1036 | defer tmp.cleanup(); | 1036 | defer tmp.cleanup(); |
| 1037 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; | 1037 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; |
| 1038 | defer diagnostics.deinit(); | 1038 | defer diagnostics.deinit(); |
| ... | @@ -1084,7 +1084,7 @@ test "pipeToFileSystem strip_components" { | ... | @@ -1084,7 +1084,7 @@ test "pipeToFileSystem strip_components" { |
| 1084 | const data = @embedFile("tar/testdata/example.tar"); | 1084 | const data = @embedFile("tar/testdata/example.tar"); |
| 1085 | var reader: std.Io.Reader = .fixed(data); | 1085 | var reader: std.Io.Reader = .fixed(data); |
| 1086 | 1086 | ||
| 1087 | var tmp = testing.tmpDir(.{ .no_follow = true }); | 1087 | var tmp = testing.tmpDir(.{ .follow_symlinks = false }); |
| 1088 | defer tmp.cleanup(); | 1088 | defer tmp.cleanup(); |
| 1089 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; | 1089 | var diagnostics: Diagnostics = .{ .allocator = testing.allocator }; |
| 1090 | defer diagnostics.deinit(); | 1090 | defer diagnostics.deinit(); |
| ... | @@ -1145,7 +1145,7 @@ test "executable bit" { | ... | @@ -1145,7 +1145,7 @@ test "executable bit" { |
| 1145 | for ([_]PipeOptions.ModeMode{ .ignore, .executable_bit_only }) |opt| { | 1145 | for ([_]PipeOptions.ModeMode{ .ignore, .executable_bit_only }) |opt| { |
| 1146 | var reader: std.Io.Reader = .fixed(data); | 1146 | var reader: std.Io.Reader = .fixed(data); |
| 1147 | 1147 | ||
| 1148 | var tmp = testing.tmpDir(.{ .no_follow = true }); | 1148 | var tmp = testing.tmpDir(.{ .follow_symlinks = false }); |
| 1149 | //defer tmp.cleanup(); | 1149 | //defer tmp.cleanup(); |
| 1150 | 1150 | ||
| 1151 | pipeToFileSystem(tmp.dir, &reader, .{ | 1151 | pipeToFileSystem(tmp.dir, &reader, .{ |