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.
This commit is contained in:
Frank Praznik 2024-03-20 10:42:07 -04:00
parent 18feaa52dd
commit 4a7e3beeb9
4 changed files with 11 additions and 3 deletions

View File

@ -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

View File

@ -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

View File

@ -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_ */

View File

@ -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);