From bb9cddabac9f0e2f3113ce9f97c999898e3dc7f7 Mon Sep 17 00:00:00 2001 From: jason Date: Tue, 12 May 2026 18:24:08 -0400 Subject: [PATCH] linux.Stat -> linux.Statx This provides access to os.Stat.creation_time for Linux. Added a cast to string_interner.cpp for 32-bit compiles. --- core/os/dir_linux.odin | 4 ++-- core/os/file_linux.odin | 6 ++---- core/os/process_linux.odin | 8 ++++---- core/os/stat_linux.odin | 13 ++++++------- src/string_interner.cpp | 4 ++-- 5 files changed, 16 insertions(+), 19 deletions(-) diff --git a/core/os/dir_linux.odin b/core/os/dir_linux.odin index 1ca2ef9b4..b8b69eb7d 100644 --- a/core/os/dir_linux.odin +++ b/core/os/dir_linux.odin @@ -97,8 +97,8 @@ _read_directory_iterator_init :: proc(it: ^Read_Directory_Iterator, f: ^File) { return } - stat: linux.Stat - errno := linux.fstat(linux.Fd(fd(f)), &stat) + stat: linux.Statx + errno := linux.statx(linux.Fd(fd(f)), "", {.EMPTY_PATH}, {.MODE}, &stat) if errno != .NONE { read_directory_iterator_set_error(it, name(f), _get_platform_error(errno)) return diff --git a/core/os/file_linux.odin b/core/os/file_linux.odin index d4223ba5d..a92dbad73 100644 --- a/core/os/file_linux.odin +++ b/core/os/file_linux.odin @@ -279,10 +279,8 @@ _write_at :: proc(f: ^File_Impl, p: []byte, offset: i64) -> (nt: i64, err: Error @(no_sanitize_memory) _file_size :: proc(f: ^File_Impl) -> (n: i64, err: Error) { - // TODO: Identify 0-sized "pseudo" files and return No_Size. This would - // eliminate the need for the _read_entire_pseudo_file procs. - s: linux.Stat = --- - errno := linux.fstat(f.fd, &s) + s: linux.Statx = --- + errno := linux.statx(f.fd, "", {.EMPTY_PATH}, {.SIZE, .MODE}, &s) if errno != .NONE { return 0, _get_platform_error(errno) } diff --git a/core/os/process_linux.odin b/core/os/process_linux.odin index 5e6eff335..1cfc48ca6 100644 --- a/core/os/process_linux.odin +++ b/core/os/process_linux.odin @@ -129,8 +129,8 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator defer linux.close(proc_fd) username_if: if .Username in selection { - s: linux.Stat - if errno = linux.fstat(proc_fd, &s); errno != .NONE { + s: linux.Statx + if errno = linux.statx(proc_fd, "", {.EMPTY_PATH}, {.UID}, &s); errno != .NONE { err = _get_platform_error(errno) break username_if } @@ -438,8 +438,8 @@ _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) { strings.write_string(&exe_builder, executable_name) exe_path = strings.to_cstring(&exe_builder) or_return - stat := linux.Stat{} - if linux.stat(exe_path, &stat) == .NONE && .IFREG in stat.mode && .IXUSR in stat.mode { + stat: linux.Statx + if linux.statx(linux.AT_FDCWD, exe_path, {}, {.MODE}, &stat) == .NONE && .IFREG in stat.mode && .IXUSR in stat.mode { found = true break } diff --git a/core/os/stat_linux.odin b/core/os/stat_linux.odin index 082279e8d..3abddc275 100644 --- a/core/os/stat_linux.odin +++ b/core/os/stat_linux.odin @@ -11,8 +11,8 @@ _fstat :: proc(f: ^File, allocator: runtime.Allocator) -> (File_Info, Error) { } _fstat_internal :: proc(fd: linux.Fd, allocator: runtime.Allocator) -> (fi: File_Info, err: Error) { - s: linux.Stat - errno := linux.fstat(fd, &s) + s: linux.Statx + errno := linux.statx(fd, "", {.EMPTY_PATH}, {.TYPE, .MODE, .ATIME, .MTIME, .CTIME, .INO, .SIZE}, &s) if errno != .NONE { return {}, _get_platform_error(errno) } @@ -28,7 +28,6 @@ _fstat_internal :: proc(fd: linux.Fd, allocator: runtime.Allocator) -> (fi: File } mode := transmute(Permissions)(0o7777 & transmute(u32)s.mode) - // TODO: As of Linux 4.11, the new statx syscall can retrieve creation_time fi = File_Info { fullpath = _get_full_path(fd, allocator) or_return, name = "", @@ -36,9 +35,9 @@ _fstat_internal :: proc(fd: linux.Fd, allocator: runtime.Allocator) -> (fi: File size = i64(s.size), mode = mode, type = type, - modification_time = time.Time {i64(s.mtime.time_sec) * i64(time.Second) + i64(s.mtime.time_nsec)}, - access_time = time.Time {i64(s.atime.time_sec) * i64(time.Second) + i64(s.atime.time_nsec)}, - creation_time = time.Time{i64(s.ctime.time_sec) * i64(time.Second) + i64(s.ctime.time_nsec)}, // regular stat does not provide this + modification_time = time.Time {i64(s.mtime.sec) * i64(time.Second) + i64(s.mtime.nsec)}, + access_time = time.Time {i64(s.atime.sec) * i64(time.Second) + i64(s.atime.nsec)}, + creation_time = time.Time {i64(s.btime.sec) * i64(time.Second) + i64(s.btime.nsec)}, } fi.creation_time = fi.modification_time _, fi.name = split_path(fi.fullpath) @@ -76,4 +75,4 @@ _same_file :: proc(fi1, fi2: File_Info) -> bool { _is_reserved_name :: proc(path: string) -> bool { return false -} \ No newline at end of file +} diff --git a/src/string_interner.cpp b/src/string_interner.cpp index 660dbc61d..916263fa3 100644 --- a/src/string_interner.cpp +++ b/src/string_interner.cpp @@ -81,7 +81,7 @@ gb_internal String string_interner_load(InternedString interned) { u8 *base = cast(u8 *)interner + interned.value; u32 str_len = *cast(u32 *)base; u8 *text = base + 4; - String str = { text, str_len }; + String str = { text, cast(isize)str_len }; return str; } @@ -228,4 +228,4 @@ gb_internal void *string_interner_thread_local_arena_alloc(StringInternerThreadL u8 *return_head = tl_arena->data + new_head; tl_arena->cursor = cursor; return return_head; -} \ No newline at end of file +}