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.
This commit is contained in:
Tim Kientzle 2007-04-14 02:37:22 +00:00
parent 05d91e4363
commit 1df7aefccf
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=168701
3 changed files with 75 additions and 11 deletions

View File

@ -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"

View File

@ -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;
@ -885,6 +890,14 @@ _archive_write_close(struct archive *_a)
lutimes(p->name, times);
#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)
@ -1380,6 +1393,12 @@ set_ownership(struct archive_write_disk *a)
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)

View File

@ -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