diff -urNp coreutils-6.12-orig/lib/utimens.c coreutils-6.12/lib/utimens.c --- coreutils-6.12-orig/lib/utimens.c 2008-06-06 12:49:08.000000000 +0200 +++ coreutils-6.12/lib/utimens.c 2008-06-06 12:52:24.000000000 +0200 @@ -103,6 +103,17 @@ gl_futimens (int fd ATTRIBUTE_UNUSED, if (fd < 0) { int result = utimensat (AT_FDCWD, file, timespec, 0); +# ifdef __linux__ + /* Work around what might be a kernel bug: + http://bugzilla.redhat.com/442352 + http://bugzilla.redhat.com/449910 + It appears that utimensat can mistakenly return 280 rather + than 0 to indicate success. + 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 +121,17 @@ gl_futimens (int fd ATTRIBUTE_UNUSED, #if HAVE_FUTIMENS { int result = futimens (fd, timespec); +# ifdef __linux__ + /* Work around what might be a kernel bug: + http://bugzilla.redhat.com/442352 + http://bugzilla.redhat.com/449910 + It appears that utimens can mistakenly return 280 rather + than 0 to indicate success. + 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 -urNp coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am --- coreutils-6.12-orig/tests/Makefile.am 2008-06-05 10:52:49.000000000 +0200 +++ coreutils-6.12/tests/Makefile.am 2008-06-05 13:23:02.000000000 +0200 @@ -215,6 +215,7 @@ TESTS = \ misc/tty-eof \ misc/unexpand \ misc/uniq \ + misc/utimensat-touchcp \ chmod/c-option \ chmod/equal-x \ chmod/equals \ diff -urNp coreutils-6.12-orig/tests/misc/utimensat-touchcp coreutils-6.12/tests/misc/utimensat-touchcp --- coreutils-6.12-orig/tests/misc/utimensat-touchcp 1970-01-01 01:00:00.000000000 +0100 +++ coreutils-6.12/tests/misc/utimensat-touchcp 2008-06-05 13:22:01.000000000 +0200 @@ -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