--- coreutils-6.12.org/ChangeLog 2008-06-01 00:00:38.000000000 +0200 +++ coreutils-6.12.org/ChangeLog 2008-06-03 16:10:44.835855000 +0200 @@ -1,3 +1,10 @@ +2008-06-02 Eric Blake + + Provide fallback for older kernels. + * lib/utimens.c (gl_futimens) [HAVE_UTIMENSAT, HAVE_FUTIMENS]: + Provide runtime fallback if kernel lacks support. + Reported by Mike Frysinger. + 2008-05-31 Jim Meyering Version 6.12. --- coreutils-6.12.org/lib/utimens.c 2008-06-03 16:14:36.099344000 +0200 +++ coreutils-6.12.org/lib/utimens.c 2008-06-03 16:32:05.045167638 +0200 @@ -96,20 +96,30 @@ #endif /* POSIX 200x added two interfaces to set file timestamps with - nanosecond resolution. */ + nanosecond resolution. We provide a fallback for ENOSYS (for + example, compiling against Linux 2.6.25 kernel headers and glibc + 2.7, but running on Linux 2.6.18 kernel). */ #if HAVE_UTIMENSAT if (fd < 0) - return utimensat (AT_FDCWD, file, timespec, 0); + { + int result = utimensat (AT_FDCWD, file, timespec, 0); + if (result == 0 || errno != ENOSYS) + return result; + } #endif #if HAVE_FUTIMENS - return futimens (fd, timespec); -#else + { + int result = futimens (fd, timespec); + if (result == 0 || errno != ENOSYS) + return result; + } +#endif /* The platform lacks an interface to set file timestamps with nanosecond resolution, so do the best we can, discarding any fractional part of the timestamp. */ { -# if HAVE_FUTIMESAT || HAVE_WORKING_UTIMES +#if HAVE_FUTIMESAT || HAVE_WORKING_UTIMES struct timeval timeval[2]; struct timeval const *t; if (timespec) @@ -125,9 +135,9 @@ if (fd < 0) { -# if HAVE_FUTIMESAT +# if HAVE_FUTIMESAT return futimesat (AT_FDCWD, file, t); -# endif +# endif } else { @@ -141,21 +151,21 @@ worth optimizing, and who knows what other messed-up systems are out there? So play it safe and fall back on the code below. */ -# if HAVE_FUTIMESAT +# if HAVE_FUTIMESAT if (futimesat (fd, NULL, t) == 0) return 0; -# elif HAVE_FUTIMES +# elif HAVE_FUTIMES if (futimes (fd, t) == 0) return 0; -# endif +# endif } -# endif /* HAVE_FUTIMESAT || HAVE_WORKING_UTIMES */ +#endif /* HAVE_FUTIMESAT || HAVE_WORKING_UTIMES */ if (!file) { -# if ! (HAVE_FUTIMESAT || (HAVE_WORKING_UTIMES && HAVE_FUTIMES)) +#if ! (HAVE_FUTIMESAT || (HAVE_WORKING_UTIMES && HAVE_FUTIMES)) errno = ENOSYS; -# endif +#endif /* Prefer EBADF to ENOSYS if both error numbers apply. */ if (errno == ENOSYS) @@ -170,9 +180,9 @@ return -1; } -# if HAVE_WORKING_UTIMES +#if HAVE_WORKING_UTIMES return utimes (file, t); -# else +#else { struct utimbuf utimbuf; struct utimbuf const *ut; @@ -187,9 +197,8 @@ return utime (file, ut); } -# endif /* !HAVE_WORKING_UTIMES */ +#endif /* !HAVE_WORKING_UTIMES */ } -#endif /* !HAVE_FUTIMENS */ } /* Set the access and modification time stamps of FILE to be