aboutsummaryrefslogtreecommitdiff
path: root/src/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/socket.c')
-rw-r--r--src/socket.c106
1 files changed, 96 insertions, 10 deletions
diff --git a/src/socket.c b/src/socket.c
index e32701f..fdce7d1 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -395,17 +395,101 @@ pass_fd (const char *socket_name, int fd, unsigned maxtime)
fd_set listenset;
int fd_max;
+struct sockinst
+{
+ struct sockinst *prev, *next;
+ int fd;
+ int (*handler) (int, void *);
+ void *data;
+};
+
+struct sockinst *si_head, *si_tail;
+
+static struct sockinst *
+find_socket (int fd)
+{
+ struct sockinst *sp;
+
+ for (sp = si_head; sp; sp = sp->next)
+ if (sp->fd == fd)
+ break;
+ return sp;
+}
+
+struct sockinst *
+find_socket_handler (int (*handler) (int, void *))
+{
+ struct sockinst *sp;
+
+ for (sp = si_head; sp; sp = sp->next)
+ if (sp->handler == handler)
+ break;
+ return sp;
+}
+
+static int
+calc_fd_max ()
+{
+ struct sockinst *sp;
+
+ fd_max = -1;
+ for (sp = si_head; sp; sp = sp->next)
+ if (sp->fd > fd_max)
+ fd_max = sp->fd;
+}
+
+void *
+register_socket (int fd, int (*handler) (int, void *), void *data)
+{
+ struct sockinst *sip = xmalloc (sizeof *sip);
+ sip->fd = fd;
+ sip->handler = handler;
+ sip->data = data;
+ sip->next = NULL;
+ sip->prev = si_tail;
+ if (si_tail)
+ si_tail->next = sip;
+ else
+ si_head = sip;
+ si_tail = sip;
+ FD_SET (fd, &listenset);
+ if (fd_max == -1)
+ calc_fd_max ();
+ else if (fd > fd_max)
+ fd_max = fd;
+ return sip;
+}
+
+void
+deregister_socket (int fd)
+{
+ struct sockinst *sp = find_socket (fd);
+
+ if (!sp)
+ return;
+ if (sp->prev)
+ sp->prev->next = sp->next;
+ else
+ si_head = sp->next;
+ if (sp->next)
+ sp->next->prev = sp->prev;
+ else
+ si_tail = sp->prev;
+ free (sp);
+ FD_CLR (fd, &listenset);
+ fd_max = -1;
+}
+
+
int
-register_socket (int socktype, int fd)
+register_program_socket (int socktype, int fd, void *data)
{
if (socktype == SOCK_STREAM && listen (fd, 8) == -1)
{
logmsg (LOG_ERR, "listen: %s", strerror (errno));
return 1;
}
- FD_SET (fd, &listenset);
- if (fd > fd_max)
- fd_max = fd;
+ register_socket (fd, progman_accept, data);
return 0;
}
@@ -430,18 +514,20 @@ enable_socket (int fd)
void
pies_pause ()
{
+ if (fd_max == -1)
+ calc_fd_max ();
+
while (1)
{
fd_set rdset = listenset;
int rc = select (fd_max + 1, &rdset, NULL, NULL, NULL);
if (rc > 0)
{
- int i;
- for (i = 0; i <= fd_max; i++)
- {
- if (FD_ISSET (i, &rdset))
- progman_accept (i);
- }
+ struct sockinst *sp;
+
+ for (sp = si_head; sp; sp = sp->next)
+ if (FD_ISSET (sp->fd, &rdset))
+ sp->handler (sp->fd, sp->data);
break;
}
else if (rc < 0)

Return to:

Send suggestions and report system problems to the System administrator.