Hello!
CentOS 5.11 (glibc 2.5) does not have utimensat function, so there is
no nanosecond precision of file times available. Currently, the test
fails with:
/tmp/cc36u3o7.o: In function
`_D3std4file17__T8setTimesTAyaZ8setTimesFAyaS3std8datetime7systime7SysTimeS3std8datetime7systime7SysTimeZ16trustedUtimensatFNbNiNeiPxaKxG2S4core3sys5posix6signal8timespeciZi':
/home/uros/git/gcc/libphobos/testsuite/../src/std/file.d:1272:
undefined reference to `utimensat'
collect2: error: ld returned 1 exit status
compiler exited with status 1
Attached patch detects utimensat function during configure time and
falls back to utimes in case utimensat is not available.
2019-05-08 Uroš Bizjak <[email protected]>
PR d/90261
* m4/druntime/libraries.m4 (DRUNTIME_LIBRARIES_CLIB):
Check for utimensat function.
* configure: Regenerate
* Makefile.in: Regenerate
* libdruntime/gcc/config.d.in: Add Have_Utimensat.
* libdruntime/Makefile.in: Regenerate.
* libdruntime/core/sys/posix/sys/stat.d [version (CRuntime_Glibc)]:
Declare utimensat and futimens only with Have_Utimensat.
* src/Makefile.in: Regenerate.
* src/std/file.d: Call testTimes with non-zero argument only
when utimensat is defined.
* testsuite/Makefile.in: Regenerate.
BTW: The same fix as applied to CRuntime_Glibc can also be applied to
FreeBSD version, which currently reads:
// Since FreeBSD 11:
version (none)
{
int utimensat(int dirfd, const char *pathname,
ref const(timespec)[2] times, int flags);
int futimens(int fd, ref const(timespec)[2] times);
}
BTW2: The testcase now fails in another place in src/std/file.d on
CentOS 5.11 (and probably other non-modern systems):
// Tests sub-second precision of querying file times.
// Should pass on most modern systems running on modern filesystems.
// Exceptions:
// - FreeBSD, where one would need to first set the
// vfs.timestamp_precision sysctl to a value greater than zero.
// - OS X, where the native filesystem (HFS+) stores filesystem
// timestamps with 1-second precision.
This test should check the availability of utimensat on linux,
otherwise the resolution is only in seconds range.
Patch was bootstrapped and regression tested on x86_64-linux-gnu
{,-m32} with CentOS 5.11 and Fedora 30.
Uros.
diff --git a/libphobos/Makefile.in b/libphobos/Makefile.in
index 58368c92b492..de5c7d04fee3 100644
--- a/libphobos/Makefile.in
+++ b/libphobos/Makefile.in
@@ -215,6 +215,7 @@ DCFG_HAVE_64BIT_ATOMICS = @DCFG_HAVE_64BIT_ATOMICS@
DCFG_HAVE_ATOMIC_BUILTINS = @DCFG_HAVE_ATOMIC_BUILTINS@
DCFG_HAVE_LIBATOMIC = @DCFG_HAVE_LIBATOMIC@
DCFG_HAVE_QSORT_R = @DCFG_HAVE_QSORT_R@
+DCFG_HAVE_UTIMENSAT = @DCFG_HAVE_UTIMENSAT@
DCFG_MINFO_BRACKETING = @DCFG_MINFO_BRACKETING@
DCFG_THREAD_MODEL = @DCFG_THREAD_MODEL@
DEFS = @DEFS@
diff --git a/libphobos/configure b/libphobos/configure
index 95a2b4232187..a33debdd97b0 100755
--- a/libphobos/configure
+++ b/libphobos/configure
@@ -651,6 +651,7 @@ LIBATOMIC
DCFG_HAVE_LIBATOMIC
DCFG_HAVE_64BIT_ATOMICS
DCFG_HAVE_ATOMIC_BUILTINS
+DCFG_HAVE_UTIMENSAT
DCFG_HAVE_QSORT_R
OS_LINK_SPEC
DCFG_DLPI_TLS_MODID
@@ -11635,7 +11636,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11638 "configure"
+#line 11639 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11741,7 +11742,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11744 "configure"
+#line 11745 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -14393,6 +14394,13 @@ if test "x$ac_cv_func_qsort_r" = xyes; then :
fi
+ DCFG_HAVE_UTIMENSAT=false
+ ac_fn_c_check_func "$LINENO" "utimensat" "ac_cv_func_utimensat"
+if test "x$ac_cv_func_utimensat" = xyes; then :
+ DCFG_HAVE_UTIMENSAT=true
+fi
+
+
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
diff --git a/libphobos/libdruntime/Makefile.in
b/libphobos/libdruntime/Makefile.in
index 19ee94fc370d..bdcc1979046f 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -547,6 +547,7 @@ DCFG_HAVE_64BIT_ATOMICS = @DCFG_HAVE_64BIT_ATOMICS@
DCFG_HAVE_ATOMIC_BUILTINS = @DCFG_HAVE_ATOMIC_BUILTINS@
DCFG_HAVE_LIBATOMIC = @DCFG_HAVE_LIBATOMIC@
DCFG_HAVE_QSORT_R = @DCFG_HAVE_QSORT_R@
+DCFG_HAVE_UTIMENSAT = @DCFG_HAVE_UTIMENSAT@
DCFG_MINFO_BRACKETING = @DCFG_MINFO_BRACKETING@
DCFG_THREAD_MODEL = @DCFG_THREAD_MODEL@
DEFS = @DEFS@
diff --git a/libphobos/libdruntime/core/sys/posix/sys/stat.d
b/libphobos/libdruntime/core/sys/posix/sys/stat.d
index 76e4460550df..9161912b8cb9 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/stat.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/stat.d
@@ -975,9 +975,14 @@ version (CRuntime_Glibc)
enum UTIME_NOW = 0x3fffffff;
enum UTIME_OMIT = 0x3ffffffe;
- int utimensat(int dirfd, const char *pathname,
- ref const(timespec)[2] times, int flags);
- int futimens(int fd, ref const(timespec)[2] times);
+ // utimensat was added in glibc in 2.6.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90261
+ import gcc.config : Have_Utimensat;
+ static if (Have_Utimensat)
+ {
+ int utimensat(int dirfd, const char *pathname,
+ ref const(timespec)[2] times, int flags);
+ int futimens(int fd, ref const(timespec)[2] times);
+ }
}
else version (Darwin)
{
diff --git a/libphobos/libdruntime/gcc/config.d.in
b/libphobos/libdruntime/gcc/config.d.in
index 9c58af0e4f65..0a3782ff2b47 100644
--- a/libphobos/libdruntime/gcc/config.d.in
+++ b/libphobos/libdruntime/gcc/config.d.in
@@ -49,3 +49,6 @@ enum GNU_Have_LibAtomic = @DCFG_HAVE_LIBATOMIC@;
// Do we have qsort_r function
enum Have_Qsort_R = @DCFG_HAVE_QSORT_R@;
+
+// Do we have utimensat function
+enum Have_Utimensat = @DCFG_HAVE_UTIMENSAT@;
diff --git a/libphobos/m4/druntime/libraries.m4
b/libphobos/m4/druntime/libraries.m4
index a7aab4dd88be..74f9f040cdf2 100644
--- a/libphobos/m4/druntime/libraries.m4
+++ b/libphobos/m4/druntime/libraries.m4
@@ -236,5 +236,8 @@ AC_DEFUN([DRUNTIME_LIBRARIES_CLIB],
DCFG_HAVE_QSORT_R=false
AC_CHECK_FUNC(qsort_r, [DCFG_HAVE_QSORT_R=true])
AC_SUBST(DCFG_HAVE_QSORT_R)
+ DCFG_HAVE_UTIMENSAT=false
+ AC_CHECK_FUNC(utimensat, [DCFG_HAVE_UTIMENSAT=true])
+ AC_SUBST(DCFG_HAVE_UTIMENSAT)
AC_LANG_POP([C])
])
diff --git a/libphobos/src/Makefile.in b/libphobos/src/Makefile.in
index 5a46cb9c4bde..27c1391f6103 100644
--- a/libphobos/src/Makefile.in
+++ b/libphobos/src/Makefile.in
@@ -286,6 +286,7 @@ DCFG_HAVE_64BIT_ATOMICS = @DCFG_HAVE_64BIT_ATOMICS@
DCFG_HAVE_ATOMIC_BUILTINS = @DCFG_HAVE_ATOMIC_BUILTINS@
DCFG_HAVE_LIBATOMIC = @DCFG_HAVE_LIBATOMIC@
DCFG_HAVE_QSORT_R = @DCFG_HAVE_QSORT_R@
+DCFG_HAVE_UTIMENSAT = @DCFG_HAVE_UTIMENSAT@
DCFG_MINFO_BRACKETING = @DCFG_MINFO_BRACKETING@
DCFG_THREAD_MODEL = @DCFG_THREAD_MODEL@
DEFS = @DEFS@
diff --git a/libphobos/src/std/file.d b/libphobos/src/std/file.d
index 9ba992944ebd..8c0c85da35ed 100644
--- a/libphobos/src/std/file.d
+++ b/libphobos/src/std/file.d
@@ -1344,7 +1344,7 @@ if (isConvertibleToString!R)
}
testTimes(0);
- version (linux)
+ static if (is(typeof(&utimensat)))
testTimes(123_456_7);
rmdirRecurse(newdir);
diff --git a/libphobos/testsuite/Makefile.in b/libphobos/testsuite/Makefile.in
index efbd884d7ae7..735a36e426a4 100644
--- a/libphobos/testsuite/Makefile.in
+++ b/libphobos/testsuite/Makefile.in
@@ -159,6 +159,7 @@ DCFG_HAVE_64BIT_ATOMICS = @DCFG_HAVE_64BIT_ATOMICS@
DCFG_HAVE_ATOMIC_BUILTINS = @DCFG_HAVE_ATOMIC_BUILTINS@
DCFG_HAVE_LIBATOMIC = @DCFG_HAVE_LIBATOMIC@
DCFG_HAVE_QSORT_R = @DCFG_HAVE_QSORT_R@
+DCFG_HAVE_UTIMENSAT = @DCFG_HAVE_UTIMENSAT@
DCFG_MINFO_BRACKETING = @DCFG_MINFO_BRACKETING@
DCFG_THREAD_MODEL = @DCFG_THREAD_MODEL@
DEFS = @DEFS@