diff options
author | kientzle <kientzle@FreeBSD.org> | 2005-11-06 23:38:01 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2005-11-06 23:38:01 +0000 |
commit | 5ae83a3b6a9bfa94da179b38c43a4c8c64267994 (patch) | |
tree | 6f97641cbb88c02005ff0d98a75fc6b583cf9c63 /lib | |
parent | 08de7f1aa66753c62e8a10848525b8de9892b5a6 (diff) | |
download | FreeBSD-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')
-rw-r--r-- | lib/libarchive/archive_platform.h | 1 | ||||
-rw-r--r-- | lib/libarchive/archive_read_support_format_iso9660.c | 44 | ||||
-rw-r--r-- | lib/libarchive/configure.ac.in | 2 |
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 |