| From b566edc2489a889d97416d2390be7796aa8cdbeb Mon Sep 17 00:00:00 2001 |
| From: Eric Blake <ebb9@byu.net> |
| Date: Mon, 2 Jun 2008 15:08:14 -0600 |
| Subject: [PATCH] Provide futimens/utimensat fallbacks for older kernels. |
| |
| * lib/utimens.c (gl_futimens) [HAVE_UTIMENSAT, HAVE_FUTIMENS]: |
| Provide runtime fallback if kernel lacks support. |
| Reported by Mike Frysinger. |
| |
| Signed-off-by: Eric Blake <ebb9@byu.net> |
| |
| lib/utimens.c | 43 ++++++++++++++++++++++++++----------------- |
| 1 file changed, 26 insertions(+), 17 deletions(-) |
| |
| diff --git a/lib/utimens.c b/lib/utimens.c |
| index 25bc965..134310b 100644 |
| |
| |
| @@ -96,20 +96,30 @@ gl_futimens (int fd ATTRIBUTE_UNUSED, |
| #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 @@ gl_futimens (int fd ATTRIBUTE_UNUSED, |
| |
| if (fd < 0) |
| { |
| -# if HAVE_FUTIMESAT |
| +# if HAVE_FUTIMESAT |
| return futimesat (AT_FDCWD, file, t); |
| -# endif |
| +# endif |
| } |
| else |
| { |
| @@ -141,21 +151,21 @@ gl_futimens (int fd ATTRIBUTE_UNUSED, |
| 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 @@ gl_futimens (int fd ATTRIBUTE_UNUSED, |
| 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 @@ gl_futimens (int fd ATTRIBUTE_UNUSED, |
| |
| 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 |
| -- |
| 1.5.5.1 |