Merge pull request #3528 from BrzVlad/fix-sgen-check-before-collections
[mono.git] / mono / metadata / socket-io.c
index 95bac2301bd8b5f9d0dc20e5adb70b777ebf1faf..d4d168da76691a76c3f041b40cf2c45dde95d775 100644 (file)
@@ -62,6 +62,7 @@
 #include <mono/utils/mono-threads.h>
 #include <mono/utils/mono-memory-model.h>
 #include <mono/utils/networking.h>
+#include <mono/utils/w32handle.h>
 
 #include <time.h>
 #ifdef HAVE_SYS_TIME_H
@@ -773,16 +774,15 @@ ves_icall_System_Net_Sockets_Socket_Accept_internal (SOCKET sock, gint32 *werror
 
        MONO_EXIT_GC_SAFE;
 
+       if (newsock == INVALID_SOCKET)
+               *werror = WSAGetLastError ();
+
        mono_thread_info_uninstall_interrupt (&interrupted);
-       if (interrupted) {
+       if (interrupted)
                *werror = WSAEINTR;
-               return NULL;
-       }
 
-       if (newsock == INVALID_SOCKET) {
-               *werror = WSAGetLastError ();
+       if (*werror)
                return NULL;
-       }
        
        return GUINT_TO_POINTER (newsock);
 }
@@ -1335,15 +1335,13 @@ ves_icall_System_Net_Sockets_Socket_Connect_internal (SOCKET sock, MonoObject *s
 
        MONO_EXIT_GC_SAFE;
 
-       mono_thread_info_uninstall_interrupt (&interrupted);
-       if (interrupted) {
-               *werror = WSAEINTR;
-               return;
-       }
-
        if (ret == SOCKET_ERROR)
                *werror = WSAGetLastError ();
 
+       mono_thread_info_uninstall_interrupt (&interrupted);
+       if (interrupted)
+               *werror = WSAEINTR;
+
        g_free (sa);
 }
 
