From 48ce800aa5a2ccee204ad3960a20c4ca14acb3a1 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Wed, 1 Mar 2017 10:33:20 +0100 Subject: [PATCH] VMS: compensate for gmtime_r() parameter pointer size With VMS C, the second parameter takes a 32-bit pointer. When building with 64-bit pointer size default, we must compensate. Reviewed-by: Andy Polyakov (Merged from https://github.com/openssl/openssl/pull/2811) --- crypto/o_time.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/crypto/o_time.c b/crypto/o_time.c index aa74340c7a..3690232505 100755 --- a/crypto/o_time.c +++ b/crypto/o_time.c @@ -15,7 +15,29 @@ struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result) { struct tm *ts = NULL; -#if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_MACOSX) +#if defined(OPENSSL_THREADS) && defined(OPENSSL_SYS_VMS) + { + /* + * On VMS, gmtime_r() takes a 32-bit pointer as second argument. + * Since we can't know that |result| is in a space that can easily + * translate to a 32-bit pointer, we must store temporarly on stack + * and copy the result. The stack is always reachable with 32-bit + * pointers. + */ +#if defined(OPENSSL_SYS_VMS) && __INITIAL_POINTER_SIZE +# pragma pointer_size save +# pragma pointer_size 32 +#endif + struct tm data, *ts2 = &data; +#if defined OPENSSL_SYS_VMS && __INITIAL_POINTER_SIZE +# pragma pointer_size restore +#endif + if (gmtime_r(timer, ts2) == NULL) + return NULL; + memcpy(result, ts2, sizeof(struct tm)); + ts = result; + } +#elif defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_MACOSX) if (gmtime_r(timer, result) == NULL) return NULL; ts = result;