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