aboutsummaryrefslogtreecommitdiff
path: root/sbin/dhclient/dispatch.c
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/dhclient/dispatch.c')
-rw-r--r--sbin/dhclient/dispatch.c44
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, &timespec_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;