Module: check_mk
Branch: master
Commit: f2e47d7b9369aec61969a77d45c16fb0bc644ea7
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=f2e47d7b9369ae…
Author: Sven Panne <sp(a)mathias-kettner.de>
Date: Fri Sep 8 15:23:34 2017 +0200
Some localtime_s/localtime_r Kung Fu, level: Black belt :-P
Change-Id: Ib9735c0b466baa384e8f06285748d3cff4a2560e
---
configure.ac | 8 ++++++++
livestatus/src/ChronoUtils.h | 25 ++++++++++++++++++++++++-
2 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index d00f144..44ef454 100644
--- a/configure.ac
+++ b/configure.ac
@@ -164,6 +164,14 @@ AC_DEFINE([_GLIBCXX_REGEX_STATE_LIMIT], [2500],
AC_DEFINE([BOOST_SYSTEM_NO_DEPRECATED], [1], [we do not want any old stuff])
+# GCC is a bit picky about redefinitions of built-in macros. Alas, "built-in"
+# simply means "starts with double underscore", so we have to hack around that
+# below. Note that clang is happy, even without the guard.
+AH_VERBATIM([__STDC_WANT_LIB_EXT1__], [/* we want C11 library extensions */
+#ifndef __STDC_WANT_LIB_EXT1__
+# define __STDC_WANT_LIB_EXT1__ 1
+#endif])
+
# HACKING ALERT: automake can't really handle optional subdirectories, so we
# have to do this in a slightly hacky way by using M4's silent includes.
m4_sinclude([livestatus/config_files.m4])
diff --git a/livestatus/src/ChronoUtils.h b/livestatus/src/ChronoUtils.h
index 5399b37..a55d22d 100644
--- a/livestatus/src/ChronoUtils.h
+++ b/livestatus/src/ChronoUtils.h
@@ -26,7 +26,7 @@
#define ChronoUtils_h
#include "config.h" // IWYU pragma: keep
-#include <sys/time.h>
+#include <time.h>
#include <chrono>
#include <cstdlib>
#include <ctime>
@@ -46,7 +46,30 @@ inline double elapsed_ms_since(std::chrono::steady_clock::time_point
then) {
inline tm to_tm(std::chrono::system_clock::time_point tp) {
time_t t = std::chrono::system_clock::to_time_t(tp);
struct tm ret;
+ // NOTE: A brilliant example of how to make a simple API function a total
+ // chaos follows...
+#if defined(__STDC_LIB_EXT1__)
+ // C11 function, only guaranteed to be available when a
+ // #define __STDC_WANT_LIB_EXT1_ 1
+ // is done before including <time.h>. Signature:
+ // struct tm *localtime_s(const time_t *restrict timer,
+ // struct tm *restrict result)
+ localtime_s(&t, &ret);
+#elif defined(__WIN32)
+ // Win32 variant, it keeps us entertained with swapped parameters and a
+ // different return value, yay! Signature:
+ // errno_t localtime_s(struct tm* _tm, const time_t *time)
+ // We have to de-confuse cppcheck:
+ // cppcheck-suppress uninitvar
+ localtime_s(&ret, &t);
+#else
+ // POSIX.1-2008 variant, available under MinGW64 only under obscure
+ // circumstances, so better avoid it there. Signature:
+ // struct tm *localtime(const time_t *timer)
localtime_r(&t, &ret);
+#endif
+ // Reason: see Win32 section above
+ // cppcheck-suppress uninitvar
return ret;
}