summaryrefslogtreecommitdiffstats
path: root/lib/libarchive/archive_write_disk.c
diff options
context:
space:
mode:
authorkientzle <kientzle@FreeBSD.org>2007-04-14 02:37:22 +0000
committerkientzle <kientzle@FreeBSD.org>2007-04-14 02:37:22 +0000
commit06c7ab197542b866eabdc016004b744e8720c6f6 (patch)
tree568743dd038378291a88b1ec614d65bb763717a7 /lib/libarchive/archive_write_disk.c
parentdff4ea292c7a48641ee96f58a7cfe8807733f5ed (diff)
downloadFreeBSD-src-06c7ab197542b866eabdc016004b744e8720c6f6.zip
FreeBSD-src-06c7ab197542b866eabdc016004b744e8720c6f6.tar.gz
More portability improvements from Martin Koeppe:
conditionally use utime() when utimes() is not available; allow the most common wide-char functions to be replaced when local alternatives are lacking.
Diffstat (limited to 'lib/libarchive/archive_write_disk.c')
-rw-r--r--lib/libarchive/archive_write_disk.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/lib/libarchive/archive_write_disk.c b/lib/libarchive/archive_write_disk.c
index 8980cd0..dc10c7b 100644
--- a/lib/libarchive/archive_write_disk.c
+++ b/lib/libarchive/archive_write_disk.c
@@ -80,6 +80,9 @@ __FBSDID("$FreeBSD$");
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
+#ifdef HAVE_UTIME_H
+#include <utime.h>
+#endif
#include "archive.h"
#include "archive_string.h"
@@ -876,6 +879,8 @@ _archive_write_close(struct archive *_a)
while (p != NULL) {
a->pst = NULL; /* Mark stat cache as out-of-date. */
if (p->fixup & TODO_TIMES) {
+#ifdef HAVE_UTIMES
+ /* {f,l,}utimes() are preferred, when available. */
struct timeval times[2];
times[1].tv_sec = p->mtime;
times[1].tv_usec = p->mtime_nanos / 1000;
@@ -886,6 +891,14 @@ _archive_write_close(struct archive *_a)
#else
utimes(p->name, times);
#endif
+#else
+ /* utime() is more portable, but less precise. */
+ struct utimbuf times;
+ times.modtime = p->mtime;
+ times.actime = p->atime;
+
+ utime(p->name, times);
+#endif
}
if (p->fixup & TODO_MODE_BASE)
chmod(p->name, p->mode);
@@ -1380,6 +1393,12 @@ success:
return (ARCHIVE_OK);
}
+#ifdef HAVE_UTIMES
+/*
+ * The utimes()-family functions provide high resolution and
+ * a way to set time on an fd or a symlink. We prefer them
+ * when they're available.
+ */
static int
set_time(struct archive_write_disk *a)
{
@@ -1420,6 +1439,38 @@ set_time(struct archive_write_disk *a)
/* XXX TODO: Can FreeBSD restore ctime? XXX */
return (ARCHIVE_OK);
}
+#elif defined(HAVE_UTIME)
+/*
+ * utime() is an older, more standard interface that we'll use
+ * if utimes() isn't available.
+ */
+static int
+set_time(struct archive_write_disk *a)
+{
+ const struct stat *st = archive_entry_stat(a->entry);
+ struct utimbuf times;
+
+ times.modtime = st->st_mtime;
+ times.actime = st->st_atime;
+ if (!S_ISLNK(a->mode) && utimes(a->name, times) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't update time for %s", a->name);
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+}
+#else
+/* This platform doesn't give us a way to restore the time. */
+static int
+set_time(struct archive_write_disk *a)
+{
+ (void)a; /* UNUSED */
+ archive_set_error(&a->archive, errno,
+ "Can't update time for %s", a->name);
+ return (ARCHIVE_WARN);
+}
+#endif
+
static int
set_mode(struct archive_write_disk *a, int mode)
OpenPOWER on IntegriCloud