#undef DEBUG
static guint32 startup_count=0;
-static GPtrArray *sockets=NULL;
static pthread_key_t error_key;
static mono_once_t error_key_once=MONO_ONCE_INIT;
-static void socket_close (gpointer handle);
+static void socket_close (gpointer handle, gpointer data);
struct _WapiHandleOps _wapi_socket_ops = {
socket_close, /* close */
/* No capabilities to register */
}
-static void socket_close (gpointer handle)
+static void socket_close (gpointer handle, gpointer data G_GNUC_UNUSED)
{
int ret;
return;
}
- g_ptr_array_remove_fast (sockets, handle);
-
do {
ret = close (GPOINTER_TO_UINT(handle));
} while (ret == -1 && errno == EINTR &&
return(WSAVERNOTSUPPORTED);
}
- if (startup_count == 0) {
- sockets = g_ptr_array_new();
- }
-
startup_count++;
/* I've no idea what is the minor version of the spec I read */
return(0);
}
+static gboolean
+cleanup_close (gpointer handle, gpointer data)
+{
+ _wapi_handle_ops_close (handle, NULL);
+ return TRUE;
+}
+
int WSACleanup(void)
{
- guint32 i;
-
#ifdef DEBUG
g_message ("%s: cleaning up", __func__);
#endif
/* Do nothing */
return(0);
}
-
- /* Close down all sockets */
- for (i = 0; i < sockets->len; i++) {
- gpointer handle;
-
- handle = g_ptr_array_index (sockets, i);
- _wapi_handle_ops_close (handle);
- }
- g_ptr_array_free (sockets, FALSE);
- sockets = NULL;
-
+ _wapi_handle_foreach (WAPI_HANDLE_SOCKET, cleanup_close, NULL);
return(0);
}
return(INVALID_SOCKET);
}
- g_ptr_array_add (sockets, new_handle);
-
#ifdef DEBUG
g_message ("%s: returning newly accepted socket handle %p with",
__func__, new_handle);
{
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
-
+ struct timeval tv;
+ void *tmp_val;
+
if (startup_count == 0) {
WSASetLastError (WSANOTINITIALISED);
return(SOCKET_ERROR);
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
-
- ret = getsockopt (fd, level, optname, optval, optlen);
+
+ tmp_val = optval;
+ if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) {
+ tmp_val = &tv;
+ *optlen = sizeof (tv);
+ }
+
+ ret = getsockopt (fd, level, optname, tmp_val, optlen);
if (ret == -1) {
gint errnum = errno;
#ifdef DEBUG
return(SOCKET_ERROR);
}
+
+ if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) {
+ *((int *) optval) = tv.tv_sec * 1000 + tv.tv_usec;
+ *optlen = sizeof (int);
+ }
return(ret);
}
{
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
+ const void *tmp_val;
+ struct timeval tv;
if (startup_count == 0) {
WSASetLastError (WSANOTINITIALISED);
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
-
- ret = setsockopt (fd, level, optname, optval, optlen);
+
+ tmp_val = optval;
+ if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) {
+ int ms = *((int *) optval);
+ tv.tv_sec = ms / 1000;
+ tv.tv_usec = ms % 1000;
+ tmp_val = &tv;
+ optlen = sizeof (tv);
+ }
+
+ ret = setsockopt (fd, level, optname, tmp_val, optlen);
if (ret == -1) {
gint errnum = errno;
#ifdef DEBUG
return(INVALID_SOCKET);
}
- g_ptr_array_add (sockets, handle);
-
#ifdef DEBUG
g_message ("%s: returning socket handle %p", __func__, handle);
#endif