From 3b73222cfb0f08123ef2e6cbc3976dde94029e8e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bj=C3=B6rn=20Jacke?= Date: Fri, 6 Nov 2009 06:42:45 -0500 Subject: [PATCH] add support for setting timestamps with ns resolution. utimensat and futimens are defined in POSIX.1-2008. They are available on Linux since glibc 2.6 and kernel 2.6.22. SVN-Revision: 1583 --- CMakeLists.txt | 2 ++ configure.ac | 2 +- libarchive/archive_write_disk.c | 26 +++++++++++++++++++++++--- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d549c1288..fed6ac402 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -381,6 +381,8 @@ CHECK_FUNCTION_EXISTS_GLIBC(tzset HAVE_TZSET) CHECK_FUNCTION_EXISTS_GLIBC(unsetenv HAVE_UNSETENV) CHECK_FUNCTION_EXISTS_GLIBC(utime HAVE_UTIME) CHECK_FUNCTION_EXISTS_GLIBC(utimes HAVE_UTIMES) +CHECK_FUNCTION_EXISTS_GLIBC(futimens HAVE_FUTIMENS) +CHECK_FUNCTION_EXISTS_GLIBC(utimensat HAVE_UTIMENSAT) CHECK_FUNCTION_EXISTS_GLIBC(vfork HAVE_VFORK) CHECK_FUNCTION_EXISTS_GLIBC(wcrtomb HAVE_WCRTOMB) CHECK_FUNCTION_EXISTS_GLIBC(wcscpy HAVE_WCSCPY) diff --git a/configure.ac b/configure.ac index 21b3a7215..d1084c65c 100644 --- a/configure.ac +++ b/configure.ac @@ -355,7 +355,7 @@ AC_CHECK_FUNCS([lchflags lchmod lchown link lstat]) AC_CHECK_FUNCS([lutimes memmove memset mkdir mkfifo mknod]) AC_CHECK_FUNCS([nl_langinfo pipe poll readlink select setenv setlocale]) AC_CHECK_FUNCS([strchr strdup strerror strncpy_s strrchr symlink timegm]) -AC_CHECK_FUNCS([tzset unsetenv utime utimes vfork]) +AC_CHECK_FUNCS([tzset unsetenv utime futimens utimensat utimes vfork]) AC_CHECK_FUNCS([wcrtomb wcscpy wcslen wctomb wmemcmp wmemcpy]) # detects cygwin-1.7, as opposed to older versions AC_CHECK_FUNCS([cygwin_conv_path]) diff --git a/libarchive/archive_write_disk.c b/libarchive/archive_write_disk.c index 36853370e..772219657 100644 --- a/libarchive/archive_write_disk.c +++ b/libarchive/archive_write_disk.c @@ -1829,11 +1829,31 @@ set_ownership(struct archive_write_disk *a) return (ARCHIVE_WARN); } -#ifdef HAVE_UTIMES + +#if defined(HAVE_UTIMENSAT) && defined(HAVE_FUTIMENS) +/* + * utimensat() and futimens() are defined in POSIX.1-2008. They provide ns + * resolution and setting times on fd and on symlinks, too. + */ +static int +set_time(int fd, int mode, const char *name, + time_t atime, long atime_nsec, + time_t mtime, long mtime_nsec) +{ + struct timespec ts[2]; + ts[0].tv_sec = atime; + ts[0].tv_nsec = atime_nsec; + ts[1].tv_sec = mtime; + ts[1].tv_nsec = mtime_nsec; + if (fd >= 0) + return futimens(fd, ts); + return utimensat(AT_FDCWD, name, ts, AT_SYMLINK_NOFOLLOW); +} +#elif HAVE_UTIMES /* - * The utimes()-family functions provide high resolution and + * The utimes()-family functions provide µs-resolution and * a way to set time on an fd or a symlink. We prefer them - * when they're available. + * when they're available and utimensat/futimens aren't there. */ static int set_time(int fd, int mode, const char *name, -- 2.47.3