Mercurial > dropbear
diff dbutil.c @ 928:7cd89d4e0335
Add new monotonic_now() wrapper so that timeouts are unaffected by
system clock changes
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 13 Mar 2014 23:50:09 +0800 |
parents | ff597bf2cfb0 |
children | 8f04e36622c0 |
line wrap: on
line diff
--- a/dbutil.c Thu Mar 13 23:08:47 2014 +0800 +++ b/dbutil.c Thu Mar 13 23:50:09 2014 +0800 @@ -48,6 +48,19 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "config.h" + +#ifdef __linux__ +#define _GNU_SOURCE +/* To call clock_gettime() directly */ +#include <sys/syscall.h> +#endif /* __linux */ + +#ifdef HAVE_MACH_MACH_TIME_H +#include <mach/mach_time.h> +#include <mach/mach.h> +#endif + #include "includes.h" #include "dbutil.h" #include "buffer.h" @@ -932,3 +945,33 @@ return c; } +time_t monotonic_now() { + +#if defined(__linux__) && defined(SYS_clock_gettime) + /* CLOCK_MONOTONIC_COARSE was added in Linux 2.6.32. Probably cheaper. */ +#ifndef CLOCK_MONOTONIC_COARSE +#define CLOCK_MONOTONIC_COARSE 6 +#endif + static clockid_t clock_source = CLOCK_MONOTONIC_COARSE; + struct timespec ts; + + if (syscall(SYS_clock_gettime, clock_source, &ts) == EINVAL) { + clock_source = CLOCK_MONOTONIC; + syscall(SYS_clock_gettime, CLOCK_MONOTONIC, &ts); + } + return ts.tv_sec; +#elif defined(HAVE_MACH_ABSOLUTE_TIME) + /* OS X, see https://developer.apple.com/library/mac/qa/qa1398/_index.html */ + mach_timebase_info_data_t timebase_info; + if (timebase_info.denom == 0) { + mach_timebase_info(&timebase_info); + } + return mach_absolute_time() * timebase_info.numer / timebase_info.denom + / 1e9; +#else + /* Fallback for everything else - this will sometimes go backwards */ + return time(NULL); +#endif + +} +