diff mbox series

[d] : Fix PR90261, FAIL: libphobos.phobos/std/file.d on CentOS 5.11, Linux 2.6.18

Message ID CAFULd4abOvNfGGPxRqnSLZbeY+FUmOqgowQDRveOaGzmKWtaxg@mail.gmail.com
State New
Headers show
Series [d] : Fix PR90261, FAIL: libphobos.phobos/std/file.d on CentOS 5.11, Linux 2.6.18 | expand

Commit Message

Uros Bizjak May 8, 2019, 11:52 a.m. UTC
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  <ubizjak@gmail.com>

    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.

Comments

Uros Bizjak June 17, 2019, 11:08 a.m. UTC | #1
Ping.

On Wed, May 8, 2019 at 1:52 PM Uros Bizjak <ubizjak@gmail.com> wrote:
>
> 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  <ubizjak@gmail.com>
>
>     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 mbox series

Patch

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@