From 4298ac9305d89cadf90ebb01f0e85bb74fea2c1e Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Wed, 14 Oct 2015 23:53:52 -0500 Subject: include timegm fallback --- crypto/Makefile.am | 6 +++++ crypto/compat/timegm.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 crypto/compat/timegm.c (limited to 'crypto') diff --git a/crypto/Makefile.am b/crypto/Makefile.am index e1e785d..40d82cd 100644 --- a/crypto/Makefile.am +++ b/crypto/Makefile.am @@ -73,6 +73,12 @@ if !HAVE_INET_PTON libcompat_la_SOURCES += compat/inet_pton.c endif +if !HAVE_TIMEGM +if !HAVE__MKGMTIME +libcompat_la_SOURCES += compat/timegm.c +endif +endif + if !HAVE_REALLOCARRAY libcompat_la_SOURCES += compat/reallocarray.c endif diff --git a/crypto/compat/timegm.c b/crypto/compat/timegm.c new file mode 100644 index 0000000..2007140 --- /dev/null +++ b/crypto/compat/timegm.c @@ -0,0 +1,71 @@ +/* + * timegm shims based on example code from in the glibc timegm manpage. + * + * These should be replaced with lockless versions that do not require + * modifying global state. + */ + +#include +#include +#include +#include + +#ifdef _WIN32 +#include +time_t +timegm(struct tm *tm) +{ + time_t ret; + char *tz, *buf; + static volatile HANDLE mtx = NULL; + + if (!mtx) { + HANDLE p = CreateMutex(NULL, FALSE, NULL); + if (InterlockedCompareExchangePointer( + (void **)&mtx, (void *)p, NULL)) + CloseHandle(p); + } + WaitForSingleObject(mtx, INFINITE); + tz = getenv("TZ"); + if (tz) { + if (asprintf(&buf, "TZ=%s", tz) == -1) + buf = NULL; + } + putenv("TZ=UTC"); + tzset(); + ret = mktime(tm); + if (buf) { + putenv(buf); + free(buf); + } else + putenv("TZ="); + tzset(); + ReleaseMutex(mtx); + return ret; +} +#else +#include +time_t +timegm(struct tm *tm) +{ + time_t ret; + char *tz; + static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; + + pthread_mutex_lock(&mtx); + tz = getenv("TZ"); + if (tz) + tz = strdup(tz); + setenv("TZ", "", 1); + tzset(); + ret = mktime(tm); + if (tz) { + setenv("TZ", tz, 1); + free(tz); + } else + unsetenv("TZ"); + tzset(); + pthread_mutex_unlock(&mtx); + return ret; +} +#endif -- cgit v1.2.3-55-g6feb