Hash :
6829a6c0
Author :
Date :
2011-04-25T10:38:33
Revert "use _GL_ATTRIBUTE_CONST and _GL_ATTRIBUTE_PURE" This reverts commit 349d7fe0e307d59d508b3579317ee8d4eacfeb9c. Revert accidentally-pushed patch. Not yet ready.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
/* sockets.c --- wrappers for Windows socket functions
Copyright (C) 2008-2011 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Written by Simon Josefsson */
#include <config.h>
/* Specification. */
#include "sockets.h"
#if WINDOWS_SOCKETS
/* This includes winsock2.h on MinGW. */
# include <sys/socket.h>
# include "fd-hook.h"
/* Get set_winsock_errno, FD_TO_SOCKET etc. */
# include "w32sock.h"
static int
close_fd_maybe_socket (const struct fd_hook *remaining_list,
gl_close_fn primary,
int fd)
{
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. */
/* FIXME: other applications, like squid, use an undocumented
_free_osfhnd free function. But this is not enough: The 'osfile'
flags for fd also needs to be cleared, but it is hard to access it.
Instead, here we just close twice the file descriptor. */
if (closesocket (sock))
{
set_winsock_errno ();
return -1;
}
else
{
/* This call frees the file descriptor and does a
CloseHandle ((HANDLE) _get_osfhandle (fd)), which fails. */
_close (fd);
return 0;
}
}
else
/* Some other type of file descriptor. */
return execute_close_hooks (remaining_list, primary, fd);
}
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 */;
#endif /* WINDOWS_SOCKETS */
int
gl_sockets_startup (int version _GL_UNUSED)
{
#if WINDOWS_SOCKETS
if (version > initialized_sockets_version)
{
WSADATA data;
int err;
err = WSAStartup (version, &data);
if (err != 0)
return 1;
if (data.wVersion < version)
return 2;
if (initialized_sockets_version == 0)
register_fd_hook (close_fd_maybe_socket, ioctl_fd_maybe_socket,
&fd_sockets_hook);
initialized_sockets_version = version;
}
#endif
return 0;
}
int
gl_sockets_cleanup (void)
{
#if WINDOWS_SOCKETS
int err;
initialized_sockets_version = 0;
unregister_fd_hook (&fd_sockets_hook);
err = WSACleanup ();
if (err != 0)
return 1;
#endif
return 0;
}