| author | |
| committer | |
| log | 8632a28ca95a5a491bde57fdc45d9a0ce3cf597e |
| tree | aa5d5f1db57d1037d5a18a92b69c594425bcb204 |
| parent | 9bbb8e0d8e8ce413ad2a9125b1eb9ddbf32b6c87 |
and rename OperationNotSupported to OperationUnsupported8 files changed, 220 insertions(+), 152 deletions(-)
lib/std/Io.zig+3-1| ... | ... | @@ -670,7 +670,8 @@ pub const VTable = struct { |
| 670 | 670 | dirOpenFile: *const fn (?*anyopaque, Dir, []const u8, File.OpenFlags) File.OpenError!File, |
| 671 | 671 | dirClose: *const fn (?*anyopaque, []const Dir) void, |
| 672 | 672 | dirRead: *const fn (?*anyopaque, *Dir.Reader, []Dir.Entry) Dir.Reader.Error!usize, |
| 673 | dirRealPath: *const fn (?*anyopaque, Dir, path_name: []const u8, out_buffer: []u8) Dir.RealPathError!usize, | |
| 673 | dirRealPath: *const fn (?*anyopaque, Dir, out_buffer: []u8) Dir.RealPathError!usize, | |
| 674 | dirRealPathFile: *const fn (?*anyopaque, Dir, path_name: []const u8, out_buffer: []u8) Dir.RealPathFileError!usize, | |
| 674 | 675 | dirDeleteFile: *const fn (?*anyopaque, Dir, []const u8) Dir.DeleteFileError!void, |
| 675 | 676 | dirDeleteDir: *const fn (?*anyopaque, Dir, []const u8) Dir.DeleteDirError!void, |
| 676 | 677 | dirRename: *const fn (?*anyopaque, old_dir: Dir, old_sub_path: []const u8, new_dir: Dir, new_sub_path: []const u8) Dir.RenameError!void, |
| ... | ... | @@ -709,6 +710,7 @@ pub const VTable = struct { |
| 709 | 710 | fileTryLock: *const fn (?*anyopaque, File, File.Lock) File.LockError!bool, |
| 710 | 711 | fileUnlock: *const fn (?*anyopaque, File) void, |
| 711 | 712 | fileDowngradeLock: *const fn (?*anyopaque, File) File.DowngradeLockError!void, |
| 713 | fileRealPath: *const fn (?*anyopaque, File, out_buffer: []u8) File.RealPathError!usize, | |
| 712 | 714 | |
| 713 | 715 | processExecutableOpen: *const fn (?*anyopaque, File.OpenFlags) std.process.OpenExecutableError!File, |
| 714 | 716 | processExecutablePath: *const fn (?*anyopaque, buffer: []u8) std.process.ExecutablePathError!usize, |
lib/std/Io/Dir.zig+50-65| ... | ... | @@ -766,95 +766,80 @@ pub fn statFile(dir: Dir, io: Io, sub_path: []const u8, options: StatFileOptions |
| 766 | 766 | return io.vtable.dirStatFile(io.userdata, dir, sub_path, options); |
| 767 | 767 | } |
| 768 | 768 | |
| 769 | pub const RealPathError = error{ | |
| 770 | FileNotFound, | |
| 771 | AccessDenied, | |
| 772 | PermissionDenied, | |
| 773 | NotSupported, | |
| 774 | NotDir, | |
| 775 | SymLinkLoop, | |
| 776 | InputOutput, | |
| 777 | FileTooBig, | |
| 778 | IsDir, | |
| 779 | ProcessFdQuotaExceeded, | |
| 780 | SystemFdQuotaExceeded, | |
| 781 | NoDevice, | |
| 782 | SystemResources, | |
| 783 | NoSpaceLeft, | |
| 784 | FileSystem, | |
| 785 | DeviceBusy, | |
| 786 | SharingViolation, | |
| 787 | PipeBusy, | |
| 788 | /// On Windows, `\\server` or `\\server\share` was not found. | |
| 789 | NetworkNotFound, | |
| 790 | PathAlreadyExists, | |
| 791 | /// On Windows, antivirus software is enabled by default. It can be | |
| 792 | /// disabled, but Windows Update sometimes ignores the user's preference | |
| 793 | /// and re-enables it. When enabled, antivirus software on Windows | |
| 794 | /// intercepts file system operations and makes them significantly slower | |
| 795 | /// in addition to possibly failing with this error code. | |
| 796 | AntivirusInterference, | |
| 797 | /// On Windows, the volume does not contain a recognized file system. File | |
| 798 | /// system drivers might not be loaded, or the volume may be corrupt. | |
| 799 | UnrecognizedVolume, | |
| 800 | } || PathNameError || Io.Cancelable || Io.UnexpectedError; | |
| 769 | pub const RealPathError = File.RealPathError; | |
| 770 | ||
| 771 | /// Obtains the canonicalized absolute path name of `sub_path` relative to this | |
| 772 | /// `Dir`. If `sub_path` is absolute, ignores this `Dir` handle and obtains the | |
| 773 | /// canonicalized absolute pathname of `sub_path` argument. | |
| 774 | /// | |
| 775 | /// This function has limited platform support, and using it can lead to | |
| 776 | /// unnecessary failures and race conditions. It is generally advisable to | |
| 777 | /// avoid this function entirely. | |
| 778 | pub fn realPath(dir: Dir, io: Io, out_buffer: []u8) RealPathError!usize { | |
| 779 | return io.vtable.dirRealPath(io.userdata, dir, out_buffer); | |
| 780 | } | |
| 801 | 781 | |
| 802 | /// This function returns the canonicalized absolute path name of `sub_path` | |
| 803 | /// relative to this `Dir`. If `sub_path` is absolute, ignores this `Dir` | |
| 804 | /// handle and returns the canonicalized absolute pathname of `sub_path` | |
| 805 | /// argument. | |
| 782 | pub const RealPathFileError = RealPathError || PathNameError; | |
| 783 | ||
| 784 | /// Obtains the canonicalized absolute path name of `sub_path` relative to this | |
| 785 | /// `Dir`. If `sub_path` is absolute, ignores this `Dir` handle and obtains the | |
| 786 | /// canonicalized absolute pathname of `sub_path` argument. | |
| 806 | 787 | /// |
| 807 | /// This function is not universally supported by all platforms, and using this | |
| 808 | /// function can lead to unnecessary failures and race conditions. | |
| 788 | /// This function has limited platform support, and using it can lead to | |
| 789 | /// unnecessary failures and race conditions. It is generally advisable to | |
| 790 | /// avoid this function entirely. | |
| 809 | 791 | /// |
| 810 | 792 | /// See also: |
| 811 | /// * `realPathAlloc`. | |
| 812 | /// * `realPathAbsolute`. | |
| 813 | pub fn realPath(dir: Dir, io: Io, sub_path: []const u8, out_buffer: []u8) RealPathError!usize { | |
| 814 | return io.vtable.dirRealPath(io.userdata, dir, sub_path, out_buffer); | |
| 793 | /// * `realPathFileAlloc`. | |
| 794 | /// * `realPathFileAbsolute`. | |
| 795 | pub fn realPathFile(dir: Dir, io: Io, sub_path: []const u8, out_buffer: []u8) RealPathFileError!usize { | |
| 796 | return io.vtable.dirRealPathFile(io.userdata, dir, sub_path, out_buffer); | |
| 815 | 797 | } |
| 816 | 798 | |
| 817 | pub const RealPathAllocError = RealPathError || Allocator.Error; | |
| 799 | pub const RealPathFileAllocError = RealPathFileError || Allocator.Error; | |
| 818 | 800 | |
| 819 | /// Same as `realPath` except allocates result. | |
| 801 | /// Same as `realPathFile` except allocates result. | |
| 820 | 802 | /// |
| 821 | /// This function is not universally supported by all platforms, and using this | |
| 822 | /// function can lead to unnecessary failures and race conditions. | |
| 803 | /// This function has limited platform support, and using it can lead to | |
| 804 | /// unnecessary failures and race conditions. It is generally advisable to | |
| 805 | /// avoid this function entirely. | |
| 823 | 806 | /// |
| 824 | 807 | /// See also: |
| 825 | /// * `realPath`. | |
| 826 | /// * `realPathAbsolute`. | |
| 827 | pub fn realPathAlloc(dir: Dir, io: Io, sub_path: []const u8, allocator: Allocator) RealPathAllocError![:0]u8 { | |
| 808 | /// * `realPathFile`. | |
| 809 | /// * `realPathFileAbsolute`. | |
| 810 | pub fn realPathFileAlloc(dir: Dir, io: Io, sub_path: []const u8, allocator: Allocator) RealPathFileAllocError![:0]u8 { | |
| 828 | 811 | var buffer: [max_path_bytes]u8 = undefined; |
| 829 | const n = try realPath(dir, io, sub_path, &buffer); | |
| 812 | const n = try realPathFile(dir, io, sub_path, &buffer); | |
| 830 | 813 | return allocator.dupeZ(u8, buffer[0..n]); |
| 831 | 814 | } |
| 832 | 815 | |
| 833 | /// Same as `realPath` except `absolute_path` is asserted to be an absolute | |
| 816 | /// Same as `realPathFile` except `absolute_path` is asserted to be an absolute | |
| 834 | 817 | /// path. |
| 835 | 818 | /// |
| 836 | /// This function is not universally supported by all platforms, and using this | |
| 837 | /// function can lead to unnecessary failures and race conditions. | |
| 819 | /// This function has limited platform support, and using it can lead to | |
| 820 | /// unnecessary failures and race conditions. It is generally advisable to | |
| 821 | /// avoid this function entirely. | |
| 838 | 822 | /// |
| 839 | 823 | /// See also: |
| 840 | /// * `realPath`. | |
| 841 | /// * `realPathAlloc`. | |
| 842 | pub fn realPathAbsolute(io: Io, absolute_path: []const u8, out_buffer: []u8) RealPathError!usize { | |
| 824 | /// * `realPathFile`. | |
| 825 | /// * `realPathFileAlloc`. | |
| 826 | pub fn realPathFileAbsolute(io: Io, absolute_path: []const u8, out_buffer: []u8) RealPathFileError!usize { | |
| 843 | 827 | assert(path.isAbsolute(absolute_path)); |
| 844 | return io.vtable.dirRealPath(io.userdata, .cwd(), absolute_path, out_buffer); | |
| 828 | return io.vtable.dirRealPathFile(io.userdata, .cwd(), absolute_path, out_buffer); | |
| 845 | 829 | } |
| 846 | 830 | |
| 847 | /// Same as `realPathAbsolute` except allocates result. | |
| 831 | /// Same as `realPathFileAbsolute` except allocates result. | |
| 848 | 832 | /// |
| 849 | /// This function is not universally supported by all platforms, and using this | |
| 850 | /// function can lead to unnecessary failures and race conditions. | |
| 833 | /// This function has limited platform support, and using it can lead to | |
| 834 | /// unnecessary failures and race conditions. It is generally advisable to | |
| 835 | /// avoid this function entirely. | |
| 851 | 836 | /// |
| 852 | 837 | /// See also: |
| 853 | /// * `realPathAbsolute`. | |
| 854 | /// * `realPath`. | |
| 855 | pub fn realPathAbsoluteAlloc(io: Io, absolute_path: []const u8, allocator: Allocator) RealPathAllocError![:0]u8 { | |
| 838 | /// * `realPathFileAbsolute`. | |
| 839 | /// * `realPathFile`. | |
| 840 | pub fn realPathFileAbsoluteAlloc(io: Io, absolute_path: []const u8, allocator: Allocator) RealPathFileAllocError![:0]u8 { | |
| 856 | 841 | var buffer: [max_path_bytes]u8 = undefined; |
| 857 | const n = try realPathAbsolute(io, absolute_path, &buffer); | |
| 842 | const n = try realPathFileAbsolute(io, absolute_path, &buffer); | |
| 858 | 843 | return allocator.dupeZ(u8, buffer[0..n]); |
| 859 | 844 | } |
| 860 | 845 | |
| ... | ... | @@ -1765,7 +1750,7 @@ pub const SetFilePermissionsError = PathNameError || SetPermissionsError || erro |
| 1765 | 1750 | SystemFdQuotaExceeded, |
| 1766 | 1751 | /// `SetFilePermissionsOptions.follow_symlinks` was set to false, which is |
| 1767 | 1752 | /// not allowed by the file system or operating system. |
| 1768 | OperationNotSupported, | |
| 1753 | OperationUnsupported, | |
| 1769 | 1754 | }; |
| 1770 | 1755 | |
| 1771 | 1756 | pub const SetFilePermissionsOptions = struct { |
lib/std/Io/File.zig+49| ... | ... | @@ -627,6 +627,55 @@ pub fn downgradeLock(file: File, io: Io) LockError!void { |
| 627 | 627 | return io.vtable.fileDowngradeLock(io.userdata, file); |
| 628 | 628 | } |
| 629 | 629 | |
| 630 | pub const RealPathError = error{ | |
| 631 | /// This operating system, file system, or `Io` implementation does not | |
| 632 | /// support realpath operations. | |
| 633 | OperationUnsupported, | |
| 634 | /// The full file system path could not fit into the provided buffer, or | |
| 635 | /// due to its length could not be obtained via realpath functions no | |
| 636 | /// matter the buffer size provided. | |
| 637 | NameTooLong, | |
| 638 | FileNotFound, | |
| 639 | AccessDenied, | |
| 640 | PermissionDenied, | |
| 641 | NotDir, | |
| 642 | SymLinkLoop, | |
| 643 | InputOutput, | |
| 644 | FileTooBig, | |
| 645 | IsDir, | |
| 646 | ProcessFdQuotaExceeded, | |
| 647 | SystemFdQuotaExceeded, | |
| 648 | NoDevice, | |
| 649 | SystemResources, | |
| 650 | NoSpaceLeft, | |
| 651 | FileSystem, | |
| 652 | DeviceBusy, | |
| 653 | SharingViolation, | |
| 654 | PipeBusy, | |
| 655 | /// On Windows, `\\server` or `\\server\share` was not found. | |
| 656 | NetworkNotFound, | |
| 657 | PathAlreadyExists, | |
| 658 | /// On Windows, antivirus software is enabled by default. It can be | |
| 659 | /// disabled, but Windows Update sometimes ignores the user's preference | |
| 660 | /// and re-enables it. When enabled, antivirus software on Windows | |
| 661 | /// intercepts file system operations and makes them significantly slower | |
| 662 | /// in addition to possibly failing with this error code. | |
| 663 | AntivirusInterference, | |
| 664 | /// On Windows, the volume does not contain a recognized file system. File | |
| 665 | /// system drivers might not be loaded, or the volume may be corrupt. | |
| 666 | UnrecognizedVolume, | |
| 667 | } || Io.Cancelable || Io.UnexpectedError; | |
| 668 | ||
| 669 | /// Obtains the canonicalized absolute path name corresponding to an open file | |
| 670 | /// handle. | |
| 671 | /// | |
| 672 | /// This function has limited platform support, and using it can lead to | |
| 673 | /// unnecessary failures and race conditions. It is generally advisable to | |
| 674 | /// avoid this function entirely. | |
| 675 | pub fn realPath(file: File, io: Io, out_buffer: []u8) RealPathError!usize { | |
| 676 | return io.vtable.fileRealPath(io.userdata, file, out_buffer); | |
| 677 | } | |
| 678 | ||
| 630 | 679 | test { |
| 631 | 680 | _ = Reader; |
| 632 | 681 | _ = Writer; |
lib/std/Io/Threaded.zig+50-16| ... | ... | @@ -716,6 +716,7 @@ pub fn io(t: *Threaded) Io { |
| 716 | 716 | .dirClose = dirClose, |
| 717 | 717 | .dirRead = dirRead, |
| 718 | 718 | .dirRealPath = dirRealPath, |
| 719 | .dirRealPathFile = dirRealPathFile, | |
| 719 | 720 | .dirDeleteFile = dirDeleteFile, |
| 720 | 721 | .dirDeleteDir = dirDeleteDir, |
| 721 | 722 | .dirRename = dirRename, |
| ... | ... | @@ -752,6 +753,7 @@ pub fn io(t: *Threaded) Io { |
| 752 | 753 | .fileTryLock = fileTryLock, |
| 753 | 754 | .fileUnlock = fileUnlock, |
| 754 | 755 | .fileDowngradeLock = fileDowngradeLock, |
| 756 | .fileRealPath = fileRealPath, | |
| 755 | 757 | |
| 756 | 758 | .processExecutableOpen = processExecutableOpen, |
| 757 | 759 | .processExecutablePath = processExecutablePath, |
| ... | ... | @@ -848,6 +850,7 @@ pub fn ioBasic(t: *Threaded) Io { |
| 848 | 850 | .dirClose = dirClose, |
| 849 | 851 | .dirRead = dirRead, |
| 850 | 852 | .dirRealPath = dirRealPath, |
| 853 | .dirRealPathFile = dirRealPathFile, | |
| 851 | 854 | .dirDeleteFile = dirDeleteFile, |
| 852 | 855 | .dirDeleteDir = dirDeleteDir, |
| 853 | 856 | .dirRename = dirRename, |
| ... | ... | @@ -884,6 +887,7 @@ pub fn ioBasic(t: *Threaded) Io { |
| 884 | 887 | .fileTryLock = fileTryLock, |
| 885 | 888 | .fileUnlock = fileUnlock, |
| 886 | 889 | .fileDowngradeLock = fileDowngradeLock, |
| 890 | .fileRealPath = fileRealPath, | |
| 887 | 891 | |
| 888 | 892 | .processExecutableOpen = processExecutableOpen, |
| 889 | 893 | .processExecutablePath = processExecutablePath, |
| ... | ... | @@ -3848,22 +3852,21 @@ fn dirReadUnimplemented(userdata: ?*anyopaque, dir_reader: *Dir.Reader, buffer: |
| 3848 | 3852 | return error.Unimplemented; |
| 3849 | 3853 | } |
| 3850 | 3854 | |
| 3851 | const dirRealPath = switch (native_os) { | |
| 3852 | .windows => dirRealPathWindows, | |
| 3853 | else => dirRealPathPosix, | |
| 3855 | const dirRealPathFile = switch (native_os) { | |
| 3856 | .windows => dirRealPathFileWindows, | |
| 3857 | else => dirRealPathFilePosix, | |
| 3854 | 3858 | }; |
| 3855 | 3859 | |
| 3856 | fn dirRealPathWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, out_buffer: []u8) Dir.RealPathError!usize { | |
| 3860 | fn dirRealPathFileWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, out_buffer: []u8) Dir.RealPathFileError!usize { | |
| 3857 | 3861 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 3858 | const w = windows; | |
| 3859 | 3862 | const current_thread = Thread.getCurrent(t); |
| 3860 | 3863 | |
| 3861 | 3864 | try current_thread.checkCancel(); |
| 3862 | 3865 | |
| 3863 | var path_name_w = try w.sliceToPrefixedFileW(dir.handle, sub_path); | |
| 3866 | var path_name_w = try windows.sliceToPrefixedFileW(dir.handle, sub_path); | |
| 3864 | 3867 | |
| 3865 | 3868 | const h_file = blk: { |
| 3866 | const res = w.OpenFile(path_name_w.span(), .{ | |
| 3869 | const res = windows.OpenFile(path_name_w.span(), .{ | |
| 3867 | 3870 | .dir = dir.handle, |
| 3868 | 3871 | .access_mask = .{ |
| 3869 | 3872 | .GENERIC = .{ .READ = true }, |
| ... | ... | @@ -3877,9 +3880,13 @@ fn dirRealPathWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, out |
| 3877 | 3880 | }; |
| 3878 | 3881 | break :blk res; |
| 3879 | 3882 | }; |
| 3880 | defer w.CloseHandle(h_file); | |
| 3883 | defer windows.CloseHandle(h_file); | |
| 3884 | return realPathWindows(current_thread, h_file, out_buffer); | |
| 3885 | } | |
| 3881 | 3886 | |
| 3882 | const wide_slice = w.GetFinalPathNameByHandle(h_file, .{}, out_buffer); | |
| 3887 | fn realPathWindows(current_thread: *Thread, h_file: windows.HANDLE, out_buffer: []u8) Dir.RealPathFileError { | |
| 3888 | _ = current_thread; // TODO move GetFinalPathNameByHandle logic into std.Io.Threaded and add cancel checks | |
| 3889 | const wide_slice = windows.GetFinalPathNameByHandle(h_file, .{}, out_buffer); | |
| 3883 | 3890 | |
| 3884 | 3891 | const len = std.unicode.calcWtf8Len(wide_slice); |
| 3885 | 3892 | if (len > out_buffer.len) |
| ... | ... | @@ -3888,9 +3895,8 @@ fn dirRealPathWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, out |
| 3888 | 3895 | return std.unicode.wtf16LeToWtf8(out_buffer, wide_slice); |
| 3889 | 3896 | } |
| 3890 | 3897 | |
| 3891 | fn dirRealPathPosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, out_buffer: []u8) Dir.RealPathError!usize { | |
| 3892 | if (native_os == .wasi) @compileError("unsupported operating system"); | |
| 3893 | const max_path_bytes = std.fs.max_path_bytes; | |
| 3898 | fn dirRealPathFilePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, out_buffer: []u8) Dir.RealPathFileError!usize { | |
| 3899 | if (native_os == .wasi) return error.OperationUnsupported; | |
| 3894 | 3900 | |
| 3895 | 3901 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 3896 | 3902 | const current_thread = Thread.getCurrent(t); |
| ... | ... | @@ -3949,7 +3955,35 @@ fn dirRealPathPosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, out_b |
| 3949 | 3955 | } |
| 3950 | 3956 | }; |
| 3951 | 3957 | errdefer posix.close(fd); |
| 3958 | return realPathPosix(current_thread, fd, out_buffer); | |
| 3959 | } | |
| 3960 | ||
| 3961 | const dirRealPath = switch (native_os) { | |
| 3962 | .windows => dirRealPathWindows, | |
| 3963 | else => dirRealPathPosix, | |
| 3964 | }; | |
| 3965 | ||
| 3966 | fn dirRealPathPosix(userdata: ?*anyopaque, dir: Dir, out_buffer: []u8) Dir.RealPathError!usize { | |
| 3967 | if (native_os == .wasi) return error.OperationUnsupported; | |
| 3968 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | |
| 3969 | const current_thread = Thread.getCurrent(t); | |
| 3970 | return realPathPosix(current_thread, dir.handle, out_buffer); | |
| 3971 | } | |
| 3972 | ||
| 3973 | fn dirRealPathWindows(userdata: ?*anyopaque, dir: Dir, out_buffer: []u8) Dir.RealPathError!usize { | |
| 3974 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | |
| 3975 | const current_thread = Thread.getCurrent(t); | |
| 3976 | return realPathWindows(current_thread, dir.handle, out_buffer); | |
| 3977 | } | |
| 3978 | ||
| 3979 | fn fileRealPath(userdata: ?*anyopaque, file: File, out_buffer: []u8) File.RealPathError!usize { | |
| 3980 | if (native_os == .wasi) return error.OperationUnsupported; | |
| 3981 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | |
| 3982 | const current_thread = Thread.getCurrent(t); | |
| 3983 | return realPathPosix(current_thread, file.handle, out_buffer); | |
| 3984 | } | |
| 3952 | 3985 | |
| 3986 | fn realPathPosix(current_thread: *Thread, fd: posix.fd_t, out_buffer: []u8) File.RealPathError!usize { | |
| 3953 | 3987 | switch (native_os) { |
| 3954 | 3988 | .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => { |
| 3955 | 3989 | // On macOS, we can use F.GETPATH fcntl command to query the OS for |
| ... | ... | @@ -4049,7 +4083,7 @@ fn dirRealPathPosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, out_b |
| 4049 | 4083 | return len; |
| 4050 | 4084 | }, |
| 4051 | 4085 | .netbsd, .dragonfly => { |
| 4052 | @memset(out_buffer[0..max_path_bytes], 0); | |
| 4086 | @memset(out_buffer[0..Dir.max_path_bytes], 0); | |
| 4053 | 4087 | try current_thread.beginSyscall(); |
| 4054 | 4088 | while (true) { |
| 4055 | 4089 | switch (posix.errno(std.c.fcntl(fd, posix.F.GETPATH, out_buffer))) { |
| ... | ... | @@ -4077,7 +4111,7 @@ fn dirRealPathPosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, out_b |
| 4077 | 4111 | } |
| 4078 | 4112 | return std.mem.indexOfScalar(u8, &out_buffer, 0) orelse out_buffer.len; |
| 4079 | 4113 | }, |
| 4080 | else => @compileError("unsupported OS"), | |
| 4114 | else => return error.OperationUnsupported, | |
| 4081 | 4115 | } |
| 4082 | 4116 | comptime unreachable; |
| 4083 | 4117 | } |
| ... | ... | @@ -5108,7 +5142,7 @@ fn posixFchmodat( |
| 5108 | 5142 | .NOENT => return error.FileNotFound, |
| 5109 | 5143 | .NOTDIR => return error.FileNotFound, |
| 5110 | 5144 | .NOMEM => return error.SystemResources, |
| 5111 | .OPNOTSUPP => return error.OperationNotSupported, | |
| 5145 | .OPNOTSUPP => return error.OperationUnsupported, | |
| 5112 | 5146 | .PERM => return error.PermissionDenied, |
| 5113 | 5147 | .ROFS => return error.ReadOnlyFileSystem, |
| 5114 | 5148 | else => |err| return posix.unexpectedErrno(err), |
| ... | ... | @@ -5144,7 +5178,7 @@ fn posixFchmodat( |
| 5144 | 5178 | .NOENT => return error.FileNotFound, |
| 5145 | 5179 | .NOMEM => return error.SystemResources, |
| 5146 | 5180 | .NOTDIR => return error.FileNotFound, |
| 5147 | .OPNOTSUPP => return error.OperationNotSupported, | |
| 5181 | .OPNOTSUPP => return error.OperationUnsupported, | |
| 5148 | 5182 | .PERM => return error.PermissionDenied, |
| 5149 | 5183 | .ROFS => return error.ReadOnlyFileSystem, |
| 5150 | 5184 | .NOSYS => { |
lib/std/fs/test.zig+53-57| ... | ... | @@ -4,6 +4,7 @@ const native_os = builtin.os.tag; |
| 4 | 4 | const std = @import("../std.zig"); |
| 5 | 5 | const Io = std.Io; |
| 6 | 6 | const mem = std.mem; |
| 7 | const Allocator = std.mem.Allocator; | |
| 7 | 8 | const wasi = std.os.wasi; |
| 8 | 9 | const windows = std.os.windows; |
| 9 | 10 | const ArenaAllocator = std.heap.ArenaAllocator; |
| ... | ... | @@ -27,38 +28,57 @@ const PathType = enum { |
| 27 | 28 | fn isSupported(self: PathType, target_os: std.Target.Os) bool { |
| 28 | 29 | return switch (self) { |
| 29 | 30 | .relative => true, |
| 30 | .absolute => target_os.tag == .windows, // TODO: implement getPathForHandle for other targets | |
| 31 | .absolute => switch (target_os.tag) { | |
| 32 | .windows, | |
| 33 | .driverkit, | |
| 34 | .ios, | |
| 35 | .maccatalyst, | |
| 36 | .macos, | |
| 37 | .tvos, | |
| 38 | .visionos, | |
| 39 | .watchos, | |
| 40 | .linux, | |
| 41 | .illumos, | |
| 42 | .freebsd, | |
| 43 | .serenity, | |
| 44 | => true, | |
| 45 | ||
| 46 | .dragonfly => target_os.version_range.semver.max.order(.{ .major = 6, .minor = 0, .patch = 0 }) != .lt, | |
| 47 | .netbsd => target_os.version_range.semver.max.order(.{ .major = 10, .minor = 0, .patch = 0 }) != .lt, | |
| 48 | else => false, | |
| 49 | }, | |
| 31 | 50 | .unc => target_os.tag == .windows, |
| 32 | 51 | }; |
| 33 | 52 | } |
| 34 | 53 | |
| 35 | 54 | const TransformError = Dir.RealPathError || error{OutOfMemory}; |
| 36 | const TransformFn = fn (allocator: mem.Allocator, dir: Dir, relative_path: [:0]const u8) TransformError![:0]const u8; | |
| 55 | const TransformFn = fn (Allocator, Io, Dir, relative_path: [:0]const u8) TransformError![:0]const u8; | |
| 37 | 56 | |
| 38 | 57 | fn getTransformFn(comptime path_type: PathType) TransformFn { |
| 39 | 58 | switch (path_type) { |
| 40 | 59 | .relative => return struct { |
| 41 | fn transform(allocator: mem.Allocator, dir: Dir, relative_path: [:0]const u8) TransformError![:0]const u8 { | |
| 60 | fn transform(allocator: Allocator, io: Io, dir: Dir, relative_path: [:0]const u8) TransformError![:0]const u8 { | |
| 42 | 61 | _ = allocator; |
| 62 | _ = io; | |
| 43 | 63 | _ = dir; |
| 44 | 64 | return relative_path; |
| 45 | 65 | } |
| 46 | 66 | }.transform, |
| 47 | 67 | .absolute => return struct { |
| 48 | fn transform(allocator: mem.Allocator, dir: Dir, relative_path: [:0]const u8) TransformError![:0]const u8 { | |
| 68 | fn transform(allocator: Allocator, io: Io, dir: Dir, relative_path: [:0]const u8) TransformError![:0]const u8 { | |
| 49 | 69 | // The final path may not actually exist which would cause realpath to fail. |
| 50 | 70 | // So instead, we get the path of the dir and join it with the relative path. |
| 51 | 71 | var fd_path_buf: [Dir.max_path_bytes]u8 = undefined; |
| 52 | const dir_path = try getPathForHandle(dir.handle, &fd_path_buf); | |
| 72 | const dir_path = fd_path_buf[0..try dir.realPath(io, &fd_path_buf)]; | |
| 53 | 73 | return Dir.path.joinZ(allocator, &.{ dir_path, relative_path }); |
| 54 | 74 | } |
| 55 | 75 | }.transform, |
| 56 | 76 | .unc => return struct { |
| 57 | fn transform(allocator: mem.Allocator, dir: Dir, relative_path: [:0]const u8) TransformError![:0]const u8 { | |
| 77 | fn transform(allocator: Allocator, io: Io, dir: Dir, relative_path: [:0]const u8) TransformError![:0]const u8 { | |
| 58 | 78 | // Any drive absolute path (C:\foo) can be converted into a UNC path by |
| 59 | 79 | // using '127.0.0.1' as the server name and '<drive letter>$' as the share name. |
| 60 | 80 | var fd_path_buf: [Dir.max_path_bytes]u8 = undefined; |
| 61 | const dir_path = try getPathForHandle(dir.handle, &fd_path_buf); | |
| 81 | const dir_path = fd_path_buf[0..try dir.realPath(io, &fd_path_buf)]; | |
| 62 | 82 | const windows_path_type = windows.getWin32PathType(u8, dir_path); |
| 63 | 83 | switch (windows_path_type) { |
| 64 | 84 | .unc_absolute => return Dir.path.joinZ(allocator, &.{ dir_path, relative_path }), |
| ... | ... | @@ -77,19 +97,6 @@ const PathType = enum { |
| 77 | 97 | } |
| 78 | 98 | }; |
| 79 | 99 | |
| 80 | fn getPathForHandle(handle: File.Handle, out_buffer: *[Dir.max_path_bytes]u8) ![]u8 { | |
| 81 | switch (native_os) { | |
| 82 | .windows => { | |
| 83 | var wide_buf: [windows.PATH_MAX_WIDE]u16 = undefined; | |
| 84 | const wide_slice = try windows.GetFinalPathNameByHandle(handle, .{}, wide_buf[0..]); | |
| 85 | ||
| 86 | const end_index = std.unicode.wtf16LeToWtf8(out_buffer, wide_slice); | |
| 87 | return out_buffer[0..end_index]; | |
| 88 | }, | |
| 89 | else => @compileError("TODO or unsupported"), | |
| 90 | } | |
| 91 | } | |
| 92 | ||
| 93 | 100 | const TestContext = struct { |
| 94 | 101 | io: Io, |
| 95 | 102 | path_type: PathType, |
| ... | ... | @@ -99,7 +106,7 @@ const TestContext = struct { |
| 99 | 106 | dir: Dir, |
| 100 | 107 | transform_fn: *const PathType.TransformFn, |
| 101 | 108 | |
| 102 | pub fn init(path_type: PathType, path_sep: u8, allocator: mem.Allocator, transform_fn: *const PathType.TransformFn) TestContext { | |
| 109 | pub fn init(path_type: PathType, path_sep: u8, allocator: Allocator, transform_fn: *const PathType.TransformFn) TestContext { | |
| 103 | 110 | const tmp = tmpDir(.{ .iterate = true }); |
| 104 | 111 | return .{ |
| 105 | 112 | .io = testing.io, |
| ... | ... | @@ -123,7 +130,7 @@ const TestContext = struct { |
| 123 | 130 | /// `TestContext.deinit`. |
| 124 | 131 | pub fn transformPath(self: *TestContext, relative_path: [:0]const u8) ![:0]const u8 { |
| 125 | 132 | const allocator = self.arena.allocator(); |
| 126 | const transformed_path = try self.transform_fn(allocator, self.dir, relative_path); | |
| 133 | const transformed_path = try self.transform_fn(allocator, self.io, self.dir, relative_path); | |
| 127 | 134 | if (native_os == .windows) { |
| 128 | 135 | const transformed_sep_path = try allocator.dupeZ(u8, transformed_path); |
| 129 | 136 | std.mem.replaceScalar(u8, transformed_sep_path, switch (self.path_sep) { |
| ... | ... | @@ -268,7 +275,7 @@ fn testReadLink(io: Io, dir: Dir, target_path: []const u8, symlink_path: []const |
| 268 | 275 | try expectEqualStrings(target_path, actual); |
| 269 | 276 | } |
| 270 | 277 | |
| 271 | fn testReadLinkW(allocator: mem.Allocator, dir: Dir, target_path: []const u8, symlink_path: []const u8) !void { | |
| 278 | fn testReadLinkW(allocator: Allocator, dir: Dir, target_path: []const u8, symlink_path: []const u8) !void { | |
| 272 | 279 | const target_path_w = try std.unicode.wtf8ToWtf16LeAlloc(allocator, target_path); |
| 273 | 280 | defer allocator.free(target_path_w); |
| 274 | 281 | // Calling the W functions directly requires the path to be NT-prefixed |
| ... | ... | @@ -281,7 +288,7 @@ fn testReadLinkW(allocator: mem.Allocator, dir: Dir, target_path: []const u8, sy |
| 281 | 288 | |
| 282 | 289 | fn testReadLinkAbsolute(io: Io, target_path: []const u8, symlink_path: []const u8) !void { |
| 283 | 290 | var buffer: [Dir.max_path_bytes]u8 = undefined; |
| 284 | const given = try Dir.readLinkAbsolute(io, symlink_path, buffer[0..]); | |
| 291 | const given = buffer[0..try Dir.readLinkAbsolute(io, symlink_path, &buffer)]; | |
| 285 | 292 | try expectEqualStrings(target_path, given); |
| 286 | 293 | } |
| 287 | 294 | |
| ... | ... | @@ -339,7 +346,7 @@ test "accessAbsolute" { |
| 339 | 346 | var tmp = tmpDir(.{}); |
| 340 | 347 | defer tmp.cleanup(); |
| 341 | 348 | |
| 342 | const base_path = try tmp.dir.realPathAlloc(io, ".", gpa); | |
| 349 | const base_path = try tmp.dir.realPathFileAlloc(io, ".", gpa); | |
| 343 | 350 | defer gpa.free(base_path); |
| 344 | 351 | |
| 345 | 352 | try Dir.accessAbsolute(io, base_path, .{}); |
| ... | ... | @@ -358,7 +365,7 @@ test "openDirAbsolute" { |
| 358 | 365 | const tmp_ino = (try tmp.dir.stat(io)).inode; |
| 359 | 366 | |
| 360 | 367 | try tmp.dir.makeDir(io, "subdir", .default_dir); |
| 361 | const sub_path = try tmp.dir.realPathAlloc(io, "subdir", gpa); | |
| 368 | const sub_path = try tmp.dir.realPathFileAlloc(io, "subdir", gpa); | |
| 362 | 369 | defer gpa.free(sub_path); |
| 363 | 370 | |
| 364 | 371 | // Can open sub_path |
| ... | ... | @@ -434,10 +441,10 @@ test "openDir non-cwd parent '..'" { |
| 434 | 441 | var dir = try subdir.openDir(io, "..", .{}); |
| 435 | 442 | defer dir.close(io); |
| 436 | 443 | |
| 437 | const expected_path = try tmp.dir.realPathAlloc(io, ".", gpa); | |
| 444 | const expected_path = try tmp.dir.realPathFileAlloc(io, ".", gpa); | |
| 438 | 445 | defer gpa.free(expected_path); |
| 439 | 446 | |
| 440 | const actual_path = try dir.realPathAlloc(io, ".", gpa); | |
| 447 | const actual_path = try dir.realPathFileAlloc(io, ".", gpa); | |
| 441 | 448 | defer gpa.free(actual_path); |
| 442 | 449 | |
| 443 | 450 | try expectEqualStrings(expected_path, actual_path); |
| ... | ... | @@ -461,7 +468,7 @@ test "readLinkAbsolute" { |
| 461 | 468 | defer arena_allocator.deinit(); |
| 462 | 469 | const arena = arena_allocator.allocator(); |
| 463 | 470 | |
| 464 | const base_path = try tmp.dir.realPathAlloc(io, ".", arena); | |
| 471 | const base_path = try tmp.dir.realPathFileAlloc(io, ".", arena); | |
| 465 | 472 | |
| 466 | 473 | { |
| 467 | 474 | const target_path = try Dir.path.join(arena, &.{ base_path, "file.txt" }); |
| ... | ... | @@ -647,11 +654,6 @@ test "Dir.Iterator but dir is deleted during iteration" { |
| 647 | 654 | // Now, when we try to iterate, the next call should return null immediately. |
| 648 | 655 | const entry = try iterator.next(io); |
| 649 | 656 | try testing.expect(entry == null); |
| 650 | ||
| 651 | // On Linux, we can opt-in to receiving a more specific error by calling `nextLinux` | |
| 652 | if (native_os == .linux) { | |
| 653 | try expectError(error.DirNotFound, iterator.nextLinux()); | |
| 654 | } | |
| 655 | 657 | } |
| 656 | 658 | |
| 657 | 659 | fn entryEql(lhs: Dir.Entry, rhs: Dir.Entry) bool { |
| ... | ... | @@ -671,47 +673,41 @@ test "Dir.realPath smoke test" { |
| 671 | 673 | try testWithAllSupportedPathTypes(struct { |
| 672 | 674 | fn impl(ctx: *TestContext) !void { |
| 673 | 675 | const io = ctx.io; |
| 674 | const allocator = ctx.arena.allocator(); | |
| 676 | const arena = ctx.arena.allocator(); | |
| 675 | 677 | const test_file_path = try ctx.transformPath("test_file"); |
| 676 | 678 | const test_dir_path = try ctx.transformPath("test_dir"); |
| 677 | 679 | var buf: [Dir.max_path_bytes]u8 = undefined; |
| 678 | 680 | |
| 679 | 681 | // FileNotFound if the path doesn't exist |
| 680 | try expectError(error.FileNotFound, ctx.dir.realPathAlloc(io, test_file_path, allocator)); | |
| 681 | try expectError(error.FileNotFound, ctx.dir.realPath(io, test_file_path, &buf)); | |
| 682 | try expectError(error.FileNotFound, ctx.dir.realPathAlloc(io, test_dir_path, allocator)); | |
| 683 | try expectError(error.FileNotFound, ctx.dir.realPath(io, test_dir_path, &buf)); | |
| 682 | try expectError(error.FileNotFound, ctx.dir.realPathFileAlloc(io, test_file_path, arena)); | |
| 683 | try expectError(error.FileNotFound, ctx.dir.realPathFile(io, test_file_path, &buf)); | |
| 684 | try expectError(error.FileNotFound, ctx.dir.realPathFileAlloc(io, test_dir_path, arena)); | |
| 685 | try expectError(error.FileNotFound, ctx.dir.realPathFile(io, test_dir_path, &buf)); | |
| 684 | 686 | |
| 685 | 687 | // Now create the file and dir |
| 686 | 688 | try ctx.dir.writeFile(io, .{ .sub_path = test_file_path, .data = "" }); |
| 687 | 689 | try ctx.dir.makeDir(io, test_dir_path, .default_dir); |
| 688 | 690 | |
| 689 | 691 | const base_path = try ctx.transformPath("."); |
| 690 | const base_realpath = try ctx.dir.realPathAlloc(io, base_path, allocator); | |
| 691 | const expected_file_path = try Dir.path.join( | |
| 692 | allocator, | |
| 693 | &.{ base_realpath, "test_file" }, | |
| 694 | ); | |
| 695 | const expected_dir_path = try Dir.path.join( | |
| 696 | allocator, | |
| 697 | &.{ base_realpath, "test_dir" }, | |
| 698 | ); | |
| 692 | const base_realpath = try ctx.dir.realPathFileAlloc(io, base_path, arena); | |
| 693 | const expected_file_path = try Dir.path.join(arena, &.{ base_realpath, "test_file" }); | |
| 694 | const expected_dir_path = try Dir.path.join(arena, &.{ base_realpath, "test_dir" }); | |
| 699 | 695 | |
| 700 | 696 | // First, test non-alloc version |
| 701 | 697 | { |
| 702 | const file_path = try ctx.dir.realPath(io, test_file_path, &buf); | |
| 698 | const file_path = buf[0..try ctx.dir.realPathFile(io, test_file_path, &buf)]; | |
| 703 | 699 | try expectEqualStrings(expected_file_path, file_path); |
| 704 | 700 | |
| 705 | const dir_path = try ctx.dir.realPath(io, test_dir_path, &buf); | |
| 701 | const dir_path = buf[0..try ctx.dir.realPathFile(io, test_dir_path, &buf)]; | |
| 706 | 702 | try expectEqualStrings(expected_dir_path, dir_path); |
| 707 | 703 | } |
| 708 | 704 | |
| 709 | 705 | // Next, test alloc version |
| 710 | 706 | { |
| 711 | const file_path = try ctx.dir.realPathAlloc(io, test_file_path, allocator); | |
| 707 | const file_path = try ctx.dir.realPathFileAlloc(io, test_file_path, arena); | |
| 712 | 708 | try expectEqualStrings(expected_file_path, file_path); |
| 713 | 709 | |
| 714 | const dir_path = try ctx.dir.realPathAlloc(io, test_dir_path, allocator); | |
| 710 | const dir_path = try ctx.dir.realPathFileAlloc(io, test_dir_path, arena); | |
| 715 | 711 | try expectEqualStrings(expected_dir_path, dir_path); |
| 716 | 712 | } |
| 717 | 713 | } |
| ... | ... | @@ -1114,7 +1110,7 @@ test "renameAbsolute" { |
| 1114 | 1110 | defer arena.deinit(); |
| 1115 | 1111 | const allocator = arena.allocator(); |
| 1116 | 1112 | |
| 1117 | const base_path = try tmp_dir.dir.realPathAlloc(io, ".", allocator); | |
| 1113 | const base_path = try tmp_dir.dir.realPathFileAlloc(io, ".", allocator); | |
| 1118 | 1114 | |
| 1119 | 1115 | try expectError(error.FileNotFound, Dir.renameAbsolute( |
| 1120 | 1116 | try Dir.path.join(allocator, &.{ base_path, "missing_file_name" }), |
| ... | ... | @@ -2022,7 +2018,7 @@ test "'.' and '..' in absolute functions" { |
| 2022 | 2018 | defer arena.deinit(); |
| 2023 | 2019 | const allocator = arena.allocator(); |
| 2024 | 2020 | |
| 2025 | const base_path = try tmp.dir.realPathAlloc(io, ".", allocator); | |
| 2021 | const base_path = try tmp.dir.realPathFileAlloc(io, ".", allocator); | |
| 2026 | 2022 | |
| 2027 | 2023 | const subdir_path = try Dir.path.join(allocator, &.{ base_path, "./subdir" }); |
| 2028 | 2024 | try Dir.makeDirAbsolute(io, subdir_path, .default_dir); |
| ... | ... | @@ -2140,8 +2136,8 @@ test "invalid UTF-8/WTF-8 paths" { |
| 2140 | 2136 | try expectError(expected_err, ctx.dir.statFile(io, invalid_path, .{})); |
| 2141 | 2137 | |
| 2142 | 2138 | if (native_os != .wasi) { |
| 2143 | try expectError(expected_err, ctx.dir.realPath(io, invalid_path, &[_]u8{})); | |
| 2144 | try expectError(expected_err, ctx.dir.realPathAlloc(io, invalid_path, testing.allocator)); | |
| 2139 | try expectError(expected_err, ctx.dir.realPathFile(io, invalid_path, &[_]u8{})); | |
| 2140 | try expectError(expected_err, ctx.dir.realPathFileAlloc(io, invalid_path, testing.allocator)); | |
| 2145 | 2141 | } |
| 2146 | 2142 | |
| 2147 | 2143 | try expectError(expected_err, Dir.rename(ctx.dir, invalid_path, ctx.dir, invalid_path, io)); |
| ... | ... | @@ -2402,7 +2398,7 @@ test "fchmodat smoke test" { |
| 2402 | 2398 | |
| 2403 | 2399 | var test_link = true; |
| 2404 | 2400 | tmp.dir.setFilePermissions(io, "symlink", .fromMode(0o600), .{ .follow_symlinks = false }) catch |err| switch (err) { |
| 2405 | error.OperationNotSupported => test_link = false, | |
| 2401 | error.OperationUnsupported => test_link = false, | |
| 2406 | 2402 | else => |e| return e, |
| 2407 | 2403 | }; |
| 2408 | 2404 | if (test_link) try expectMode(io, tmp.dir, "symlink", .fromMode(0o600)); |
lib/std/os/windows.zig+2| ... | ... | @@ -3620,6 +3620,8 @@ pub const GetFinalPathNameByHandleFormat = struct { |
| 3620 | 3620 | /// NT or DOS volume name (e.g., `\Device\HarddiskVolume0\foo.txt` versus `C:\foo.txt`). |
| 3621 | 3621 | /// If DOS volume name format is selected, note that this function does *not* prepend |
| 3622 | 3622 | /// `\\?\` prefix to the resultant path. |
| 3623 | /// | |
| 3624 | /// TODO move this function into std.Io.Threaded and add cancelation checks | |
| 3623 | 3625 | pub fn GetFinalPathNameByHandle( |
| 3624 | 3626 | hFile: HANDLE, |
| 3625 | 3627 | fmt: GetFinalPathNameByHandleFormat, |
lib/std/posix.zig+12-12| ... | ... | @@ -1527,7 +1527,7 @@ pub fn bind(sock: socket_t, addr: *const sockaddr, len: socklen_t) BindError!voi |
| 1527 | 1527 | |
| 1528 | 1528 | pub const ListenError = error{ |
| 1529 | 1529 | FileDescriptorNotASocket, |
| 1530 | OperationNotSupported, | |
| 1530 | OperationUnsupported, | |
| 1531 | 1531 | } || std.Io.net.IpAddress.ListenError || std.Io.net.UnixAddress.ListenError; |
| 1532 | 1532 | |
| 1533 | 1533 | pub fn listen(sock: socket_t, backlog: u31) ListenError!void { |
| ... | ... | @@ -1540,7 +1540,7 @@ pub fn listen(sock: socket_t, backlog: u31) ListenError!void { |
| 1540 | 1540 | .ADDRINUSE => return error.AddressInUse, |
| 1541 | 1541 | .BADF => unreachable, |
| 1542 | 1542 | .NOTSOCK => return error.FileDescriptorNotASocket, |
| 1543 | .OPNOTSUPP => return error.OperationNotSupported, | |
| 1543 | .OPNOTSUPP => return error.OperationUnsupported, | |
| 1544 | 1544 | else => |err| return unexpectedErrno(err), |
| 1545 | 1545 | } |
| 1546 | 1546 | } |
| ... | ... | @@ -2202,7 +2202,7 @@ pub const FanotifyMarkError = error{ |
| 2202 | 2202 | SystemResources, |
| 2203 | 2203 | UserMarkQuotaExceeded, |
| 2204 | 2204 | NotDir, |
| 2205 | OperationNotSupported, | |
| 2205 | OperationUnsupported, | |
| 2206 | 2206 | PermissionDenied, |
| 2207 | 2207 | NotSameFileSystem, |
| 2208 | 2208 | NameTooLong, |
| ... | ... | @@ -2242,7 +2242,7 @@ pub fn fanotify_markZ( |
| 2242 | 2242 | .NOMEM => return error.SystemResources, |
| 2243 | 2243 | .NOSPC => return error.UserMarkQuotaExceeded, |
| 2244 | 2244 | .NOTDIR => return error.NotDir, |
| 2245 | .OPNOTSUPP => return error.OperationNotSupported, | |
| 2245 | .OPNOTSUPP => return error.OperationUnsupported, | |
| 2246 | 2246 | .PERM => return error.PermissionDenied, |
| 2247 | 2247 | .XDEV => return error.NotSameFileSystem, |
| 2248 | 2248 | else => |err| return unexpectedErrno(err), |
| ... | ... | @@ -3466,7 +3466,7 @@ pub const SetSockOptError = error{ |
| 3466 | 3466 | /// Setting the socket option requires more elevated permissions. |
| 3467 | 3467 | PermissionDenied, |
| 3468 | 3468 | |
| 3469 | OperationNotSupported, | |
| 3469 | OperationUnsupported, | |
| 3470 | 3470 | NetworkDown, |
| 3471 | 3471 | FileDescriptorNotASocket, |
| 3472 | 3472 | SocketNotBound, |
| ... | ... | @@ -3502,7 +3502,7 @@ pub fn setsockopt(fd: socket_t, level: i32, optname: u32, opt: []const u8) SetSo |
| 3502 | 3502 | .NOBUFS => return error.SystemResources, |
| 3503 | 3503 | .PERM => return error.PermissionDenied, |
| 3504 | 3504 | .NODEV => return error.NoDevice, |
| 3505 | .OPNOTSUPP => return error.OperationNotSupported, | |
| 3505 | .OPNOTSUPP => return error.OperationUnsupported, | |
| 3506 | 3506 | else => |err| return unexpectedErrno(err), |
| 3507 | 3507 | } |
| 3508 | 3508 | } |
| ... | ... | @@ -3712,7 +3712,7 @@ pub const PrctlError = error{ |
| 3712 | 3712 | /// or PR_MPX_DISABLE_MANAGEMENT |
| 3713 | 3713 | UnsupportedFeature, |
| 3714 | 3714 | /// Can only occur with PR_SET_FP_MODE |
| 3715 | OperationNotSupported, | |
| 3715 | OperationUnsupported, | |
| 3716 | 3716 | PermissionDenied, |
| 3717 | 3717 | } || UnexpectedError; |
| 3718 | 3718 | |
| ... | ... | @@ -3736,7 +3736,7 @@ pub fn prctl(option: PR, args: anytype) PrctlError!u31 { |
| 3736 | 3736 | .FAULT => return error.InvalidAddress, |
| 3737 | 3737 | .INVAL => unreachable, |
| 3738 | 3738 | .NODEV, .NXIO => return error.UnsupportedFeature, |
| 3739 | .OPNOTSUPP => return error.OperationNotSupported, | |
| 3739 | .OPNOTSUPP => return error.OperationUnsupported, | |
| 3740 | 3740 | .PERM, .BUSY => return error.PermissionDenied, |
| 3741 | 3741 | .RANGE => unreachable, |
| 3742 | 3742 | else => |err| return unexpectedErrno(err), |
| ... | ... | @@ -3995,7 +3995,7 @@ pub const PtraceError = error{ |
| 3995 | 3995 | DeviceBusy, |
| 3996 | 3996 | InputOutput, |
| 3997 | 3997 | NameTooLong, |
| 3998 | OperationNotSupported, | |
| 3998 | OperationUnsupported, | |
| 3999 | 3999 | OutOfMemory, |
| 4000 | 4000 | ProcessNotFound, |
| 4001 | 4001 | PermissionDenied, |
| ... | ... | @@ -4097,7 +4097,7 @@ pub fn ptrace(request: u32, pid: pid_t, addr: usize, data: usize) PtraceError!vo |
| 4097 | 4097 | .INVAL => unreachable, |
| 4098 | 4098 | .PERM => error.PermissionDenied, |
| 4099 | 4099 | .BUSY => error.DeviceBusy, |
| 4100 | .NOTSUP => error.OperationNotSupported, | |
| 4100 | .NOTSUP => error.OperationUnsupported, | |
| 4101 | 4101 | else => |err| return unexpectedErrno(err), |
| 4102 | 4102 | }, |
| 4103 | 4103 | |
| ... | ... | @@ -4108,7 +4108,7 @@ pub fn ptrace(request: u32, pid: pid_t, addr: usize, data: usize) PtraceError!vo |
| 4108 | 4108 | pub const NameToFileHandleAtError = error{ |
| 4109 | 4109 | FileNotFound, |
| 4110 | 4110 | NotDir, |
| 4111 | OperationNotSupported, | |
| 4111 | OperationUnsupported, | |
| 4112 | 4112 | NameTooLong, |
| 4113 | 4113 | Unexpected, |
| 4114 | 4114 | }; |
| ... | ... | @@ -4137,7 +4137,7 @@ pub fn name_to_handle_atZ( |
| 4137 | 4137 | .INVAL => unreachable, // bad flags, or handle_bytes too big |
| 4138 | 4138 | .NOENT => return error.FileNotFound, |
| 4139 | 4139 | .NOTDIR => return error.NotDir, |
| 4140 | .OPNOTSUPP => return error.OperationNotSupported, | |
| 4140 | .OPNOTSUPP => return error.OperationUnsupported, | |
| 4141 | 4141 | .OVERFLOW => return error.NameTooLong, |
| 4142 | 4142 | else => |err| return unexpectedErrno(err), |
| 4143 | 4143 | } |
lib/std/posix/test.zig+1-1| ... | ... | @@ -503,7 +503,7 @@ test "rename smoke test" { |
| 503 | 503 | var tmp = tmpDir(.{}); |
| 504 | 504 | defer tmp.cleanup(); |
| 505 | 505 | |
| 506 | const base_path = try tmp.dir.realPathAlloc(io, ".", gpa); | |
| 506 | const base_path = try tmp.dir.realPathFileAlloc(io, ".", gpa); | |
| 507 | 507 | defer gpa.free(base_path); |
| 508 | 508 | |
| 509 | 509 | const mode: posix.mode_t = if (native_os == .windows) 0 else 0o666; |