Tor  0.4.7.0-alpha-dev
tor_gettimeofday.c
Go to the documentation of this file.
1 /* Copyright (c) 2003-2004, Roger Dingledine
2  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3  * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
5 
6 /**
7  * \file tor_gettimeofday.c
8  * \brief Implementat gettimeofday() for windows, and other platforms without
9  * it.
10  **/
11 
12 #include "orconfig.h"
13 #include "lib/err/torerr.h"
15 #include "lib/cc/torint.h"
16 
17 #include <stddef.h>
18 #include <stdlib.h>
19 
20 #ifdef HAVE_SYS_TIME_H
21 #include <sys/time.h>
22 #endif
23 
24 #ifdef _WIN32
25 #include <windows.h>
26 #endif
27 
28 #ifdef HAVE_SYS_TYPES_H
29 #include <sys/types.h>
30 #endif
31 
32 #ifndef HAVE_GETTIMEOFDAY
33 #ifdef HAVE_FTIME
34 #include <sys/timeb.h>
35 #endif
36 #endif
37 
38 /** Set *timeval to the current time of day. On error, log and terminate.
39  * (Same as gettimeofday(timeval,NULL), but never returns -1.)
40  */
41 MOCK_IMPL(void,
43 {
44 #ifdef _WIN32
45  /* Epoch bias copied from perl: number of units between windows epoch and
46  * Unix epoch. */
47 #define EPOCH_BIAS UINT64_C(116444736000000000)
48 #define UNITS_PER_SEC UINT64_C(10000000)
49 #define USEC_PER_SEC UINT64_C(1000000)
50 #define UNITS_PER_USEC UINT64_C(10)
51  union {
52  uint64_t ft_64;
53  FILETIME ft_ft;
54  } ft;
55  /* number of 100-nsec units since Jan 1, 1601 */
56  GetSystemTimeAsFileTime(&ft.ft_ft);
57  if (ft.ft_64 < EPOCH_BIAS) {
58  /* LCOV_EXCL_START */
59  raw_assert_unreached_msg("System time is before 1970; failing.");
60  /* LCOV_EXCL_STOP */
61  }
62  ft.ft_64 -= EPOCH_BIAS;
63  timeval->tv_sec = (unsigned) (ft.ft_64 / UNITS_PER_SEC);
64  timeval->tv_usec = (unsigned) ((ft.ft_64 / UNITS_PER_USEC) % USEC_PER_SEC);
65 #elif defined(HAVE_GETTIMEOFDAY)
66  if (gettimeofday(timeval, NULL)) {
67  /* LCOV_EXCL_START */
68  /* If gettimeofday dies, we have either given a bad timezone (we didn't),
69  or segfaulted.*/
70  raw_assert_unreached_msg("gettimeofday failed");
71  /* LCOV_EXCL_STOP */
72  }
73 #elif defined(HAVE_FTIME)
74  struct timeb tb;
75  ftime(&tb);
76  timeval->tv_sec = tb.time;
77  timeval->tv_usec = tb.millitm * 1000;
78 #else
79 #error "No way to get time."
80 #endif /* defined(_WIN32) || ... */
81  return;
82 }
#define MOCK_IMPL(rv, funcname, arglist)
Definition: testsupport.h:133
#define USEC_PER_SEC
Definition: timers.c:104
void tor_gettimeofday(struct timeval *timeval)
Header for tor_gettimeofday.c.
Headers for torerr.c.
Integer definitions used throughout Tor.