diff --git a/hostapd/Makefile b/hostapd/Makefile index 87ff9b4fe..b4704bafa 100644 --- a/hostapd/Makefile +++ b/hostapd/Makefile @@ -84,6 +84,14 @@ CONFIG_ELOOP=eloop endif OBJS += ../src/utils/$(CONFIG_ELOOP).o OBJS_c += ../src/utils/$(CONFIG_ELOOP).o + +ifeq ($(CONFIG_ELOOP), eloop) +# Using glibc < 2.17 requires -lrt for clock_gettime() +LIBS += -lrt +LIBS_c += -lrt +LIBS_h += -lrt +endif + OBJS += ../src/utils/common.o OBJS += ../src/utils/wpa_debug.o OBJS_c += ../src/utils/wpa_debug.o diff --git a/src/utils/eloop.c b/src/utils/eloop.c index 2d6aac7e0..e983edcfb 100644 --- a/src/utils/eloop.c +++ b/src/utils/eloop.c @@ -31,7 +31,7 @@ struct eloop_sock { struct eloop_timeout { struct dl_list list; - struct os_time time; + struct os_reltime time; void *eloop_data; void *user_data; eloop_timeout_handler handler; @@ -484,7 +484,7 @@ int eloop_register_timeout(unsigned int secs, unsigned int usecs, timeout = os_zalloc(sizeof(*timeout)); if (timeout == NULL) return -1; - if (os_get_time(&timeout->time) < 0) { + if (os_get_reltime(&timeout->time) < 0) { os_free(timeout); return -1; } @@ -514,7 +514,7 @@ int eloop_register_timeout(unsigned int secs, unsigned int usecs, /* Maintain timeouts in order of increasing time */ dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) { - if (os_time_before(&timeout->time, &tmp->time)) { + if (os_reltime_before(&timeout->time, &tmp->time)) { dl_list_add(tmp->list.prev, &timeout->list); return 0; } @@ -558,13 +558,13 @@ int eloop_cancel_timeout(eloop_timeout_handler handler, int eloop_cancel_timeout_one(eloop_timeout_handler handler, void *eloop_data, void *user_data, - struct os_time *remaining) + struct os_reltime *remaining) { struct eloop_timeout *timeout, *prev; int removed = 0; - struct os_time now; + struct os_reltime now; - os_get_time(&now); + os_get_reltime(&now); remaining->sec = remaining->usec = 0; dl_list_for_each_safe(timeout, prev, &eloop.timeout, @@ -573,8 +573,8 @@ int eloop_cancel_timeout_one(eloop_timeout_handler handler, (timeout->eloop_data == eloop_data) && (timeout->user_data == user_data)) { removed = 1; - if (os_time_before(&now, &timeout->time)) - os_time_sub(&timeout->time, &now, remaining); + if (os_reltime_before(&now, &timeout->time)) + os_reltime_sub(&timeout->time, &now, remaining); eloop_remove_timeout(timeout); break; } @@ -603,7 +603,7 @@ int eloop_deplete_timeout(unsigned int req_secs, unsigned int req_usecs, eloop_timeout_handler handler, void *eloop_data, void *user_data) { - struct os_time now, requested, remaining; + struct os_reltime now, requested, remaining; struct eloop_timeout *tmp; dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) { @@ -612,9 +612,9 @@ int eloop_deplete_timeout(unsigned int req_secs, unsigned int req_usecs, tmp->user_data == user_data) { requested.sec = req_secs; requested.usec = req_usecs; - os_get_time(&now); - os_time_sub(&tmp->time, &now, &remaining); - if (os_time_before(&requested, &remaining)) { + os_get_reltime(&now); + os_reltime_sub(&tmp->time, &now, &remaining); + if (os_reltime_before(&requested, &remaining)) { eloop_cancel_timeout(handler, eloop_data, user_data); eloop_register_timeout(requested.sec, @@ -634,7 +634,7 @@ int eloop_replenish_timeout(unsigned int req_secs, unsigned int req_usecs, eloop_timeout_handler handler, void *eloop_data, void *user_data) { - struct os_time now, requested, remaining; + struct os_reltime now, requested, remaining; struct eloop_timeout *tmp; dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) { @@ -643,9 +643,9 @@ int eloop_replenish_timeout(unsigned int req_secs, unsigned int req_usecs, tmp->user_data == user_data) { requested.sec = req_secs; requested.usec = req_usecs; - os_get_time(&now); - os_time_sub(&tmp->time, &now, &remaining); - if (os_time_before(&remaining, &requested)) { + os_get_reltime(&now); + os_reltime_sub(&tmp->time, &now, &remaining); + if (os_reltime_before(&remaining, &requested)) { eloop_cancel_timeout(handler, eloop_data, user_data); eloop_register_timeout(requested.sec, @@ -776,7 +776,7 @@ void eloop_run(void) struct timeval _tv; #endif /* CONFIG_ELOOP_POLL */ int res; - struct os_time tv, now; + struct os_reltime tv, now; #ifndef CONFIG_ELOOP_POLL rfds = os_malloc(sizeof(*rfds)); @@ -793,9 +793,9 @@ void eloop_run(void) timeout = dl_list_first(&eloop.timeout, struct eloop_timeout, list); if (timeout) { - os_get_time(&now); - if (os_time_before(&now, &timeout->time)) - os_time_sub(&timeout->time, &now, &tv); + os_get_reltime(&now); + if (os_reltime_before(&now, &timeout->time)) + os_reltime_sub(&timeout->time, &now, &tv); else tv.sec = tv.usec = 0; #ifdef CONFIG_ELOOP_POLL @@ -837,8 +837,8 @@ void eloop_run(void) timeout = dl_list_first(&eloop.timeout, struct eloop_timeout, list); if (timeout) { - os_get_time(&now); - if (!os_time_before(&now, &timeout->time)) { + os_get_reltime(&now); + if (!os_reltime_before(&now, &timeout->time)) { void *eloop_data = timeout->eloop_data; void *user_data = timeout->user_data; eloop_timeout_handler handler = @@ -883,9 +883,9 @@ void eloop_terminate(void) void eloop_destroy(void) { struct eloop_timeout *timeout, *prev; - struct os_time now; + struct os_reltime now; - os_get_time(&now); + os_get_reltime(&now); dl_list_for_each_safe(timeout, prev, &eloop.timeout, struct eloop_timeout, list) { int sec, usec; diff --git a/src/utils/eloop.h b/src/utils/eloop.h index 274714f88..d3980fa49 100644 --- a/src/utils/eloop.h +++ b/src/utils/eloop.h @@ -207,7 +207,7 @@ int eloop_cancel_timeout(eloop_timeout_handler handler, */ int eloop_cancel_timeout_one(eloop_timeout_handler handler, void *eloop_data, void *user_data, - struct os_time *remaining); + struct os_reltime *remaining); /** * eloop_is_timeout_registered - Check if a timeout is already registered diff --git a/src/utils/eloop_win.c b/src/utils/eloop_win.c index e87d82ac9..a1f999648 100644 --- a/src/utils/eloop_win.c +++ b/src/utils/eloop_win.c @@ -31,7 +31,7 @@ struct eloop_event { struct eloop_timeout { struct dl_list list; - struct os_time time; + struct os_reltime time; void *eloop_data; void *user_data; eloop_timeout_handler handler; @@ -244,7 +244,7 @@ int eloop_register_timeout(unsigned int secs, unsigned int usecs, timeout = os_zalloc(sizeof(*timeout)); if (timeout == NULL) return -1; - if (os_get_time(&timeout->time) < 0) { + if (os_get_reltime(&timeout->time) < 0) { os_free(timeout); return -1; } @@ -271,7 +271,7 @@ int eloop_register_timeout(unsigned int secs, unsigned int usecs, /* Maintain timeouts in order of increasing time */ dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) { - if (os_time_before(&timeout->time, &tmp->time)) { + if (os_reltime_before(&timeout->time, &tmp->time)) { dl_list_add(tmp->list.prev, &timeout->list); return 0; } @@ -313,13 +313,13 @@ int eloop_cancel_timeout(eloop_timeout_handler handler, int eloop_cancel_timeout_one(eloop_timeout_handler handler, void *eloop_data, void *user_data, - struct os_time *remaining) + struct os_reltime *remaining) { struct eloop_timeout *timeout, *prev; int removed = 0; - struct os_time now; + struct os_reltime now; - os_get_time(&now); + os_get_reltime(&now); remaining->sec = remaining->usec = 0; dl_list_for_each_safe(timeout, prev, &eloop.timeout, @@ -328,8 +328,8 @@ int eloop_cancel_timeout_one(eloop_timeout_handler handler, (timeout->eloop_data == eloop_data) && (timeout->user_data == user_data)) { removed = 1; - if (os_time_before(&now, &timeout->time)) - os_time_sub(&timeout->time, &now, remaining); + if (os_reltime_before(&now, &timeout->time)) + os_reltime_sub(&timeout->time, &now, remaining); eloop_remove_timeout(timeout); break; } @@ -358,7 +358,7 @@ int eloop_deplete_timeout(unsigned int req_secs, unsigned int req_usecs, eloop_timeout_handler handler, void *eloop_data, void *user_data) { - struct os_time now, requested, remaining; + struct os_reltime now, requested, remaining; struct eloop_timeout *tmp; dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) { @@ -367,9 +367,9 @@ int eloop_deplete_timeout(unsigned int req_secs, unsigned int req_usecs, tmp->user_data == user_data) { requested.sec = req_secs; requested.usec = req_usecs; - os_get_time(&now); - os_time_sub(&tmp->time, &now, &remaining); - if (os_time_before(&requested, &remaining)) { + os_get_reltime(&now); + os_reltime_sub(&tmp->time, &now, &remaining); + if (os_reltime_before(&requested, &remaining)) { eloop_cancel_timeout(handler, eloop_data, user_data); eloop_register_timeout(requested.sec, @@ -389,7 +389,7 @@ int eloop_replenish_timeout(unsigned int req_secs, unsigned int req_usecs, eloop_timeout_handler handler, void *eloop_data, void *user_data) { - struct os_time now, requested, remaining; + struct os_reltime now, requested, remaining; struct eloop_timeout *tmp; dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) { @@ -398,9 +398,9 @@ int eloop_replenish_timeout(unsigned int req_secs, unsigned int req_usecs, tmp->user_data == user_data) { requested.sec = req_secs; requested.usec = req_usecs; - os_get_time(&now); - os_time_sub(&tmp->time, &now, &remaining); - if (os_time_before(&remaining, &requested)) { + os_get_reltime(&now); + os_reltime_sub(&tmp->time, &now, &remaining); + if (os_reltime_before(&remaining, &requested)) { eloop_cancel_timeout(handler, eloop_data, user_data); eloop_register_timeout(requested.sec, @@ -530,7 +530,7 @@ int eloop_register_signal_reconfig(eloop_signal_handler handler, void eloop_run(void) { - struct os_time tv, now; + struct os_reltime tv, now; DWORD count, ret, timeout_val, err; size_t i; @@ -542,9 +542,9 @@ void eloop_run(void) timeout = dl_list_first(&eloop.timeout, struct eloop_timeout, list); if (timeout) { - os_get_time(&now); - if (os_time_before(&now, &timeout->time)) - os_time_sub(&timeout->time, &now, &tv); + os_get_reltime(&now); + if (os_reltime_before(&now, &timeout->time)) + os_reltime_sub(&timeout->time, &now, &tv); } count = 0; @@ -583,8 +583,8 @@ void eloop_run(void) timeout = dl_list_first(&eloop.timeout, struct eloop_timeout, list); if (timeout) { - os_get_time(&now); - if (!os_time_before(&now, &timeout->time)) { + os_get_reltime(&now); + if (!os_reltime_before(&now, &timeout->time)) { void *eloop_data = timeout->eloop_data; void *user_data = timeout->user_data; eloop_timeout_handler handler = diff --git a/src/utils/os.h b/src/utils/os.h index 2aab13af0..77dc6e38a 100644 --- a/src/utils/os.h +++ b/src/utils/os.h @@ -23,6 +23,11 @@ struct os_time { os_time_t usec; }; +struct os_reltime { + os_time_t sec; + os_time_t usec; +}; + /** * os_get_time - Get current time (sec, usec) * @t: Pointer to buffer for the time @@ -30,21 +35,56 @@ struct os_time { */ int os_get_time(struct os_time *t); +/** + * os_get_reltime - Get relative time (sec, usec) + * @t: Pointer to buffer for the time + * Returns: 0 on success, -1 on failure + */ +int os_get_reltime(struct os_reltime *t); -/* Helper macros for handling struct os_time */ -#define os_time_before(a, b) \ - ((a)->sec < (b)->sec || \ - ((a)->sec == (b)->sec && (a)->usec < (b)->usec)) +/* Helpers for handling struct os_time */ + +static inline int os_time_before(struct os_time *a, struct os_time *b) +{ + return (a->sec < b->sec) || + (a->sec == b->sec && a->usec < b->usec); +} + + +static inline void os_time_sub(struct os_time *a, struct os_time *b, + struct os_time *res) +{ + res->sec = a->sec - b->sec; + res->usec = a->usec - b->usec; + if (res->usec < 0) { + res->sec--; + res->usec += 1000000; + } +} + + +/* Helpers for handling struct os_reltime */ + +static inline int os_reltime_before(struct os_reltime *a, + struct os_reltime *b) +{ + return (a->sec < b->sec) || + (a->sec == b->sec && a->usec < b->usec); +} + + +static inline void os_reltime_sub(struct os_reltime *a, struct os_reltime *b, + struct os_reltime *res) +{ + res->sec = a->sec - b->sec; + res->usec = a->usec - b->usec; + if (res->usec < 0) { + res->sec--; + res->usec += 1000000; + } +} -#define os_time_sub(a, b, res) do { \ - (res)->sec = (a)->sec - (b)->sec; \ - (res)->usec = (a)->usec - (b)->usec; \ - if ((res)->usec < 0) { \ - (res)->sec--; \ - (res)->usec += 1000000; \ - } \ -} while (0) /** * os_mktime - Convert broken-down time into seconds since 1970-01-01 diff --git a/src/utils/os_internal.c b/src/utils/os_internal.c index e4b7fdb18..2cb0d1262 100644 --- a/src/utils/os_internal.c +++ b/src/utils/os_internal.c @@ -41,6 +41,17 @@ int os_get_time(struct os_time *t) } +int os_get_reltime(struct os_reltime *t) +{ + int res; + struct timeval tv; + res = gettimeofday(&tv, NULL); + t->sec = tv.tv_sec; + t->usec = tv.tv_usec; + return res; +} + + int os_mktime(int year, int month, int day, int hour, int min, int sec, os_time_t *t) { diff --git a/src/utils/os_none.c b/src/utils/os_none.c index cabf73bd8..228c4724c 100644 --- a/src/utils/os_none.c +++ b/src/utils/os_none.c @@ -26,6 +26,12 @@ int os_get_time(struct os_time *t) } +int os_get_reltime(struct os_reltime *t) +{ + return -1; +} + + int os_mktime(int year, int month, int day, int hour, int min, int sec, os_time_t *t) { diff --git a/src/utils/os_unix.c b/src/utils/os_unix.c index 960073a50..fa67fdfb6 100644 --- a/src/utils/os_unix.c +++ b/src/utils/os_unix.c @@ -60,6 +60,43 @@ int os_get_time(struct os_time *t) } +int os_get_reltime(struct os_reltime *t) +{ +#if defined(CLOCK_BOOTTIME) + static clockid_t clock_id = CLOCK_BOOTTIME; +#elif defined(CLOCK_MONOTONIC) + static clockid_t clock_id = CLOCK_MONOTONIC; +#else + static clockid_t clock_id = CLOCK_REALTIME; +#endif + struct timespec ts; + int res; + + while (1) { + res = clock_gettime(clock_id, &ts); + if (res == 0) { + t->sec = ts.tv_sec; + t->usec = ts.tv_nsec / 1000; + return 0; + } + switch (clock_id) { +#ifdef CLOCK_BOOTTIME + case CLOCK_BOOTTIME: + clock_id = CLOCK_MONOTONIC; + break; +#endif +#ifdef CLOCK_MONOTONIC + case CLOCK_MONOTONIC: + clock_id = CLOCK_REALTIME; + break; +#endif + case CLOCK_REALTIME: + return -1; + } + } +} + + int os_mktime(int year, int month, int day, int hour, int min, int sec, os_time_t *t) { diff --git a/src/utils/os_win32.c b/src/utils/os_win32.c index 163cebefc..1cfa7a5f8 100644 --- a/src/utils/os_win32.c +++ b/src/utils/os_win32.c @@ -47,6 +47,17 @@ int os_get_time(struct os_time *t) } +int os_get_reltime(struct os_reltime *t) +{ + /* consider using performance counters or so instead */ + struct os_time now; + int res = os_get_time(&now); + t->sec = now.sec; + t->usec = now.usec; + return res; +} + + int os_mktime(int year, int month, int day, int hour, int min, int sec, os_time_t *t) { diff --git a/wlantest/Makefile b/wlantest/Makefile index a08fd547d..175fb515f 100644 --- a/wlantest/Makefile +++ b/wlantest/Makefile @@ -19,6 +19,8 @@ CFLAGS += -I. CFLAGS += -I../src CFLAGS += -I../src/utils +# glibc < 2.17 needs -lrt for clock_gettime() +LIBS += -lrt ifndef LDO LDO=$(CC) @@ -112,7 +114,7 @@ wlantest: $(OBJS) $(LIBWLANTEST) $(LDO) $(LDFLAGS) -o wlantest $(OBJS) -L. -lwlantest $(LIBS) wlantest_cli: $(OBJS_cli) $(LIBWLANTEST) - $(LDO) $(LDFLAGS) -o wlantest_cli $(OBJS_cli) -L. -lwlantest + $(LDO) $(LDFLAGS) -o wlantest_cli $(OBJS_cli) -L. -lwlantest $(LIBS) test_vectors: $(TOBJS) $(LIBWLANTEST) $(LDO) $(LDFLAGS) -o test_vectors $(TOBJS) -L. -lwlantest $(LIBS) diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile index 8dcb71b12..f6a46d28e 100644 --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -113,6 +113,13 @@ endif OBJS += ../src/utils/$(CONFIG_ELOOP).o OBJS_c += ../src/utils/$(CONFIG_ELOOP).o +ifeq ($(CONFIG_ELOOP), eloop) +# Using glibc < 2.17 requires -lrt for clock_gettime() +LIBS += -lrt +LIBS_c += -lrt +LIBS_p += -lrt +endif + ifdef CONFIG_ELOOP_POLL CFLAGS += -DCONFIG_ELOOP_POLL endif diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index 7baacaa6f..625ff2860 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -884,7 +884,7 @@ scan: void wpa_supplicant_update_scan_int(struct wpa_supplicant *wpa_s, int sec) { - struct os_time remaining, new_int; + struct os_reltime remaining, new_int; int cancelled; cancelled = eloop_cancel_timeout_one(wpa_supplicant_scan, wpa_s, NULL, @@ -892,7 +892,7 @@ void wpa_supplicant_update_scan_int(struct wpa_supplicant *wpa_s, int sec) new_int.sec = sec; new_int.usec = 0; - if (cancelled && os_time_before(&remaining, &new_int)) { + if (cancelled && os_reltime_before(&remaining, &new_int)) { new_int.sec = remaining.sec; new_int.usec = remaining.usec; }