diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:04:11 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:04:11 -0800 |
commit | 4c5a5fb53bccceff331bae70f748bf9b4609fe0a (patch) | |
tree | d6ae69d0d3f4a4d760a3254ec326bca4a8afacfe /common.c | |
parent | e95877ecfa1170d77b1ec1f66752725cdda01b64 (diff) | |
download | external_dhcpcd-4c5a5fb53bccceff331bae70f748bf9b4609fe0a.zip external_dhcpcd-4c5a5fb53bccceff331bae70f748bf9b4609fe0a.tar.gz external_dhcpcd-4c5a5fb53bccceff331bae70f748bf9b4609fe0a.tar.bz2 |
Code drop from //branches/cupcake/...@124589
Diffstat (limited to 'common.c')
-rw-r--r-- | common.c | 97 |
1 files changed, 60 insertions, 37 deletions
@@ -25,6 +25,11 @@ * SUCH DAMAGE. */ +#ifdef __APPLE__ +# include <mach/mach_time.h> +# include <mach/kern_return.h> +#endif + #include <sys/param.h> #include <sys/time.h> @@ -33,7 +38,6 @@ #ifdef BSD # include <paths.h> #endif -#include <poll.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -48,6 +52,8 @@ # define _PATH_DEVNULL "/dev/null" #endif +int clock_monotonic = 0; + /* Handy routine to read very long lines in text files. * This means we read the whole line and avoid any nasty buffer overflows. */ ssize_t @@ -151,25 +157,6 @@ close_fds(void) } int -fd_hasdata(int fd) -{ - struct pollfd fds; - int retval; - - if (fd == -1) - return -1; - fds.fd = fd; - fds.events = POLLIN; - fds.revents = 0; - retval = poll(&fds, 1, 0); - if (retval == -1) - return -1; - if (retval > 0 && fds.revents & POLLIN) - return retval; - return 0; -} - -int set_cloexec(int fd) { int flags; @@ -202,41 +189,77 @@ set_nonblock(int fd) * Which is why we use CLOCK_MONOTONIC, but it is not available on all * platforms. */ +#define NO_MONOTONIC "host does not support a monotonic clock - timing can skew" int -get_time(struct timeval *tp) +get_monotonic(struct timeval *tp) { + static int posix_clock_set = 0; #if defined(_POSIX_MONOTONIC_CLOCK) && defined(CLOCK_MONOTONIC) struct timespec ts; static clockid_t posix_clock; - static int posix_clock_set = 0; - if (!posix_clock_set) { - if (sysconf(_SC_MONOTONIC_CLOCK) >= 0) + if (posix_clock_set == 0) { + if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { posix_clock = CLOCK_MONOTONIC; - else - posix_clock = CLOCK_REALTIME; + clock_monotonic = 1; + } posix_clock_set = 1; } - if (clock_gettime(posix_clock, &ts) == -1) - return -1; + if (clock_monotonic) { + if (clock_gettime(posix_clock, &ts) == 0) { + tp->tv_sec = ts.tv_sec; + tp->tv_usec = ts.tv_nsec / 1000; + return 0; + } + } +#elif defined(__APPLE__) +#define NSEC_PER_SEC 1000000000 + /* We can use mach kernel functions here. + * This is crap though - why can't they implement clock_gettime?*/ + static struct mach_timebase_info info = { 0, 0 }; + static double factor = 0.0; + uint64_t nano; + long rem; + + if (posix_clock_set == 0) { + if (mach_timebase_info(&info) == KERN_SUCCESS) { + factor = (double)info.numer / (double)info.denom; + clock_monotonic = 1; + } + posix_clock_set = 1; + } + if (clock_monotonic) { + nano = mach_absolute_time(); + if ((info.denom != 1 || info.numer != 1) && factor != 0.0) + nano *= factor; + tp->tv_sec = nano / NSEC_PER_SEC; + rem = nano % NSEC_PER_SEC; + if (rem < 0) { + tp->tv_sec--; + rem += NSEC_PER_SEC; + } + tp->tv_usec = rem / 1000; + return 0; + } +#endif - tp->tv_sec = ts.tv_sec; - tp->tv_usec = ts.tv_nsec / 1000; - return 0; -#else + /* Something above failed, so fall back to gettimeofday */ + if (!posix_clock_set) { + logger(LOG_WARNING, NO_MONOTONIC); + posix_clock_set = 1; + } return gettimeofday(tp, NULL); -#endif } time_t uptime(void) { - struct timeval tp; + struct timeval tv; - if (get_time(&tp) == -1) + if (get_monotonic(&tv) == -1) return -1; - return tp.tv_sec; + return tv.tv_sec; } int @@ -247,7 +270,7 @@ writepid(int fd, pid_t pid) if (ftruncate(fd, (off_t)0) == -1) return -1; - snprintf(spid, sizeof(spid), "%u", pid); + snprintf(spid, sizeof(spid), "%u\n", pid); len = pwrite(fd, spid, strlen(spid), (off_t)0); if (len != (ssize_t)strlen(spid)) return -1; |