diff options
author | kientzle <kientzle@FreeBSD.org> | 2007-04-14 02:37:22 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2007-04-14 02:37:22 +0000 |
commit | 06c7ab197542b866eabdc016004b744e8720c6f6 (patch) | |
tree | 568743dd038378291a88b1ec614d65bb763717a7 | |
parent | dff4ea292c7a48641ee96f58a7cfe8807733f5ed (diff) | |
download | FreeBSD-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.c | 28 | ||||
-rw-r--r-- | lib/libarchive/archive_write_disk.c | 51 | ||||
-rw-r--r-- | lib/libarchive/config_freebsd.h | 7 |
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 |