include timegm fallback

This commit is contained in:
Brent Cook
2015-10-14 23:53:52 -05:00
parent 1dd79f5d8f
commit 4298ac9305
6 changed files with 86 additions and 6 deletions

View File

@@ -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

71
crypto/compat/timegm.c Normal file
View File

@@ -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 <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef _WIN32
#include <windows.h>
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 <pthread.h>
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