diff options
Diffstat (limited to 'src/libstrongswan/utils/utils/time.c')
-rw-r--r-- | src/libstrongswan/utils/utils/time.c | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/src/libstrongswan/utils/utils/time.c b/src/libstrongswan/utils/utils/time.c new file mode 100644 index 000000000..c67ae93f2 --- /dev/null +++ b/src/libstrongswan/utils/utils/time.c @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2008-2014 Tobias Brunner + * Copyright (C) 2005-2008 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#ifdef WIN32 +/* for GetTickCount64, Windows 7 */ +# define _WIN32_WINNT 0x0601 +#endif + +#define _GNU_SOURCE +#include <utils/utils.h> + +#include <inttypes.h> +#include <time.h> + +/** + * Return monotonic time + */ +time_t time_monotonic(timeval_t *tv) +{ +#ifdef WIN32 + ULONGLONG ms; + time_t s; + + ms = GetTickCount64(); + s = ms / 1000; + if (tv) + { + tv->tv_sec = s; + tv->tv_usec = (ms - (s * 1000)) * 1000; + } + return s; +#else /* !WIN32 */ +#if defined(HAVE_CLOCK_GETTIME) && \ + (defined(HAVE_CONDATTR_CLOCK_MONOTONIC) || \ + defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC)) + /* as we use time_monotonic() for condvar operations, we use the + * monotonic time source only if it is also supported by pthread. */ + timespec_t ts; + + if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) + { + if (tv) + { + tv->tv_sec = ts.tv_sec; + tv->tv_usec = ts.tv_nsec / 1000; + } + return ts.tv_sec; + } +#endif /* HAVE_CLOCK_GETTIME && (...) */ + /* Fallback to non-monotonic timestamps: + * On MAC OS X, creating monotonic timestamps is rather difficult. We + * could use mach_absolute_time() and catch sleep/wakeup notifications. + * We stick to the simpler (non-monotonic) gettimeofday() for now. + * But keep in mind: we need the same time source here as in condvar! */ + if (!tv) + { + return time(NULL); + } + if (gettimeofday(tv, NULL) != 0) + { /* should actually never fail if passed pointers are valid */ + return -1; + } + return tv->tv_sec; +#endif /* !WIN32 */ +} + +/** + * Described in header. + */ +int time_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, + const void *const *args) +{ + static const char* months[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + time_t *time = *((time_t**)(args[0])); + bool utc = *((int*)(args[1])); + struct tm t, *ret = NULL; + + if (*time != UNDEFINED_TIME) + { + if (utc) + { + ret = gmtime_r(time, &t); + } + else + { + ret = localtime_r(time, &t); + } + } + if (ret == NULL) + { + return print_in_hook(data, "--- -- --:--:--%s----", + utc ? " UTC " : " "); + } + return print_in_hook(data, "%s %02d %02d:%02d:%02d%s%04d", + months[t.tm_mon], t.tm_mday, t.tm_hour, t.tm_min, + t.tm_sec, utc ? " UTC " : " ", t.tm_year + 1900); +} + +/** + * Described in header. + */ +int time_delta_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, + const void *const *args) +{ + char* unit = "second"; + time_t *arg1 = *((time_t**)(args[0])); + time_t *arg2 = *((time_t**)(args[1])); + u_int64_t delta = llabs(*arg1 - *arg2); + + if (delta > 2 * 60 * 60 * 24) + { + delta /= 60 * 60 * 24; + unit = "day"; + } + else if (delta > 2 * 60 * 60) + { + delta /= 60 * 60; + unit = "hour"; + } + else if (delta > 2 * 60) + { + delta /= 60; + unit = "minute"; + } + return print_in_hook(data, "%" PRIu64 " %s%s", delta, unit, + (delta == 1) ? "" : "s"); +} |