@@ -1422,10 +1420,10 @@ ves_icall_System_Net_Sockets_Socket_Disconnect_internal (SOCKET sock, MonoBoolea
        MONO_ENTER_GC_SAFE;
 
        if (_wapi_disconnectex != NULL) {
-               if (!_wapi_disconnectex (sock, NULL, TF_REUSE_SOCKET, 0))
+               if (!_wapi_disconnectex (sock, NULL, reuse ? TF_REUSE_SOCKET : 0, 0))
                        *werror = WSAGetLastError ();
        } else if (_wapi_transmitfile != NULL) {
-               if (!_wapi_transmitfile (sock, NULL, 0, 0, NULL, NULL, TF_DISCONNECT | TF_REUSE_SOCKET))
+               if (!_wapi_transmitfile (sock, NULL, 0, 0, NULL, NULL, TF_DISCONNECT | (reuse ? TF_REUSE_SOCKET : 0)))
                        *werror = WSAGetLastError ();
        } else {
                *werror = ERROR_NOT_SUPPORTED;
@@ -1480,16 +1478,15 @@ ves_icall_System_Net_Sockets_Socket_Receive_internal (SOCKET sock, MonoArray *bu
 
        MONO_EXIT_GC_SAFE;
 
+       if (ret == SOCKET_ERROR)
+               *werror = WSAGetLastError ();
+
        mono_thread_info_uninstall_interrupt (&interrupted);
-       if (interrupted) {
+       if (interrupted)
                *werror = WSAEINTR;
-               return 0;
-       }
 
-       if (ret == SOCKET_ERROR) {
-               *werror = WSAGetLastError ();
+       if (*werror)
                return 0;
-       }
 
        return ret;
 }
@@ -1526,16 +1523,15 @@ ves_icall_System_Net_Sockets_Socket_Receive_array_internal (SOCKET sock, MonoArr
 
        MONO_EXIT_GC_SAFE;
 
+       if (ret == SOCKET_ERROR)
+               *werror = WSAGetLastError ();
+
        mono_thread_info_uninstall_interrupt (&interrupted);
-       if (interrupted) {
+       if (interrupted)
                *werror = WSAEINTR;
-               return 0;
-       }
 
-       if (ret == SOCKET_ERROR) {
-               *werror = WSAGetLastError ();
+       if (*werror)
                return 0;
-       }
 
        return recv;
 }
@@ -1587,16 +1583,16 @@ ves_icall_System_Net_Sockets_Socket_ReceiveFrom_internal (SOCKET sock, MonoArray
 
        MONO_EXIT_GC_SAFE;
 
+       if (ret == SOCKET_ERROR)
+               *werror = WSAGetLastError ();
+
        mono_thread_info_uninstall_interrupt (&interrupted);
-       if (interrupted) {
-               g_free (sa);
+
+       if (interrupted)
                *werror = WSAEINTR;
-               return 0;
-       }
 
-       if (ret==SOCKET_ERROR) {
-               g_free (sa);
-               *werror = WSAGetLastError ();
+       if (*werror) {
+               g_free(sa);
                return 0;
        }
 
@@ -1659,16 +1655,15 @@ ves_icall_System_Net_Sockets_Socket_Send_internal (SOCKET sock, MonoArray *buffe
 
        MONO_EXIT_GC_SAFE;
 
+       if (ret == SOCKET_ERROR)
+               *werror = WSAGetLastError ();
+
        mono_thread_info_uninstall_interrupt (&interrupted);
-       if (interrupted) {
+       if (interrupted)
                *werror = WSAEINTR;
-               return 0;
-       }
 
-       if (ret == SOCKET_ERROR) {
-               *werror = WSAGetLastError ();
+       if (*werror)
                return 0;
-       }
 
        return ret;
 }
@@ -1705,17 +1700,16 @@ ves_icall_System_Net_Sockets_Socket_Send_array_internal (SOCKET sock, MonoArray
 
        MONO_EXIT_GC_SAFE;
 
+       if (ret == SOCKET_ERROR)
+               *werror = WSAGetLastError ();
+
        mono_thread_info_uninstall_interrupt (&interrupted);
-       if (interrupted) {
+       if (interrupted)
                *werror = WSAEINTR;
-               return 0;
-       }
 
-       if (ret == SOCKET_ERROR) {
-               *werror = WSAGetLastError ();
+       if (*werror)
                return 0;
-       }
-       
+
        return sent;
 }
 
@@ -1772,18 +1766,18 @@ ves_icall_System_Net_Sockets_Socket_SendTo_internal (SOCKET sock, MonoArray *buf
 
        MONO_EXIT_GC_SAFE;
 
+       if (ret == SOCKET_ERROR)
+               *werror = WSAGetLastError ();
+
        mono_thread_info_uninstall_interrupt (&interrupted);
-       if (interrupted) {
-               g_free (sa);
+       if (interrupted)
                *werror = WSAEINTR;
-               return 0;
-       }
 
-       if (ret == SOCKET_ERROR)
-               *werror = WSAGetLastError ();
+       g_free(sa);
+
+       if (*werror)
+               return 0;
 
-       g_free (sa);
-       
        return ret;
 }
 
@@ -1960,7 +1954,7 @@ ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal (SOCKET sock, g
        int system_level = 0;
        int system_name = 0;
        int ret;
-       int val;
+       int val = 0;
        socklen_t valsize = sizeof (val);
        struct linger linger;
        socklen_t lingersize = sizeof (linger);
@@ -2453,14 +2447,14 @@ ves_icall_System_Net_Sockets_Socket_Shutdown_internal (SOCKET sock, gint32 how,
 
        MONO_EXIT_GC_SAFE;
 
+       if (ret == SOCKET_ERROR)
+               *werror = WSAGetLastError ();
+
        mono_thread_info_uninstall_interrupt (&interrupted);
        if (interrupted) {
                *werror = WSAEINTR;
-               return;
        }
 
-       if (ret == SOCKET_ERROR)
-               *werror = WSAGetLastError ();
 }
 
 gint
@@ -2675,8 +2669,16 @@ ves_icall_System_Net_Dns_GetHostByName_internal (MonoString *host, MonoString **
                }
        }
 
+#ifdef HOST_WIN32
+       // Win32 APIs already returns local interface addresses for empty hostname ("")
+       // so we never want to add them manually.
+       add_local_ips = FALSE;
+       if (mono_get_address_info(hostname, 0, MONO_HINT_CANONICAL_NAME | hint, &info))
+               add_info_ok = FALSE;
+#else
        if (*hostname && mono_get_address_info (hostname, 0, MONO_HINT_CANONICAL_NAME | hint, &info))
                add_info_ok = FALSE;
+#endif
 
        g_free(hostname);