]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add C11 localtime_r and gmtime_r shims for Windows
authorOndřej Surý <ondrej@isc.org>
Fri, 13 Mar 2020 07:38:37 +0000 (08:38 +0100)
committerEvan Hunt <each@isc.org>
Tue, 17 Mar 2020 22:45:35 +0000 (15:45 -0700)
On Windows, C11 localtime_r() and gmtime_r() functions are not
available.  While localtime() and gmtime() functions are already thread
safe because they use Thread Local Storage, it's quite ugly to #ifdef
around every localtime_r() and gmtime_r() usage to make the usage also
thread-safe on POSIX platforms.

The commit adds wrappers around Windows localtime_s() and gmtime_s()
functions.

NOTE: The implementation of localtime_s and gmtime_s in Microsoft CRT
are incompatible with the C standard since it has reversed parameter
order and errno_t return type.

(cherry picked from commit 08f4c7d6c094c93ce7df093a8aa0890618959c83)

bin/dig/dig.c
bin/dnssec/dnssec-settime.c
bin/dnssec/dnssec-signzone.c
lib/dns/gen-win32.h
lib/dns/gen.c
lib/dns/update.c
lib/isc/win32/include/isc/time.h

index 706299e75a8f61ceec3e98c069c2f960018b6fc1..996cbb9495ccbfd7c7905a0463b765d4c5521b35 100644 (file)
@@ -277,11 +277,7 @@ received(unsigned int bytes, isc_sockaddr_t *from, dig_query_t *query) {
                        printf(";; Query time: %ld msec\n", (long) diff / 1000);
                printf(";; SERVER: %s(%s)\n", fromtext, query->servname);
                time(&tnow);
-#if defined(ISC_PLATFORM_USETHREADS) && !defined(WIN32)
                (void)localtime_r(&tnow, &tmnow);
-#else
-               tmnow  = *localtime(&tnow);
-#endif
 
 #ifdef WIN32
                /*
index 62ef8422c74b7c24f3cf112e10e0b25432883068..e128ee7b4bf92b05b548025c8f9c97fcd1885409 100644 (file)
@@ -121,15 +121,16 @@ printtime(dst_key_t *key, int type, const char *tag, bool epoch,
        } else if (epoch) {
                fprintf(stream, "%d\n", (int) when);
        } else {
-               time_t now = (time_t)when;
-#ifdef _MSC_VER
-               struct tm *tm = localtime(&now); /* Thread specific. */
-#else
+               time_t now = when;
                struct tm t, *tm = localtime_r(&now, &t);
-#endif
                unsigned int flen;
                char timebuf[80];
 
+               if (tm == NULL) {
+                       fprintf(stream, "INVALID\n");
+                       return;
+               }
+
                flen = strftime(timebuf, sizeof(timebuf),
                                "%a %b %e %H:%M:%S %Y", tm);
                INSIST(flen > 0U && flen < sizeof(timebuf));
index 8d93be83fa30191ed77cea2c1ba1a3b2f591d403..cd235b2e8f9a9e072b35247f9b4d838a7c722f44 100644 (file)
@@ -2955,16 +2955,13 @@ writeset(const char *prefix, dns_rdatatype_t type) {
 static void
 print_time(FILE *fp) {
        time_t currenttime = time(NULL);
-#ifdef _MSC_VER
-       struct tm *tm = localtime(&currenttime); /* Thread specific. */
-#else
        struct tm t, *tm = localtime_r(&currenttime, &t);
-#endif
        unsigned int flen;
        char timebuf[80];
 
-       if (outputformat != dns_masterformat_text)
+       if (tm == NULL || outputformat != dns_masterformat_text) {
                return;
+       }
 
        flen = strftime(timebuf, sizeof(timebuf), "%a %b %e %H:%M:%S %Y", tm);
        INSIST(flen > 0U && flen < sizeof(timebuf));
index 47910326506a406d943af223601d8ade83b6939c..18a98950c3210a5ee493c1f071e85f7af38b0234 100644 (file)
@@ -62,6 +62,7 @@
 #include <stdbool.h>
 #include <stdio.h>
 #include <string.h>
+#include <time.h>
 #include <windows.h>
 
 #include <isc/lang.h>
@@ -268,6 +269,16 @@ end_directory(isc_dir_t *dir) {
                FindClose(dir->handle);
 }
 
+inline struct tm *
+gmtime_r(const time_t *clock, struct tm *result) {
+       errno_t ret = gmtime_s(result, clock);
+       if (ret != 0) {
+               errno = ret;
+               return (NULL);
+       }
+       return (result);
+}
+
 ISC_LANG_ENDDECLS
 
 #endif /* DNS_GEN_WIN32_H */
index 589cd205265c92c9291567dc93ac36afaa7c64ce..fe6fef0de2fa2135ac725382ec3a289d1f80c89e 100644 (file)
@@ -689,11 +689,7 @@ main(int argc, char **argv) {
        }
 
        if (now != -1) {
-#ifdef _MSC_VER
-               struct tm *tm = gmtime(&now); /* Thread specific. */
-#else
                struct tm t, *tm = gmtime_r(&now, &t);
-#endif
 
                if (tm != NULL && tm->tm_year > 104) {
                        n = snprintf(year, sizeof(year), "-%d",
index f73564299182d1f1d01666a70a7234db10a24574..085cc5509cedf3f09a4d40946c97dad910b3a957 100644 (file)
@@ -2082,16 +2082,12 @@ dns_update_signaturesinc(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db,
 
 static isc_stdtime_t
 epoch_to_yyyymmdd(time_t when) {
-       struct tm *tm;
-
-#if defined(ISC_PLATFORM_USETHREADS) && !defined(WIN32)
-       struct tm tm0;
-       tm = localtime_r(&when, &tm0);
-#else
-       tm = localtime(&when);
-#endif
-       return (((tm->tm_year + 1900) * 10000) +
-               ((tm->tm_mon + 1) * 100) + tm->tm_mday);
+       struct tm t, *tm = localtime_r(&when, &t);
+       if (tm == NULL) {
+               return (0);
+       }
+       return (((tm->tm_year + 1900) * 10000) + ((tm->tm_mon + 1) * 100) +
+               tm->tm_mday);
 }
 
 uint32_t
index 486f527c6050c6c81bd000ad50a18248d278ee64..8494736fea1a0192a724ece44a29d25d3489c96c 100644 (file)
@@ -13,6 +13,7 @@
 #ifndef ISC_TIME_H
 #define ISC_TIME_H 1
 
+#include <errno.h>
 #include <inttypes.h>
 #include <stdbool.h>
 #include <windows.h>
 #include <isc/lang.h>
 #include <isc/types.h>
 
+/***
+ *** POSIX Shims
+ ***/
+
+inline struct tm *
+gmtime_r(const time_t *clock, struct tm *result) {
+       errno_t ret = gmtime_s(result, clock);
+       if (ret != 0) {
+               errno = ret;
+               return (NULL);
+       }
+       return (result);
+}
+
+inline struct tm *
+localtime_r(const time_t *clock, struct tm *result) {
+       errno_t ret = localtime_s(result, clock);
+       if (ret != 0) {
+               errno = ret;
+               return (NULL);
+       }
+       return (result);
+}
+
 /***
  *** Intervals
  ***/