summaryrefslogtreecommitdiffstats
path: root/lib/libarchive
diff options
context:
space:
mode:
authorkientzle <kientzle@FreeBSD.org>2005-11-06 23:38:01 +0000
committerkientzle <kientzle@FreeBSD.org>2005-11-06 23:38:01 +0000
commit5ae83a3b6a9bfa94da179b38c43a4c8c64267994 (patch)
tree6f97641cbb88c02005ff0d98a75fc6b583cf9c63 /lib/libarchive
parent08de7f1aa66753c62e8a10848525b8de9892b5a6 (diff)
downloadFreeBSD-src-5ae83a3b6a9bfa94da179b38c43a4c8c64267994.zip
FreeBSD-src-5ae83a3b6a9bfa94da179b38c43a4c8c64267994.tar.gz
Portability: timegm() isn't standard, so check for timegm() in
the configure script and substitute mktime() when necessary. Thanks to: Darin Broady
Diffstat (limited to 'lib/libarchive')
-rw-r--r--lib/libarchive/archive_platform.h1
-rw-r--r--lib/libarchive/archive_read_support_format_iso9660.c44
-rw-r--r--lib/libarchive/configure.ac.in2
3 files changed, 44 insertions, 3 deletions
diff --git a/lib/libarchive/archive_platform.h b/lib/libarchive/archive_platform.h
index d5a9d85..7ccb6f1 100644
--- a/lib/libarchive/archive_platform.h
+++ b/lib/libarchive/archive_platform.h
@@ -93,6 +93,7 @@
#define HAVE_SYS_TIME_H 1
#define HAVE_SYS_TYPES_H 1
#define HAVE_SYS_WAIT_H 1
+#define HAVE_TIMEGM 1
#define HAVE_UNISTD_H 1
#define HAVE_WCHAR_H 1
#define HAVE_ZLIB_H 1
diff --git a/lib/libarchive/archive_read_support_format_iso9660.c b/lib/libarchive/archive_read_support_format_iso9660.c
index 33806b9..25482a2 100644
--- a/lib/libarchive/archive_read_support_format_iso9660.c
+++ b/lib/libarchive/archive_read_support_format_iso9660.c
@@ -179,6 +179,7 @@ static int archive_read_format_iso9660_read_header(struct archive *,
struct archive_entry *);
static const char *build_pathname(struct archive_string *, struct file_info *);
static void dump_isodirrec(FILE *, const struct iso9660_directory_record *);
+static time_t time_from_tm(struct tm *);
static time_t isodate17(const void *);
static time_t isodate7(const void *);
static int isPVD(struct iso9660 *, const char *);
@@ -950,6 +951,7 @@ isodate7(const void *p)
struct tm tm;
const unsigned char *v = (const unsigned char *)p;
int offset;
+ memset(&tm, 0, sizeof(tm));
tm.tm_year = v[0];
tm.tm_mon = v[1] - 1;
tm.tm_mday = v[2];
@@ -962,7 +964,7 @@ isodate7(const void *p)
tm.tm_hour -= offset / 4;
tm.tm_min -= (offset % 4) * 15;
}
- return (timegm(&tm));
+ return (time_from_tm(&tm));
}
static time_t
@@ -971,6 +973,7 @@ isodate17(const void *p)
struct tm tm;
const unsigned char *v = (const unsigned char *)p;
int offset;
+ memset(&tm, 0, sizeof(tm));
tm.tm_year = (v[0] - '0') * 1000 + (v[1] - '0') * 100
+ (v[2] - '0') * 10 + (v[3] - '0')
- 1900;
@@ -985,7 +988,44 @@ isodate17(const void *p)
tm.tm_hour -= offset / 4;
tm.tm_min -= (offset % 4) * 15;
}
- return (timegm(&tm));
+ return (time_from_tm(&tm));
+}
+
+/*
+ * timegm() converts a struct tm to a time_t, except it isn't standard,
+ * so I provide my own function here that (ideally) is just a wrapper
+ * for timegm().
+ */
+static time_t
+time_from_tm(struct tm *t)
+{
+#if HAVE_TIMEGM
+ return (timegm(t));
+#else
+ /*
+ * Unfortunately, timegm() isn't standard. The standard
+ * mktime() function is a close match, except that it uses
+ * local timezone instead of GMT. Close enough for now.
+ * Note that it is not possible to emulate timegm() using
+ * standard interfaces:
+ * * ANSI C90 does not even guarantee that time_t is
+ * an arithmetic type, so time adjustments can only be
+ * done by manipulating struct tm elements. You cannot
+ * portably calculate time_t values.
+ * * POSIX does promise that time_t is an arithmetic type
+ * measured in seconds, so you can do time_t calculations
+ * while remaining POSIX-compliant.
+ * * Neither ANSI nor POSIX provides an easy way to measure
+ * the timezone offset, so you can't adjust mktime() to
+ * work like timegm().
+ * * POSIX does not promise that the epoch begins in 1970,
+ * so you can't write a portable timegm() function from
+ * scratch.
+ */
+ time_t result = mktime(t);
+ /* TODO: Find a way to improve this approximation to timegm(). */
+ return result;
+#endif
}
static const char *
diff --git a/lib/libarchive/configure.ac.in b/lib/libarchive/configure.ac.in
index 8b597ca..58042ed 100644
--- a/lib/libarchive/configure.ac.in
+++ b/lib/libarchive/configure.ac.in
@@ -79,7 +79,7 @@ AC_FUNC_STRERROR_R
AC_CHECK_FUNCS([acl_create_entry acl_init acl_set_fd acl_set_fd_np acl_set_file])
AC_CHECK_FUNCS([chflags fchdir fchflags fchmod fchown futimes])
AC_CHECK_FUNCS([lchflags lchmod lchown lutimes memmove])
-AC_CHECK_FUNCS([memset mkdir mkfifo strchr strdup strerror strrchr])
+AC_CHECK_FUNCS([memset mkdir mkfifo strchr strdup strerror strrchr timegm])
# MacOS has an acl.h that isn't POSIX. It can be detected by
# checking for ACL_USER
OpenPOWER on IntegriCloud