Standardized Mainsoft ConstraintCollection tests.
[mono.git] / mono / io-layer / sockets.c
index 59855ef49618cd2224fa16339e41fa2ad4c7b497..b2cf55faf211c4398f153bba7e86636c7d907b4a 100644 (file)
 #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 */
@@ -57,7 +56,7 @@ static void socket_ops_init (void)
        /* No capabilities to register */
 }
 
-static void socket_close (gpointer handle)
+static void socket_close (gpointer handle, gpointer data G_GNUC_UNUSED)
 {
        int ret;
 
@@ -70,8 +69,6 @@ static void socket_close (gpointer handle)
                return;
        }
 
-       g_ptr_array_remove_fast (sockets, handle);
-
        do {
                ret = close (GPOINTER_TO_UINT(handle));
        } while (ret == -1 && errno == EINTR &&
@@ -98,10 +95,6 @@ int WSAStartup(guint32 requested, WapiWSAData *data)
                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 */
@@ -120,10 +113,15 @@ int WSAStartup(guint32 requested, WapiWSAData *data)
        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
@@ -132,18 +130,8 @@ int WSACleanup(void)
                /* 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);
 }
 
@@ -241,8 +229,6 @@ guint32 _wapi_accept(guint32 fd, struct sockaddr *addr, socklen_t *addrlen)
                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);
@@ -406,7 +392,9 @@ int _wapi_getsockopt(guint32 fd, int level, int optname, void *optval,
 {
        gpointer handle = GUINT_TO_POINTER (fd);
        int ret;
-       
+       struct timeval tv;
+       void *tmp_val;
+
        if (startup_count == 0) {
                WSASetLastError (WSANOTINITIALISED);
                return(SOCKET_ERROR);
@@ -416,8 +404,14 @@ int _wapi_getsockopt(guint32 fd, int level, int optname, void *optval,
                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
@@ -430,6 +424,11 @@ int _wapi_getsockopt(guint32 fd, int level, int optname, void *optval,
                
                return(SOCKET_ERROR);
        }
+
+       if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) {
+               *((int *) optval)  = tv.tv_sec * 1000 + tv.tv_usec;
+               *optlen = sizeof (int);
+       }
        
        return(ret);
 }
@@ -615,6 +614,8 @@ int _wapi_setsockopt(guint32 fd, int level, int optname,
 {
        gpointer handle = GUINT_TO_POINTER (fd);
        int ret;
+       const void *tmp_val;
+       struct timeval tv;
        
        if (startup_count == 0) {
                WSASetLastError (WSANOTINITIALISED);
@@ -625,8 +626,17 @@ int _wapi_setsockopt(guint32 fd, int level, int optname,
                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
@@ -719,8 +729,6 @@ guint32 _wapi_socket(int domain, int type, int protocol, void *unused,
                return(INVALID_SOCKET);
        }
 
-       g_ptr_array_add (sockets, handle);
-
 #ifdef DEBUG
        g_message ("%s: returning socket handle %p", __func__, handle);
 #endif