From 3fb6d8965b63711d3095ea1f418e400f35b25c82 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Wed, 26 Aug 2026 20:44:01 +0200 Subject: [PATCH] [core:os] add `device` to `File_Info` --- core/os/dir_windows.odin | 1 + core/os/stat.odin | 1 + core/os/stat_linux.odin | 1 + core/os/stat_posix.odin | 1 + core/os/stat_wasi.odin | 5 +++-- core/os/stat_windows.odin | 1 + core/sys/linux/wrappers.odin | 8 ++++++++ 7 files changed, 16 insertions(+), 2 deletions(-) diff --git a/core/os/dir_windows.odin b/core/os/dir_windows.odin index 9d245f6ad..895e907c8 100644 --- a/core/os/dir_windows.odin +++ b/core/os/dir_windows.odin @@ -42,6 +42,7 @@ find_data_to_file_info :: proc(base_path: string, d: ^win32.WIN32_FIND_DATAW, al #assert(size_of(fi.inode) == size_of(file_id_info.FileId)) #assert(size_of(fi.inode) == 16) runtime.mem_copy_non_overlapping(&fi.inode, &file_id_info.FileId, 16) + fi.device = file_id_info.VolumeSerialNumber } return diff --git a/core/os/stat.odin b/core/os/stat.odin index fa92e8a8e..f15784358 100644 --- a/core/os/stat.odin +++ b/core/os/stat.odin @@ -14,6 +14,7 @@ File_Info :: struct { name: string, // base name of the file inode: u128, // might be zero if cannot be determined + device: u64, // might be zero if cannot be determined size: i64 `fmt:"M"`, // length in bytes for regular files; system-dependent for other file types mode: Permissions, // file permission flags type: File_Type, diff --git a/core/os/stat_linux.odin b/core/os/stat_linux.odin index 3abddc275..7da562c0f 100644 --- a/core/os/stat_linux.odin +++ b/core/os/stat_linux.odin @@ -32,6 +32,7 @@ _fstat_internal :: proc(fd: linux.Fd, allocator: runtime.Allocator) -> (fi: File fullpath = _get_full_path(fd, allocator) or_return, name = "", inode = u128(u64(s.ino)), + device = u64(linux.makedev(s.dev_major, s.dev_minor)), size = i64(s.size), mode = mode, type = type, diff --git a/core/os/stat_posix.odin b/core/os/stat_posix.odin index 924860744..b2ce42d47 100644 --- a/core/os/stat_posix.odin +++ b/core/os/stat_posix.odin @@ -12,6 +12,7 @@ internal_stat :: proc(stat: posix.stat_t, fullpath: string) -> (fi: File_Info) { _, fi.name = split_path(fi.fullpath) fi.inode = u128(stat.st_ino) + fi.device = u64(stat.st_dev) fi.size = i64(stat.st_size) fi.mode = transmute(Permissions)u32(transmute(posix._mode_t)(stat.st_mode - posix.S_IFMT)) diff --git a/core/os/stat_wasi.odin b/core/os/stat_wasi.odin index 5f5e6fe45..2cdbb8fa9 100644 --- a/core/os/stat_wasi.odin +++ b/core/os/stat_wasi.odin @@ -10,8 +10,9 @@ internal_stat :: proc(stat: wasi.filestat_t, fullpath: string) -> (fi: File_Info fi.fullpath = fullpath _, fi.name = split_path(fi.fullpath) - fi.inode = u128(stat.ino) - fi.size = i64(stat.size) + fi.inode = u128(stat.ino) + fi.device = u64(stat.dev) + fi.size = i64(stat.size) switch stat.filetype { case .BLOCK_DEVICE: fi.type = .Block_Device diff --git a/core/os/stat_windows.odin b/core/os/stat_windows.odin index 35f2ae86b..0cc646e83 100644 --- a/core/os/stat_windows.odin +++ b/core/os/stat_windows.odin @@ -298,6 +298,7 @@ _file_info_from_get_file_information_by_handle :: proc(path: string, h: win32.HA fi.fullpath = path fi.name = basename(path) fi.inode = u128(u64(d.nFileIndexHigh)<<32 + u64(d.nFileIndexLow)) + fi.device = u64(d.dwVolumeSerialNumber) fi.size = i64(d.nFileSizeHigh)<<32 + i64(d.nFileSizeLow) type, mode := _file_type_mode_from_file_attributes(d.dwFileAttributes, h, 0) fi.type = type diff --git a/core/sys/linux/wrappers.odin b/core/sys/linux/wrappers.odin index 53eb80f86..46c67600c 100644 --- a/core/sys/linux/wrappers.odin +++ b/core/sys/linux/wrappers.odin @@ -146,3 +146,11 @@ perf_cache_config :: #force_inline proc "contextless" (id: Perf_Hardware_Cache_I res: Perf_Hardware_Cache_Result_Id) -> u64 { return u64(id) | (u64(op) << 8) | (u64(res) << 16) } + +/// Constructs a Dev from major and minor device numbers +makedev :: #force_inline proc "contextless" (major, minor: u32) -> Dev { + return Dev((u64(minor & 0xff)) | + (u64(major & 0xfff) << 8) | + (u64(minor & ~u32(0xff)) << 12) | + (u64(major & ~u32(0xfff)) << 32)) +}