/* * Generic async UNIX file IO handling * * Copyright 1996,1997 Alex Korobka * Copyright 1998 Marcus Meissner */ /* * This file handles asynchronous signaling for UNIX filedescriptors. * The passed handler gets called when input arrived for the filedescriptor. * * This is done either by the kernel or (in the WINSOCK case) by the pipe * handler, since pipes do not support asynchronous signaling. * (Not all possible filedescriptors support async IO. Generic files do not * for instance, sockets do, ptys don't.) * * To make this a bit better, we would need an additional thread doing select() */ #include #include #include #include #include #include #include #include #ifdef HAVE_SYS_PARAM_H # include #endif #ifdef HAVE_SYS_FILIO_H # include #endif #ifdef HAVE_SYS_FILE_H # include #endif #include "xmalloc.h" #include "windef.h" #include "miscemu.h" #include "selectors.h" #include "sig_context.h" #include "async.h" #include "debug.h" typedef struct _async_fd { int unixfd; void (*handler)(int fd,void *private); void *private; } ASYNC_FD; static ASYNC_FD *asyncfds = NULL; static int nrofasyncfds = 0; /*************************************************************************** * ASYNC_sigio [internal] * * Signal handler for asynchronous IO. * * Note: This handler and the function it calls may not block. Neither they * are allowed to use blocking IO (write/read). No memory management. * No possible blocking synchronization of any kind. */ HANDLER_DEF(ASYNC_sigio) { struct timeval timeout; fd_set rset,wset; int i,maxfd=0; HANDLER_INIT(); if (!nrofasyncfds) return; FD_ZERO(&rset); FD_ZERO(&wset); for (i=nrofasyncfds;i--;) { if (asyncfds[i].unixfd == -1) continue; FD_SET(asyncfds[i].unixfd,&rset); FD_SET(asyncfds[i].unixfd,&wset); if (maxfd"); #endif #ifdef FASYNC if (-1==fcntl(unixfd,F_GETFL,&flags)) { perror("fcntl F_GETFL"); return FALSE; } if (async) flags|=FASYNC; else flags&=~FASYNC; if (-1==fcntl(unixfd,F_SETFL,&flags)) { perror("fcntl F_SETFL FASYNC"); return FALSE; } return TRUE; #else return FALSE; #endif } /*************************************************************************** * ASYNC_RegisterFD [internal] * * Register a UNIX filedescriptor with handler and private data pointer. * this function is _NOT_ safe to be called from a signal handler. * * Additional Constraint: The handler passed to this function _MUST_ adhere * to the same signalsafeness as ASYNC_sigio itself. (nonblocking, no thread/ * signal unsafe operations, no blocking synchronization) */ void ASYNC_RegisterFD(int unixfd,void (*handler)(int fd,void *private),void *private) { int i; SIGNAL_MaskAsyncEvents( TRUE ); for (i=0;i