--- 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__ */