Blob Blame History Raw
diff -Naurp coreutils-6.12.orig/lib/utimens.c coreutils-6.12/lib/utimens.c
--- coreutils-6.12.orig/lib/utimens.c	2008-10-06 16:21:11.000000000 -0400
+++ coreutils-6.12/lib/utimens.c	2008-10-06 16:26:33.000000000 -0400
@@ -103,6 +103,18 @@ gl_futimens (int fd ATTRIBUTE_UNUSED,
   if (fd < 0)
     {
       int result = utimensat (AT_FDCWD, file, timespec, 0);
+# ifdef __linux__
+       /* Work around xen kernel bug:
+        http://bugzilla.redhat.com/442352
+        http://bugzilla.redhat.com/449910
+        When running on a sufficiently old (pre-RHEL5.3) x86_64 xen
+        kernel, utimensat can mistakenly return its syscall number (280 on
+        x86_64) rather than the proper ENOSYS code, due to a xen bug.
+        FIXME: remove in 2010 or whenever the offending kernels
+        are no longer in common use.  */
+       if (0 < result)
+         errno = ENOSYS;
+# endif
       if (result == 0 || errno != ENOSYS)
         return result;
     }
@@ -110,6 +122,18 @@ gl_futimens (int fd ATTRIBUTE_UNUSED,
 #if HAVE_FUTIMENS
   {
     int result = futimens (fd, timespec);
+# ifdef __linux__
+       /* Work around xen kernel bug:
+        http://bugzilla.redhat.com/442352
+        http://bugzilla.redhat.com/449910
+        When running on a sufficiently old (pre-RHEL5.3) x86_64 xen
+        kernel, utimensat can mistakenly return its syscall number (280 on
+        x86_64) rather than the proper ENOSYS code, due to a xen bug.
+        FIXME: remove in 2010 or whenever the offending kernels
+        are no longer in common use.  */
+    if (0 < result)
+       errno = ENOSYS;
+# endif
     if (result == 0 || errno != ENOSYS)
       return result;
   }
diff -Naurp coreutils-6.12.orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am
--- coreutils-6.12.orig/tests/Makefile.am	2008-10-06 16:21:11.000000000 -0400
+++ coreutils-6.12/tests/Makefile.am	2008-10-06 16:22:04.000000000 -0400
@@ -215,6 +215,7 @@ TESTS =						\
   misc/tty-eof					\
   misc/unexpand					\
   misc/uniq					\
+  misc/utimensat-touchcp  \
   chmod/c-option				\
   chmod/equal-x					\
   chmod/equals					\
diff -Naurp coreutils-6.12.orig/tests/misc/utimensat-touchcp coreutils-6.12/tests/misc/utimensat-touchcp
--- coreutils-6.12.orig/tests/misc/utimensat-touchcp	1969-12-31 19:00:00.000000000 -0500
+++ coreutils-6.12/tests/misc/utimensat-touchcp	2008-10-06 16:22:04.000000000 -0400
@@ -0,0 +1,33 @@
+#!/bin/sh
+# Make sure touch -r and cp -pr works without hanging.
+
+if test "$VERBOSE" = yes; then
+  set -x
+  touch --version
+  cp --version
+fi
+
+. $srcdir/test-lib.sh
+
+touch a.old || framework_failure
+sleep 1
+
+fail=0
+
+#check for touch
+touch -r a.old a || fail=1
+ls -l --full-time a >time1
+ls -l --full-time a.old >time2
+sed -i 's/a.old/a/' time2
+cmp time1 time2 > /dev/null 2>&1 || fail=1
+test $fail = 1 && diff time1 time2 2> /dev/null
+
+#check for cp
+cp -pr a.old b || fail=1
+ls -l --full-time a >time1
+ls -l --full-time a.old >time2
+sed -i 's/a.old/a/' time2
+cmp time1 time2 > /dev/null 2>&1 || fail=1
+test $fail = 1 && diff time1 time2 2> /dev/null
+
+(exit $fail); exit $fail