aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrent Cook <bcook@openbsd.org>2015-10-14 23:53:52 -0500
committerBrent Cook <bcook@openbsd.org>2015-10-15 09:16:38 -0500
commit4298ac9305d89cadf90ebb01f0e85bb74fea2c1e (patch)
treee58171fce41da919e0005b167fab19185c4d002d
parent1dd79f5d8f617afdb0f5d51ac0278d7b4f84b82f (diff)
downloadportable-4298ac9305d89cadf90ebb01f0e85bb74fea2c1e.tar.gz
portable-4298ac9305d89cadf90ebb01f0e85bb74fea2c1e.tar.bz2
portable-4298ac9305d89cadf90ebb01f0e85bb74fea2c1e.zip
include timegm fallback
-rw-r--r--.gitignore1
-rw-r--r--crypto/Makefile.am6
-rw-r--r--crypto/compat/timegm.c71
-rw-r--r--include/compat/limits.h5
-rw-r--r--include/compat/time.h6
-rw-r--r--m4/check-libc.m43
6 files changed, 86 insertions, 6 deletions
diff --git a/.gitignore b/.gitignore
index 499205f..03ed14a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -129,6 +129,7 @@ include/openssl/*.h
129!/crypto/compat/posix_win.c 129!/crypto/compat/posix_win.c
130!/crypto/compat/bsd_asprintf.c 130!/crypto/compat/bsd_asprintf.c
131!/crypto/compat/inet_pton.c 131!/crypto/compat/inet_pton.c
132!/crypto/compat/timegm.c
132!/crypto/compat/ui_openssl_win.c 133!/crypto/compat/ui_openssl_win.c
133!/crypto/CMakeLists.txt 134!/crypto/CMakeLists.txt
134/crypto 135/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
73libcompat_la_SOURCES += compat/inet_pton.c 73libcompat_la_SOURCES += compat/inet_pton.c
74endif 74endif
75 75
76if !HAVE_TIMEGM
77if !HAVE__MKGMTIME
78libcompat_la_SOURCES += compat/timegm.c
79endif
80endif
81
76if !HAVE_REALLOCARRAY 82if !HAVE_REALLOCARRAY
77libcompat_la_SOURCES += compat/reallocarray.c 83libcompat_la_SOURCES += compat/reallocarray.c
78endif 84endif
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 @@
1/*
2 * timegm shims based on example code from in the glibc timegm manpage.
3 *
4 * These should be replaced with lockless versions that do not require
5 * modifying global state.
6 */
7
8#include <time.h>
9#include <stdlib.h>
10#include <stdio.h>
11#include <string.h>
12
13#ifdef _WIN32
14#include <windows.h>
15time_t
16timegm(struct tm *tm)
17{
18 time_t ret;
19 char *tz, *buf;
20 static volatile HANDLE mtx = NULL;
21
22 if (!mtx) {
23 HANDLE p = CreateMutex(NULL, FALSE, NULL);
24 if (InterlockedCompareExchangePointer(
25 (void **)&mtx, (void *)p, NULL))
26 CloseHandle(p);
27 }
28 WaitForSingleObject(mtx, INFINITE);
29 tz = getenv("TZ");
30 if (tz) {
31 if (asprintf(&buf, "TZ=%s", tz) == -1)
32 buf = NULL;
33 }
34 putenv("TZ=UTC");
35 tzset();
36 ret = mktime(tm);
37 if (buf) {
38 putenv(buf);
39 free(buf);
40 } else
41 putenv("TZ=");
42 tzset();
43 ReleaseMutex(mtx);
44 return ret;
45}
46#else
47#include <pthread.h>
48time_t
49timegm(struct tm *tm)
50{
51 time_t ret;
52 char *tz;
53 static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
54
55 pthread_mutex_lock(&mtx);
56 tz = getenv("TZ");
57 if (tz)
58 tz = strdup(tz);
59 setenv("TZ", "", 1);
60 tzset();
61 ret = mktime(tm);
62 if (tz) {
63 setenv("TZ", tz, 1);
64 free(tz);
65 } else
66 unsetenv("TZ");
67 tzset();
68 pthread_mutex_unlock(&mtx);
69 return ret;
70}
71#endif
diff --git a/include/compat/limits.h b/include/compat/limits.h
index ca96125..18cabf1 100644
--- a/include/compat/limits.h
+++ b/include/compat/limits.h
@@ -3,9 +3,6 @@
3 * limits.h compatibility shim 3 * limits.h compatibility shim
4 */ 4 */
5 5
6#ifndef LIBCRYPTOCOMPAT_LIMITS_H
7#define LIBCRYPTOCOMPAT_LIMITS_H
8
9#ifdef _MSC_VER 6#ifdef _MSC_VER
10#if _MSC_VER >= 1900 7#if _MSC_VER >= 1900
11#include <../ucrt/limits.h> 8#include <../ucrt/limits.h>
@@ -22,5 +19,3 @@
22#define PATH_MAX MAXPATHLEN 19#define PATH_MAX MAXPATHLEN
23#endif 20#endif
24#endif 21#endif
25
26#endif
diff --git a/include/compat/time.h b/include/compat/time.h
index 3ef3bad..3a87548 100644
--- a/include/compat/time.h
+++ b/include/compat/time.h
@@ -14,6 +14,10 @@
14#include_next <time.h> 14#include_next <time.h>
15#endif 15#endif
16 16
17#ifdef _WIN32 17#ifndef HAVE_TIMEGM
18#ifdef HAVE__MKGMTIME
18#define timegm(tm) _mkgmtime(tm) 19#define timegm(tm) _mkgmtime(tm)
20#else
21time_t timegm(struct tm *tm);
22#endif
19#endif 23#endif
diff --git a/m4/check-libc.m4 b/m4/check-libc.m4
index c0df011..3efc686 100644
--- a/m4/check-libc.m4
+++ b/m4/check-libc.m4
@@ -4,6 +4,7 @@ AC_CHECK_HEADERS([err.h readpassphrase.h])
4# Check for general libc functions 4# Check for general libc functions
5AC_CHECK_FUNCS([asprintf inet_pton memmem readpassphrase reallocarray]) 5AC_CHECK_FUNCS([asprintf inet_pton memmem readpassphrase reallocarray])
6AC_CHECK_FUNCS([strlcat strlcpy strndup strnlen strsep strtonum]) 6AC_CHECK_FUNCS([strlcat strlcpy strndup strnlen strsep strtonum])
7AC_CHECK_FUNCS([timegm _mkgmtime])
7AM_CONDITIONAL([HAVE_ASPRINTF], [test "x$ac_cv_func_asprintf" = xyes]) 8AM_CONDITIONAL([HAVE_ASPRINTF], [test "x$ac_cv_func_asprintf" = xyes])
8AM_CONDITIONAL([HAVE_INET_PTON], [test "x$ac_cv_func_inet_pton" = xyes]) 9AM_CONDITIONAL([HAVE_INET_PTON], [test "x$ac_cv_func_inet_pton" = xyes])
9AM_CONDITIONAL([HAVE_MEMMEM], [test "x$ac_cv_func_memmem" = xyes]) 10AM_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])
15AM_CONDITIONAL([HAVE_STRNLEN], [test "x$ac_cv_func_strnlen" = xyes]) 16AM_CONDITIONAL([HAVE_STRNLEN], [test "x$ac_cv_func_strnlen" = xyes])
16AM_CONDITIONAL([HAVE_STRSEP], [test "x$ac_cv_func_strsep" = xyes]) 17AM_CONDITIONAL([HAVE_STRSEP], [test "x$ac_cv_func_strsep" = xyes])
17AM_CONDITIONAL([HAVE_STRTONUM], [test "x$ac_cv_func_strtonum" = xyes]) 18AM_CONDITIONAL([HAVE_STRTONUM], [test "x$ac_cv_func_strtonum" = xyes])
19AM_CONDITIONAL([HAVE_TIMEGM], [test "x$ac_cv_func_timegm" = xyes])
20AM_CONDITIONAL([HAVE__MKGMTIME], [test "x$ac_cv_func__mkgmtime" = xyes])
18]) 21])
19 22
20AC_DEFUN([CHECK_SYSCALL_COMPAT], [ 23AC_DEFUN([CHECK_SYSCALL_COMPAT], [