summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stefw@gnome.org>2013-03-03 09:57:24 +0100
committerStef Walter <stefw@gnome.org>2013-03-03 10:07:14 +0100
commitd9076a99c59bb0132b25277a2340f428c9b6c98e (patch)
tree8b0339f9e46b3f9b3eb2df8e5691030cde1eb6d5
parent2737be8914270275d07ccf4526a4ba8b781c195e (diff)
Add compat gmtime_r() and timegm() functions
Not available on Win32 or ancient unixes
-rw-r--r--common/compat.c55
-rw-r--r--common/compat.h15
-rw-r--r--configure.ac6
3 files changed, 76 insertions, 0 deletions
diff --git a/common/compat.c b/common/compat.c
index 76847e0..0eb35f8 100644
--- a/common/compat.c
+++ b/common/compat.c
@@ -552,6 +552,61 @@ vasprintf (char **strp,
#endif /* HAVE_VASPRINTF */
+#ifndef HAVE_GMTIME_R
+
+struct tm *
+gmtime_r (const time_t *timep,
+ struct tm *result)
+{
+#ifdef OS_WIN32
+ /*
+ * On win32 gmtime() returns thread local storage, so we can
+ * just copy it out into the buffer without worrying about races.
+ */
+ struct tm *tg;
+ tg = gmtime (timep);
+ if (!tg)
+ return NULL;
+ memcpy (result, tg, sizeof (struct tm));
+ return result;
+#else
+ #error Need either gmtime_r() function on Unix
+#endif
+}
+
+#endif /* HAVE_GMTIME_R */
+
+#ifndef HAVE_TIMEGM
+
+time_t
+timegm (struct tm *tm)
+{
+ time_t tl, tb;
+ struct tm tg;
+
+ tl = mktime (tm);
+ if (tl == -1) {
+ tm->tm_hour--;
+ tl = mktime (tm);
+ if (tl == -1)
+ return -1;
+ tl += 3600;
+ }
+ gmtime_r (&tl, &tg);
+ tg.tm_isdst = 0;
+ tb = mktime (&tg);
+ if (tb == -1) {
+ tg.tm_hour--;
+ tb = mktime (&tg);
+ if (tb == -1)
+ return -1;
+ tb += 3600;
+ }
+ return (tl - (tb - tl));
+}
+
+#endif /* HAVE_TIMEGM */
+
#if !defined(HAVE_MKDTEMP) || !defined(HAVE_MKSTEMP)
#include <sys/stat.h>
#include <fcntl.h>
diff --git a/common/compat.h b/common/compat.h
index 0299cd3..7eb42a5 100644
--- a/common/compat.h
+++ b/common/compat.h
@@ -272,4 +272,19 @@ int vasprintf (char **strp,
#endif /* HAVE_VASPRINTF */
+#ifndef HAVE_GMTIME_R
+#include <time.h>
+
+struct tm * gmtime_r (const time_t *timep,
+ struct tm *result);
+
+#endif /* HAVE_GMTIME_R */
+
+#ifndef HAVE_TIMEGM
+#include <time.h>
+
+time_t timegm (struct tm *tm);
+
+#endif /* HAVE_TIMEGM */
+
#endif /* __COMPAT_H__ */
diff --git a/configure.ac b/configure.ac
index ac049c9..1c618e9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -78,6 +78,12 @@ if test "$os_unix" = "yes"; then
AC_CHECK_FUNCS([getprogname getexecname basename mkstemp mkdtemp])
AC_CHECK_FUNCS([strnstr memdup strndup])
AC_CHECK_FUNCS([asprintf vasprintf vsnprintf])
+ AC_CHECK_FUNCS([timegm])
+
+ # Required functions
+ AC_CHECK_FUNCS([gmtime_r],
+ [AC_DEFINE([HAVE_GMTIME_R], 1, [Whether gmtime_r() is available])],
+ [AC_MSG_ERROR([could not find required gmtime_r() function])])
# Check if these are declared and/or available to link against
AC_CHECK_DECLS([program_invocation_short_name])