Mercurial > dropbear
comparison dbutil.c @ 952:ef8d939de3dd
Fix clock_gettime handling
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 28 Jul 2014 22:48:48 +0800 |
parents | d93a6bcf616f |
children | 356a25a108a3 |
comparison
equal
deleted
inserted
replaced
951:9a48d8bcfeed | 952:ef8d939de3dd |
---|---|
943 c |= (xa[i] ^ xb[i]); | 943 c |= (xa[i] ^ xb[i]); |
944 } | 944 } |
945 return c; | 945 return c; |
946 } | 946 } |
947 | 947 |
948 time_t monotonic_now() { | |
949 | |
950 #if defined(__linux__) && defined(SYS_clock_gettime) | 948 #if defined(__linux__) && defined(SYS_clock_gettime) |
951 /* CLOCK_MONOTONIC_COARSE was added in Linux 2.6.32. Probably cheaper. */ | 949 /* CLOCK_MONOTONIC_COARSE was added in Linux 2.6.32 but took a while to |
950 reach userspace include headers */ | |
952 #ifndef CLOCK_MONOTONIC_COARSE | 951 #ifndef CLOCK_MONOTONIC_COARSE |
953 #define CLOCK_MONOTONIC_COARSE 6 | 952 #define CLOCK_MONOTONIC_COARSE 6 |
954 #endif | 953 #endif |
955 static clockid_t clock_source = CLOCK_MONOTONIC_COARSE; | 954 static clockid_t get_linux_clock_source() { |
956 struct timespec ts; | 955 struct timespec ts; |
957 | 956 if (syscall(SYS_clock_gettime, CLOCK_MONOTONIC_COARSE, &ts) == 0) { |
958 if (syscall(SYS_clock_gettime, clock_source, &ts) == EINVAL) { | 957 return CLOCK_MONOTONIC_COARSE; |
959 clock_source = CLOCK_MONOTONIC; | 958 } |
960 syscall(SYS_clock_gettime, CLOCK_MONOTONIC, &ts); | 959 if (syscall(SYS_clock_gettime, CLOCK_MONOTONIC, &ts) == 0) { |
961 } | 960 return CLOCK_MONOTONIC; |
962 return ts.tv_sec; | 961 } |
963 #elif defined(HAVE_MACH_ABSOLUTE_TIME) | 962 return -1; |
963 } | |
964 #endif | |
965 | |
966 time_t monotonic_now() { | |
967 #if defined(__linux__) && defined(SYS_clock_gettime) | |
968 static clockid_t clock_source = -2; | |
969 | |
970 if (clock_source == -2) { | |
971 /* First time, find out which one works. | |
972 -1 will fall back to time() */ | |
973 clock_source = get_linux_clock_source(); | |
974 } | |
975 | |
976 if (clock_source >= 0) { | |
977 struct timespec ts; | |
978 if (syscall(SYS_clock_gettime, clock_source, &ts) != 0) { | |
979 /* Intermittent clock failures should not happen */ | |
980 dropbear_exit("Clock broke"); | |
981 } | |
982 return ts.tv_sec; | |
983 } | |
984 #endif /* linux clock_gettime */ | |
985 | |
986 #if defined(HAVE_MACH_ABSOLUTE_TIME) | |
964 /* OS X, see https://developer.apple.com/library/mac/qa/qa1398/_index.html */ | 987 /* OS X, see https://developer.apple.com/library/mac/qa/qa1398/_index.html */ |
965 static mach_timebase_info_data_t timebase_info; | 988 static mach_timebase_info_data_t timebase_info; |
966 if (timebase_info.denom == 0) { | 989 if (timebase_info.denom == 0) { |
967 mach_timebase_info(&timebase_info); | 990 mach_timebase_info(&timebase_info); |
968 } | 991 } |
969 return mach_absolute_time() * timebase_info.numer / timebase_info.denom | 992 return mach_absolute_time() * timebase_info.numer / timebase_info.denom |
970 / 1e9; | 993 / 1e9; |
971 #else | 994 #endif /* osx mach_absolute_time */ |
995 | |
972 /* Fallback for everything else - this will sometimes go backwards */ | 996 /* Fallback for everything else - this will sometimes go backwards */ |
973 return time(NULL); | 997 return time(NULL); |
974 #endif | 998 } |
975 | 999 |
976 } | |
977 |