summaryrefslogtreecommitdiff
path: root/lib/sockets.c
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2011-04-18 02:34:47 +0200
committerBruno Haible <bruno@clisp.org>2011-04-19 12:07:33 +0200
commit6110d07dee40692d43f2ef8884230e0d53c56548 (patch)
treec9ad90ba1bc0bacbdf4a8a7c5e7181b04628f165 /lib/sockets.c
parent12856373f8fd28a9d4453d6df97b2fdd17ced398 (diff)
downloadgnulib-6110d07dee40692d43f2ef8884230e0d53c56548.tar.gz
ioctl: Remove link dependency on native Windows.
* lib/fd-hook.h: Renamed from lib/close-hook.h. (gl_close_fn, gl_ioctl_fn): New types. (struct fd_hook): Renamed from struct close_hook. Change type of private_close_fn field. Add private_ioctl_fn field. (close_hook_fn): Add parameter for primary close method. (execute_close_hooks, execute_all_close_hooks): Likewise. (ioctl_hook_fn): New type. (execute_ioctl_hooks, execute_all_ioctl_hooks): New declarations. (register_fd_hook): Renamed from register_close_hook. Add ioctl_hook argument. (unregister_fd_hook): Renamed from unregister_close_hook. * lib/fd-hook.c: Renamed from lib/close-hook.c. Don't include <unistd.h>. (close): Remove undef. (anchor): Update. (execute_close_hooks): Add argument for primary close method. (execute_all_close_hooks): Likewise. (execute_ioctl_hooks, execute_all_ioctl_hooks): New functions. (register_fd_hook): Renamed from register_close_hook. Add ioctl_hook argument. Allow each argument to be NULL. (unregister_fd_hook): Renamed from unregister_close_hook. * lib/close.c (rpl_close): Pass 'close' function pointer to execute_all_close_hooks. * lib/ioctl.c: Include <errno.h>, fd-hook.h. (primary_ioctl): New function. (ioctl): Don't call ioctlsocket here. Instead, call execute_all_ioctl_hooks. * lib/sockets.c (close_fd_maybe_socket): Add argument for primary close method. (ioctl_fd_maybe_socket): New function, with code from lib/ioctl.c. (fd_sockets_hook): Renamed from close_sockets_hook. (gl_sockets_startup, gl_sockets_cleanup): Update. * modules/fd-hook: Renamed from modules/close-hook. Update. * modules/close (Depends-on): Add fd-hook, remove close-hook. * modules/sockets (Depends-on): Likewise. * modules/ioctl (Depends-on): Add fd-hook. * tests/test-nonblocking.c (main): Use GNULIB_TEST_SOCKET, not GNULIB_SOCKET.
Diffstat (limited to 'lib/sockets.c')
-rw-r--r--lib/sockets.c43
1 files changed, 37 insertions, 6 deletions
diff --git a/lib/sockets.c b/lib/sockets.c
index 4e905e1ddd..42b8f9ea58 100644
--- a/lib/sockets.c
+++ b/lib/sockets.c
@@ -27,13 +27,15 @@
/* This includes winsock2.h on MinGW. */
# include <sys/socket.h>
-# include "close-hook.h"
+# include "fd-hook.h"
/* Get set_winsock_errno, FD_TO_SOCKET etc. */
# include "w32sock.h"
static int
-close_fd_maybe_socket (int fd, const struct close_hook *remaining_list)
+close_fd_maybe_socket (const struct fd_hook *remaining_list,
+ gl_close_fn primary,
+ int fd)
{
SOCKET sock;
WSANETWORKEVENTS ev;
@@ -64,10 +66,38 @@ close_fd_maybe_socket (int fd, const struct close_hook *remaining_list)
}
else
/* Some other type of file descriptor. */
- return execute_close_hooks (fd, remaining_list);
+ return execute_close_hooks (remaining_list, primary, fd);
}
-static struct close_hook close_sockets_hook;
+static int
+ioctl_fd_maybe_socket (const struct fd_hook *remaining_list,
+ gl_ioctl_fn primary,
+ int fd, int request, void *arg)
+{
+ SOCKET sock;
+ WSANETWORKEVENTS ev;
+
+ /* Test whether fd refers to a socket. */
+ sock = FD_TO_SOCKET (fd);
+ ev.lNetworkEvents = 0xDEADBEEF;
+ WSAEnumNetworkEvents (sock, NULL, &ev);
+ if (ev.lNetworkEvents != 0xDEADBEEF)
+ {
+ /* fd refers to a socket. */
+ if (ioctlsocket (sock, request, arg) < 0)
+ {
+ set_winsock_errno ();
+ return -1;
+ }
+ else
+ return 0;
+ }
+ else
+ /* Some other type of file descriptor. */
+ return execute_ioctl_hooks (remaining_list, primary, fd, request, arg);
+}
+
+static struct fd_hook fd_sockets_hook;
static int initialized_sockets_version /* = 0 */;
@@ -90,7 +120,8 @@ gl_sockets_startup (int version _GL_UNUSED)
return 2;
if (initialized_sockets_version == 0)
- register_close_hook (close_fd_maybe_socket, &close_sockets_hook);
+ register_fd_hook (close_fd_maybe_socket, ioctl_fd_maybe_socket,
+ &fd_sockets_hook);
initialized_sockets_version = version;
}
@@ -107,7 +138,7 @@ gl_sockets_cleanup (void)
initialized_sockets_version = 0;
- unregister_close_hook (&close_sockets_hook);
+ unregister_fd_hook (&fd_sockets_hook);
err = WSACleanup ();
if (err != 0)