tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

tor_gettimeofday.c (2162B)


      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"
     14 #include "lib/wallclock/tor_gettimeofday.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,
     42 tor_gettimeofday, (struct timeval *timeval))
     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 }