|
@@ -0,0 +1,82 @@
|
|
|
+/* Copyright (c) 2003-2004, Roger Dingledine
|
|
|
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
|
|
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
|
|
|
+/* See LICENSE for licensing information */
|
|
|
+
|
|
|
+/**
|
|
|
+ * \file compat_time.c
|
|
|
+ * \brief Portable wrappers for finding out the current time, running
|
|
|
+ * timers, etc.
|
|
|
+ **/
|
|
|
+
|
|
|
+#include "orconfig.h"
|
|
|
+#include "lib/err/torerr.h"
|
|
|
+#include "lib/wallclock/tor_gettimeofday.h"
|
|
|
+
|
|
|
+#include <stddef.h>
|
|
|
+#include <stdlib.h>
|
|
|
+
|
|
|
+#ifdef HAVE_SYS_TIME_H
|
|
|
+#include <sys/time.h>
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifdef _WIN32
|
|
|
+#include <windows.h>
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifdef HAVE_SYS_TYPES_H
|
|
|
+#include <sys/types.h>
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifndef HAVE_GETTIMEOFDAY
|
|
|
+#ifdef HAVE_FTIME
|
|
|
+#include <sys/timeb.h>
|
|
|
+#endif
|
|
|
+#endif
|
|
|
+
|
|
|
+/** Set *timeval to the current time of day. On error, log and terminate.
|
|
|
+ * (Same as gettimeofday(timeval,NULL), but never returns -1.)
|
|
|
+ */
|
|
|
+MOCK_IMPL(void,
|
|
|
+tor_gettimeofday, (struct timeval *timeval))
|
|
|
+{
|
|
|
+#ifdef _WIN32
|
|
|
+ /* Epoch bias copied from perl: number of units between windows epoch and
|
|
|
+ * Unix epoch. */
|
|
|
+#define EPOCH_BIAS U64_LITERAL(116444736000000000)
|
|
|
+#define UNITS_PER_SEC U64_LITERAL(10000000)
|
|
|
+#define USEC_PER_SEC U64_LITERAL(1000000)
|
|
|
+#define UNITS_PER_USEC U64_LITERAL(10)
|
|
|
+ union {
|
|
|
+ uint64_t ft_64;
|
|
|
+ FILETIME ft_ft;
|
|
|
+ } ft;
|
|
|
+ /* number of 100-nsec units since Jan 1, 1601 */
|
|
|
+ GetSystemTimeAsFileTime(&ft.ft_ft);
|
|
|
+ if (ft.ft_64 < EPOCH_BIAS) {
|
|
|
+ /* LCOV_EXCL_START */
|
|
|
+ log_err(LD_GENERAL,"System time is before 1970; failing.");
|
|
|
+ exit(1); // exit ok: system clock is broken.
|
|
|
+ /* LCOV_EXCL_STOP */
|
|
|
+ }
|
|
|
+ ft.ft_64 -= EPOCH_BIAS;
|
|
|
+ timeval->tv_sec = (unsigned) (ft.ft_64 / UNITS_PER_SEC);
|
|
|
+ timeval->tv_usec = (unsigned) ((ft.ft_64 / UNITS_PER_USEC) % USEC_PER_SEC);
|
|
|
+#elif defined(HAVE_GETTIMEOFDAY)
|
|
|
+ if (gettimeofday(timeval, NULL)) {
|
|
|
+ /* LCOV_EXCL_START */
|
|
|
+ /* If gettimeofday dies, we have either given a bad timezone (we didn't),
|
|
|
+ or segfaulted.*/
|
|
|
+ raw_assert_unreached_msg("gettimeofday failed");
|
|
|
+ /* LCOV_EXCL_STOP */
|
|
|
+ }
|
|
|
+#elif defined(HAVE_FTIME)
|
|
|
+ struct timeb tb;
|
|
|
+ ftime(&tb);
|
|
|
+ timeval->tv_sec = tb.time;
|
|
|
+ timeval->tv_usec = tb.millitm * 1000;
|
|
|
+#else
|
|
|
+#error "No way to get time."
|
|
|
+#endif /* defined(_WIN32) || ... */
|
|
|
+ return;
|
|
|
+}
|