summaryrefslogtreecommitdiff
path: root/m4
diff options
context:
space:
mode:
authorEric Blake <ebb9@byu.net>2009-12-17 07:32:00 -0700
committerEric Blake <ebb9@byu.net>2009-12-19 16:58:45 -0700
commit9a669cf64253a2b2149d7f7cc5e0664c1bc7dda9 (patch)
treeeb13f397b1f14e24aa856ca20dbf15ce47e91f7b /m4
parent68f0f1af0f2cc75615d89234494dca043e99a73d (diff)
downloadgnulib-9a669cf64253a2b2149d7f7cc5e0664c1bc7dda9.tar.gz
futimens, utimensat: work around Linux bug
futimens is trivial - let fdutimens do the work. utimensat is tougher: we don't want to call into local_utimensat, because that can cause unnecessary chdir. So we have to repeat the logic from utimens.c. * m4/futimens.m4 (gl_FUNC_FUTIMENS): Detect ctime bug. * m4/utimensat.m4 (gl_FUNC_UTIMENSAT): Likewise. * lib/utimensat.c (rpl_utimensat): Work around it. * lib/futimens.c (rpl_futimens): Adjust comment.
Diffstat (limited to 'm4')
-rw-r--r--m4/futimens.m433
-rw-r--r--m4/utimensat.m428
2 files changed, 45 insertions, 16 deletions
diff --git a/m4/futimens.m4 b/m4/futimens.m4
index 0547e7ad54..ba5d6b666f 100644
--- a/m4/futimens.m4
+++ b/m4/futimens.m4
@@ -1,4 +1,4 @@
-# serial 1
+# serial 2
# See if we need to provide futimens replacement.
dnl Copyright (C) 2009 Free Software Foundation, Inc.
@@ -22,17 +22,32 @@ AC_DEFUN([gl_FUNC_FUTIMENS],
[AC_RUN_IFELSE([AC_LANG_PROGRAM([[
#include <fcntl.h>
#include <sys/stat.h>
+#include <unistd.h>
+]], [[struct timespec ts[2] = { { 1, UTIME_OMIT }, { 1, UTIME_NOW } };
+ int fd = creat ("conftest.file", 0600);
+ struct stat st;
+ if (fd < 0) return 1;
+ if (futimens (AT_FDCWD, NULL)) return 2;
+ if (futimens (fd, ts)) return 3;
+ sleep (1);
+ ts[0].tv_nsec = UTIME_NOW;
+ ts[1].tv_nsec = UTIME_OMIT;
+ if (futimens (fd, ts)) return 4;
+ if (fstat (fd, &st)) return 5;
+ if (st.st_ctime < st.st_atime) return 6;
+ ]])],
+ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#ifdef __linux__
-/* The Linux kernel added futimens in 2.6.22, but it had bugs until 2.6.26.
- Always replace futimens to support older kernels. */
+/* The Linux kernel added futimens in 2.6.22, but has bugs with UTIME_OMIT
+ in 2.6.32. Always replace futimens to support older kernels. */
choke me
#endif
-]], [[struct timespec ts[2] = { { 1, UTIME_OMIT }, { 1, UTIME_OMIT } };
- if (futimens (AT_FDCWD, NULL)) return 1;
- return futimens (open (".", O_RDONLY), ts);]])],
- [gl_cv_func_futimens_works=yes],
- [gl_cv_func_futimens_works="needs runtime check"],
- [gl_cv_func_futimens_works="guessing no"])])
+ ]])],
+ [gl_cv_func_futimens_works=yes],
+ [gl_cv_func_futimens_works="needs runtime check"])],
+ [gl_cv_func_futimens_works=no],
+ [gl_cv_func_futimens_works="guessing no"])
+ rm -f conftest.file])
if test "$gl_cv_func_futimens_works" != yes; then
REPLACE_FUTIMENS=1
AC_LIBOBJ([futimens])
diff --git a/m4/utimensat.m4 b/m4/utimensat.m4
index 2a6033f2c0..21e1ea526d 100644
--- a/m4/utimensat.m4
+++ b/m4/utimensat.m4
@@ -1,4 +1,4 @@
-# serial 1
+# serial 2
# See if we need to provide utimensat replacement.
dnl Copyright (C) 2009 Free Software Foundation, Inc.
@@ -22,15 +22,29 @@ AC_DEFUN([gl_FUNC_UTIMENSAT],
[AC_RUN_IFELSE([AC_LANG_PROGRAM([[
#include <fcntl.h>
#include <sys/stat.h>
+#include <unistd.h>
+]], [[struct timespec ts[2] = { { 1, UTIME_OMIT }, { 1, UTIME_NOW } };
+ struct stat st;
+ const char *f = "conftest.file";
+ if (close (creat (f, 0600))) return 1;
+ if (utimensat (AT_FDCWD, f, NULL, AT_SYMLINK_NOFOLLOW)) return 2;
+ if (utimensat (AT_FDCWD, f, ts, 0)) return 3;
+ sleep (1);
+ ts[0].tv_nsec = UTIME_NOW;
+ ts[1].tv_nsec = UTIME_OMIT;
+ if (utimensat (AT_FDCWD, f, ts, 0)) return 4;
+ if (stat (f, &st)) return 5;
+ if (st.st_ctime < st.st_atime) return 6;]])],
+ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#ifdef __linux__
-/* The Linux kernel added utimensat in 2.6.22, but it had bugs until 2.6.26.
- Always replace utimensat to support older kernels. */
+/* The Linux kernel added utimensat in 2.6.22, but has bugs with UTIME_OMIT
+ in 2.6.32. Always replace utimensat to support older kernels. */
choke me
#endif
-]], [[struct timespec ts[2] = { { 1, UTIME_OMIT }, { 1, UTIME_OMIT } };
- return utimensat (AT_FDCWD, ".", NULL, AT_SYMLINK_NOFOLLOW);]])],
- [gl_cv_func_utimensat_works=yes],
- [gl_cv_func_utimensat_works="needs runtime check"],
+ ]])],
+ [gl_cv_func_utimensat_works=yes],
+ [gl_cv_func_utimensat_works="needs runtime check"])],
+ [gl_cv_func_utimensat_works=no],
[gl_cv_func_utimensat_works="guessing no"])])
if test "$gl_cv_func_utimensat_works" != yes; then
REPLACE_UTIMENSAT=1