diff options
Diffstat (limited to 'contrib/wpa_supplicant/eloop.c')
-rw-r--r-- | contrib/wpa_supplicant/eloop.c | 553 |
1 files changed, 0 insertions, 553 deletions
diff --git a/contrib/wpa_supplicant/eloop.c b/contrib/wpa_supplicant/eloop.c deleted file mode 100644 index 9cac792..0000000 --- a/contrib/wpa_supplicant/eloop.c +++ /dev/null @@ -1,553 +0,0 @@ -/* - * Event loop based on select() loop - * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#include "includes.h" - -#include "common.h" -#include "eloop.h" - - -struct eloop_sock { - int sock; - void *eloop_data; - void *user_data; - eloop_sock_handler handler; -}; - -struct eloop_timeout { - struct os_time time; - void *eloop_data; - void *user_data; - eloop_timeout_handler handler; - struct eloop_timeout *next; -}; - -struct eloop_signal { - int sig; - void *user_data; - eloop_signal_handler handler; - int signaled; -}; - -struct eloop_sock_table { - int count; - struct eloop_sock *table; - int changed; -}; - -struct eloop_data { - void *user_data; - - int max_sock; - - struct eloop_sock_table readers; - struct eloop_sock_table writers; - struct eloop_sock_table exceptions; - - struct eloop_timeout *timeout; - - int signal_count; - struct eloop_signal *signals; - int signaled; - int pending_terminate; - - int terminate; - int reader_table_changed; -}; - -static struct eloop_data eloop; - - -int eloop_init(void *user_data) -{ - os_memset(&eloop, 0, sizeof(eloop)); - eloop.user_data = user_data; - return 0; -} - - -static int eloop_sock_table_add_sock(struct eloop_sock_table *table, - int sock, eloop_sock_handler handler, - void *eloop_data, void *user_data) -{ - struct eloop_sock *tmp; - - if (table == NULL) - return -1; - - tmp = (struct eloop_sock *) - os_realloc(table->table, - (table->count + 1) * sizeof(struct eloop_sock)); - if (tmp == NULL) - return -1; - - tmp[table->count].sock = sock; - tmp[table->count].eloop_data = eloop_data; - tmp[table->count].user_data = user_data; - tmp[table->count].handler = handler; - table->count++; - table->table = tmp; - if (sock > eloop.max_sock) - eloop.max_sock = sock; - table->changed = 1; - - return 0; -} - - -static void eloop_sock_table_remove_sock(struct eloop_sock_table *table, - int sock) -{ - int i; - - if (table == NULL || table->table == NULL || table->count == 0) - return; - - for (i = 0; i < table->count; i++) { - if (table->table[i].sock == sock) - break; - } - if (i == table->count) - return; - if (i != table->count - 1) { - os_memmove(&table->table[i], &table->table[i + 1], - (table->count - i - 1) * - sizeof(struct eloop_sock)); - } - table->count--; - table->changed = 1; -} - - -static void eloop_sock_table_set_fds(struct eloop_sock_table *table, - fd_set *fds) -{ - int i; - - FD_ZERO(fds); - - if (table->table == NULL) - return; - - for (i = 0; i < table->count; i++) - FD_SET(table->table[i].sock, fds); -} - - -static void eloop_sock_table_dispatch(struct eloop_sock_table *table, - fd_set *fds) -{ - int i; - - if (table == NULL || table->table == NULL) - return; - - table->changed = 0; - for (i = 0; i < table->count; i++) { - if (FD_ISSET(table->table[i].sock, fds)) { - table->table[i].handler(table->table[i].sock, - table->table[i].eloop_data, - table->table[i].user_data); - if (table->changed) - break; - } - } -} - - -static void eloop_sock_table_destroy(struct eloop_sock_table *table) -{ - if (table) - os_free(table->table); -} - - -int eloop_register_read_sock(int sock, eloop_sock_handler handler, - void *eloop_data, void *user_data) -{ - return eloop_register_sock(sock, EVENT_TYPE_READ, handler, - eloop_data, user_data); -} - - -void eloop_unregister_read_sock(int sock) -{ - eloop_unregister_sock(sock, EVENT_TYPE_READ); -} - - -static struct eloop_sock_table *eloop_get_sock_table(eloop_event_type type) -{ - switch (type) { - case EVENT_TYPE_READ: - return &eloop.readers; - case EVENT_TYPE_WRITE: - return &eloop.writers; - case EVENT_TYPE_EXCEPTION: - return &eloop.exceptions; - } - - return NULL; -} - - -int eloop_register_sock(int sock, eloop_event_type type, - eloop_sock_handler handler, - void *eloop_data, void *user_data) -{ - struct eloop_sock_table *table; - - table = eloop_get_sock_table(type); - return eloop_sock_table_add_sock(table, sock, handler, - eloop_data, user_data); -} - - -void eloop_unregister_sock(int sock, eloop_event_type type) -{ - struct eloop_sock_table *table; - - table = eloop_get_sock_table(type); - eloop_sock_table_remove_sock(table, sock); -} - - -int eloop_register_timeout(unsigned int secs, unsigned int usecs, - eloop_timeout_handler handler, - void *eloop_data, void *user_data) -{ - struct eloop_timeout *timeout, *tmp, *prev; - - timeout = os_malloc(sizeof(*timeout)); - if (timeout == NULL) - return -1; - if (os_get_time(&timeout->time) < 0) { - os_free(timeout); - return -1; - } - timeout->time.sec += secs; - timeout->time.usec += usecs; - while (timeout->time.usec >= 1000000) { - timeout->time.sec++; - timeout->time.usec -= 1000000; - } - timeout->eloop_data = eloop_data; - timeout->user_data = user_data; - timeout->handler = handler; - timeout->next = NULL; - - if (eloop.timeout == NULL) { - eloop.timeout = timeout; - return 0; - } - - prev = NULL; - tmp = eloop.timeout; - while (tmp != NULL) { - if (os_time_before(&timeout->time, &tmp->time)) - break; - prev = tmp; - tmp = tmp->next; - } - - if (prev == NULL) { - timeout->next = eloop.timeout; - eloop.timeout = timeout; - } else { - timeout->next = prev->next; - prev->next = timeout; - } - - return 0; -} - - -int eloop_cancel_timeout(eloop_timeout_handler handler, - void *eloop_data, void *user_data) -{ - struct eloop_timeout *timeout, *prev, *next; - int removed = 0; - - prev = NULL; - timeout = eloop.timeout; - while (timeout != NULL) { - next = timeout->next; - - if (timeout->handler == handler && - (timeout->eloop_data == eloop_data || - eloop_data == ELOOP_ALL_CTX) && - (timeout->user_data == user_data || - user_data == ELOOP_ALL_CTX)) { - if (prev == NULL) - eloop.timeout = next; - else - prev->next = next; - os_free(timeout); - removed++; - } else - prev = timeout; - - timeout = next; - } - - return removed; -} - - -int eloop_is_timeout_registered(eloop_timeout_handler handler, - void *eloop_data, void *user_data) -{ - struct eloop_timeout *tmp; - - tmp = eloop.timeout; - while (tmp != NULL) { - if (tmp->handler == handler && - tmp->eloop_data == eloop_data && - tmp->user_data == user_data) - return 1; - - tmp = tmp->next; - } - - return 0; -} - - -#ifndef CONFIG_NATIVE_WINDOWS -static void eloop_handle_alarm(int sig) -{ - fprintf(stderr, "eloop: could not process SIGINT or SIGTERM in two " - "seconds. Looks like there\n" - "is a bug that ends up in a busy loop that " - "prevents clean shutdown.\n" - "Killing program forcefully.\n"); - exit(1); -} -#endif /* CONFIG_NATIVE_WINDOWS */ - - -static void eloop_handle_signal(int sig) -{ - int i; - -#ifndef CONFIG_NATIVE_WINDOWS - if ((sig == SIGINT || sig == SIGTERM) && !eloop.pending_terminate) { - /* Use SIGALRM to break out from potential busy loops that - * would not allow the program to be killed. */ - eloop.pending_terminate = 1; - signal(SIGALRM, eloop_handle_alarm); - alarm(2); - } -#endif /* CONFIG_NATIVE_WINDOWS */ - - eloop.signaled++; - for (i = 0; i < eloop.signal_count; i++) { - if (eloop.signals[i].sig == sig) { - eloop.signals[i].signaled++; - break; - } - } -} - - -static void eloop_process_pending_signals(void) -{ - int i; - - if (eloop.signaled == 0) - return; - eloop.signaled = 0; - - if (eloop.pending_terminate) { -#ifndef CONFIG_NATIVE_WINDOWS - alarm(0); -#endif /* CONFIG_NATIVE_WINDOWS */ - eloop.pending_terminate = 0; - } - - for (i = 0; i < eloop.signal_count; i++) { - if (eloop.signals[i].signaled) { - eloop.signals[i].signaled = 0; - eloop.signals[i].handler(eloop.signals[i].sig, - eloop.user_data, - eloop.signals[i].user_data); - } - } -} - - -int eloop_register_signal(int sig, eloop_signal_handler handler, - void *user_data) -{ - struct eloop_signal *tmp; - - tmp = (struct eloop_signal *) - os_realloc(eloop.signals, - (eloop.signal_count + 1) * - sizeof(struct eloop_signal)); - if (tmp == NULL) - return -1; - - tmp[eloop.signal_count].sig = sig; - tmp[eloop.signal_count].user_data = user_data; - tmp[eloop.signal_count].handler = handler; - tmp[eloop.signal_count].signaled = 0; - eloop.signal_count++; - eloop.signals = tmp; - signal(sig, eloop_handle_signal); - - return 0; -} - - -int eloop_register_signal_terminate(eloop_signal_handler handler, - void *user_data) -{ - int ret = eloop_register_signal(SIGINT, handler, user_data); - if (ret == 0) - ret = eloop_register_signal(SIGTERM, handler, user_data); - return ret; -} - - -int eloop_register_signal_reconfig(eloop_signal_handler handler, - void *user_data) -{ -#ifdef CONFIG_NATIVE_WINDOWS - return 0; -#else /* CONFIG_NATIVE_WINDOWS */ - return eloop_register_signal(SIGHUP, handler, user_data); -#endif /* CONFIG_NATIVE_WINDOWS */ -} - - -void eloop_run(void) -{ - fd_set *rfds, *wfds, *efds; - int res; - struct timeval _tv; - struct os_time tv, now; - - rfds = os_malloc(sizeof(*rfds)); - wfds = os_malloc(sizeof(*wfds)); - efds = os_malloc(sizeof(*efds)); - if (rfds == NULL || wfds == NULL || efds == NULL) { - printf("eloop_run - malloc failed\n"); - goto out; - } - - while (!eloop.terminate && - (eloop.timeout || eloop.readers.count > 0 || - eloop.writers.count > 0 || eloop.exceptions.count > 0)) { - if (eloop.timeout) { - os_get_time(&now); - if (os_time_before(&now, &eloop.timeout->time)) - os_time_sub(&eloop.timeout->time, &now, &tv); - else - tv.sec = tv.usec = 0; -#if 0 - printf("next timeout in %lu.%06lu sec\n", - tv.sec, tv.usec); -#endif - _tv.tv_sec = tv.sec; - _tv.tv_usec = tv.usec; - } - - eloop_sock_table_set_fds(&eloop.readers, rfds); - eloop_sock_table_set_fds(&eloop.writers, wfds); - eloop_sock_table_set_fds(&eloop.exceptions, efds); - res = select(eloop.max_sock + 1, rfds, wfds, efds, - eloop.timeout ? &_tv : NULL); - if (res < 0 && errno != EINTR && errno != 0) { - perror("select"); - goto out; - } - eloop_process_pending_signals(); - - /* check if some registered timeouts have occurred */ - if (eloop.timeout) { - struct eloop_timeout *tmp; - - os_get_time(&now); - if (!os_time_before(&now, &eloop.timeout->time)) { - tmp = eloop.timeout; - eloop.timeout = eloop.timeout->next; - tmp->handler(tmp->eloop_data, - tmp->user_data); - os_free(tmp); - } - - } - - if (res <= 0) - continue; - - eloop_sock_table_dispatch(&eloop.readers, rfds); - eloop_sock_table_dispatch(&eloop.writers, wfds); - eloop_sock_table_dispatch(&eloop.exceptions, efds); - } - -out: - os_free(rfds); - os_free(wfds); - os_free(efds); -} - - -void eloop_terminate(void) -{ - eloop.terminate = 1; -} - - -void eloop_destroy(void) -{ - struct eloop_timeout *timeout, *prev; - - timeout = eloop.timeout; - while (timeout != NULL) { - prev = timeout; - timeout = timeout->next; - os_free(prev); - } - eloop_sock_table_destroy(&eloop.readers); - eloop_sock_table_destroy(&eloop.writers); - eloop_sock_table_destroy(&eloop.exceptions); - os_free(eloop.signals); -} - - -int eloop_terminated(void) -{ - return eloop.terminate; -} - - -void eloop_wait_for_read_sock(int sock) -{ - fd_set rfds; - - if (sock < 0) - return; - - FD_ZERO(&rfds); - FD_SET(sock, &rfds); - select(sock + 1, &rfds, NULL, NULL, NULL); -} - - -void * eloop_get_user_data(void) -{ - return eloop.user_data; -} |