| author | |
| committer | |
| log | f3723b42e1f05d14479d6f5507943cd1905e0fcf |
| tree | 3941dddf0af4affbc29c5a2dc8f4cc16b800f74f |
| parent | 446c145ca86b014d6743f5666e9ee1d671b56045 |
4 files changed, 69 insertions(+), 18 deletions(-)
lib/std/Io/Dir.zig+33| ... | @@ -989,6 +989,39 @@ pub fn renameAbsolute(io: Io, old_path: []const u8, new_path: []const u8) Rename | ... | @@ -989,6 +989,39 @@ pub fn renameAbsolute(io: Io, old_path: []const u8, new_path: []const u8) Rename |
| 989 | return io.vtable.dirRename(io.userdata, my_cwd, old_path, my_cwd, new_path); | 989 | return io.vtable.dirRename(io.userdata, my_cwd, old_path, my_cwd, new_path); |
| 990 | } | 990 | } |
| 991 | 991 | ||
| 992 | pub const HardLinkOptions = struct { | ||
| 993 | follow_symlinks: bool = true, | ||
| 994 | }; | ||
| 995 | |||
| 996 | pub const HardLinkError = error{ | ||
| 997 | AccessDenied, | ||
| 998 | PermissionDenied, | ||
| 999 | DiskQuota, | ||
| 1000 | PathAlreadyExists, | ||
| 1001 | HardwareFailure, | ||
| 1002 | /// Either the OS or the filesystem does not support hard links. | ||
| 1003 | OperationUnsupported, | ||
| 1004 | SymLinkLoop, | ||
| 1005 | LinkQuotaExceeded, | ||
| 1006 | FileNotFound, | ||
| 1007 | SystemResources, | ||
| 1008 | NoSpaceLeft, | ||
| 1009 | ReadOnlyFileSystem, | ||
| 1010 | NotSameFileSystem, | ||
| 1011 | NotDir, | ||
| 1012 | } || Io.Cancelable || PathNameError || Io.UnexpectedError; | ||
| 1013 | |||
| 1014 | pub fn hardLink( | ||
| 1015 | old_dir: Dir, | ||
| 1016 | old_sub_path: []const u8, | ||
| 1017 | new_dir: Dir, | ||
| 1018 | new_sub_path: []const u8, | ||
| 1019 | io: Io, | ||
| 1020 | options: HardLinkOptions, | ||
| 1021 | ) HardLinkError!void { | ||
| 1022 | return io.vtable.dirHardLink(io.userdata, old_dir, old_sub_path, new_dir, new_sub_path, options); | ||
| 1023 | } | ||
| 1024 | |||
| 992 | /// Use with `symLink`, `symLinkAtomic`, and `symLinkAbsolute` to | 1025 | /// Use with `symLink`, `symLinkAtomic`, and `symLinkAbsolute` to |
| 993 | /// specify whether the symlink will point to a file or a directory. This value | 1026 | /// specify whether the symlink will point to a file or a directory. This value |
| 994 | /// is ignored on all hosts except Windows where creating symlinks to different | 1027 | /// is ignored on all hosts except Windows where creating symlinks to different |
lib/std/Io/File.zig+5-1| ... | @@ -17,6 +17,7 @@ pub const Atomic = @import("File/Atomic.zig"); | ... | @@ -17,6 +17,7 @@ pub const Atomic = @import("File/Atomic.zig"); |
| 17 | 17 | ||
| 18 | pub const Handle = std.posix.fd_t; | 18 | pub const Handle = std.posix.fd_t; |
| 19 | pub const INode = std.posix.ino_t; | 19 | pub const INode = std.posix.ino_t; |
| 20 | pub const NLink = std.posix.nlink_t; | ||
| 20 | pub const Uid = std.posix.uid_t; | 21 | pub const Uid = std.posix.uid_t; |
| 21 | pub const Gid = std.posix.gid_t; | 22 | pub const Gid = std.posix.gid_t; |
| 22 | 23 | ||
| ... | @@ -47,6 +48,7 @@ pub const Stat = struct { | ... | @@ -47,6 +48,7 @@ pub const Stat = struct { |
| 47 | /// The FileIndex on Windows is similar. It is a number for a file that | 48 | /// The FileIndex on Windows is similar. It is a number for a file that |
| 48 | /// is unique to each filesystem. | 49 | /// is unique to each filesystem. |
| 49 | inode: INode, | 50 | inode: INode, |
| 51 | nlink: NLink, | ||
| 50 | size: u64, | 52 | size: u64, |
| 51 | permissions: Permissions, | 53 | permissions: Permissions, |
| 52 | kind: Kind, | 54 | kind: Kind, |
| ... | @@ -101,9 +103,11 @@ pub const OpenFlags = struct { | ... | @@ -101,9 +103,11 @@ pub const OpenFlags = struct { |
| 101 | mode: OpenMode = .read_only, | 103 | mode: OpenMode = .read_only, |
| 102 | 104 | ||
| 103 | /// Determines the behavior when opening a path that refers to a directory. | 105 | /// Determines the behavior when opening a path that refers to a directory. |
| 106 | /// | ||
| 104 | /// If set to true, directories may be opened, but `error.IsDir` is still | 107 | /// If set to true, directories may be opened, but `error.IsDir` is still |
| 105 | /// possible in certain scenarios, e.g. attempting to open a directory with | 108 | /// possible in certain scenarios, e.g. attempting to open a directory with |
| 106 | /// write permissions. | 109 | /// write permissions. |
| 110 | /// | ||
| 107 | /// If set to false, `error.IsDir` will always be returned when opening a directory. | 111 | /// If set to false, `error.IsDir` will always be returned when opening a directory. |
| 108 | /// | 112 | /// |
| 109 | /// When set to false: | 113 | /// When set to false: |
| ... | @@ -289,7 +293,7 @@ pub fn sync(file: File, io: Io) SyncError!void { | ... | @@ -289,7 +293,7 @@ pub fn sync(file: File, io: Io) SyncError!void { |
| 289 | return io.vtable.fileSync(io.userdata, file); | 293 | return io.vtable.fileSync(io.userdata, file); |
| 290 | } | 294 | } |
| 291 | 295 | ||
| 292 | /// Test whether the file refers to a terminal. | 296 | /// Test whether the file refers to a terminal (similar to libc "isatty"). |
| 293 | /// | 297 | /// |
| 294 | /// See also: | 298 | /// See also: |
| 295 | /// * `enableAnsiEscapeCodes` | 299 | /// * `enableAnsiEscapeCodes` |
lib/std/Io/Threaded.zig+30-16| ... | @@ -1829,19 +1829,21 @@ fn dirStatFileLinux( | ... | @@ -1829,19 +1829,21 @@ fn dirStatFileLinux( |
| 1829 | dir.handle, | 1829 | dir.handle, |
| 1830 | sub_path_posix, | 1830 | sub_path_posix, |
| 1831 | flags, | 1831 | flags, |
| 1832 | .{ .TYPE = true, .MODE = true, .ATIME = true, .MTIME = true, .CTIME = true, .INO = true, .SIZE = true }, | 1832 | .{ |
| 1833 | .TYPE = true, | ||
| 1834 | .MODE = true, | ||
| 1835 | .ATIME = true, | ||
| 1836 | .MTIME = true, | ||
| 1837 | .CTIME = true, | ||
| 1838 | .INO = true, | ||
| 1839 | .SIZE = true, | ||
| 1840 | .NLINK = true, | ||
| 1841 | }, | ||
| 1833 | &statx, | 1842 | &statx, |
| 1834 | ); | 1843 | ); |
| 1835 | switch (sys.errno(rc)) { | 1844 | switch (sys.errno(rc)) { |
| 1836 | .SUCCESS => { | 1845 | .SUCCESS => { |
| 1837 | current_thread.endSyscall(); | 1846 | current_thread.endSyscall(); |
| 1838 | assert(statx.mask.TYPE); | ||
| 1839 | assert(statx.mask.MODE); | ||
| 1840 | assert(statx.mask.ATIME); | ||
| 1841 | assert(statx.mask.MTIME); | ||
| 1842 | assert(statx.mask.CTIME); | ||
| 1843 | assert(statx.mask.INO); | ||
| 1844 | assert(statx.mask.SIZE); | ||
| 1845 | return statFromLinux(&statx); | 1847 | return statFromLinux(&statx); |
| 1846 | }, | 1848 | }, |
| 1847 | .INTR => { | 1849 | .INTR => { |
| ... | @@ -2082,19 +2084,21 @@ fn fileStatLinux(userdata: ?*anyopaque, file: File) File.StatError!File.Stat { | ... | @@ -2082,19 +2084,21 @@ fn fileStatLinux(userdata: ?*anyopaque, file: File) File.StatError!File.Stat { |
| 2082 | file.handle, | 2084 | file.handle, |
| 2083 | "", | 2085 | "", |
| 2084 | linux.AT.EMPTY_PATH, | 2086 | linux.AT.EMPTY_PATH, |
| 2085 | .{ .TYPE = true, .MODE = true, .ATIME = true, .MTIME = true, .CTIME = true, .INO = true, .SIZE = true }, | 2087 | .{ |
| 2088 | .TYPE = true, | ||
| 2089 | .MODE = true, | ||
| 2090 | .ATIME = true, | ||
| 2091 | .MTIME = true, | ||
| 2092 | .CTIME = true, | ||
| 2093 | .INO = true, | ||
| 2094 | .SIZE = true, | ||
| 2095 | .NLINK = true, | ||
| 2096 | }, | ||
| 2086 | &statx, | 2097 | &statx, |
| 2087 | ); | 2098 | ); |
| 2088 | switch (sys.errno(rc)) { | 2099 | switch (sys.errno(rc)) { |
| 2089 | .SUCCESS => { | 2100 | .SUCCESS => { |
| 2090 | current_thread.endSyscall(); | 2101 | current_thread.endSyscall(); |
| 2091 | assert(statx.mask.TYPE); | ||
| 2092 | assert(statx.mask.MODE); | ||
| 2093 | assert(statx.mask.ATIME); | ||
| 2094 | assert(statx.mask.MTIME); | ||
| 2095 | assert(statx.mask.CTIME); | ||
| 2096 | assert(statx.mask.INO); | ||
| 2097 | assert(statx.mask.SIZE); | ||
| 2098 | return statFromLinux(&statx); | 2102 | return statFromLinux(&statx); |
| 2099 | }, | 2103 | }, |
| 2100 | .INTR => { | 2104 | .INTR => { |
| ... | @@ -10499,11 +10503,20 @@ fn clockToWasi(clock: Io.Clock) std.os.wasi.clockid_t { | ... | @@ -10499,11 +10503,20 @@ fn clockToWasi(clock: Io.Clock) std.os.wasi.clockid_t { |
| 10499 | } | 10503 | } |
| 10500 | 10504 | ||
| 10501 | fn statFromLinux(stx: *const std.os.linux.Statx) File.Stat { | 10505 | fn statFromLinux(stx: *const std.os.linux.Statx) File.Stat { |
| 10506 | assert(stx.mask.TYPE); | ||
| 10507 | assert(stx.mask.MODE); | ||
| 10508 | assert(stx.mask.ATIME); | ||
| 10509 | assert(stx.mask.MTIME); | ||
| 10510 | assert(stx.mask.CTIME); | ||
| 10511 | assert(stx.mask.INO); | ||
| 10512 | assert(stx.mask.SIZE); | ||
| 10513 | assert(stx.mask.NLINK); | ||
| 10502 | const atime = stx.atime; | 10514 | const atime = stx.atime; |
| 10503 | const mtime = stx.mtime; | 10515 | const mtime = stx.mtime; |
| 10504 | const ctime = stx.ctime; | 10516 | const ctime = stx.ctime; |
| 10505 | return .{ | 10517 | return .{ |
| 10506 | .inode = stx.ino, | 10518 | .inode = stx.ino, |
| 10519 | .nlink = stx.nlink, | ||
| 10507 | .size = stx.size, | 10520 | .size = stx.size, |
| 10508 | .permissions = .fromMode(stx.mode), | 10521 | .permissions = .fromMode(stx.mode), |
| 10509 | .kind = switch (stx.mode & std.os.linux.S.IFMT) { | 10522 | .kind = switch (stx.mode & std.os.linux.S.IFMT) { |
| ... | @@ -10528,6 +10541,7 @@ fn statFromPosix(st: *const posix.Stat) File.Stat { | ... | @@ -10528,6 +10541,7 @@ fn statFromPosix(st: *const posix.Stat) File.Stat { |
| 10528 | const ctime = st.ctime(); | 10541 | const ctime = st.ctime(); |
| 10529 | return .{ | 10542 | return .{ |
| 10530 | .inode = st.ino, | 10543 | .inode = st.ino, |
| 10544 | .nlink = st.nlink, | ||
| 10531 | .size = @bitCast(st.size), | 10545 | .size = @bitCast(st.size), |
| 10532 | .permissions = .fromMode(st.mode), | 10546 | .permissions = .fromMode(st.mode), |
| 10533 | .kind = k: { | 10547 | .kind = k: { |
lib/std/c.zig+1-1| ... | @@ -162,7 +162,7 @@ pub const nlink_t = switch (native_os) { | ... | @@ -162,7 +162,7 @@ pub const nlink_t = switch (native_os) { |
| 162 | .freebsd, .serenity => u64, | 162 | .freebsd, .serenity => u64, |
| 163 | .openbsd, .netbsd, .illumos => u32, | 163 | .openbsd, .netbsd, .illumos => u32, |
| 164 | .haiku => i32, | 164 | .haiku => i32, |
| 165 | else => void, | 165 | else => u0, |
| 166 | }; | 166 | }; |
| 167 | 167 | ||
| 168 | pub const uid_t = switch (native_os) { | 168 | pub const uid_t = switch (native_os) { |