From a11f15860ae39ecdc8173243a211cdafc8ac893c Mon Sep 17 00:00:00 2001 From: Martin Matuska Date: Mon, 13 Jan 2020 14:23:00 +0100 Subject: [PATCH] Windows: use _localtime64_s and _gmtime64_s where appropriate --- CMakeLists.txt | 1 + build/cmake/config.h.in | 3 + configure.ac | 2 +- cpio/cpio.c | 17 +++- libarchive/archive_getdate.c | 102 ++++++++++++++++--- libarchive/archive_read_support_format_rar.c | 19 +++- libarchive/archive_write_set_format_warc.c | 11 +- libarchive/archive_write_set_format_xar.c | 6 +- libarchive/archive_write_set_format_zip.c | 15 ++- tar/util.c | 15 ++- 10 files changed, 164 insertions(+), 27 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 51c4c00d3..552aef961 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1392,6 +1392,7 @@ CHECK_FUNCTION_EXISTS_GLIBC(wctomb HAVE_WCTOMB) CHECK_FUNCTION_EXISTS_GLIBC(_ctime64_s HAVE__CTIME64_S) CHECK_FUNCTION_EXISTS_GLIBC(_fseeki64 HAVE__FSEEKI64) CHECK_FUNCTION_EXISTS_GLIBC(_get_timezone HAVE__GET_TIMEZONE) +CHECK_FUNCTION_EXISTS_GLIBC(_gmtime64_s HAVE__GMTIME64_S) CHECK_FUNCTION_EXISTS_GLIBC(_localtime64_s HAVE__LOCALTIME64_S) CHECK_FUNCTION_EXISTS_GLIBC(_mkgmtime64 HAVE__MKGMTIME64) diff --git a/build/cmake/config.h.in b/build/cmake/config.h.in index 3b1f0b95c..fcbd80c5a 100644 --- a/build/cmake/config.h.in +++ b/build/cmake/config.h.in @@ -1210,6 +1210,9 @@ typedef uint64_t uintmax_t; /* Define to 1 if you have the `_get_timezone' function. */ #cmakedefine HAVE__GET_TIMEZONE 1 +/* Define to 1 if you have the `_gmtime64_s' function. */ +#cmakedefine HAVE__GMTIME64_S 1 + /* Define to 1 if you have the `_localtime64_s' function. */ #cmakedefine HAVE__LOCALTIME64_S 1 diff --git a/configure.ac b/configure.ac index ce90ee839..072ea90f7 100644 --- a/configure.ac +++ b/configure.ac @@ -641,7 +641,7 @@ AC_CHECK_FUNCS([strchr strdup strerror strncpy_s strrchr symlink timegm]) AC_CHECK_FUNCS([tzset unlinkat unsetenv utime utimensat utimes vfork]) AC_CHECK_FUNCS([wcrtomb wcscmp wcscpy wcslen wctomb wmemcmp wmemcpy wmemmove]) AC_CHECK_FUNCS([_ctime64_s _fseeki64]) -AC_CHECK_FUNCS([_get_timezone _localtime64_s _mkgmtime64]) +AC_CHECK_FUNCS([_get_timezone _gmtime64_s _localtime64_s _mkgmtime64]) # detects cygwin-1.7, as opposed to older versions AC_CHECK_FUNCS([cygwin_conv_path]) diff --git a/cpio/cpio.c b/cpio/cpio.c index f8dd62c54..da5c39860 100644 --- a/cpio/cpio.c +++ b/cpio/cpio.c @@ -1140,9 +1140,13 @@ list_item_verbose(struct cpio *cpio, struct archive_entry *entry) time_t mtime; static time_t now; struct tm *ltime; -#ifdef HAVE_LOCALTIME_R +#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S) struct tm tmbuf; #endif +#if defined(HAVE__LOCALTIME64_S) + errno_t terr; + __time64_t tmptime; +#endif if (!now) time(&now); @@ -1190,10 +1194,17 @@ list_item_verbose(struct cpio *cpio, struct archive_entry *entry) else fmt = cpio->day_first ? "%e %b %H:%M" : "%b %e %H:%M"; #endif -#ifdef HAVE_LOCALTIME_R +#if defined(HAVE_LOCALTIME_R) ltime = localtime_r(&mtime, &tmbuf); +#elif defined(HAVE__LOCALTIME64_S) + tmptime = mtime; + terr = _localtime64_s(&tmbuf, &tmptime); + if (terr) + ltime = NULL; + else + ltime = &tmbuf; #else - ltime = localtime(&mtime) + ltime = localtime(&mtime); #endif strftime(date, sizeof(date), fmt, ltime); diff --git a/libarchive/archive_getdate.c b/libarchive/archive_getdate.c index aff4ac4c9..3ec5bba88 100644 --- a/libarchive/archive_getdate.c +++ b/libarchive/archive_getdate.c @@ -698,9 +698,13 @@ Convert(time_t Month, time_t Day, time_t Year, time_t Julian; int i; struct tm *ltime; -#ifdef HAVE_LOCALTIME_R +#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S) struct tm tmbuf; #endif +#if defined(HAVE__LOCALTIME64_S) + errno_t terr; + __time64_t tmptime; +#endif if (Year < 69) Year += 2000; @@ -727,8 +731,15 @@ Convert(time_t Month, time_t Day, time_t Year, Julian *= DAY; Julian += Timezone; Julian += Hours * HOUR + Minutes * MINUTE + Seconds; -#ifdef HAVE_LOCALTIME_R +#if defined(HAVE_LOCALTIME_R) ltime = localtime_r(&Julian, &tmbuf); +#elif defined(HAVE__LOCALTIME64_S) + tmptime = Julian; + terr = _localtime64_s(&tmbuf, &tmptime); + if (terr) + ltime = NULL; + else + ltime = &tmbuf; #else ltime = localtime(&Julian); #endif @@ -744,18 +755,36 @@ DSTcorrect(time_t Start, time_t Future) time_t StartDay; time_t FutureDay; struct tm *ltime; -#ifdef HAVE_LOCALTIME_R +#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S) struct tm tmbuf; #endif +#if defined(HAVE__LOCALTIME64_S) + errno_t terr; + __time64_t tmptime; +#endif -#ifdef HAVE_LOCALTIME_R +#if defined(HAVE_LOCALTIME_R) ltime = localtime_r(&Start, &tmbuf); +#elif defined(HAVE__LOCALTIME64_S) + tmptime = Start; + terr = _localtime64_s(&tmbuf, &tmptime); + if (terr) + ltime = NULL; + else + ltime = &tmbuf; #else ltime = localtime(&Start); #endif StartDay = (ltime->tm_hour + 1) % 24; -#ifdef HAVE_LOCALTIME_R +#if defined(HAVE_LOCALTIME_R) ltime = localtime_r(&Future, &tmbuf); +#elif defined(HAVE__LOCALTIME64_S) + tmptime = Future; + terr = _localtime64_s(&tmbuf, &tmptime); + if (terr) + ltime = NULL; + else + ltime = &tmbuf; #else ltime = localtime(&Future); #endif @@ -770,13 +799,24 @@ RelativeDate(time_t Start, time_t zone, int dstmode, { struct tm *tm; time_t t, now; -#ifdef HAVE_GMTIME_R +#if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S) struct tm tmbuf; #endif +#if defined(HAVE__GMTIME64_S) + errno_t terr; + __time64_t tmptime; +#endif t = Start - zone; -#ifdef HAVE_GMTIME_R +#if defined(HAVE_GMTIME_R) tm = gmtime_r(&t, &tmbuf); +#elif defined(HAVE__GMTIME64_S) + tmptime = t; + terr = _gmtime64_s(&tmbuf, &tmptime); + if (terr) + tm = NULL; + else + tm = &tmbuf; #else tm = gmtime(&t); #endif @@ -795,14 +835,25 @@ RelativeMonth(time_t Start, time_t Timezone, time_t RelMonth) struct tm *tm; time_t Month; time_t Year; -#ifdef HAVE_LOCALTIME_R +#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S) struct tm tmbuf; #endif +#if defined(HAVE__LOCALTIME64_S) + errno_t terr; + __time64_t tmptime; +#endif if (RelMonth == 0) return 0; -#ifdef HAVE_LOCALTIME_R +#if defined(HAVE_LOCALTIME_R) tm = localtime_r(&Start, &tmbuf); +#elif defined(HAVE__LOCALTIME64_S) + tmptime = Start; + terr = _localtime64_s(&tmbuf, &tmptime); + if (terr) + tm = NULL; + else + tm = &tmbuf; #else tm = localtime(&Start); #endif @@ -942,6 +993,10 @@ __archive_get_date(time_t now, const char *p) time_t Start; time_t tod; long tzone; +#if defined(HAVE__LOCALTIME64_S) || defined(HAVE__GMTIME64_S) + errno_t terr; + __time64_t tmptime; +#endif /* Clear out the parsed token array. */ memset(tokens, 0, sizeof(tokens)); @@ -950,22 +1005,36 @@ __archive_get_date(time_t now, const char *p) gds = &_gds; /* Look up the current time. */ -#ifdef HAVE_LOCALTIME_R +#if defined(HAVE_LOCALTIME_R) tm = localtime_r(&now, &local); +#elif defined(HAVE__LOCALTIME64_S) + tmptime = now; + terr = _localtime64_s(&local, &tmptime); + if (terr) + tm = NULL; + else + tm = &local; #else memset(&local, 0, sizeof(local)); tm = localtime(&now); #endif if (tm == NULL) return -1; -#ifndef HAVE_LOCALTIME_R +#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE__LOCALTIME64_S) local = *tm; #endif /* Look up UTC if we can and use that to determine the current * timezone offset. */ -#ifdef HAVE_GMTIME_R +#if defined(HAVE_GMTIME_R) gmt_ptr = gmtime_r(&now, &gmt); +#elif defined(HAVE__GMTIME64_S) + tmptime = now; + terr = _gmtime64_s(&gmt, &tmptime); + if (terr) + gmt_ptr = NULL; + else + gmt_ptr = &gmt; #else memset(&gmt, 0, sizeof(gmt)); gmt_ptr = gmtime(&now); @@ -1007,8 +1076,15 @@ __archive_get_date(time_t now, const char *p) * time components instead of the local timezone. */ if (gds->HaveZone && gmt_ptr != NULL) { now -= gds->Timezone; -#ifdef HAVE_GMTIME_R +#if defined(HAVE_GMTIME_R) gmt_ptr = gmtime_r(&now, &gmt); +#elif defined(HAVE__GMTIME64_S) + tmptime = now; + terr = _gmtime64_s(&gmt, &tmptime); + if (terr) + gmt_ptr = NULL; + else + gmt_ptr = &gmt; #else gmt_ptr = gmtime(&now); #endif diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c index 153dc908d..fe5903b64 100644 --- a/libarchive/archive_read_support_format_rar.c +++ b/libarchive/archive_read_support_format_rar.c @@ -1720,11 +1720,15 @@ read_exttime(const char *p, struct rar *rar, const char *endp) unsigned rmode, flags, rem, j, count; int ttime, i; struct tm *tm; -#ifdef HAVE_LOCALTIME_R - struct tm tmbuf; -#endif time_t t; long nsec; +#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S) + struct tm tmbuf; +#endif +#if defined(HAVE__LOCALTIME64_S) + errno_t terr; + __time64_t tmptime; +#endif if (p + 2 > endp) return (-1); @@ -1756,8 +1760,15 @@ read_exttime(const char *p, struct rar *rar, const char *endp) rem = (((unsigned)(unsigned char)*p) << 16) | (rem >> 8); p++; } -#ifdef HAVE_LOCALTIME_R +#if defined(HAVE_LOCALTIME_R) tm = localtime_r(&t, &tmbuf); +#elif defined(HAVE__LOCALTIME64_S) + tmptime = t; + terr = _localtime64_s(&tmbuf, &tmptime); + if (terr) + tm = NULL; + else + tm = &tmbuf; #else tm = localtime(&t); #endif diff --git a/libarchive/archive_write_set_format_warc.c b/libarchive/archive_write_set_format_warc.c index edad072cf..00f15ff9d 100644 --- a/libarchive/archive_write_set_format_warc.c +++ b/libarchive/archive_write_set_format_warc.c @@ -332,6 +332,10 @@ xstrftime(struct archive_string *as, const char *fmt, time_t t) struct tm *rt; #if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S) struct tm timeHere; +#endif +#if defined(HAVE__GMTIME64_S) + errno_t terr; + __time64_t tmptime; #endif char strtime[100]; size_t len; @@ -340,7 +344,12 @@ xstrftime(struct archive_string *as, const char *fmt, time_t t) if ((rt = gmtime_r(&t, &timeHere)) == NULL) return; #elif defined(HAVE__GMTIME64_S) - _gmtime64_s(&timeHere, &t); + tmptime = t; + terr = _gmtime64_s(&timeHere, &tmptime); + if (terr) + rt = NULL; + else + rt = &timeHere; #else if ((rt = gmtime(&t)) == NULL) return; diff --git a/libarchive/archive_write_set_format_xar.c b/libarchive/archive_write_set_format_xar.c index 5e4b90e06..6efd99553 100644 --- a/libarchive/archive_write_set_format_xar.c +++ b/libarchive/archive_write_set_format_xar.c @@ -878,11 +878,15 @@ xmlwrite_time(struct archive_write *a, xmlTextWriterPtr writer, { char timestr[100]; struct tm tm; +#if defined(HAVE__GMTIME64_S) + __time64_t tmptime; +#endif #if defined(HAVE_GMTIME_R) gmtime_r(&t, &tm); #elif defined(HAVE__GMTIME64_S) - _gmtime64_s(&tm, &t); + tmptime = t; + _gmtime64_s(&tm, &tmptime); #else memcpy(&tm, gmtime(&t), sizeof(tm)); #endif diff --git a/libarchive/archive_write_set_format_zip.c b/libarchive/archive_write_set_format_zip.c index 1a020aadd..917350d56 100644 --- a/libarchive/archive_write_set_format_zip.c +++ b/libarchive/archive_write_set_format_zip.c @@ -1372,14 +1372,25 @@ dos_time(const time_t unix_time) { struct tm *t; unsigned int dt; -#ifdef HAVE_LOCALTIME_R +#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S) struct tm tmbuf; #endif +#if defined(HAVE__LOCALTIME64_S) + errno_t terr; + __time64_t tmptime; +#endif /* This will not preserve time when creating/extracting the archive * on two systems with different time zones. */ -#ifdef HAVE_LOCALTIME_R +#if defined(HAVE_LOCALTIME_R) t = localtime_r(&unix_time, &tmbuf); +#elif defined(HAVE__LOCALTIME64_S) + tmptime = unix_time; + terr = _localtime64_s(&tmbuf, &tmptime); + if (terr) + t = NULL; + else + t = &tmbuf; #else t = localtime(&unix_time); #endif diff --git a/tar/util.c b/tar/util.c index 85c5446a9..8ebec64c4 100644 --- a/tar/util.c +++ b/tar/util.c @@ -667,9 +667,13 @@ list_item_verbose(struct bsdtar *bsdtar, FILE *out, struct archive_entry *entry) time_t tim; static time_t now; struct tm *ltime; -#ifdef HAVE_LOCALTIME_R +#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S) struct tm tmbuf; #endif +#if defined(HAVE__LOCALTIME64_S) + errno_t terr; + __time64_t tmptime; +#endif /* * We avoid collecting the entire list in memory at once by @@ -741,8 +745,15 @@ list_item_verbose(struct bsdtar *bsdtar, FILE *out, struct archive_entry *entry) fmt = bsdtar->day_first ? DAY_FMT " %b %Y" : "%b " DAY_FMT " %Y"; else fmt = bsdtar->day_first ? DAY_FMT " %b %H:%M" : "%b " DAY_FMT " %H:%M"; -#ifdef HAVE_LOCALTIME_R +#if defined(HAVE_LOCALTIME_R) ltime = localtime_r(&tim, &tmbuf); +#elif defined(HAVE__LOCALTIME64_S) + tmptime = tim; + terr = _localtime64_s(&tmbuf, &tmptime); + if (terr) + ltime = NULL; + else + ltime = &tmbuf; #else ltime = localtime(&tim); #endif -- 2.47.2