|  | @@ -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;
 | 
	
		
			
				|  |  | +}
 |