/* Copyright (c) 2012, David Goulet <dgoulet@ev0ke.net> * Jacob Appelbaum <jacob@torproject.org> * Copyright (c) 2012, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** * \file clock-darwin.c * \brief Contains clock primitives for Mac OS X (Tested on 10.8.2) **/ #include "config.h" #include "clock.h" #include <stdio.h> #include <sys/time.h> #include <time.h> #ifdef __APPLE__ #include <mach/clock.h> #include <mach/clock_priv.h> #include <mach/mach.h> #include <mach/clock_types.h> #include <mach/mach_traps.h> #include <mach/clock_reply.h> #include <mach/mach_time.h> #include <mach/mach_error.h> #endif #include <assert.h> /** * Get current real time value and store it into time. * * @param time where the current time is stored * @return clock_gettime syscall return value */ int clock_get_real_time(struct tlsdate_time *time) { /* Safety net */ assert(time); kern_return_t r; clock_serv_t cclock; mach_timespec_t mts; r = host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); if (r != KERN_SUCCESS) { fprintf(stderr, "host_get_clock_service failed!\n"); return -1; } r = clock_get_time(cclock, &mts); if (r != KERN_SUCCESS) { fprintf(stderr, "clock_get_time failed!\n"); return -1; } r = mach_port_deallocate(mach_task_self(), cclock); if (r != KERN_SUCCESS) { fprintf(stderr, "mach_port_deallocate failed!\n"); return -1; } time->tp.tv_sec = mts.tv_sec; time->tp.tv_nsec = mts.tv_nsec; return r; } /** * Set current real time clock using time. * * @param time where the current time to set is stored * @return clock_settime syscall return value */ int clock_set_real_time(const struct tlsdate_time *time) { /* Safety net */ assert(time); //printf ("V: server time %u\n", (unsigned int) time->tp.tv_sec); int r; struct timeval tv = {time->tp.tv_sec, 0}; r = settimeofday(&tv, NULL); if (r != 0) { fprintf(stderr, "setimeofday failed!\n"); return -1; } return r; } /** * Init a tlsdate_time structure. * * @param sec is the seconds * @param nsec is the nanoseconds */ void clock_init_time(struct tlsdate_time *time, time_t sec, long nsec) { /* Safety net */ assert(time); time->tp.tv_sec = sec; time->tp.tv_nsec = nsec; }