summaryrefslogtreecommitdiffstats
path: root/control.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2009-01-12 16:39:01 +0000
committerRoy Marples <roy@marples.name>2009-01-12 16:39:01 +0000
commite467f4b21724ad4c3c9f7a3ee9af91c4385a8a88 (patch)
tree8337a6a5ba3d2bb2a4db5f23a2831fe32de2b0e4 /control.c
parente0c05611c032b8a1e75a11aa8bdbfecf34acf785 (diff)
downloaddhcpcd-e467f4b21724ad4c3c9f7a3ee9af91c4385a8a88.tar.xz
Remove the limit for the number of connections to the control socket.
Send the dhcpcd-run-hooks enviornment to listeners on the control socket.
Diffstat (limited to 'control.c')
-rw-r--r--control.c91
1 files changed, 52 insertions, 39 deletions
diff --git a/control.c b/control.c
index 185638ff..75120826 100644
--- a/control.c
+++ b/control.c
@@ -36,56 +36,61 @@
#include "config.h"
#include "common.h"
+#include "dhcpcd.h"
#include "control.h"
#include "eloop.h"
-#include "dhcpcd.h"
static int fd = -1;
struct sockaddr_un sun;
static char buffer[1024];
static char *argvp[255];
-static int fds[5];
+struct fd_list *fds = NULL;
static void
remove_control_data(void *arg)
{
- size_t i;
-
- for (i = 0; i < sizeof(fds); i++) {
- if (&fds[i] == arg) {
- close(fds[i]);
- delete_event(fds[i]);
- fds[i] = -1;
+ struct fd_list *l, *last = NULL;
+
+ for (l = fds; l != NULL; l = l->next) {
+ if (l == arg) {
+ close(l->fd);
+ delete_event(l->fd);
+ if (last == NULL)
+ fds = l->next;
+ else
+ last->next = l->next;
+ free(l);
+ break;
}
+ last = l;
}
}
static void
handle_control_data(void *arg)
{
+ struct fd_list *l = arg;
ssize_t bytes;
- int argc, *s = arg;
+ int argc;
char *e, *p;
char **ap;
- for (;;) {
- bytes = read(*s, buffer, sizeof(buffer));
- if (bytes == -1 || bytes == 0) {
- remove_control_data(arg);
- return;
- }
- p = buffer;
- e = buffer + bytes;
- argc = 0;
- ap = argvp;
- while (p < e && (size_t)argc < sizeof(argvp)) {
- argc++;
- *ap++ = p;
- p += strlen(p) + 1;
- }
- handle_args(*s, argc, argvp);
+ bytes = read(l->fd, buffer, sizeof(buffer));
+ if (bytes == -1 || bytes == 0) {
+ remove_control_data(l);
+ return;
}
+ p = buffer;
+ e = buffer + bytes;
+ argc = 0;
+ ap = argvp;
+ while (p < e && (size_t)argc < sizeof(argvp)) {
+ argc++;
+ *ap++ = p;
+ p += strlen(p) + 1;
+ }
+ handle_args(l, argc, argvp);
}
/* ARGSUSED */
@@ -94,21 +99,18 @@ handle_control(_unused void *arg)
{
struct sockaddr_un run;
socklen_t len;
- size_t i;
-
- for (i = 0; i < sizeof(fds); i++) {
- if (fds[i] == -1)
- break;
- }
- if (i >= sizeof(fds))
- return;
+ struct fd_list *l;
+ int f;
len = sizeof(run);
- if ((fds[i] = accept(fd, (struct sockaddr *)&run, &len)) == -1)
+ if ((f = accept(fd, (struct sockaddr *)&run, &len)) == -1)
return;
- add_event(fds[i], handle_control_data, &fds[i]);
- /* Timeout the connection after 5 minutes - should be plenty */
- add_timeout_sec(300, remove_control_data, &fds[i]);
+ l = xmalloc(sizeof(*l));
+ l->fd = f;
+ l->listener = 0;
+ l->next = fds;
+ fds = l;
+ add_event(l->fd, handle_control_data, l);
}
static int
@@ -139,7 +141,6 @@ start_control(void)
close(fd);
return -1;
}
- memset(fds, -1, sizeof(fds));
add_event(fd, handle_control, NULL);
return fd;
}
@@ -148,10 +149,22 @@ int
stop_control(void)
{
int retval = 0;
+ struct fd_list *l, *ll;
+
+ delete_event(fd);
if (close(fd) == -1)
retval = 1;
+ fd = -1;
if (unlink(CONTROLSOCKET) == -1)
retval = -1;
+ l = fds;
+ while (l != NULL) {
+ ll = l->next;
+ delete_event(l->fd);
+ close(l->fd);
+ free(l);
+ l = ll;
+ }
return retval;
}