aboutsummaryrefslogtreecommitdiffstats
path: root/src/interface.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/interface.c62
1 files changed, 60 insertions, 2 deletions
diff --git a/src/interface.c b/src/interface.c
index 4220935ed..1e6fb4445 100644
--- a/src/interface.c
+++ b/src/interface.c
@@ -26,6 +26,7 @@
#include "permission.h"
#include "sllist.h"
#include "utils.h"
+#include "ioops.h"
#include <stdio.h>
#include <stdlib.h>
@@ -62,6 +63,9 @@ static size_t interface_max_command_list_size =
static size_t interface_max_output_buffer_size =
INTERFACE_MAX_OUTPUT_BUFFER_SIZE_DEFAULT;
+/* List of registered external IO handlers */
+static struct ioOps *ioList;
+
/* maybe make conf option for this, or... 32 might be good enough */
static long int interface_list_cache_size = 32;
@@ -488,6 +492,7 @@ int doIOForInterfaces(void)
{
fd_set rfds;
fd_set wfds;
+ fd_set efds;
struct timeval tv;
int i;
int selret;
@@ -499,12 +504,43 @@ int doIOForInterfaces(void)
while (1) {
fdmax = 0;
+ FD_ZERO( &rfds );
+ FD_ZERO( &wfds );
+ FD_ZERO( &efds );
addInterfacesReadyToReadAndListenSocketToFdSet(&rfds, &fdmax);
addInterfacesForBufferFlushToFdSet(&wfds, &fdmax);
- selret = select(fdmax + 1, &rfds, &wfds, NULL, &tv);
+ // Add fds for all registered IO handlers
+ if( ioList ) {
+ struct ioOps *i = ioList;
+ while( i ) {
+ struct ioOps *current = i;
+ int fdnum;
+ assert( current->fdset );
+ fdnum = current->fdset( &rfds, &wfds, &efds );
+ if( fdmax < fdnum )
+ fdmax = fdnum;
+ i = i->next;
+ }
+ }
+
+ selret = select(fdmax + 1, &rfds, &wfds, &efds, &tv);
+
+ if (selret < 0 && errno == EINTR)
+ break;
+
+ // Consume fds for all registered IO handlers
+ if( ioList ) {
+ struct ioOps *i = ioList;
+ while( i ) {
+ struct ioOps *current = i;
+ assert( current->consume );
+ selret = current->consume( selret, &rfds, &wfds, &efds );
+ i = i->next;
+ }
+ }
- if (selret == 0 || (selret < 0 && errno == EINTR))
+ if (selret == 0)
break;
if (selret < 0) {
@@ -794,3 +830,25 @@ static void printInterfaceOutBuffer(Interface * interface)
interface->send_buf_used = 0;
}
+
+// From ioops.h:
+void registerIO( struct ioOps *ops )
+{
+ assert( ops != NULL );
+
+ ops->next = ioList;
+ ioList = ops;
+ ops->prev = NULL;
+ if( ops->next )
+ ops->next->prev = ops;
+}
+
+void deregisterIO( struct ioOps *ops )
+{
+ assert( ops != NULL );
+
+ if( ioList == ops )
+ ioList = ops->next;
+ else if( ops->prev != NULL )
+ ops->prev->next = ops->next;
+}