diff --git a/library/changes b/library/changes index e670397..4a42668 100644 --- a/library/changes +++ b/library/changes @@ -28,6 +28,10 @@ and address resolution errors trash the 'errno' variable instead and leaving 'h_errno' always set to 0. Fixed. +- For sockets, ioctl() and fcntl() now interact on the FIONBIO/FIOASYNC + requests (ioctl) and the O_NOBLOCK/O_ASYNC flags (fcntl). + + c.lib 1.183 (13.11.2004) diff --git a/library/fcntl_fcntl.c b/library/fcntl_fcntl.c index e8a225f..636acc3 100644 --- a/library/fcntl_fcntl.c +++ b/library/fcntl_fcntl.c @@ -1,5 +1,5 @@ /* - * $Id: fcntl_fcntl.c,v 1.2 2004-08-07 09:15:32 obarthel Exp $ + * $Id: fcntl_fcntl.c,v 1.3 2004-11-27 12:43:11 obarthel Exp $ * * :ts=4 * @@ -126,10 +126,13 @@ fcntl(int file_descriptor, int cmd, ... /* int arg */ ) SHOWMSG("cmd=F_GETFL"); + result = 0; + if(FLAG_IS_SET(fd->fd_Flags,FDF_NON_BLOCKING)) - result = O_NONBLOCK; - else - result = 0; + SET_FLAG(result,O_NONBLOCK); + + if(FLAG_IS_SET(fd->fd_Flags,FDF_ASYNC_IO)) + SET_FLAG(result,O_ASYNC); break; @@ -168,6 +171,31 @@ fcntl(int file_descriptor, int cmd, ... /* int arg */ ) CLEAR_FLAG(fd->fd_Flags,FDF_NON_BLOCKING); } + if((FLAG_IS_SET(flags,O_ASYNC) && FLAG_IS_CLEAR(fd->fd_Flags,FDF_ASYNC_IO)) || + (FLAG_IS_CLEAR(flags,O_ASYNC) && FLAG_IS_SET(fd->fd_Flags,FDF_ASYNC_IO))) + { + message.action = file_hook_action_set_async; + message.block = FLAG_IS_SET(flags,O_ASYNC); + + assert( fd->fd_Hook != NULL ); + + CallHookPkt(fd->fd_Hook,fd,&message); + + result = message.result; + if(result < 0) + { + errno = message.error; + + va_end(arg); + goto out; + } + + if(FLAG_IS_SET(flags,O_ASYNC)) + SET_FLAG(fd->fd_Flags,FDF_ASYNC_IO); + else + CLEAR_FLAG(fd->fd_Flags,FDF_ASYNC_IO); + } + va_end(arg); break; diff --git a/library/include/fcntl.h b/library/include/fcntl.h index f49a59d..8bdf589 100644 --- a/library/include/fcntl.h +++ b/library/include/fcntl.h @@ -1,5 +1,5 @@ /* - * $Id: fcntl.h,v 1.2 2004-08-07 09:15:33 obarthel Exp $ + * $Id: fcntl.h,v 1.3 2004-11-27 12:43:12 obarthel Exp $ * * :ts=4 * @@ -67,6 +67,7 @@ extern "C" { #define O_NONBLOCK (1<<6) #define O_SYNC (0) #define O_NOCTTY (0) +#define O_ASYNC (1<<7) /****************************************************************************/ diff --git a/library/socket_hook_entry.c b/library/socket_hook_entry.c index 3eb198b..dcced5d 100644 --- a/library/socket_hook_entry.c +++ b/library/socket_hook_entry.c @@ -1,5 +1,5 @@ /* - * $Id: socket_hook_entry.c,v 1.1.1.1 2004-07-26 16:31:14 obarthel Exp $ + * $Id: socket_hook_entry.c,v 1.2 2004-11-27 12:43:11 obarthel Exp $ * * :ts=4 * @@ -41,6 +41,10 @@ /****************************************************************************/ +#include + +/****************************************************************************/ + void __socket_hook_entry( struct Hook * UNUSED unused_hook, @@ -49,6 +53,7 @@ __socket_hook_entry( { struct FileInfoBlock * fib; int error = OK; + int param; int result; assert( message != NULL && fd != NULL ); @@ -129,6 +134,28 @@ __socket_hook_entry( break; + case file_hook_action_set_blocking: + + SHOWMSG("file_hook_action_set_blocking"); + + param = (int)(message->block == 0); + + result = __IoctlSocket(fd->fd_DefaultFile,FIONBIO,¶m); + error = errno; + + break; + + case file_hook_action_set_async: + + SHOWMSG("file_hook_action_set_async"); + + param = (int)(message->block != 0); + + result = __IoctlSocket(fd->fd_DefaultFile,FIOASYNC,¶m); + error = errno; + + break; + case file_hook_action_examine: SHOWMSG("file_hook_action_examine"); diff --git a/library/socket_ioctl.c b/library/socket_ioctl.c index fa0abd6..03c4951 100644 --- a/library/socket_ioctl.c +++ b/library/socket_ioctl.c @@ -1,5 +1,5 @@ /* - * $Id: socket_ioctl.c,v 1.1.1.1 2004-07-26 16:31:16 obarthel Exp $ + * $Id: socket_ioctl.c,v 1.2 2004-11-27 12:43:11 obarthel Exp $ * * :ts=4 * @@ -47,6 +47,10 @@ /****************************************************************************/ +#include + +/****************************************************************************/ + int ioctl(int sockfd,unsigned long request, ... /* char *arg */) { @@ -81,6 +85,26 @@ ioctl(int sockfd,unsigned long request, ... /* char *arg */) result = __IoctlSocket((LONG)fd->fd_DefaultFile,request,param); PROFILE_ON(); + if(result == OK) + { + int * arg = (int *)param; + + if(request == FIONBIO) + { + if((*arg) != 0) + SET_FLAG(fd->fd_Flags,FDF_NON_BLOCKING); + else + CLEAR_FLAG(fd->fd_Flags,FDF_NON_BLOCKING); + } + else if (request == FIOASYNC) + { + if((*arg) != 0) + SET_FLAG(fd->fd_Flags,FDF_ASYNC_IO); + else + CLEAR_FLAG(fd->fd_Flags,FDF_ASYNC_IO); + } + } + va_end(arg); out: diff --git a/library/stdio_headers.h b/library/stdio_headers.h index f39120e..f795a55 100644 --- a/library/stdio_headers.h +++ b/library/stdio_headers.h @@ -1,5 +1,5 @@ /* - * $Id: stdio_headers.h,v 1.3 2004-11-14 11:06:27 obarthel Exp $ + * $Id: stdio_headers.h,v 1.4 2004-11-27 12:43:11 obarthel Exp $ * * :ts=4 * @@ -252,6 +252,8 @@ struct iob to have its protection bits updated after it has been closed */ #define FDF_CACHE_POSITION (1UL<<9) /* Cache the file position. */ +#define FDF_ASYNC_IO (1UL<<10) /* File was switched into asynchronous I/O + mode (sockets only). */ /****************************************************************************/ @@ -306,7 +308,8 @@ enum file_hook_action_t file_hook_action_info, file_hook_action_duplicate_fd, file_hook_action_seek_and_extend, - file_hook_action_is_interactive + file_hook_action_is_interactive, + file_hook_action_set_async }; /****************************************************************************/