From d6ee2d5d2454f5023c78d59e7464c9c902d6597b Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Tue, 12 Mar 2024 14:01:17 -0700 Subject: [PATCH] Use `utimensat()` on FreeBSD FreeBSD only claims to support POSIX 2001 [0]. But they do in fact support `utimensat()`. This adds a specific check to opt them in to using it. This value was selected by consulting [1]. See discussion on #3952. Further addresses #3748. [0] https://github.com/freebsd/freebsd-src/blob/937a0055858a098027f464abf0b2b1ec5d36748f/sys/sys/unistd.h#L96 [1] https://docs.freebsd.org/en/books/porters-handbook/versions/ --- programs/util.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/programs/util.c b/programs/util.c index 862fc80080d..116f88e103b 100644 --- a/programs/util.c +++ b/programs/util.c @@ -23,16 +23,27 @@ extern "C" { #include #include +#if defined(__FreeBSD__) +#include /* __FreeBSD_version */ +#endif /* #ifdef __FreeBSD__ */ + #if defined(_WIN32) # include /* utime */ # include /* _chmod */ +# define ZSTD_USE_UTIMENSAT 0 #else # include /* chown, stat */ -# if PLATFORM_POSIX_VERSION < 200809L || !defined(st_mtime) -# include /* utime */ +# include /* utimensat, st_mtime */ +# if (PLATFORM_POSIX_VERSION >= 200809L && defined(st_mtime)) \ + || (defined(__FreeBSD__) && __FreeBSD_version >= 1100056) +# define ZSTD_USE_UTIMENSAT 1 # else +# define ZSTD_USE_UTIMENSAT 0 +# endif +# if ZSTD_USE_UTIMENSAT # include /* AT_FDCWD */ -# include /* utimensat */ +# else +# include /* utime */ # endif #endif @@ -259,7 +270,12 @@ int UTIL_utime(const char* filename, const stat_t *statbuf) * that struct stat has a struct timespec st_mtim member. We need this * check because there are some platforms that claim to be POSIX 2008 * compliant but which do not have st_mtim... */ -#if (PLATFORM_POSIX_VERSION >= 200809L) && defined(st_mtime) + /* FreeBSD has implemented POSIX 2008 for a long time but still only + * advertises support for POSIX 2001. They have a version macro that + * lets us safely gate them in. + * See https://docs.freebsd.org/en/books/porters-handbook/versions/. + */ +#if ZSTD_USE_UTIMENSAT { /* (atime, mtime) */ struct timespec timebuf[2] = { {0, UTIME_NOW} }; @@ -1546,7 +1562,6 @@ int UTIL_countCores(int logical) #elif defined(__FreeBSD__) -#include #include /* Use physical core sysctl when available