From 4a7e3beeb94e4d3a0afd6a476ef4d31182dc6b36 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Wed, 20 Mar 2024 10:42:07 -0400 Subject: [PATCH] filesystem: Use high-res file times on more platforms Some POSIX platforms don't define macros to note the presence of the POSIX.1-2008 st_*tim timespec members of the stat struct, so check if this member exists during CMake configuration and conditionally enable it. Apple platforms use st_*timespec naming, which is supported as of OSX 10.6. SDL3 requires 10.9+, so no fallback is needed. Android only supports the POSIX.1-2008 semantics as of API version 26 or higher, so this has to be conditionally enabled in the makefile build via an API version definition check. In other cases, file times fall back to the legacy path with second precision. --- CMakeLists.txt | 1 + include/build_config/SDL_build_config.h.cmake | 1 + include/build_config/SDL_build_config_android.h | 3 ++- src/filesystem/posix/SDL_sysfsops.c | 9 +++++++-- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c235d0fa5..a9f2c04e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1149,6 +1149,7 @@ if(SDL_LIBC) endif() check_struct_has_member("struct sigaction" "sa_sigaction" "signal.h" HAVE_SA_SIGACTION) + check_struct_has_member("struct stat" "st_mtim" "sys/stat.h" HAVE_ST_MTIM) endif() else() set(headers diff --git a/include/build_config/SDL_build_config.h.cmake b/include/build_config/SDL_build_config.h.cmake index 951771e49..f8eb06aea 100644 --- a/include/build_config/SDL_build_config.h.cmake +++ b/include/build_config/SDL_build_config.h.cmake @@ -190,6 +190,7 @@ #cmakedefine HAVE_POSIX_FALLOCATE 1 #cmakedefine HAVE_SIGACTION 1 #cmakedefine HAVE_SA_SIGACTION 1 +#cmakedefine HAVE_ST_MTIM 1 #cmakedefine HAVE_SETJMP 1 #cmakedefine HAVE_NANOSLEEP 1 #cmakedefine HAVE_GMTIME_R 1 diff --git a/include/build_config/SDL_build_config_android.h b/include/build_config/SDL_build_config_android.h index 19df2278f..49044b0b7 100644 --- a/include/build_config/SDL_build_config_android.h +++ b/include/build_config/SDL_build_config_android.h @@ -198,9 +198,10 @@ #define SDL_CAMERA_DRIVER_ANDROID 1 #define SDL_CAMERA_DRIVER_DUMMY 1 -/* Enable nl_langinfo on version 26 and higher. */ +/* Enable nl_langinfo and high-res file times on version 26 and higher. */ #if __ANDROID_API__ >= 26 #define HAVE_NL_LANGINFO 1 +#define HAVE_ST_MTIM 1 #endif #endif /* SDL_build_config_android_h_ */ diff --git a/src/filesystem/posix/SDL_sysfsops.c b/src/filesystem/posix/SDL_sysfsops.c index 8e4939f1a..fcc38ed9b 100644 --- a/src/filesystem/posix/SDL_sysfsops.c +++ b/src/filesystem/posix/SDL_sysfsops.c @@ -124,11 +124,16 @@ int SDL_SYS_GetPathInfo(const char *path, SDL_PathInfo *info) info->size = (Uint64) statbuf.st_size; } -#if (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200809L) || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 700) - /* Use high-res file times, if available. */ +#if defined(HAVE_ST_MTIM) + /* POSIX.1-2008 standard */ info->create_time = (SDL_Time)SDL_SECONDS_TO_NS(statbuf.st_ctim.tv_sec) + statbuf.st_ctim.tv_nsec; info->modify_time = (SDL_Time)SDL_SECONDS_TO_NS(statbuf.st_mtim.tv_sec) + statbuf.st_mtim.tv_nsec; info->access_time = (SDL_Time)SDL_SECONDS_TO_NS(statbuf.st_atim.tv_sec) + statbuf.st_atim.tv_nsec; +#elif defined(SDL_PLATFORM_APPLE) + /* Apple platform stat structs use 'st_*timespec' naming. */ + info->create_time = (SDL_Time)SDL_SECONDS_TO_NS(statbuf.st_ctimespec.tv_sec) + statbuf.st_ctimespec.tv_nsec; + info->modify_time = (SDL_Time)SDL_SECONDS_TO_NS(statbuf.st_mtimespec.tv_sec) + statbuf.st_mtimespec.tv_nsec; + info->access_time = (SDL_Time)SDL_SECONDS_TO_NS(statbuf.st_atimespec.tv_sec) + statbuf.st_atimespec.tv_nsec; #else info->create_time = (SDL_Time)SDL_SECONDS_TO_NS(statbuf.st_ctime); info->modify_time = (SDL_Time)SDL_SECONDS_TO_NS(statbuf.st_mtime);