From 55077435bf53bb8273e1b23c1690798312d6abc6 Mon Sep 17 00:00:00 2001 From: LeRoyce Pearson Date: Sun, 8 Mar 2020 14:27:49 -0600 Subject: [PATCH 1/4] Expose file inode (linux) and file index (windows) --- lib/std/fs/file.zig | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/std/fs/file.zig b/lib/std/fs/file.zig index 5b51f19f41..47f13080f4 100644 --- a/lib/std/fs/file.zig +++ b/lib/std/fs/file.zig @@ -28,6 +28,10 @@ pub const File = struct { pub const async_block_allowed_no = if (io.is_async) false else {}; pub const Mode = os.mode_t; + pub const INode = switch (builtin.os.tag) { + .windows => os.windows.LARGE_INTEGER, + else => u64, + }; pub const default_mode = switch (builtin.os.tag) { .windows => 0, @@ -145,6 +149,7 @@ pub const File = struct { } pub const Stat = struct { + inode: INode, size: u64, mode: Mode, @@ -174,6 +179,7 @@ pub const File = struct { else => return windows.unexpectedStatus(rc), } return Stat{ + .inode = info.InternalInformation.IndexNumber, .size = @bitCast(u64, info.StandardInformation.EndOfFile), .mode = 0, .atime = windows.fromSysTime(info.BasicInformation.LastAccessTime), @@ -187,6 +193,7 @@ pub const File = struct { const mtime = st.mtime(); const ctime = st.ctime(); return Stat{ + .inode = st.ino, .size = @bitCast(u64, st.size), .mode = st.mode, .atime = @as(i64, atime.tv_sec) * std.time.ns_per_s + atime.tv_nsec, From e1c1ca99031a76b44ba1bdce0d10acb4513af8d6 Mon Sep 17 00:00:00 2001 From: LeRoyce Pearson Date: Sun, 8 Mar 2020 15:47:50 -0600 Subject: [PATCH 2/4] Add documentation about Stat.inode --- lib/std/fs/file.zig | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/std/fs/file.zig b/lib/std/fs/file.zig index 47f13080f4..a4ce898682 100644 --- a/lib/std/fs/file.zig +++ b/lib/std/fs/file.zig @@ -28,8 +28,13 @@ pub const File = struct { pub const async_block_allowed_no = if (io.is_async) false else {}; pub const Mode = os.mode_t; + + /// The type that is used to represent the inode/file index number. On windows this is a + /// LARGE_INTEGER (i64), and on linux this is a u64. pub const INode = switch (builtin.os.tag) { .windows => os.windows.LARGE_INTEGER, + // TODO: Handle possibility of 128 bit numbers? ReFS on windows server 2012 uses a 128 bit file + // index. See https://docs.microsoft.com/en-us/windows/win32/api/fileapi/ns-fileapi-by_handle_file_information else => u64, }; @@ -149,7 +154,16 @@ pub const File = struct { } pub const Stat = struct { + /// A number that the system uses to point to the file metadata. This number is not guaranteed to be + /// unique across time, as some file systems may reuse an inode after it's file has been deleted. + /// Some systems may change the inode of a file over time. + /// + /// On Linux, the inode _is_ structure that stores the metadata, and the inode _number_ is what + /// you see here: the index number of the inode. + /// + /// The FileIndex on Windows is similar. It is a number for a file that is unique to each filesystem. inode: INode, + size: u64, mode: Mode, From cb84875eed42b4721de5b2cc356c4a6719eb0516 Mon Sep 17 00:00:00 2001 From: LeRoyce Pearson Date: Sun, 8 Mar 2020 18:31:18 -0600 Subject: [PATCH 3/4] Define ino_t for systems not yet defining it Also, use ino_t instead of u64 in fs.File.INode --- lib/std/fs/file.zig | 2 +- lib/std/os/bits/darwin.zig | 3 ++- lib/std/os/bits/dragonfly.zig | 4 +++- lib/std/os/bits/freebsd.zig | 3 ++- lib/std/os/bits/linux/x86_64.zig | 3 ++- lib/std/os/bits/netbsd.zig | 3 ++- lib/std/os/bits/wasi.zig | 1 + 7 files changed, 13 insertions(+), 6 deletions(-) diff --git a/lib/std/fs/file.zig b/lib/std/fs/file.zig index a4ce898682..33307a9dd6 100644 --- a/lib/std/fs/file.zig +++ b/lib/std/fs/file.zig @@ -35,7 +35,7 @@ pub const File = struct { .windows => os.windows.LARGE_INTEGER, // TODO: Handle possibility of 128 bit numbers? ReFS on windows server 2012 uses a 128 bit file // index. See https://docs.microsoft.com/en-us/windows/win32/api/fileapi/ns-fileapi-by_handle_file_information - else => u64, + else => os.ino_t, }; pub const default_mode = switch (builtin.os.tag) { diff --git a/lib/std/os/bits/darwin.zig b/lib/std/os/bits/darwin.zig index fb933c6698..6808af0315 100644 --- a/lib/std/os/bits/darwin.zig +++ b/lib/std/os/bits/darwin.zig @@ -53,6 +53,7 @@ pub const mach_timebase_info_data = extern struct { }; pub const off_t = i64; +pub const ino_t = u64; /// Renamed to Stat to not conflict with the stat function. /// atime, mtime, and ctime have functions to return `timespec`, @@ -64,7 +65,7 @@ pub const Stat = extern struct { dev: i32, mode: u16, nlink: u16, - ino: u64, + ino: ino_t, uid: u32, gid: u32, rdev: i32, diff --git a/lib/std/os/bits/dragonfly.zig b/lib/std/os/bits/dragonfly.zig index c6c23affa7..27b2733b76 100644 --- a/lib/std/os/bits/dragonfly.zig +++ b/lib/std/os/bits/dragonfly.zig @@ -138,8 +138,10 @@ pub const MAP_SIZEALIGN = 262144; pub const PATH_MAX = 1024; +pub const ino_t = c_ulong; + pub const Stat = extern struct { - ino: c_ulong, + ino: ino_t, nlink: c_uint, dev: c_uint, mode: c_ushort, diff --git a/lib/std/os/bits/freebsd.zig b/lib/std/os/bits/freebsd.zig index b7d14934f5..02fe7e75b3 100644 --- a/lib/std/os/bits/freebsd.zig +++ b/lib/std/os/bits/freebsd.zig @@ -98,6 +98,7 @@ pub const msghdr_const = extern struct { }; pub const off_t = i64; +pub const ino_t = u64; /// Renamed to Stat to not conflict with the stat function. /// atime, mtime, and ctime have functions to return `timespec`, @@ -107,7 +108,7 @@ pub const off_t = i64; /// methods to accomplish this. pub const Stat = extern struct { dev: u64, - ino: u64, + ino: ino_t, nlink: usize, mode: u16, diff --git a/lib/std/os/bits/linux/x86_64.zig b/lib/std/os/bits/linux/x86_64.zig index 608f74e2d3..e92591d94e 100644 --- a/lib/std/os/bits/linux/x86_64.zig +++ b/lib/std/os/bits/linux/x86_64.zig @@ -481,6 +481,7 @@ pub const msghdr_const = extern struct { }; pub const off_t = i64; +pub const ino_t = u64; /// Renamed to Stat to not conflict with the stat function. /// atime, mtime, and ctime have functions to return `timespec`, @@ -490,7 +491,7 @@ pub const off_t = i64; /// methods to accomplish this. pub const Stat = extern struct { dev: u64, - ino: u64, + ino: ino_t, nlink: usize, mode: u32, diff --git a/lib/std/os/bits/netbsd.zig b/lib/std/os/bits/netbsd.zig index 89e0998d6d..735485695a 100644 --- a/lib/std/os/bits/netbsd.zig +++ b/lib/std/os/bits/netbsd.zig @@ -69,6 +69,7 @@ pub const msghdr_const = extern struct { }; pub const off_t = i64; +pub const ino_t = u64; /// Renamed to Stat to not conflict with the stat function. /// atime, mtime, and ctime have functions to return `timespec`, @@ -79,7 +80,7 @@ pub const off_t = i64; pub const Stat = extern struct { dev: u64, mode: u32, - ino: u64, + ino: ino_t, nlink: usize, uid: u32, diff --git a/lib/std/os/bits/wasi.zig b/lib/std/os/bits/wasi.zig index f56e53504e..8fb85e1fcd 100644 --- a/lib/std/os/bits/wasi.zig +++ b/lib/std/os/bits/wasi.zig @@ -178,6 +178,7 @@ pub const FILESTAT_SET_MTIM: fstflags_t = 0x0004; pub const FILESTAT_SET_MTIM_NOW: fstflags_t = 0x0008; pub const inode_t = u64; +pub const ino_t = inode_t; pub const linkcount_t = u32; From 25d9ab95dd8a691963453c4507d519051eaebb0c Mon Sep 17 00:00:00 2001 From: LeRoyce Pearson Date: Sun, 8 Mar 2020 21:52:36 -0600 Subject: [PATCH 4/4] Use os.ino_t for everything Also, define ino_t for windows --- lib/std/fs/file.zig | 11 +---------- lib/std/os/bits/windows.zig | 1 + 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/lib/std/fs/file.zig b/lib/std/fs/file.zig index 33307a9dd6..8f7a46ad3e 100644 --- a/lib/std/fs/file.zig +++ b/lib/std/fs/file.zig @@ -29,15 +29,6 @@ pub const File = struct { pub const Mode = os.mode_t; - /// The type that is used to represent the inode/file index number. On windows this is a - /// LARGE_INTEGER (i64), and on linux this is a u64. - pub const INode = switch (builtin.os.tag) { - .windows => os.windows.LARGE_INTEGER, - // TODO: Handle possibility of 128 bit numbers? ReFS on windows server 2012 uses a 128 bit file - // index. See https://docs.microsoft.com/en-us/windows/win32/api/fileapi/ns-fileapi-by_handle_file_information - else => os.ino_t, - }; - pub const default_mode = switch (builtin.os.tag) { .windows => 0, else => 0o666, @@ -162,7 +153,7 @@ pub const File = struct { /// you see here: the index number of the inode. /// /// The FileIndex on Windows is similar. It is a number for a file that is unique to each filesystem. - inode: INode, + inode: os.ino_t, size: u64, mode: Mode, diff --git a/lib/std/os/bits/windows.zig b/lib/std/os/bits/windows.zig index ba2725e0a9..05486c8f7b 100644 --- a/lib/std/os/bits/windows.zig +++ b/lib/std/os/bits/windows.zig @@ -4,6 +4,7 @@ usingnamespace @import("../windows/bits.zig"); const ws2_32 = @import("../windows/ws2_32.zig"); pub const fd_t = HANDLE; +pub const ino_t = LARGE_INTEGER; pub const pid_t = HANDLE; pub const mode_t = u0;