diff options
Diffstat (limited to 'sbin/dhclient/dispatch.c')
-rw-r--r-- | sbin/dhclient/dispatch.c | 44 |
1 files changed, 31 insertions, 13 deletions
diff --git a/sbin/dhclient/dispatch.c b/sbin/dhclient/dispatch.c index 310f477f8a4f..06bd31e5ec82 100644 --- a/sbin/dhclient/dispatch.c +++ b/sbin/dhclient/dispatch.c @@ -56,6 +56,10 @@ #define assert_aligned(p, align) assert((((uintptr_t)p) & ((align) - 1)) == 0) static struct protocol *protocols; +static const struct timespec timespec_intmax_ms = { + .tv_sec = INT_MAX / 1000, + .tv_nsec = (INT_MAX % 1000) * 1000000 +}; static struct timeout *timeouts; static struct timeout *free_timeouts; static int interfaces_invalidated; @@ -76,7 +80,6 @@ discover_interfaces(struct interface_info *iface) { struct ifaddrs *ifap, *ifa; struct ifreq *tif; - int len = IFNAMSIZ + sizeof(struct sockaddr_storage); if (getifaddrs(&ifap) != 0) error("getifaddrs failed"); @@ -119,7 +122,7 @@ discover_interfaces(struct interface_info *iface) LLADDR(foo), foo->sdl_alen); } if (!iface->ifp) { - if ((tif = calloc(1, len)) == NULL) + if ((tif = calloc(1, sizeof(struct ifreq))) == NULL) error("no space to remember ifp"); strlcpy(tif->ifr_name, ifa->ifa_name, IFNAMSIZ); iface->ifp = tif; @@ -155,7 +158,9 @@ dispatch(void) int count, live_interfaces, i, to_msec, nfds = 0; struct protocol *l; struct pollfd *fds; - time_t howlong; + struct timespec howlong; + + clock_gettime(CLOCK_MONOTONIC, &time_now); for (l = protocols; l; l = l->next) nfds++; @@ -173,7 +178,7 @@ another: if (timeouts) { struct timeout *t; - if (timeouts->when <= cur_time) { + if (timespeccmp(&timeouts->when, &time_now, <=)) { t = timeouts; timeouts = timeouts->next; (*(t->func))(t->what); @@ -188,10 +193,10 @@ another: * int for poll, while not polling with a * negative timeout and blocking indefinitely. */ - howlong = timeouts->when - cur_time; - if (howlong > INT_MAX / 1000) - howlong = INT_MAX / 1000; - to_msec = howlong * 1000; + timespecsub(&timeouts->when, &time_now, &howlong); + if (timespeccmp(&howlong, ×pec_intmax_ms, >)) + howlong = timespec_intmax_ms; + to_msec = howlong.tv_sec * 1000 + howlong.tv_nsec / 1000000; } else to_msec = -1; @@ -218,14 +223,16 @@ another: /* Not likely to be transitory... */ if (count == -1) { if (errno == EAGAIN || errno == EINTR) { - time(&cur_time); + clock_gettime(CLOCK_MONOTONIC, &time_now); + cur_time = time(NULL); continue; } else error("poll: %m"); } /* Get the current time... */ - time(&cur_time); + clock_gettime(CLOCK_MONOTONIC, &time_now); + cur_time = time(NULL); i = 0; for (l = protocols; l; l = l->next) { @@ -356,7 +363,18 @@ active: } void -add_timeout(time_t when, void (*where)(void *), void *what) +add_timeout(time_t when_s, void (*where)(void *), void *what) +{ + struct timespec when; + + cur_time = time(NULL); + clock_gettime(CLOCK_MONOTONIC, &when); + when.tv_sec += when_s - cur_time; + add_timeout_timespec(when, where, what); +} + +void +add_timeout_timespec(struct timespec when, void (*where)(void *), void *what) { struct timeout *t, *q; @@ -395,7 +413,7 @@ add_timeout(time_t when, void (*where)(void *), void *what) /* Now sort this timeout into the timeout list. */ /* Beginning of list? */ - if (!timeouts || timeouts->when > q->when) { + if (!timeouts || timespeccmp(&timeouts->when, &q->when, >)) { q->next = timeouts; timeouts = q; return; @@ -403,7 +421,7 @@ add_timeout(time_t when, void (*where)(void *), void *what) /* Middle of list? */ for (t = timeouts; t->next; t = t->next) { - if (t->next->when > q->when) { + if (timespeccmp(&t->next->when, &q->when, >)) { q->next = t->next; t->next = q; return; |