From f2282fb81bd908b869105882ac35644235a9f5e3 Mon Sep 17 00:00:00 2001 From: Joel Rosdahl Date: Sat, 16 Dec 2023 10:59:20 +0100 Subject: [PATCH] feat: Support st_Xtimensec fields in struct stat This increases file timestamp precision on some BSD-based OSes. Closes #1369. --- cmake/GenerateConfigurationFile.cmake | 10 ++++++++++ cmake/config.h.in | 9 +++++++++ src/util/DirEntry.hpp | 8 +++++++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/cmake/GenerateConfigurationFile.cmake b/cmake/GenerateConfigurationFile.cmake index 7ff5ae383..a732bae08 100644 --- a/cmake/GenerateConfigurationFile.cmake +++ b/cmake/GenerateConfigurationFile.cmake @@ -40,18 +40,28 @@ foreach(func IN ITEMS ${functions}) endforeach() include(CheckStructHasMember) + check_struct_has_member("struct stat" st_atim sys/stat.h HAVE_STRUCT_STAT_ST_ATIM LANGUAGE CXX) +check_struct_has_member("struct stat" st_atimensec sys/stat.h + HAVE_STRUCT_STAT_ST_ATIMENSEC LANGUAGE CXX) check_struct_has_member("struct stat" st_atimespec sys/stat.h HAVE_STRUCT_STAT_ST_ATIMESPEC LANGUAGE CXX) + check_struct_has_member("struct stat" st_ctim sys/stat.h HAVE_STRUCT_STAT_ST_CTIM LANGUAGE CXX) +check_struct_has_member("struct stat" st_ctimensec sys/stat.h + HAVE_STRUCT_STAT_ST_CTIMENSEC LANGUAGE CXX) check_struct_has_member("struct stat" st_ctimespec sys/stat.h HAVE_STRUCT_STAT_ST_CTIMESPEC LANGUAGE CXX) + check_struct_has_member("struct stat" st_mtim sys/stat.h HAVE_STRUCT_STAT_ST_MTIM LANGUAGE CXX) +check_struct_has_member("struct stat" st_mtimensec sys/stat.h + HAVE_STRUCT_STAT_ST_MTIMENSEC LANGUAGE CXX) check_struct_has_member("struct stat" st_mtimespec sys/stat.h HAVE_STRUCT_STAT_ST_MTIMESPEC LANGUAGE CXX) + check_struct_has_member("struct statfs" f_fstypename sys/mount.h HAVE_STRUCT_STATFS_F_FSTYPENAME LANGUAGE CXX) diff --git a/cmake/config.h.in b/cmake/config.h.in index 69b508368..08e9ad9ac 100644 --- a/cmake/config.h.in +++ b/cmake/config.h.in @@ -141,18 +141,27 @@ // Define if "st_atim" is a member of "struct stat". #cmakedefine HAVE_STRUCT_STAT_ST_ATIM +// Define if "st_atimensec" is a member of "struct stat". +#cmakedefine HAVE_STRUCT_STAT_ST_ATIMENSEC + // Define if "st_atimespec" is a member of "struct stat". #cmakedefine HAVE_STRUCT_STAT_ST_ATIMESPEC // Define if "st_ctim" is a member of "struct stat". #cmakedefine HAVE_STRUCT_STAT_ST_CTIM +// Define if "st_ctimensec" is a member of "struct stat". +#cmakedefine HAVE_STRUCT_STAT_ST_CTIMENSEC + // Define if "st_ctimespec" is a member of "struct stat". #cmakedefine HAVE_STRUCT_STAT_ST_CTIMESPEC // Define if "st_mtim" is a member of "struct stat". #cmakedefine HAVE_STRUCT_STAT_ST_MTIM +// Define if "st_mtimensec" is a member of "struct stat". +#cmakedefine HAVE_STRUCT_STAT_ST_MTIMENSEC + // Define if "st_mtimespec" is a member of "struct stat". #cmakedefine HAVE_STRUCT_STAT_ST_MTIMESPEC diff --git a/src/util/DirEntry.hpp b/src/util/DirEntry.hpp index 8d5b5314f..bd16e45c7 100644 --- a/src/util/DirEntry.hpp +++ b/src/util/DirEntry.hpp @@ -190,6 +190,8 @@ DirEntry::atime() const return util::TimePoint(do_stat().st_atim); #elif defined(HAVE_STRUCT_STAT_ST_ATIMESPEC) return util::TimePoint(do_stat().st_atimespec); +#elif defined(HAVE_STRUCT_STAT_ST_ATIMENSEC) + return util::TimePoint(do_stat().st_atime, do_stat().st_atimensec); #else return util::TimePoint(do_stat().st_atime, 0); #endif @@ -202,6 +204,8 @@ DirEntry::ctime() const return util::TimePoint(do_stat().st_ctim); #elif defined(HAVE_STRUCT_STAT_ST_CTIMESPEC) return util::TimePoint(do_stat().st_ctimespec); +#elif defined(HAVE_STRUCT_STAT_ST_CTIMENSEC) + return util::TimePoint(do_stat().st_ctime, do_stat().st_ctimensec); #else return util::TimePoint(do_stat().st_ctime, 0); #endif @@ -212,8 +216,10 @@ DirEntry::mtime() const { #if defined(_WIN32) || defined(HAVE_STRUCT_STAT_ST_MTIM) return util::TimePoint(do_stat().st_mtim); -#elif defined(HAVE_STRUCT_STAT_ST_CTIMESPEC) +#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC) return util::TimePoint(do_stat().st_mtimespec); +#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) + return util::TimePoint(do_stat().st_mtime, do_stat().st_mtimensec); #else return util::TimePoint(do_stat().st_mtime, 0); #endif -- 2.47.2