mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-03 22:08:25 -04:00
Add C11 localtime_r and gmtime_r shims for Windows
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 08f4c7d6c0)
This commit is contained in:
parent
bdb8e3ad85
commit
5ae4d3d94a
7 changed files with 50 additions and 28 deletions
|
|
@ -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
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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(¤ttime); /* Thread specific. */
|
||||
#else
|
||||
struct tm t, *tm = localtime_r(¤ttime, &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));
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -20,6 +21,30 @@
|
|||
#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
|
||||
***/
|
||||
|
|
|
|||
Loading…
Reference in a new issue