| author | |
| committer | |
| log | 68621afd2e203d82b6f53bf4ede951827fa98db8 |
| tree | 60899decd0062ce7786592e49ca77ab6f80d22fd |
| parent | 0e230993d51d0ecded40d5235ada4f2f64036b26 |
15 files changed, 110 insertions(+), 110 deletions(-)
lib/compiler/aro/aro/Compilation.zig+2-1| ... | @@ -2162,8 +2162,9 @@ pub fn locSlice(comp: *const Compilation, loc: Source.Location) []const u8 { | ... | @@ -2162,8 +2162,9 @@ pub fn locSlice(comp: *const Compilation, loc: Source.Location) []const u8 { |
| 2162 | } | 2162 | } |
| 2163 | 2163 | ||
| 2164 | pub fn getSourceMTimeUncached(comp: *const Compilation, source_id: Source.Id) ?u64 { | 2164 | pub fn getSourceMTimeUncached(comp: *const Compilation, source_id: Source.Id) ?u64 { |
| 2165 | const io = comp.io; | ||
| 2165 | const source = comp.getSource(source_id); | 2166 | const source = comp.getSource(source_id); |
| 2166 | if (comp.cwd.statFile(source.path)) |stat| { | 2167 | if (comp.cwd.statFile(io, source.path, .{})) |stat| { |
| 2167 | return std.math.cast(u64, stat.mtime.toSeconds()); | 2168 | return std.math.cast(u64, stat.mtime.toSeconds()); |
| 2168 | } else |_| { | 2169 | } else |_| { |
| 2169 | return null; | 2170 | return null; |
lib/std/Build/Cache/Path.zig+2-2| ... | @@ -94,14 +94,14 @@ pub fn makeOpenPath(p: Path, sub_path: []const u8, opts: Io.Dir.OpenOptions) !Io | ... | @@ -94,14 +94,14 @@ pub fn makeOpenPath(p: Path, sub_path: []const u8, opts: Io.Dir.OpenOptions) !Io |
| 94 | return p.root_dir.handle.makeOpenPath(joined_path, opts); | 94 | return p.root_dir.handle.makeOpenPath(joined_path, opts); |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | pub fn statFile(p: Path, sub_path: []const u8) !Io.Dir.Stat { | 97 | pub fn statFile(p: Path, io: Io, sub_path: []const u8) !Io.Dir.Stat { |
| 98 | var buf: [fs.max_path_bytes]u8 = undefined; | 98 | var buf: [fs.max_path_bytes]u8 = undefined; |
| 99 | const joined_path = if (p.sub_path.len == 0) sub_path else p: { | 99 | const joined_path = if (p.sub_path.len == 0) sub_path else p: { |
| 100 | break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{ | 100 | break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{ |
| 101 | p.sub_path, sub_path, | 101 | p.sub_path, sub_path, |
| 102 | }) catch return error.NameTooLong; | 102 | }) catch return error.NameTooLong; |
| 103 | }; | 103 | }; |
| 104 | return p.root_dir.handle.statFile(joined_path); | 104 | return p.root_dir.handle.statFile(io, joined_path, .{}); |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | pub fn atomicFile( | 107 | pub fn atomicFile( |
lib/std/Io.zig+1-1| ... | @@ -671,7 +671,7 @@ pub const VTable = struct { | ... | @@ -671,7 +671,7 @@ pub const VTable = struct { |
| 671 | dirMakeOpenPath: *const fn (?*anyopaque, Dir, []const u8, Dir.Permissions, Dir.OpenOptions) Dir.MakeOpenPathError!Dir, | 671 | dirMakeOpenPath: *const fn (?*anyopaque, Dir, []const u8, Dir.Permissions, Dir.OpenOptions) Dir.MakeOpenPathError!Dir, |
| 672 | dirOpenDir: *const fn (?*anyopaque, Dir, []const u8, Dir.OpenOptions) Dir.OpenError!Dir, | 672 | dirOpenDir: *const fn (?*anyopaque, Dir, []const u8, Dir.OpenOptions) Dir.OpenError!Dir, |
| 673 | dirStat: *const fn (?*anyopaque, Dir) Dir.StatError!Dir.Stat, | 673 | dirStat: *const fn (?*anyopaque, Dir) Dir.StatError!Dir.Stat, |
| 674 | dirStatPath: *const fn (?*anyopaque, Dir, []const u8, Dir.StatPathOptions) Dir.StatPathError!File.Stat, | 674 | dirStatFile: *const fn (?*anyopaque, Dir, []const u8, Dir.StatFileOptions) Dir.StatFileError!File.Stat, |
| 675 | dirAccess: *const fn (?*anyopaque, Dir, []const u8, Dir.AccessOptions) Dir.AccessError!void, | 675 | dirAccess: *const fn (?*anyopaque, Dir, []const u8, Dir.AccessOptions) Dir.AccessError!void, |
| 676 | dirCreateFile: *const fn (?*anyopaque, Dir, []const u8, File.CreateFlags) File.OpenError!File, | 676 | dirCreateFile: *const fn (?*anyopaque, Dir, []const u8, File.CreateFlags) File.OpenError!File, |
| 677 | dirOpenFile: *const fn (?*anyopaque, Dir, []const u8, File.OpenFlags) File.OpenError!File, | 677 | dirOpenFile: *const fn (?*anyopaque, Dir, []const u8, File.OpenFlags) File.OpenError!File, |
lib/std/Io/Dir.zig+6-6| ... | @@ -669,7 +669,7 @@ pub fn makeDirAbsolute(io: Io, absolute_path: []const u8, permissions: Permissio | ... | @@ -669,7 +669,7 @@ pub fn makeDirAbsolute(io: Io, absolute_path: []const u8, permissions: Permissio |
| 669 | 669 | ||
| 670 | test makeDirAbsolute {} | 670 | test makeDirAbsolute {} |
| 671 | 671 | ||
| 672 | pub const MakePathError = MakeError || StatPathError; | 672 | pub const MakePathError = MakeError || StatFileError; |
| 673 | 673 | ||
| 674 | /// Creates parent directories with default permissions as necessary to ensure | 674 | /// Creates parent directories with default permissions as necessary to ensure |
| 675 | /// `sub_path` exists as a directory. | 675 | /// `sub_path` exists as a directory. |
| ... | @@ -708,7 +708,7 @@ pub fn makePathStatus(dir: Dir, io: Io, sub_path: []const u8, permissions: Permi | ... | @@ -708,7 +708,7 @@ pub fn makePathStatus(dir: Dir, io: Io, sub_path: []const u8, permissions: Permi |
| 708 | return io.vtable.dirMakePath(io.userdata, dir, sub_path, permissions); | 708 | return io.vtable.dirMakePath(io.userdata, dir, sub_path, permissions); |
| 709 | } | 709 | } |
| 710 | 710 | ||
| 711 | pub const MakeOpenPathError = MakeError || OpenError || StatPathError; | 711 | pub const MakeOpenPathError = MakeError || OpenError || StatFileError; |
| 712 | 712 | ||
| 713 | pub const MakeOpenPathOptions = struct { | 713 | pub const MakeOpenPathOptions = struct { |
| 714 | open_options: OpenOptions = .{}, | 714 | open_options: OpenOptions = .{}, |
| ... | @@ -734,9 +734,9 @@ pub fn stat(dir: Dir, io: Io) StatError!Stat { | ... | @@ -734,9 +734,9 @@ pub fn stat(dir: Dir, io: Io) StatError!Stat { |
| 734 | return io.vtable.dirStat(io.userdata, dir); | 734 | return io.vtable.dirStat(io.userdata, dir); |
| 735 | } | 735 | } |
| 736 | 736 | ||
| 737 | pub const StatPathError = File.OpenError || File.StatError; | 737 | pub const StatFileError = File.OpenError || File.StatError; |
| 738 | 738 | ||
| 739 | pub const StatPathOptions = struct { | 739 | pub const StatFileOptions = struct { |
| 740 | follow_symlinks: bool = true, | 740 | follow_symlinks: bool = true, |
| 741 | }; | 741 | }; |
| 742 | 742 | ||
| ... | @@ -752,8 +752,8 @@ pub const StatPathOptions = struct { | ... | @@ -752,8 +752,8 @@ pub const StatPathOptions = struct { |
| 752 | /// * On Windows, `sub_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/). | 752 | /// * On Windows, `sub_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/). |
| 753 | /// * On WASI, `sub_path` should be encoded as valid UTF-8. | 753 | /// * On WASI, `sub_path` should be encoded as valid UTF-8. |
| 754 | /// * On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding. | 754 | /// * On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding. |
| 755 | pub fn statPath(dir: Dir, io: Io, sub_path: []const u8, options: StatPathOptions) StatPathError!Stat { | 755 | pub fn statFile(dir: Dir, io: Io, sub_path: []const u8, options: StatFileOptions) StatFileError!Stat { |
| 756 | return io.vtable.dirStatPath(io.userdata, dir, sub_path, options); | 756 | return io.vtable.dirStatFile(io.userdata, dir, sub_path, options); |
| 757 | } | 757 | } |
| 758 | 758 | ||
| 759 | pub const RealPathError = error{ | 759 | pub const RealPathError = error{ |
lib/std/Io/File.zig+3| ... | @@ -372,6 +372,7 @@ pub const Permissions = std.options.FilePermissions orelse if (is_windows) enum( | ... | @@ -372,6 +372,7 @@ pub const Permissions = std.options.FilePermissions orelse if (is_windows) enum( |
| 372 | _, | 372 | _, |
| 373 | 373 | ||
| 374 | pub const default_dir: @This() = .default_file; | 374 | pub const default_dir: @This() = .default_file; |
| 375 | pub const executable_file: @This() = .default_file; | ||
| 375 | pub const has_executable_bit = false; | 376 | pub const has_executable_bit = false; |
| 376 | 377 | ||
| 377 | const windows = std.os.windows; | 378 | const windows = std.os.windows; |
| ... | @@ -401,6 +402,7 @@ pub const Permissions = std.options.FilePermissions orelse if (is_windows) enum( | ... | @@ -401,6 +402,7 @@ pub const Permissions = std.options.FilePermissions orelse if (is_windows) enum( |
| 401 | /// process-scoped "umask" setting to adjust this number for file creation. | 402 | /// process-scoped "umask" setting to adjust this number for file creation. |
| 402 | default_file = 0o666, | 403 | default_file = 0o666, |
| 403 | default_dir = 0o755, | 404 | default_dir = 0o755, |
| 405 | executable_file = 0o777, | ||
| 404 | _, | 406 | _, |
| 405 | 407 | ||
| 406 | pub const has_executable_bit = true; | 408 | pub const has_executable_bit = true; |
| ... | @@ -428,6 +430,7 @@ pub const Permissions = std.options.FilePermissions orelse if (is_windows) enum( | ... | @@ -428,6 +430,7 @@ pub const Permissions = std.options.FilePermissions orelse if (is_windows) enum( |
| 428 | } else enum(u0) { | 430 | } else enum(u0) { |
| 429 | default_file = 0, | 431 | default_file = 0, |
| 430 | pub const default_dir: @This() = .default_file; | 432 | pub const default_dir: @This() = .default_file; |
| 433 | pub const executable_file: @This() = .default_file; | ||
| 431 | pub const has_executable_bit = false; | 434 | pub const has_executable_bit = false; |
| 432 | }; | 435 | }; |
| 433 | 436 |
lib/std/Io/Threaded.zig+25-25| ... | @@ -708,7 +708,7 @@ pub fn io(t: *Threaded) Io { | ... | @@ -708,7 +708,7 @@ pub fn io(t: *Threaded) Io { |
| 708 | .dirMakePath = dirMakePath, | 708 | .dirMakePath = dirMakePath, |
| 709 | .dirMakeOpenPath = dirMakeOpenPath, | 709 | .dirMakeOpenPath = dirMakeOpenPath, |
| 710 | .dirStat = dirStat, | 710 | .dirStat = dirStat, |
| 711 | .dirStatPath = dirStatPath, | 711 | .dirStatFile = dirStatFile, |
| 712 | .dirAccess = dirAccess, | 712 | .dirAccess = dirAccess, |
| 713 | .dirCreateFile = dirCreateFile, | 713 | .dirCreateFile = dirCreateFile, |
| 714 | .dirOpenFile = dirOpenFile, | 714 | .dirOpenFile = dirOpenFile, |
| ... | @@ -840,7 +840,7 @@ pub fn ioBasic(t: *Threaded) Io { | ... | @@ -840,7 +840,7 @@ pub fn ioBasic(t: *Threaded) Io { |
| 840 | .dirMakePath = dirMakePath, | 840 | .dirMakePath = dirMakePath, |
| 841 | .dirMakeOpenPath = dirMakeOpenPath, | 841 | .dirMakeOpenPath = dirMakeOpenPath, |
| 842 | .dirStat = dirStat, | 842 | .dirStat = dirStat, |
| 843 | .dirStatPath = dirStatPath, | 843 | .dirStatFile = dirStatFile, |
| 844 | .dirAccess = dirAccess, | 844 | .dirAccess = dirAccess, |
| 845 | .dirCreateFile = dirCreateFile, | 845 | .dirCreateFile = dirCreateFile, |
| 846 | .dirOpenFile = dirOpenFile, | 846 | .dirOpenFile = dirOpenFile, |
| ... | @@ -1623,7 +1623,7 @@ fn dirMakePath( | ... | @@ -1623,7 +1623,7 @@ fn dirMakePath( |
| 1623 | // could cause an infinite loop | 1623 | // could cause an infinite loop |
| 1624 | check_dir: { | 1624 | check_dir: { |
| 1625 | // workaround for windows, see https://github.com/ziglang/zig/issues/16738 | 1625 | // workaround for windows, see https://github.com/ziglang/zig/issues/16738 |
| 1626 | const fstat = dirStatPath(t, dir, component.path, .{}) catch |stat_err| switch (stat_err) { | 1626 | const fstat = dirStatFile(t, dir, component.path, .{}) catch |stat_err| switch (stat_err) { |
| 1627 | error.IsDir => break :check_dir, | 1627 | error.IsDir => break :check_dir, |
| 1628 | else => |e| return e, | 1628 | else => |e| return e, |
| 1629 | }; | 1629 | }; |
| ... | @@ -1752,7 +1752,7 @@ fn dirMakeOpenPathWindows( | ... | @@ -1752,7 +1752,7 @@ fn dirMakeOpenPathWindows( |
| 1752 | // could cause an infinite loop | 1752 | // could cause an infinite loop |
| 1753 | check_dir: { | 1753 | check_dir: { |
| 1754 | // workaround for windows, see https://github.com/ziglang/zig/issues/16738 | 1754 | // workaround for windows, see https://github.com/ziglang/zig/issues/16738 |
| 1755 | const fstat = dirStatPathWindows(t, dir, component.path, .{ | 1755 | const fstat = dirStatFileWindows(t, dir, component.path, .{ |
| 1756 | .follow_symlinks = options.follow_symlinks, | 1756 | .follow_symlinks = options.follow_symlinks, |
| 1757 | }) catch |stat_err| switch (stat_err) { | 1757 | }) catch |stat_err| switch (stat_err) { |
| 1758 | error.IsDir => break :check_dir, | 1758 | error.IsDir => break :check_dir, |
| ... | @@ -1806,19 +1806,19 @@ fn dirStat(userdata: ?*anyopaque, dir: Dir) Dir.StatError!Dir.Stat { | ... | @@ -1806,19 +1806,19 @@ fn dirStat(userdata: ?*anyopaque, dir: Dir) Dir.StatError!Dir.Stat { |
| 1806 | return fileStat(t, file); | 1806 | return fileStat(t, file); |
| 1807 | } | 1807 | } |
| 1808 | 1808 | ||
| 1809 | const dirStatPath = switch (native_os) { | 1809 | const dirStatFile = switch (native_os) { |
| 1810 | .linux => dirStatPathLinux, | 1810 | .linux => dirStatFileLinux, |
| 1811 | .windows => dirStatPathWindows, | 1811 | .windows => dirStatFileWindows, |
| 1812 | .wasi => dirStatPathWasi, | 1812 | .wasi => dirStatFileWasi, |
| 1813 | else => dirStatPathPosix, | 1813 | else => dirStatFilePosix, |
| 1814 | }; | 1814 | }; |
| 1815 | 1815 | ||
| 1816 | fn dirStatPathLinux( | 1816 | fn dirStatFileLinux( |
| 1817 | userdata: ?*anyopaque, | 1817 | userdata: ?*anyopaque, |
| 1818 | dir: Dir, | 1818 | dir: Dir, |
| 1819 | sub_path: []const u8, | 1819 | sub_path: []const u8, |
| 1820 | options: Dir.StatPathOptions, | 1820 | options: Dir.StatFileOptions, |
| 1821 | ) Dir.StatPathError!File.Stat { | 1821 | ) Dir.StatFileError!File.Stat { |
| 1822 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 1822 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 1823 | const current_thread = Thread.getCurrent(t); | 1823 | const current_thread = Thread.getCurrent(t); |
| 1824 | const linux = std.os.linux; | 1824 | const linux = std.os.linux; |
| ... | @@ -1875,12 +1875,12 @@ fn dirStatPathLinux( | ... | @@ -1875,12 +1875,12 @@ fn dirStatPathLinux( |
| 1875 | } | 1875 | } |
| 1876 | } | 1876 | } |
| 1877 | 1877 | ||
| 1878 | fn dirStatPathPosix( | 1878 | fn dirStatFilePosix( |
| 1879 | userdata: ?*anyopaque, | 1879 | userdata: ?*anyopaque, |
| 1880 | dir: Dir, | 1880 | dir: Dir, |
| 1881 | sub_path: []const u8, | 1881 | sub_path: []const u8, |
| 1882 | options: Dir.StatPathOptions, | 1882 | options: Dir.StatFileOptions, |
| 1883 | ) Dir.StatPathError!File.Stat { | 1883 | ) Dir.StatFileError!File.Stat { |
| 1884 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 1884 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 1885 | const current_thread = Thread.getCurrent(t); | 1885 | const current_thread = Thread.getCurrent(t); |
| 1886 | 1886 | ||
| ... | @@ -1889,10 +1889,10 @@ fn dirStatPathPosix( | ... | @@ -1889,10 +1889,10 @@ fn dirStatPathPosix( |
| 1889 | 1889 | ||
| 1890 | const flags: u32 = if (!options.follow_symlinks) posix.AT.SYMLINK_NOFOLLOW else 0; | 1890 | const flags: u32 = if (!options.follow_symlinks) posix.AT.SYMLINK_NOFOLLOW else 0; |
| 1891 | 1891 | ||
| 1892 | return posixStatPath(current_thread, dir.handle, sub_path_posix, flags); | 1892 | return posixStatFile(current_thread, dir.handle, sub_path_posix, flags); |
| 1893 | } | 1893 | } |
| 1894 | 1894 | ||
| 1895 | fn posixStatPath(current_thread: *Thread, dir_fd: posix.fd_t, sub_path: [:0]const u8, flags: u32) Dir.StatPathError!File.Stat { | 1895 | fn posixStatFile(current_thread: *Thread, dir_fd: posix.fd_t, sub_path: [:0]const u8, flags: u32) Dir.StatFileError!File.Stat { |
| 1896 | try current_thread.beginSyscall(); | 1896 | try current_thread.beginSyscall(); |
| 1897 | while (true) { | 1897 | while (true) { |
| 1898 | var stat = std.mem.zeroes(posix.Stat); | 1898 | var stat = std.mem.zeroes(posix.Stat); |
| ... | @@ -1927,12 +1927,12 @@ fn posixStatPath(current_thread: *Thread, dir_fd: posix.fd_t, sub_path: [:0]cons | ... | @@ -1927,12 +1927,12 @@ fn posixStatPath(current_thread: *Thread, dir_fd: posix.fd_t, sub_path: [:0]cons |
| 1927 | } | 1927 | } |
| 1928 | } | 1928 | } |
| 1929 | 1929 | ||
| 1930 | fn dirStatPathWindows( | 1930 | fn dirStatFileWindows( |
| 1931 | userdata: ?*anyopaque, | 1931 | userdata: ?*anyopaque, |
| 1932 | dir: Dir, | 1932 | dir: Dir, |
| 1933 | sub_path: []const u8, | 1933 | sub_path: []const u8, |
| 1934 | options: Dir.StatPathOptions, | 1934 | options: Dir.StatFileOptions, |
| 1935 | ) Dir.StatPathError!File.Stat { | 1935 | ) Dir.StatFileError!File.Stat { |
| 1936 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 1936 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 1937 | const file = try dirOpenFileWindows(t, dir, sub_path, .{ | 1937 | const file = try dirOpenFileWindows(t, dir, sub_path, .{ |
| 1938 | .follow_symlinks = options.follow_symlinks, | 1938 | .follow_symlinks = options.follow_symlinks, |
| ... | @@ -1941,13 +1941,13 @@ fn dirStatPathWindows( | ... | @@ -1941,13 +1941,13 @@ fn dirStatPathWindows( |
| 1941 | return fileStatWindows(t, file); | 1941 | return fileStatWindows(t, file); |
| 1942 | } | 1942 | } |
| 1943 | 1943 | ||
| 1944 | fn dirStatPathWasi( | 1944 | fn dirStatFileWasi( |
| 1945 | userdata: ?*anyopaque, | 1945 | userdata: ?*anyopaque, |
| 1946 | dir: Dir, | 1946 | dir: Dir, |
| 1947 | sub_path: []const u8, | 1947 | sub_path: []const u8, |
| 1948 | options: Dir.StatPathOptions, | 1948 | options: Dir.StatFileOptions, |
| 1949 | ) Dir.StatPathError!File.Stat { | 1949 | ) Dir.StatFileError!File.Stat { |
| 1950 | if (builtin.link_libc) return dirStatPathPosix(userdata, dir, sub_path, options); | 1950 | if (builtin.link_libc) return dirStatFilePosix(userdata, dir, sub_path, options); |
| 1951 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 1951 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 1952 | const current_thread = Thread.getCurrent(t); | 1952 | const current_thread = Thread.getCurrent(t); |
| 1953 | const wasi = std.os.wasi; | 1953 | const wasi = std.os.wasi; |
| ... | @@ -3629,7 +3629,7 @@ fn dirReadIllumos(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) D | ... | @@ -3629,7 +3629,7 @@ fn dirReadIllumos(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) D |
| 3629 | if (std.mem.eql(u8, name, ".") or std.mem.eql(u8, name, "..")) continue; | 3629 | if (std.mem.eql(u8, name, ".") or std.mem.eql(u8, name, "..")) continue; |
| 3630 | 3630 | ||
| 3631 | // illumos dirent doesn't expose type, so we have to call stat to get it. | 3631 | // illumos dirent doesn't expose type, so we have to call stat to get it. |
| 3632 | const stat = try posixStatPath(current_thread, dr.dir.handle, name, posix.AT.SYMLINK_NOFOLLOW); | 3632 | const stat = try posixStatFile(current_thread, dr.dir.handle, name, posix.AT.SYMLINK_NOFOLLOW); |
| 3633 | 3633 | ||
| 3634 | buffer[buffer_index] = .{ | 3634 | buffer[buffer_index] = .{ |
| 3635 | .name = name, | 3635 | .name = name, |
lib/std/fs/test.zig+30-27| ... | @@ -160,8 +160,8 @@ fn testWithPathTypeIfSupported(comptime path_type: PathType, comptime path_sep: | ... | @@ -160,8 +160,8 @@ fn testWithPathTypeIfSupported(comptime path_type: PathType, comptime path_sep: |
| 160 | 160 | ||
| 161 | // For use in test setup. If the symlink creation fails on Windows with | 161 | // For use in test setup. If the symlink creation fails on Windows with |
| 162 | // AccessDenied, then make the test failure silent (it is not a Zig failure). | 162 | // AccessDenied, then make the test failure silent (it is not a Zig failure). |
| 163 | fn setupSymlink(dir: Dir, target: []const u8, link: []const u8, flags: SymLinkFlags) !void { | 163 | fn setupSymlink(io: Io, dir: Dir, target: []const u8, link: []const u8, flags: SymLinkFlags) !void { |
| 164 | return dir.symLink(target, link, flags) catch |err| switch (err) { | 164 | return dir.symLink(io, target, link, flags) catch |err| switch (err) { |
| 165 | // Symlink requires admin privileges on windows, so this test can legitimately fail. | 165 | // Symlink requires admin privileges on windows, so this test can legitimately fail. |
| 166 | error.AccessDenied => if (native_os == .windows) return error.SkipZigTest else return err, | 166 | error.AccessDenied => if (native_os == .windows) return error.SkipZigTest else return err, |
| 167 | else => return err, | 167 | else => return err, |
| ... | @@ -193,15 +193,15 @@ test "Dir.readLink" { | ... | @@ -193,15 +193,15 @@ test "Dir.readLink" { |
| 193 | const canonical_dir_target_path = try ctx.toCanonicalPathSep(dir_target_path); | 193 | const canonical_dir_target_path = try ctx.toCanonicalPathSep(dir_target_path); |
| 194 | 194 | ||
| 195 | // test 1: symlink to a file | 195 | // test 1: symlink to a file |
| 196 | try setupSymlink(ctx.dir, file_target_path, "symlink1", .{}); | 196 | try setupSymlink(io, ctx.dir, file_target_path, "symlink1", .{}); |
| 197 | try testReadLink(ctx.dir, canonical_file_target_path, "symlink1"); | 197 | try testReadLink(io, ctx.dir, canonical_file_target_path, "symlink1"); |
| 198 | if (builtin.os.tag == .windows) { | 198 | if (builtin.os.tag == .windows) { |
| 199 | try testReadLinkW(testing.allocator, ctx.dir, canonical_file_target_path, "symlink1"); | 199 | try testReadLinkW(testing.allocator, ctx.dir, canonical_file_target_path, "symlink1"); |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | // test 2: symlink to a directory (can be different on Windows) | 202 | // test 2: symlink to a directory (can be different on Windows) |
| 203 | try setupSymlink(ctx.dir, dir_target_path, "symlink2", .{ .is_directory = true }); | 203 | try setupSymlink(io, ctx.dir, dir_target_path, "symlink2", .{ .is_directory = true }); |
| 204 | try testReadLink(ctx.dir, canonical_dir_target_path, "symlink2"); | 204 | try testReadLink(io, ctx.dir, canonical_dir_target_path, "symlink2"); |
| 205 | if (builtin.os.tag == .windows) { | 205 | if (builtin.os.tag == .windows) { |
| 206 | try testReadLinkW(testing.allocator, ctx.dir, canonical_dir_target_path, "symlink2"); | 206 | try testReadLinkW(testing.allocator, ctx.dir, canonical_dir_target_path, "symlink2"); |
| 207 | } | 207 | } |
| ... | @@ -211,8 +211,8 @@ test "Dir.readLink" { | ... | @@ -211,8 +211,8 @@ test "Dir.readLink" { |
| 211 | const canonical_parent_file = try ctx.toCanonicalPathSep(parent_file); | 211 | const canonical_parent_file = try ctx.toCanonicalPathSep(parent_file); |
| 212 | var subdir = try ctx.dir.makeOpenPath("subdir", .{}); | 212 | var subdir = try ctx.dir.makeOpenPath("subdir", .{}); |
| 213 | defer subdir.close(io); | 213 | defer subdir.close(io); |
| 214 | try setupSymlink(subdir, canonical_parent_file, "relative-link.txt", .{}); | 214 | try setupSymlink(io, subdir, canonical_parent_file, "relative-link.txt", .{}); |
| 215 | try testReadLink(subdir, canonical_parent_file, "relative-link.txt"); | 215 | try testReadLink(io, subdir, canonical_parent_file, "relative-link.txt"); |
| 216 | if (builtin.os.tag == .windows) { | 216 | if (builtin.os.tag == .windows) { |
| 217 | try testReadLinkW(testing.allocator, subdir, canonical_parent_file, "relative-link.txt"); | 217 | try testReadLinkW(testing.allocator, subdir, canonical_parent_file, "relative-link.txt"); |
| 218 | } | 218 | } |
| ... | @@ -246,9 +246,9 @@ test "Dir.readLink on non-symlinks" { | ... | @@ -246,9 +246,9 @@ test "Dir.readLink on non-symlinks" { |
| 246 | }.impl); | 246 | }.impl); |
| 247 | } | 247 | } |
| 248 | 248 | ||
| 249 | fn testReadLink(dir: Dir, target_path: []const u8, symlink_path: []const u8) !void { | 249 | fn testReadLink(io: Io, dir: Dir, target_path: []const u8, symlink_path: []const u8) !void { |
| 250 | var buffer: [fs.max_path_bytes]u8 = undefined; | 250 | var buffer: [fs.max_path_bytes]u8 = undefined; |
| 251 | const actual = try dir.readLink(symlink_path, buffer[0..]); | 251 | const actual = try dir.readLink(io, symlink_path, &buffer); |
| 252 | try testing.expectEqualStrings(target_path, actual); | 252 | try testing.expectEqualStrings(target_path, actual); |
| 253 | } | 253 | } |
| 254 | 254 | ||
| ... | @@ -284,7 +284,7 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" { | ... | @@ -284,7 +284,7 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" { |
| 284 | const dir_target_path = try ctx.transformPath("subdir"); | 284 | const dir_target_path = try ctx.transformPath("subdir"); |
| 285 | try ctx.dir.makeDir(io, dir_target_path, .default_dir); | 285 | try ctx.dir.makeDir(io, dir_target_path, .default_dir); |
| 286 | 286 | ||
| 287 | try setupSymlink(ctx.dir, dir_target_path, "symlink", .{ .is_directory = true }); | 287 | try setupSymlink(io, ctx.dir, dir_target_path, "symlink", .{ .is_directory = true }); |
| 288 | 288 | ||
| 289 | var symlink: Dir = switch (builtin.target.os.tag) { | 289 | var symlink: Dir = switch (builtin.target.os.tag) { |
| 290 | .windows => windows_symlink: { | 290 | .windows => windows_symlink: { |
| ... | @@ -809,11 +809,11 @@ test "Dir.statFile" { | ... | @@ -809,11 +809,11 @@ test "Dir.statFile" { |
| 809 | const io = ctx.io; | 809 | const io = ctx.io; |
| 810 | const test_file_name = try ctx.transformPath("test_file"); | 810 | const test_file_name = try ctx.transformPath("test_file"); |
| 811 | 811 | ||
| 812 | try testing.expectError(error.FileNotFound, ctx.dir.statFile(test_file_name)); | 812 | try testing.expectError(error.FileNotFound, ctx.dir.statFile(io, test_file_name, .{})); |
| 813 | 813 | ||
| 814 | try ctx.dir.writeFile(io, .{ .sub_path = test_file_name, .data = "" }); | 814 | try ctx.dir.writeFile(io, .{ .sub_path = test_file_name, .data = "" }); |
| 815 | 815 | ||
| 816 | const stat = try ctx.dir.statFile(test_file_name); | 816 | const stat = try ctx.dir.statFile(io, test_file_name, .{}); |
| 817 | try testing.expectEqual(File.Kind.file, stat.kind); | 817 | try testing.expectEqual(File.Kind.file, stat.kind); |
| 818 | } | 818 | } |
| 819 | }.impl); | 819 | }.impl); |
| ... | @@ -822,12 +822,13 @@ test "Dir.statFile" { | ... | @@ -822,12 +822,13 @@ test "Dir.statFile" { |
| 822 | test "statFile on dangling symlink" { | 822 | test "statFile on dangling symlink" { |
| 823 | try testWithAllSupportedPathTypes(struct { | 823 | try testWithAllSupportedPathTypes(struct { |
| 824 | fn impl(ctx: *TestContext) !void { | 824 | fn impl(ctx: *TestContext) !void { |
| 825 | const io = ctx.io; | ||
| 825 | const symlink_name = try ctx.transformPath("dangling-symlink"); | 826 | const symlink_name = try ctx.transformPath("dangling-symlink"); |
| 826 | const symlink_target = "." ++ fs.path.sep_str ++ "doesnotexist"; | 827 | const symlink_target = "." ++ fs.path.sep_str ++ "doesnotexist"; |
| 827 | 828 | ||
| 828 | try setupSymlink(ctx.dir, symlink_target, symlink_name, .{}); | 829 | try setupSymlink(io, ctx.dir, symlink_target, symlink_name, .{}); |
| 829 | 830 | ||
| 830 | try std.testing.expectError(error.FileNotFound, ctx.dir.statFile(symlink_name)); | 831 | try std.testing.expectError(error.FileNotFound, ctx.dir.statFile(io, symlink_name, .{})); |
| 831 | } | 832 | } |
| 832 | }.impl); | 833 | }.impl); |
| 833 | } | 834 | } |
| ... | @@ -1206,7 +1207,7 @@ test "deleteTree does not follow symlinks" { | ... | @@ -1206,7 +1207,7 @@ test "deleteTree does not follow symlinks" { |
| 1206 | var a = try tmp.dir.makeOpenPath("a", .{}); | 1207 | var a = try tmp.dir.makeOpenPath("a", .{}); |
| 1207 | defer a.close(io); | 1208 | defer a.close(io); |
| 1208 | 1209 | ||
| 1209 | try setupSymlink(a, "../b", "b", .{ .is_directory = true }); | 1210 | try setupSymlink(io, a, "../b", "b", .{ .is_directory = true }); |
| 1210 | } | 1211 | } |
| 1211 | 1212 | ||
| 1212 | try tmp.dir.deleteTree(io, "a"); | 1213 | try tmp.dir.deleteTree(io, "a"); |
| ... | @@ -1223,7 +1224,7 @@ test "deleteTree on a symlink" { | ... | @@ -1223,7 +1224,7 @@ test "deleteTree on a symlink" { |
| 1223 | 1224 | ||
| 1224 | // Symlink to a file | 1225 | // Symlink to a file |
| 1225 | try tmp.dir.writeFile(io, .{ .sub_path = "file", .data = "" }); | 1226 | try tmp.dir.writeFile(io, .{ .sub_path = "file", .data = "" }); |
| 1226 | try setupSymlink(tmp.dir, "file", "filelink", .{}); | 1227 | try setupSymlink(io, tmp.dir, "file", "filelink", .{}); |
| 1227 | 1228 | ||
| 1228 | try tmp.dir.deleteTree(io, "filelink"); | 1229 | try tmp.dir.deleteTree(io, "filelink"); |
| 1229 | try testing.expectError(error.FileNotFound, tmp.dir.access(io, "filelink", .{})); | 1230 | try testing.expectError(error.FileNotFound, tmp.dir.access(io, "filelink", .{})); |
| ... | @@ -1231,7 +1232,7 @@ test "deleteTree on a symlink" { | ... | @@ -1231,7 +1232,7 @@ test "deleteTree on a symlink" { |
| 1231 | 1232 | ||
| 1232 | // Symlink to a directory | 1233 | // Symlink to a directory |
| 1233 | try tmp.dir.makePath(io, "dir"); | 1234 | try tmp.dir.makePath(io, "dir"); |
| 1234 | try setupSymlink(tmp.dir, "dir", "dirlink", .{ .is_directory = true }); | 1235 | try setupSymlink(io, tmp.dir, "dir", "dirlink", .{ .is_directory = true }); |
| 1235 | 1236 | ||
| 1236 | try tmp.dir.deleteTree(io, "dirlink"); | 1237 | try tmp.dir.deleteTree(io, "dirlink"); |
| 1237 | try testing.expectError(error.FileNotFound, tmp.dir.access(io, "dirlink", .{})); | 1238 | try testing.expectError(error.FileNotFound, tmp.dir.access(io, "dirlink", .{})); |
| ... | @@ -1337,7 +1338,7 @@ test "makepath through existing valid symlink" { | ... | @@ -1337,7 +1338,7 @@ test "makepath through existing valid symlink" { |
| 1337 | defer tmp.cleanup(); | 1338 | defer tmp.cleanup(); |
| 1338 | 1339 | ||
| 1339 | try tmp.dir.makeDir(io, "realfolder", .default_dir); | 1340 | try tmp.dir.makeDir(io, "realfolder", .default_dir); |
| 1340 | try setupSymlink(tmp.dir, "." ++ fs.path.sep_str ++ "realfolder", "working-symlink", .{}); | 1341 | try setupSymlink(io, tmp.dir, "." ++ fs.path.sep_str ++ "realfolder", "working-symlink", .{}); |
| 1341 | 1342 | ||
| 1342 | try tmp.dir.makePath(io, "working-symlink" ++ fs.path.sep_str ++ "in-realfolder"); | 1343 | try tmp.dir.makePath(io, "working-symlink" ++ fs.path.sep_str ++ "in-realfolder"); |
| 1343 | 1344 | ||
| ... | @@ -2178,12 +2179,12 @@ test "invalid UTF-8/WTF-8 paths" { | ... | @@ -2178,12 +2179,12 @@ test "invalid UTF-8/WTF-8 paths" { |
| 2178 | 2179 | ||
| 2179 | try testing.expectError(expected_err, ctx.dir.rename(invalid_path, ctx.dir, invalid_path, io)); | 2180 | try testing.expectError(expected_err, ctx.dir.rename(invalid_path, ctx.dir, invalid_path, io)); |
| 2180 | 2181 | ||
| 2181 | try testing.expectError(expected_err, ctx.dir.symLink(invalid_path, invalid_path, .{})); | 2182 | try testing.expectError(expected_err, ctx.dir.symLink(io, invalid_path, invalid_path, .{})); |
| 2182 | if (native_os == .wasi) { | 2183 | if (native_os == .wasi) { |
| 2183 | try testing.expectError(expected_err, ctx.dir.symLinkWasi(invalid_path, invalid_path, .{})); | 2184 | try testing.expectError(expected_err, ctx.dir.symLinkWasi(invalid_path, invalid_path, .{})); |
| 2184 | } | 2185 | } |
| 2185 | 2186 | ||
| 2186 | try testing.expectError(expected_err, ctx.dir.readLink(invalid_path, &[_]u8{})); | 2187 | try testing.expectError(expected_err, ctx.dir.readLink(io, invalid_path, &[_]u8{})); |
| 2187 | if (native_os == .wasi) { | 2188 | if (native_os == .wasi) { |
| 2188 | try testing.expectError(expected_err, ctx.dir.readLinkWasi(invalid_path, &[_]u8{})); | 2189 | try testing.expectError(expected_err, ctx.dir.readLinkWasi(invalid_path, &[_]u8{})); |
| 2189 | } | 2190 | } |
| ... | @@ -2386,14 +2387,16 @@ test "File.Writer sendfile with buffered contents" { | ... | @@ -2386,14 +2387,16 @@ test "File.Writer sendfile with buffered contents" { |
| 2386 | test "readlink on Windows" { | 2387 | test "readlink on Windows" { |
| 2387 | if (native_os != .windows) return error.SkipZigTest; | 2388 | if (native_os != .windows) return error.SkipZigTest; |
| 2388 | 2389 | ||
| 2389 | try testReadlink("C:\\ProgramData", "C:\\Users\\All Users"); | 2390 | const io = testing.io; |
| 2390 | try testReadlink("C:\\Users\\Default", "C:\\Users\\Default User"); | 2391 | |
| 2391 | try testReadlink("C:\\Users", "C:\\Documents and Settings"); | 2392 | try testReadLinkWindows(io, "C:\\ProgramData", "C:\\Users\\All Users"); |
| 2393 | try testReadLinkWindows(io, "C:\\Users\\Default", "C:\\Users\\Default User"); | ||
| 2394 | try testReadLinkWindows(io, "C:\\Users", "C:\\Documents and Settings"); | ||
| 2392 | } | 2395 | } |
| 2393 | 2396 | ||
| 2394 | fn testReadlink(target_path: []const u8, symlink_path: []const u8) !void { | 2397 | fn testReadLinkWindows(io: Io, target_path: []const u8, symlink_path: []const u8) !void { |
| 2395 | var buffer: [fs.max_path_bytes]u8 = undefined; | 2398 | var buffer: [fs.max_path_bytes]u8 = undefined; |
| 2396 | const given = try Dir.readLinkAbsolute(symlink_path, buffer[0..]); | 2399 | const given = try Dir.readLinkAbsolute(io, symlink_path, &buffer); |
| 2397 | try expect(mem.eql(u8, target_path, given)); | 2400 | try expect(mem.eql(u8, target_path, given)); |
| 2398 | } | 2401 | } |
| 2399 | 2402 | ||
| ... | @@ -2424,6 +2427,6 @@ test "readlinkat" { | ... | @@ -2424,6 +2427,6 @@ test "readlinkat" { |
| 2424 | 2427 | ||
| 2425 | // read the link | 2428 | // read the link |
| 2426 | var buffer: [fs.max_path_bytes]u8 = undefined; | 2429 | var buffer: [fs.max_path_bytes]u8 = undefined; |
| 2427 | const read_link = try tmp.dir.readLink("link", &buffer); | 2430 | const read_link = try tmp.dir.readLink(io, "link", &buffer); |
| 2428 | try expect(mem.eql(u8, "file.txt", read_link)); | 2431 | try expect(mem.eql(u8, "file.txt", read_link)); |
| 2429 | } | 2432 | } |
lib/std/tar.zig+23-31| ... | @@ -653,11 +653,11 @@ fn createDirAndFile(io: Io, dir: Io.Dir, file_name: []const u8, permissions: Io. | ... | @@ -653,11 +653,11 @@ fn createDirAndFile(io: Io, dir: Io.Dir, file_name: []const u8, permissions: Io. |
| 653 | 653 | ||
| 654 | // Creates a symbolic link at path `file_name` which points to `link_name`. | 654 | // Creates a symbolic link at path `file_name` which points to `link_name`. |
| 655 | fn createDirAndSymlink(io: Io, dir: Io.Dir, link_name: []const u8, file_name: []const u8) !void { | 655 | fn createDirAndSymlink(io: Io, dir: Io.Dir, link_name: []const u8, file_name: []const u8) !void { |
| 656 | dir.symLink(link_name, file_name, .{}) catch |err| { | 656 | dir.symLink(io, link_name, file_name, .{}) catch |err| { |
| 657 | if (err == error.FileNotFound) { | 657 | if (err == error.FileNotFound) { |
| 658 | if (std.fs.path.dirname(file_name)) |dir_name| { | 658 | if (std.fs.path.dirname(file_name)) |dir_name| { |
| 659 | try dir.makePath(io, dir_name); | 659 | try dir.makePath(io, dir_name); |
| 660 | return try dir.symLink(link_name, file_name, .{}); | 660 | return try dir.symLink(io, link_name, file_name, .{}); |
| 661 | } | 661 | } |
| 662 | } | 662 | } |
| 663 | return err; | 663 | return err; |
| ... | @@ -996,15 +996,15 @@ test pipeToFileSystem { | ... | @@ -996,15 +996,15 @@ test pipeToFileSystem { |
| 996 | return err; | 996 | return err; |
| 997 | }; | 997 | }; |
| 998 | 998 | ||
| 999 | try testing.expectError(error.FileNotFound, dir.statFile("empty")); | 999 | try testing.expectError(error.FileNotFound, dir.statFile(io, "empty", .{})); |
| 1000 | try testing.expect((try dir.statFile("a/file")).kind == .file); | 1000 | try testing.expect((try dir.statFile(io, "a/file", .{})).kind == .file); |
| 1001 | try testing.expect((try dir.statFile("b/symlink")).kind == .file); // statFile follows symlink | 1001 | try testing.expect((try dir.statFile(io, "b/symlink", .{})).kind == .file); // statFile follows symlink |
| 1002 | 1002 | ||
| 1003 | var buf: [32]u8 = undefined; | 1003 | var buf: [32]u8 = undefined; |
| 1004 | try testing.expectEqualSlices( | 1004 | try testing.expectEqualSlices( |
| 1005 | u8, | 1005 | u8, |
| 1006 | "../a/file", | 1006 | "../a/file", |
| 1007 | normalizePath(try dir.readLink("b/symlink", &buf)), | 1007 | normalizePath(buf[0..try dir.readLink(io, "b/symlink", &buf)]), |
| 1008 | ); | 1008 | ); |
| 1009 | } | 1009 | } |
| 1010 | 1010 | ||
| ... | @@ -1120,28 +1120,18 @@ fn normalizePath(bytes: []u8) []u8 { | ... | @@ -1120,28 +1120,18 @@ fn normalizePath(bytes: []u8) []u8 { |
| 1120 | 1120 | ||
| 1121 | // File system mode based on tar header mode and mode_mode options. | 1121 | // File system mode based on tar header mode and mode_mode options. |
| 1122 | fn filePermissions(mode: u32, options: PipeOptions) Io.File.Permissions { | 1122 | fn filePermissions(mode: u32, options: PipeOptions) Io.File.Permissions { |
| 1123 | const default_mode = 0o666; | 1123 | return if (!Io.File.Permissions.has_executable_bit or options.mode_mode == .ignore or (mode & 0o100) == 0) |
| 1124 | 1124 | .default_file | |
| 1125 | if (!Io.File.Permissions.has_executable_bit or options.mode_mode == .ignore) | 1125 | else |
| 1126 | return .fromMode(default_mode); | 1126 | .executable_file; |
| 1127 | |||
| 1128 | const S = std.posix.S; | ||
| 1129 | |||
| 1130 | // The mode from the tar file is inspected for the owner executable bit. | ||
| 1131 | if (mode & S.IXUSR == 0) | ||
| 1132 | return .fromMode(default_mode); | ||
| 1133 | |||
| 1134 | // This bit is copied to the group and other executable bits. | ||
| 1135 | // Other bits of the mode are left as the default when creating files. | ||
| 1136 | return .fromMode(default_mode | S.IXUSR | S.IXGRP | S.IXOTH); | ||
| 1137 | } | 1127 | } |
| 1138 | 1128 | ||
| 1139 | test filePermissions { | 1129 | test filePermissions { |
| 1140 | if (!Io.File.Permissions.has_executable_bit) return error.SkipZigTest; | 1130 | if (!Io.File.Permissions.has_executable_bit) return error.SkipZigTest; |
| 1141 | try testing.expectEqual(0o666, filePermissions(0o744, PipeOptions{ .mode_mode = .ignore })); | 1131 | try testing.expectEqual(.default_file, filePermissions(0o744, .{ .mode_mode = .ignore })); |
| 1142 | try testing.expectEqual(0o777, filePermissions(0o744, PipeOptions{})); | 1132 | try testing.expectEqual(.executable_file, filePermissions(0o744, .{})); |
| 1143 | try testing.expectEqual(0o666, filePermissions(0o644, PipeOptions{})); | 1133 | try testing.expectEqual(.default_file, filePermissions(0o644, .{})); |
| 1144 | try testing.expectEqual(0o666, filePermissions(0o655, PipeOptions{})); | 1134 | try testing.expectEqual(.default_file, filePermissions(0o655, .{})); |
| 1145 | } | 1135 | } |
| 1146 | 1136 | ||
| 1147 | test "executable bit" { | 1137 | test "executable bit" { |
| ... | @@ -1167,19 +1157,21 @@ test "executable bit" { | ... | @@ -1167,19 +1157,21 @@ test "executable bit" { |
| 1167 | return err; | 1157 | return err; |
| 1168 | }; | 1158 | }; |
| 1169 | 1159 | ||
| 1170 | const fs = try tmp.dir.statFile("a/file"); | 1160 | const fs = try tmp.dir.statFile(io, "a/file", .{}); |
| 1171 | try testing.expect(fs.kind == .file); | 1161 | try testing.expect(fs.kind == .file); |
| 1172 | 1162 | ||
| 1163 | const mode = fs.permissions.toMode(); | ||
| 1164 | |||
| 1173 | if (opt == .executable_bit_only) { | 1165 | if (opt == .executable_bit_only) { |
| 1174 | // Executable bit is set for user, group and others | 1166 | // Executable bit is set for user, group and others |
| 1175 | try testing.expect(fs.mode & S.IXUSR > 0); | 1167 | try testing.expect(mode & S.IXUSR > 0); |
| 1176 | try testing.expect(fs.mode & S.IXGRP > 0); | 1168 | try testing.expect(mode & S.IXGRP > 0); |
| 1177 | try testing.expect(fs.mode & S.IXOTH > 0); | 1169 | try testing.expect(mode & S.IXOTH > 0); |
| 1178 | } | 1170 | } |
| 1179 | if (opt == .ignore) { | 1171 | if (opt == .ignore) { |
| 1180 | try testing.expect(fs.mode & S.IXUSR == 0); | 1172 | try testing.expect(mode & S.IXUSR == 0); |
| 1181 | try testing.expect(fs.mode & S.IXGRP == 0); | 1173 | try testing.expect(mode & S.IXGRP == 0); |
| 1182 | try testing.expect(fs.mode & S.IXOTH == 0); | 1174 | try testing.expect(mode & S.IXOTH == 0); |
| 1183 | } | 1175 | } |
| 1184 | } | 1176 | } |
| 1185 | } | 1177 | } |
lib/std/tar/test.zig+2-2| ... | @@ -504,6 +504,6 @@ test "case sensitivity" { | ... | @@ -504,6 +504,6 @@ test "case sensitivity" { |
| 504 | }; | 504 | }; |
| 505 | 505 | ||
| 506 | // on case sensitive os both files are created | 506 | // on case sensitive os both files are created |
| 507 | try testing.expect((try root.dir.statFile("alacritty/darkermatrix.yml")).kind == .file); | 507 | try testing.expect((try root.dir.statFile(io, "alacritty/darkermatrix.yml", .{})).kind == .file); |
| 508 | try testing.expect((try root.dir.statFile("alacritty/Darkermatrix.yml")).kind == .file); | 508 | try testing.expect((try root.dir.statFile(io, "alacritty/Darkermatrix.yml", .{})).kind == .file); |
| 509 | } | 509 | } |
lib/std/zig/WindowsSdk.zig+1-1| ... | @@ -1012,7 +1012,7 @@ const MsvcLibDir = struct { | ... | @@ -1012,7 +1012,7 @@ const MsvcLibDir = struct { |
| 1012 | var dir = std.fs.openDirAbsolute(lib_dir_path, .{}) catch return false; | 1012 | var dir = std.fs.openDirAbsolute(lib_dir_path, .{}) catch return false; |
| 1013 | defer dir.close(io); | 1013 | defer dir.close(io); |
| 1014 | 1014 | ||
| 1015 | const stat = dir.statFile("vcruntime.lib") catch return false; | 1015 | const stat = dir.statFile(io, "vcruntime.lib", .{}) catch return false; |
| 1016 | if (stat.kind != .file) | 1016 | if (stat.kind != .file) |
| 1017 | return false; | 1017 | return false; |
| 1018 | 1018 |
lib/std/zig/parser_test.zig+1-1| ... | @@ -4539,7 +4539,7 @@ test "zig fmt: Only indent multiline string literals in function calls" { | ... | @@ -4539,7 +4539,7 @@ test "zig fmt: Only indent multiline string literals in function calls" { |
| 4539 | test "zig fmt: Don't add extra newline after if" { | 4539 | test "zig fmt: Don't add extra newline after if" { |
| 4540 | try testCanonical( | 4540 | try testCanonical( |
| 4541 | \\pub fn atomicSymLink(allocator: Allocator, existing_path: []const u8, new_path: []const u8) !void { | 4541 | \\pub fn atomicSymLink(allocator: Allocator, existing_path: []const u8, new_path: []const u8) !void { |
| 4542 | \\ if (cwd().symLink(existing_path, new_path, .{})) { | 4542 | \\ if (foo().bar(existing_path, new_path, .{})) { |
| 4543 | \\ return; | 4543 | \\ return; |
| 4544 | \\ } | 4544 | \\ } |
| 4545 | \\} | 4545 | \\} |
src/Builtin.zig+2-1| ... | @@ -313,8 +313,9 @@ pub fn updateFileOnDisk(file: *File, comp: *Compilation) !void { | ... | @@ -313,8 +313,9 @@ pub fn updateFileOnDisk(file: *File, comp: *Compilation) !void { |
| 313 | assert(file.source != null); | 313 | assert(file.source != null); |
| 314 | 314 | ||
| 315 | const root_dir, const sub_path = file.path.openInfo(comp.dirs); | 315 | const root_dir, const sub_path = file.path.openInfo(comp.dirs); |
| 316 | const io = comp.io; | ||
| 316 | 317 | ||
| 317 | if (root_dir.statFile(sub_path)) |stat| { | 318 | if (root_dir.statFile(io, sub_path, .{})) |stat| { |
| 318 | if (stat.size != file.source.?.len) { | 319 | if (stat.size != file.source.?.len) { |
| 319 | std.log.warn( | 320 | std.log.warn( |
| 320 | "the cached file '{f}' had the wrong size. Expected {d}, found {d}. " ++ | 321 | "the cached file '{f}' had the wrong size. Expected {d}, found {d}. " ++ |
src/Package/Fetch.zig+10-10| ... | @@ -1440,13 +1440,13 @@ fn recursiveDirectoryCopy(f: *Fetch, dir: Io.Dir, tmp_dir: Io.Dir) anyerror!void | ... | @@ -1440,13 +1440,13 @@ fn recursiveDirectoryCopy(f: *Fetch, dir: Io.Dir, tmp_dir: Io.Dir) anyerror!void |
| 1440 | }, | 1440 | }, |
| 1441 | .sym_link => { | 1441 | .sym_link => { |
| 1442 | var buf: [fs.max_path_bytes]u8 = undefined; | 1442 | var buf: [fs.max_path_bytes]u8 = undefined; |
| 1443 | const link_name = try dir.readLink(entry.path, &buf); | 1443 | const link_name = try dir.readLink(io, entry.path, &buf); |
| 1444 | // TODO: if this would create a symlink to outside | 1444 | // TODO: if this would create a symlink to outside |
| 1445 | // the destination directory, fail with an error instead. | 1445 | // the destination directory, fail with an error instead. |
| 1446 | tmp_dir.symLink(link_name, entry.path, .{}) catch |err| switch (err) { | 1446 | tmp_dir.symLink(io, link_name, entry.path, .{}) catch |err| switch (err) { |
| 1447 | error.FileNotFound => { | 1447 | error.FileNotFound => { |
| 1448 | if (fs.path.dirname(entry.path)) |dirname| try tmp_dir.makePath(io, dirname); | 1448 | if (fs.path.dirname(entry.path)) |dirname| try tmp_dir.makePath(io, dirname); |
| 1449 | try tmp_dir.symLink(link_name, entry.path, .{}); | 1449 | try tmp_dir.symLink(io, link_name, entry.path, .{}); |
| 1450 | }, | 1450 | }, |
| 1451 | else => |e| return e, | 1451 | else => |e| return e, |
| 1452 | }; | 1452 | }; |
| ... | @@ -1698,7 +1698,7 @@ fn hashFileFallible(io: Io, dir: Io.Dir, hashed_file: *HashedFile) HashedFile.Er | ... | @@ -1698,7 +1698,7 @@ fn hashFileFallible(io: Io, dir: Io.Dir, hashed_file: *HashedFile) HashedFile.Er |
| 1698 | } | 1698 | } |
| 1699 | }, | 1699 | }, |
| 1700 | .link => { | 1700 | .link => { |
| 1701 | const link_name = try dir.readLink(hashed_file.fs_path, &buf); | 1701 | const link_name = try dir.readLink(io, hashed_file.fs_path, &buf); |
| 1702 | if (fs.path.sep != canonical_sep) { | 1702 | if (fs.path.sep != canonical_sep) { |
| 1703 | // Package hashes are intended to be consistent across | 1703 | // Package hashes are intended to be consistent across |
| 1704 | // platforms which means we must normalize path separators | 1704 | // platforms which means we must normalize path separators |
| ... | @@ -2218,13 +2218,13 @@ test "set executable bit based on file content" { | ... | @@ -2218,13 +2218,13 @@ test "set executable bit based on file content" { |
| 2218 | defer out.close(io); | 2218 | defer out.close(io); |
| 2219 | const S = std.posix.S; | 2219 | const S = std.posix.S; |
| 2220 | // expect executable bit not set | 2220 | // expect executable bit not set |
| 2221 | try std.testing.expect((try out.statFile("file1")).mode & S.IXUSR == 0); | 2221 | try std.testing.expect((try out.statFile(io, "file1", .{})).mode & S.IXUSR == 0); |
| 2222 | try std.testing.expect((try out.statFile("script_without_shebang")).mode & S.IXUSR == 0); | 2222 | try std.testing.expect((try out.statFile(io, "script_without_shebang", .{})).mode & S.IXUSR == 0); |
| 2223 | // expect executable bit set | 2223 | // expect executable bit set |
| 2224 | try std.testing.expect((try out.statFile("hello")).mode & S.IXUSR != 0); | 2224 | try std.testing.expect((try out.statFile(io, "hello", .{})).mode & S.IXUSR != 0); |
| 2225 | try std.testing.expect((try out.statFile("script")).mode & S.IXUSR != 0); | 2225 | try std.testing.expect((try out.statFile(io, "script", .{})).mode & S.IXUSR != 0); |
| 2226 | try std.testing.expect((try out.statFile("script_with_shebang_without_exec_bit")).mode & S.IXUSR != 0); | 2226 | try std.testing.expect((try out.statFile(io, "script_with_shebang_without_exec_bit", .{})).mode & S.IXUSR != 0); |
| 2227 | try std.testing.expect((try out.statFile("hello_ln")).mode & S.IXUSR != 0); | 2227 | try std.testing.expect((try out.statFile(io, "hello_ln", .{})).mode & S.IXUSR != 0); |
| 2228 | 2228 | ||
| 2229 | // | 2229 | // |
| 2230 | // $ ls -al zig-cache/tmp/OCz9ovUcstDjTC_U/zig-global-cache/p/1220fecb4c06a9da8673c87fe8810e15785f1699212f01728eadce094d21effeeef3 | 2230 | // $ ls -al zig-cache/tmp/OCz9ovUcstDjTC_U/zig-global-cache/p/1220fecb4c06a9da8673c87fe8810e15785f1699212f01728eadce094d21effeeef3 |
src/Package/Fetch/git.zig+1-1| ... | @@ -281,7 +281,7 @@ pub const Repository = struct { | ... | @@ -281,7 +281,7 @@ pub const Repository = struct { |
| 281 | const symlink_object = try repository.odb.readObject(); | 281 | const symlink_object = try repository.odb.readObject(); |
| 282 | if (symlink_object.type != .blob) return error.InvalidFile; | 282 | if (symlink_object.type != .blob) return error.InvalidFile; |
| 283 | const link_name = symlink_object.data; | 283 | const link_name = symlink_object.data; |
| 284 | dir.symLink(link_name, entry.name, .{}) catch |e| { | 284 | dir.symLink(io, link_name, entry.name, .{}) catch |e| { |
| 285 | const file_name = try std.fs.path.join(diagnostics.allocator, &.{ current_path, entry.name }); | 285 | const file_name = try std.fs.path.join(diagnostics.allocator, &.{ current_path, entry.name }); |
| 286 | errdefer diagnostics.allocator.free(file_name); | 286 | errdefer diagnostics.allocator.free(file_name); |
| 287 | const link_name_dup = try diagnostics.allocator.dupe(u8, link_name); | 287 | const link_name_dup = try diagnostics.allocator.dupe(u8, link_name); |
src/fmt.zig+1-1| ... | @@ -182,7 +182,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! | ... | @@ -182,7 +182,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! |
| 182 | // Mark any excluded files/directories as already seen, | 182 | // Mark any excluded files/directories as already seen, |
| 183 | // so that they are skipped later during actual processing | 183 | // so that they are skipped later during actual processing |
| 184 | for (excluded_files.items) |file_path| { | 184 | for (excluded_files.items) |file_path| { |
| 185 | const stat = Io.Dir.cwd().statFile(file_path) catch |err| switch (err) { | 185 | const stat = Io.Dir.cwd().statFile(io, file_path, .{}) catch |err| switch (err) { |
| 186 | error.FileNotFound => continue, | 186 | error.FileNotFound => continue, |
| 187 | // On Windows, statFile does not work for directories | 187 | // On Windows, statFile does not work for directories |
| 188 | error.IsDir => dir: { | 188 | error.IsDir => dir: { |