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

1
.gitignore vendored
View File

@ -129,6 +129,7 @@ include/openssl/*.h
!/crypto/compat/posix_win.c !/crypto/compat/posix_win.c
!/crypto/compat/bsd_asprintf.c !/crypto/compat/bsd_asprintf.c
!/crypto/compat/inet_pton.c !/crypto/compat/inet_pton.c
!/crypto/compat/timegm.c
!/crypto/compat/ui_openssl_win.c !/crypto/compat/ui_openssl_win.c
!/crypto/CMakeLists.txt !/crypto/CMakeLists.txt
/crypto /crypto

View File

@ -73,6 +73,12 @@ if !HAVE_INET_PTON
libcompat_la_SOURCES += compat/inet_pton.c libcompat_la_SOURCES += compat/inet_pton.c
endif endif
if !HAVE_TIMEGM
if !HAVE__MKGMTIME
libcompat_la_SOURCES += compat/timegm.c
endif
endif
if !HAVE_REALLOCARRAY if !HAVE_REALLOCARRAY
libcompat_la_SOURCES += compat/reallocarray.c libcompat_la_SOURCES += compat/reallocarray.c
endif 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

View File

@ -3,9 +3,6 @@
* limits.h compatibility shim * limits.h compatibility shim
*/ */
#ifndef LIBCRYPTOCOMPAT_LIMITS_H
#define LIBCRYPTOCOMPAT_LIMITS_H
#ifdef _MSC_VER #ifdef _MSC_VER
#if _MSC_VER >= 1900 #if _MSC_VER >= 1900
#include <../ucrt/limits.h> #include <../ucrt/limits.h>
@ -22,5 +19,3 @@
#define PATH_MAX MAXPATHLEN #define PATH_MAX MAXPATHLEN
#endif #endif
#endif #endif
#endif

View File

@ -14,6 +14,10 @@
#include_next <time.h> #include_next <time.h>
#endif #endif
#ifdef _WIN32 #ifndef HAVE_TIMEGM
#ifdef HAVE__MKGMTIME
#define timegm(tm) _mkgmtime(tm) #define timegm(tm) _mkgmtime(tm)
#else
time_t timegm(struct tm *tm);
#endif
#endif #endif

View File

@ -4,6 +4,7 @@ AC_CHECK_HEADERS([err.h readpassphrase.h])
# Check for general libc functions # Check for general libc functions
AC_CHECK_FUNCS([asprintf inet_pton memmem readpassphrase reallocarray]) AC_CHECK_FUNCS([asprintf inet_pton memmem readpassphrase reallocarray])
AC_CHECK_FUNCS([strlcat strlcpy strndup strnlen strsep strtonum]) AC_CHECK_FUNCS([strlcat strlcpy strndup strnlen strsep strtonum])
AC_CHECK_FUNCS([timegm _mkgmtime])
AM_CONDITIONAL([HAVE_ASPRINTF], [test "x$ac_cv_func_asprintf" = xyes]) AM_CONDITIONAL([HAVE_ASPRINTF], [test "x$ac_cv_func_asprintf" = xyes])
AM_CONDITIONAL([HAVE_INET_PTON], [test "x$ac_cv_func_inet_pton" = xyes]) AM_CONDITIONAL([HAVE_INET_PTON], [test "x$ac_cv_func_inet_pton" = xyes])
AM_CONDITIONAL([HAVE_MEMMEM], [test "x$ac_cv_func_memmem" = xyes]) AM_CONDITIONAL([HAVE_MEMMEM], [test "x$ac_cv_func_memmem" = xyes])
@ -15,6 +16,8 @@ AM_CONDITIONAL([HAVE_STRNDUP], [test "x$ac_cv_func_strndup" = xyes])
AM_CONDITIONAL([HAVE_STRNLEN], [test "x$ac_cv_func_strnlen" = xyes]) AM_CONDITIONAL([HAVE_STRNLEN], [test "x$ac_cv_func_strnlen" = xyes])
AM_CONDITIONAL([HAVE_STRSEP], [test "x$ac_cv_func_strsep" = xyes]) AM_CONDITIONAL([HAVE_STRSEP], [test "x$ac_cv_func_strsep" = xyes])
AM_CONDITIONAL([HAVE_STRTONUM], [test "x$ac_cv_func_strtonum" = xyes]) AM_CONDITIONAL([HAVE_STRTONUM], [test "x$ac_cv_func_strtonum" = xyes])
AM_CONDITIONAL([HAVE_TIMEGM], [test "x$ac_cv_func_timegm" = xyes])
AM_CONDITIONAL([HAVE__MKGMTIME], [test "x$ac_cv_func__mkgmtime" = xyes])
]) ])
AC_DEFUN([CHECK_SYSCALL_COMPAT], [ AC_DEFUN([CHECK_SYSCALL_COMPAT], [