summaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--lib/libarchive/archive_entry.c28
-rw-r--r--lib/libarchive/archive_write_disk.c51
-rw-r--r--lib/libarchive/config_freebsd.h7
3 files changed, 75 insertions, 11 deletions
diff --git a/lib/libarchive/archive_entry.c b/lib/libarchive/archive_entry.c
index c498bc0..8309d4f 100644
--- a/lib/libarchive/archive_entry.c
+++ b/lib/libarchive/archive_entry.c
@@ -59,18 +59,11 @@ __FBSDID("$FreeBSD$");
#ifdef HAVE_STRING_H
#include <string.h>
#endif
-
-/* Obtain suitable wide-character manipulation functions. */
#ifdef HAVE_WCHAR_H
#include <wchar.h>
-#else
-static size_t wcslen(const wchar_t *s)
-{
- const wchar_t *p = s;
- while (*p != L'\0')
- ++p;
- return p - s;
-}
+#endif
+
+#ifndef HAVE_WCSCPY
static wchar_t * wcscpy(wchar_t *s1, const wchar_t *s2)
{
wchar_t *dest = s1;
@@ -78,10 +71,23 @@ static wchar_t * wcscpy(wchar_t *s1, const wchar_t *s2)
++s1, ++s2;
return dest;
}
-#define wmemcpy(a,b,i) (wchar_t *)memcpy((a), (b), (i) * sizeof(wchar_t))
+#endif
+#ifndef HAVE_WCSLEN
+static size_t wcslen(const wchar_t *s)
+{
+ const wchar_t *p = s;
+ while (*p != L'\0')
+ ++p;
+ return p - s;
+}
+#endif
+#ifndef HAVE_WMEMCMP
/* Good enough for simple equality testing, but not for sorting. */
#define wmemcmp(a,b,i) memcmp((a), (b), (i) * sizeof(wchar_t))
#endif
+#ifndef HAVE_WMEMCPY
+#define wmemcpy(a,b,i) (wchar_t *)memcpy((a), (b), (i) * sizeof(wchar_t))
+#endif
#include "archive.h"
#include "archive_entry.h"
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)
diff --git a/lib/libarchive/config_freebsd.h b/lib/libarchive/config_freebsd.h
index d5f5eab..03f0724 100644
--- a/lib/libarchive/config_freebsd.h
+++ b/lib/libarchive/config_freebsd.h
@@ -80,7 +80,14 @@
#define HAVE_SYS_WAIT_H 1
#define HAVE_TIMEGM 1
#define HAVE_UNISTD_H 1
+#define HAVE_UTIME 1
+#define HAVE_UTIMES 1
+#define HAVE_UTIME_H 1
#define HAVE_WCHAR_H 1
+#define HAVE_WCSCPY 1
+#define HAVE_WCSLEN 1
+#define HAVE_WMEMCMP 1
+#define HAVE_WMEMCPY 1
#define HAVE_ZLIB_H 1
#define STDC_HEADERS 1
#define TIME_WITH_SYS_TIME 1
OpenPOWER on IntegriCloud