Ondrej Vasik c8e66e
diff -urNp coreutils-6.12-orig/lib/utimens.c coreutils-6.12/lib/utimens.c
Ondrej Vasik c8e66e
--- coreutils-6.12-orig/lib/utimens.c	2008-06-06 12:49:08.000000000 +0200
Ondrej Vasik c8e66e
+++ coreutils-6.12/lib/utimens.c	2008-06-06 12:52:24.000000000 +0200
Ondrej Vasik c8e66e
@@ -103,6 +103,17 @@ gl_futimens (int fd ATTRIBUTE_UNUSED,
Ondrej Vasik c8e66e
   if (fd < 0)
Ondrej Vasik c8e66e
     {
Ondrej Vasik c8e66e
       int result = utimensat (AT_FDCWD, file, timespec, 0);
Ondrej Vasik c8e66e
+# ifdef __linux__
Ondrej Vasik c8e66e
+       /* Work around what might be a kernel bug:
Ondrej Vasik c8e66e
+        http://bugzilla.redhat.com/442352
Ondrej Vasik c8e66e
+        http://bugzilla.redhat.com/449910
Ondrej Vasik c8e66e
+        It appears that utimensat can mistakenly return 280 rather
Ondrej Vasik c8e66e
+        than 0 to indicate success.
Ondrej Vasik c8e66e
+        FIXME: remove in 2010 or whenever the offending kernels
Ondrej Vasik c8e66e
+        are no longer in common use.  */
Ondrej Vasik c8e66e
+       if (0 < result)
Ondrej Vasik c8e66e
+         errno = ENOSYS;
Ondrej Vasik c8e66e
+# endif
Ondrej Vasik c8e66e
       if (result == 0 || errno != ENOSYS)
Ondrej Vasik c8e66e
         return result;
Ondrej Vasik c8e66e
     }
Ondrej Vasik c8e66e
@@ -110,6 +121,17 @@ gl_futimens (int fd ATTRIBUTE_UNUSED,
Ondrej Vasik c8e66e
 #if HAVE_FUTIMENS
Ondrej Vasik c8e66e
   {
Ondrej Vasik c8e66e
     int result = futimens (fd, timespec);
Ondrej Vasik c8e66e
+# ifdef __linux__
Ondrej Vasik c8e66e
+       /* Work around what might be a kernel bug:
Ondrej Vasik c8e66e
+        http://bugzilla.redhat.com/442352
Ondrej Vasik c8e66e
+        http://bugzilla.redhat.com/449910
Ondrej Vasik c8e66e
+        It appears that utimens can mistakenly return 280 rather
Ondrej Vasik c8e66e
+        than 0 to indicate success.
Ondrej Vasik c8e66e
+        FIXME: remove in 2010 or whenever the offending kernels
Ondrej Vasik c8e66e
+        are no longer in common use.  */
Ondrej Vasik c8e66e
+    if (0 < result)
Ondrej Vasik c8e66e
+       errno = ENOSYS;
Ondrej Vasik c8e66e
+# endif
Ondrej Vasik c8e66e
     if (result == 0 || errno != ENOSYS)
Ondrej Vasik c8e66e
       return result;
Ondrej Vasik c8e66e
   }
Ondrej Vasik c8e66e
diff -urNp coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am
Ondrej Vasik c8e66e
--- coreutils-6.12-orig/tests/Makefile.am	2008-06-05 10:52:49.000000000 +0200
Ondrej Vasik c8e66e
+++ coreutils-6.12/tests/Makefile.am	2008-06-05 13:23:02.000000000 +0200
Ondrej Vasik c8e66e
@@ -215,6 +215,7 @@ TESTS =						\
Ondrej Vasik c8e66e
   misc/tty-eof					\
Ondrej Vasik c8e66e
   misc/unexpand					\
Ondrej Vasik c8e66e
   misc/uniq					\
Ondrej Vasik c8e66e
+  misc/utimensat-touchcp  \
Ondrej Vasik c8e66e
   chmod/c-option				\
Ondrej Vasik c8e66e
   chmod/equal-x					\
Ondrej Vasik c8e66e
   chmod/equals					\
Ondrej Vasik c8e66e
diff -urNp coreutils-6.12-orig/tests/misc/utimensat-touchcp coreutils-6.12/tests/misc/utimensat-touchcp
Ondrej Vasik c8e66e
--- coreutils-6.12-orig/tests/misc/utimensat-touchcp	1970-01-01 01:00:00.000000000 +0100
Ondrej Vasik c8e66e
+++ coreutils-6.12/tests/misc/utimensat-touchcp	2008-06-05 13:22:01.000000000 +0200
Ondrej Vasik c8e66e
@@ -0,0 +1,33 @@
Ondrej Vasik c8e66e
+#!/bin/sh
Ondrej Vasik c8e66e
+# Make sure touch -r and cp -pr works without hanging.
Ondrej Vasik c8e66e
+
Ondrej Vasik c8e66e
+if test "$VERBOSE" = yes; then
Ondrej Vasik c8e66e
+  set -x
Ondrej Vasik c8e66e
+  touch --version
Ondrej Vasik c8e66e
+  cp --version
Ondrej Vasik c8e66e
+fi
Ondrej Vasik c8e66e
+
Ondrej Vasik c8e66e
+. $srcdir/test-lib.sh
Ondrej Vasik c8e66e
+
Ondrej Vasik c8e66e
+touch a.old || framework_failure
Ondrej Vasik c8e66e
+sleep 1
Ondrej Vasik c8e66e
+
Ondrej Vasik c8e66e
+fail=0
Ondrej Vasik c8e66e
+
Ondrej Vasik c8e66e
+#check for touch
Ondrej Vasik c8e66e
+touch -r a.old a || fail=1
Ondrej Vasik c8e66e
+ls -l --full-time a >time1
Ondrej Vasik c8e66e
+ls -l --full-time a.old >time2
Ondrej Vasik c8e66e
+sed -i 's/a.old/a/' time2
Ondrej Vasik c8e66e
+cmp time1 time2 > /dev/null 2>&1 || fail=1
Ondrej Vasik c8e66e
+test $fail = 1 && diff time1 time2 2> /dev/null
Ondrej Vasik c8e66e
+
Ondrej Vasik c8e66e
+#check for cp
Ondrej Vasik c8e66e
+cp -pr a.old b || fail=1
Ondrej Vasik c8e66e
+ls -l --full-time a >time1
Ondrej Vasik c8e66e
+ls -l --full-time a.old >time2
Ondrej Vasik c8e66e
+sed -i 's/a.old/a/' time2
Ondrej Vasik c8e66e
+cmp time1 time2 > /dev/null 2>&1 || fail=1
Ondrej Vasik c8e66e
+test $fail = 1 && diff time1 time2 2> /dev/null
Ondrej Vasik c8e66e
+
Ondrej Vasik c8e66e
+(exit $fail); exit $fail