1 /* Copyright (c) 2012, David Goulet <dgoulet@ev0ke.net>
2  *                     Jacob Appelbaum <jacob@torproject.org>
3  * Copyright (c) 2012, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
5 
6 /**
7   * \file clock-darwin.c
8   * \brief Contains clock primitives for Mac OS X (Tested on 10.8.2)
9   **/
10 
11 #include "config.h"
12 #include "clock.h"
13 #include <stdio.h>
14 #include <sys/time.h>
15 #include <time.h>
16 
17 #ifdef __APPLE__
18 #include <mach/clock.h>
19 #include <mach/clock_priv.h>
20 #include <mach/mach.h>
21 #include <mach/clock_types.h>
22 #include <mach/mach_traps.h>
23 #include <mach/clock_reply.h>
24 #include <mach/mach_time.h>
25 #include <mach/mach_error.h>
26 #endif
27 
28 #include <assert.h>
29 
30 /**
31  * Get current real time value and store it into time.
32  *
33  * @param time where the current time is stored
34  * @return clock_gettime syscall return value
35  */
clock_get_real_time(struct tlsdate_time * time)36 int clock_get_real_time(struct tlsdate_time *time)
37 {
38   /* Safety net */
39   assert(time);
40 
41   kern_return_t r;
42   clock_serv_t cclock;
43   mach_timespec_t mts;
44 
45   r = host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
46   if (r != KERN_SUCCESS)
47   {
48     fprintf(stderr, "host_get_clock_service failed!\n");
49     return -1;
50   }
51 
52   r = clock_get_time(cclock, &mts);
53   if (r != KERN_SUCCESS)
54   {
55     fprintf(stderr, "clock_get_time failed!\n");
56     return -1;
57   }
58 
59   r = mach_port_deallocate(mach_task_self(), cclock);
60   if (r != KERN_SUCCESS)
61   {
62     fprintf(stderr, "mach_port_deallocate failed!\n");
63     return -1;
64   }
65 
66   time->tp.tv_sec = mts.tv_sec;
67   time->tp.tv_nsec = mts.tv_nsec;
68   return r;
69 }
70 
71 /**
72  * Set current real time clock using time.
73  *
74  * @param time where the current time to set is stored
75  * @return clock_settime syscall return value
76  */
clock_set_real_time(const struct tlsdate_time * time)77 int clock_set_real_time(const struct tlsdate_time *time)
78 {
79   /* Safety net */
80   assert(time);
81 
82   //printf ("V: server time %u\n", (unsigned int) time->tp.tv_sec);
83   int r;
84   struct timeval tv = {time->tp.tv_sec, 0};
85 
86   r = settimeofday(&tv, NULL);
87   if (r != 0)
88   {
89     fprintf(stderr, "setimeofday failed!\n");
90     return -1;
91   }
92 
93   return r;
94 }
95 
96 /**
97  * Init a tlsdate_time structure.
98  *
99  * @param sec is the seconds
100  * @param nsec is the nanoseconds
101  */
clock_init_time(struct tlsdate_time * time,time_t sec,long nsec)102 void clock_init_time(struct tlsdate_time *time, time_t sec,
103                            long nsec)
104 {
105   /* Safety net */
106   assert(time);
107 
108   time->tp.tv_sec = sec;
109   time->tp.tv_nsec = nsec;
110 }
111