diff -urNp coreutils-8.1-orig/lib/utimens.c coreutils-8.1/lib/utimens.c
--- coreutils-8.1-orig/lib/utimens.c 2009-11-18 15:57:45.000000000 +0100
+++ coreutils-8.1/lib/utimens.c 2009-11-27 13:02:03.000000000 +0100
@@ -54,10 +54,12 @@ struct utimbuf
#undef utimensat
#if HAVE_UTIMENSAT || HAVE_FUTIMENS
-/* Cache variable for whether syscall works; used to avoid calling the
- syscall if we know it will just fail with ENOSYS. 0 = unknown, 1 =
- yes, -1 = no. */
+/* Cache variables for whether the utimensat syscall works; used to
+ avoid calling the syscall if we know it will just fail with ENOSYS.
+ There are some Linux kernel versions where a flag of 0 passes, but
+ not AT_SYMLINK_NOFOLLOW. 0 = unknown, 1 = yes, -1 = no. */
static int utimensat_works_really;
+static int lutimensat_works_really;
#endif /* HAVE_UTIMENSAT || HAVE_UTIMENSAT */
/* Solaris 9 mistakenly succeeds when given a non-directory with a
@@ -242,6 +244,7 @@ fdutimens (char const *file, int fd, str
# endif /* HAVE_FUTIMENS */
}
utimensat_works_really = -1;
+ lutimensat_works_really = -1;
#endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */
/* The platform lacks an interface to set file timestamps with
@@ -381,7 +384,7 @@ lutimens (char const *file, struct times
worry about bogus return values. */
#if HAVE_UTIMENSAT
- if (0 <= utimensat_works_really)
+ if (0 <= lutimensat_works_really)
{
int result = utimensat (AT_FDCWD, file, ts, AT_SYMLINK_NOFOLLOW);
# ifdef __linux__
@@ -397,11 +400,11 @@ lutimens (char const *file, struct times
# endif
if (result == 0 || errno != ENOSYS)
{
- utimensat_works_really = 1;
+ lutimensat_works_really = 1;
return result;
}
}
- utimensat_works_really = -1;
+ lutimensat_works_really = -1;
#endif /* HAVE_UTIMENSAT */
/* The platform lacks an interface to set file timestamps with
@@ -416,7 +419,9 @@ lutimens (char const *file, struct times
return 0;
}
-#if HAVE_LUTIMES
+/* On Linux, lutimes is a thin wrapper around utimensat, so there is
+ no point trying lutimes if utimensat failed with ENOSYS. */
+#if HAVE_LUTIMES && !HAVE_UTIMENSAT
{
struct timeval timeval[2];
struct timeval const *t;
@@ -431,9 +436,11 @@ lutimens (char const *file, struct times
else
t = NULL;
- return lutimes (file, t);
+ result = lutimes (file, t);
+ if (result == 0 || errno != ENOSYS)
+ return result;
}
-#endif /* HAVE_LUTIMES */
+#endif /* HAVE_LUTIMES && !HAVE_UTIMENSAT */
/* Out of luck for symlinks, but we still handle regular files. */
if (!(adjustment_needed || REPLACE_FUNC_STAT_FILE) && lstat (file, &st))