implemented a monotonic timestamping function, unaffected from system time changes
authorMartin Willi <martin@strongswan.org>
Mon, 31 Aug 2009 13:03:35 +0000 (15:03 +0200)
committerMartin Willi <martin@strongswan.org>
Mon, 31 Aug 2009 13:03:35 +0000 (15:03 +0200)
configure.in
src/libstrongswan/Makefile.am
src/libstrongswan/utils.c
src/libstrongswan/utils.h

index cc37816..7caa8c1 100644 (file)
@@ -908,6 +908,12 @@ AC_SEARCH_LIBS(socket, socket, [SOCKLIB=$LIBS],
 )
 AC_SUBST(SOCKLIB)
 
+dnl FreeBSD has clock_gettime in libc, Linux needs librt
+LIBS=""
+AC_SEARCH_LIBS(clock_gettime, rt, [RTLIB=$LIBS])
+AC_CHECK_FUNCS(clock_gettime)
+AC_SUBST(RTLIB)
+
 LIBS=$saved_LIBS
 dnl ======================
 
index 922a376..570c14e 100644 (file)
@@ -49,7 +49,7 @@ utils/mutex.c utils/mutex.h \
 utils/backtrace.c utils/backtrace.h \
 plugins/plugin_loader.c plugins/plugin_loader.h plugins/plugin.h
 
-libstrongswan_la_LIBADD = -lpthread $(DLLIB) $(BTLIB) $(SOCKLIB)
+libstrongswan_la_LIBADD = -lpthread $(DLLIB) $(BTLIB) $(SOCKLIB) $(RTLIB)
 
 INCLUDES = -I$(top_srcdir)/src/libstrongswan
 AM_CFLAGS = \
index 3058411..91242da 100644 (file)
@@ -163,6 +163,39 @@ bool mkdir_p(const char *path, mode_t mode)
 }
 
 /**
+ * Return monotonic time
+ */
+time_t time_monotonic(timeval_t *tv)
+{
+#if defined(HAVE_CLOCK_GETTIME)
+       timespec_t ts;
+       
+       if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
+       {
+               if (tv)
+               {
+                       tv->tv_sec = ts.tv_sec;
+                       tv->tv_usec = ts.tv_nsec / 1000;
+               }
+               return ts.tv_sec;
+       }
+#endif /* HAVE_CLOCK_MONOTONIC */
+       /* Fallback to non-monotonic timestamps:
+        * On MAC OS X, creating monotonic timestamps is rather difficult. We
+        * could use mach_absolute_time() and catch sleep/wakeup notifications.
+        * We stick to the simpler (non-monotonic) gettimeofday() for now. */
+       if (!tv)
+       {
+               return time(NULL);
+       }
+       if (gettimeofday(tv, NULL) != 0)
+       {       /* should actually never fail if passed pointers are valid */
+               return -1;
+       }
+       return tv->tv_sec;
+}
+
+/**
  * return null
  */
 void *return_null()
index 5d273d2..6b0990f 100644 (file)
@@ -25,6 +25,7 @@
 #include <sys/types.h>
 #include <stdlib.h>
 #include <stddef.h>
+#include <sys/time.h>
 
 #include <enum.h>
 
@@ -269,13 +270,25 @@ void *memstr(const void *haystack, const char *needle, size_t n);
 /**
  * Creates a directory and all required parent directories. 
  *
- * @param      path    path to the new directory
- * @param      mode    permissions of the new directory/directories 
+ * @param path         path to the new directory
+ * @param mode         permissions of the new directory/directories 
  * @return                     TRUE on success
  */
 bool mkdir_p(const char *path, mode_t mode);
 
 /**
+ * Get a timestamp from a monotonic time source.
+ *
+ * While the time()/gettimeofday() functions are affected by leap seconds
+ * and system time changes, this function returns ever increasing monotonic
+ * time stamps.
+ *
+ * @param tv           timeval struct receiving monotonic timestamps, or NULL
+ * @return                     monotonic timestamp in seconds
+ */
+time_t time_monotonic(timeval_t *tv);
+
+/**
  * returns null
  */
 void *return_null();