--- a/acpid.c +++ a/acpid.c @@ -456,6 +456,7 @@ void clean_exit_with_status(int status) { acpid_cleanup_rules(1); + delete_all_connections(); acpid_log(LOG_NOTICE, "exiting"); unlink(pidfile); exit(status); --- a/connection_list.c +++ a/connection_list.c @@ -35,9 +35,9 @@ /*---------------------------------------------------------------*/ /* private objects */ -#define MAX_CONNECTIONS 20 +static int capacity = 0; -static struct connection connection_list[MAX_CONNECTIONS]; +static struct connection *connection_list = NULL; static int nconnections = 0; @@ -56,12 +56,20 @@ add_connection(struct connection *p) { if (nconnections < 0) return; - if (nconnections >= MAX_CONNECTIONS) { - acpid_log(LOG_ERR, "Too many connections."); - /* ??? This routine should return -1 in this situation so that */ - /* callers can clean up any open fds and whatnot. */ - return; - } + + /* if the list is full, allocate more space */ + if (nconnections >= capacity) { + /* no more than 1024 */ + if (capacity > 1024) { + acpid_log(LOG_ERR, "Too many connections."); + return; + } + + /* another 20 */ + capacity += 20; + connection_list = + realloc(connection_list, sizeof(struct connection) * capacity); + } if (nconnections == 0) FD_ZERO(&allfds); @@ -82,7 +89,9 @@ delete_connection(int fd) { int i; - close(fd); + /* close anything other than stdin/stdout/stderr */ + if (fd > 2) + close(fd); /* remove from the fd set */ FD_CLR(fd, &allfds); @@ -110,6 +119,21 @@ delete_connection(int fd) /*---------------------------------------------------------------*/ +void +delete_all_connections(void) +{ + /* while there are still connections to delete */ + while (nconnections) { + /* delete the connection at the end of the list */ + delete_connection(connection_list[nconnections-1].fd); + } + + free(connection_list); + connection_list = NULL; +} + +/*---------------------------------------------------------------*/ + struct connection * find_connection(int fd) { --- a/connection_list.h +++ a/connection_list.h @@ -75,4 +75,7 @@ extern const fd_set *get_fdset(void); /* get the highest fd that was added to the list */ extern int get_highestfd(void); +/* delete all connections, closing the fds */ +extern void delete_all_connections(void); + #endif /* CONNECTION_LIST_H__ */