115 lines
3 KiB
Diff
115 lines
3 KiB
Diff
|
--- coreutils-6.12/lib/utimens.c 2008-05-29 09:21:57.000000000 -0400
|
||
|
+++ lib/utimens.c 2008-06-07 11:36:50.000000000 -0400
|
||
|
@@ -96,20 +96,42 @@
|
||
|
#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);
|
||
|
+#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)
|
||
|
+ result = 0;
|
||
|
+#endif
|
||
|
+
|
||
|
+ 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 +147,9 @@
|
||
|
|
||
|
if (fd < 0)
|
||
|
{
|
||
|
-# if HAVE_FUTIMESAT
|
||
|
+# if HAVE_FUTIMESAT
|
||
|
return futimesat (AT_FDCWD, file, t);
|
||
|
-# endif
|
||
|
+# endif
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
@@ -141,21 +163,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 +192,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 +209,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
|
||
|
|