diff options
Diffstat (limited to '')
-rw-r--r-- | src/interface.c | 62 |
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; +} |