aboutsummaryrefslogtreecommitdiffstats
path: root/common.c
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:04:11 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:04:11 -0800
commit4c5a5fb53bccceff331bae70f748bf9b4609fe0a (patch)
treed6ae69d0d3f4a4d760a3254ec326bca4a8afacfe /common.c
parente95877ecfa1170d77b1ec1f66752725cdda01b64 (diff)
downloadexternal_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.c97
1 files changed, 60 insertions, 37 deletions
diff --git a/common.c b/common.c
index 8bc2b78..d90c7d2 100644
--- a/common.c
+++ b/common.c
@@ -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;