summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 938d638)
raw | patch | inline | side by side (parent: 938d638)
author | Florian Forster <octo@collectd.org> | |
Sun, 7 May 2017 18:34:09 +0000 (20:34 +0200) | ||
committer | Florian Forster <octo@collectd.org> | |
Mon, 8 May 2017 08:43:53 +0000 (10:43 +0200) |
FreeBSD doesn't provide the "extern long timezone", presumably because
it's "only" an XSI extension, leading to a portability issue with the
previous approach.
timegm() is a non-standard function available in GNU's and BSD's libc
which is doing exactly what we need. The previous code is left as a
fallback.
Fixes: #1268
it's "only" an XSI extension, leading to a portability issue with the
previous approach.
timegm() is a non-standard function available in GNU's and BSD's libc
which is doing exactly what we need. The previous code is left as a
fallback.
Fixes: #1268
configure.ac | patch | blob | history | |
src/bind.c | patch | blob | history |
diff --git a/configure.ac b/configure.ac
index 5a265c755faa2dcc76c7bb29345ac2586f3b30bc..98f0a9072197272bcaaf787ed4635a74f0ace02f 100644 (file)
--- a/configure.ac
+++ b/configure.ac
fi
# }}} Check for strptime
+# Check for timegm {{{
+
+# These checks need -Werror because implicit function declarations are only a
+# warning ...
+SAVE_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -Werror"
+
+AC_CACHE_CHECK([for timegm],
+ [c_cv_have_timegm],
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+[[[
+#if STRPTIME_NEEDS_STANDARDS
+# ifndef _ISOC99_SOURCE
+# define _ISOC99_SOURCE 1
+# endif
+# ifndef _POSIX_C_SOURCE
+# define _POSIX_C_SOURCE 200112L
+# endif
+# ifndef _XOPEN_SOURCE
+# define _XOPEN_SOURCE 500
+# endif
+#endif
+#include <time.h>
+]]],
+[[[
+ time_t t = timegm(&(struct tm){0});
+ if (t == ((time_t) -1)) {
+ return 1;
+ }
+]]]
+ )],
+ [c_cv_have_timegm="yes"],
+ [c_cv_have_timegm="no"]
+ )
+)
+
+if test "x$c_cv_have_timegm" != "xyes"
+then
+ AC_CACHE_CHECK([for timegm with _BSD_SOURCE],
+ [c_cv_have_timegm_bsd],
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+[[[
+#if STRPTIME_NEEDS_STANDARDS
+# ifndef _ISOC99_SOURCE
+# define _ISOC99_SOURCE 1
+# endif
+# ifndef _POSIX_C_SOURCE
+# define _POSIX_C_SOURCE 200112L
+# endif
+# ifndef _XOPEN_SOURCE
+# define _XOPEN_SOURCE 500
+# endif
+#endif
+#ifndef _BSD_SOURCE
+# define _BSD_SOURCE 1
+#endif
+#include <time.h>
+]]],
+[[[
+ time_t t = timegm(&(struct tm){0});
+ if (t == ((time_t) -1)) {
+ return 1;
+ }
+]]]
+ )],
+ [c_cv_have_timegm_bsd="yes"
+ c_cv_have_timegm="yes"],
+ [c_cv_have_timegm_bsd="no"]
+ )
+ )
+fi
+
+if test "x$c_cv_have_timegm" = "xyes"
+then
+ AC_DEFINE(HAVE_TIMEGM, 1, [Define if the timegm(3) function is available.])
+ if test "x$c_cv_have_timegm_bsd" = "xyes"
+ then
+ AC_DEFINE(TIMEGM_NEEDS_BSD, 1, [Set to true if timegm is only exported in BSD mode.])
+ fi
+fi
+
+CFLAGS="$SAVE_CFLAGS"
+# }}} Check for timegm
+
AC_CHECK_FUNCS(swapctl, [have_swapctl="yes"], [have_swapctl="no"])
if test "x$have_swapctl" = "xyes"; then
AC_CACHE_CHECK([whether swapctl takes two arguments],
diff --git a/src/bind.c b/src/bind.c
index 597b90d332a4e26aef4cde068616960460d5d768..4860f1b6045667bcfebbb264ffb9ff2100e9ddc1 100644 (file)
--- a/src/bind.c
+++ b/src/bind.c
#endif
#endif /* STRPTIME_NEEDS_STANDARDS */
+#if TIMEGM_NEEDS_BSD
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE 1
+#endif
+#endif /* TIMEGM_NEEDS_BSD */
+
#include "collectd.h"
#include "common.h"
#include "plugin.h"
+#include <time.h>
+
/* Some versions of libcurl don't include this themselves and then don't have
* fd_set available. */
#if HAVE_SYS_SELECT_H
return (-1);
}
- tzset();
- *ret_value = mktime(&tm) - timezone; /* fix strptime() misinterpretation */
+#if HAVE_TIMEGM
+ time_t t = timegm(&tm);
+ if (t == ((time_t)-1)) {
+ char errbuf[1024];
+ ERROR("bind plugin: timegm() failed: %s",
+ sstrerror(errno, errbuf, sizeof(errbuf)));
+ return (-1);
+ }
+ *ret_value = t;
+#else
+ time_t t = mktime(&tm);
+ if (t == ((time_t)-1)) {
+ char errbuf[1024];
+ ERROR("bind plugin: mktime() failed: %s",
+ sstrerror(errno, errbuf, sizeof(errbuf)));
+ return (-1);
+ }
+ /* mktime assumes that tm is local time. Luckily, it also sets timezone to
+ * the offset used for the conversion, and we undo the conversion to convert
+ * back to UTC. */
+ *ret_value = t - timezone;
+#endif
xmlXPathFreeObject(xpathObj);
return (0);