Merge remote branch 'upstream/master'
[mono.git] / mono / io-layer / sockets.c
index 8e787209be10189c79fd70f444d22821c7a3a076..c068f06281d7794ba5f88e7058b10a59a00883cc 100644 (file)
@@ -8,6 +8,9 @@
  */
 
 #include <config.h>
+
+#ifndef DISABLE_SOCKETS
+
 #include <glib.h>
 #include <pthread.h>
 #include <errno.h>
@@ -20,7 +23,6 @@
 #ifdef HAVE_SYS_IOCTL_H
 #  include <sys/ioctl.h>
 #endif
-#include <sys/poll.h>
 #ifdef HAVE_SYS_FILIO_H
 #include <sys/filio.h>     /* defines FIONBIO and FIONREAD */
 #endif
@@ -39,6 +41,7 @@
 #include <mono/io-layer/socket-private.h>
 #include <mono/io-layer/handles-private.h>
 #include <mono/io-layer/socket-wrappers.h>
+#include <mono/utils/mono-poll.h>
 
 #include <netinet/in.h>
 #include <netinet/tcp.h>
@@ -311,7 +314,7 @@ int _wapi_connect(guint32 fd, const struct sockaddr *serv_addr,
        }
        
        if (connect (fd, serv_addr, addrlen) == -1) {
-               struct pollfd fds;
+               mono_pollfd fds;
                int so_error;
                socklen_t len;
                
@@ -352,7 +355,7 @@ int _wapi_connect(guint32 fd, const struct sockaddr *serv_addr,
 
                fds.fd = fd;
                fds.events = POLLOUT;
-               while (poll (&fds, 1, -1) == -1 &&
+               while (mono_poll (&fds, 1, -1) == -1 &&
                       !_wapi_thread_cur_apc_pending ()) {
                        if (errno != EINTR) {
                                errnum = errno_to_WSA (errno, __func__);
@@ -714,6 +717,15 @@ int _wapi_send(guint32 fd, const void *msg, size_t len, int send_flags)
                g_message ("%s: send error: %s", __func__, strerror (errno));
 #endif
 
+#ifdef O_NONBLOCK
+               /* At least linux returns EAGAIN/EWOULDBLOCK when the timeout has been set on
+                * a blocking socket. See bug #599488 */
+               if (errnum == EAGAIN) {
+                       ret = fcntl (fd, F_GETFL, 0);
+                       if (ret != -1 && (ret & O_NONBLOCK) == 0)
+                               errnum = ETIMEDOUT;
+               }
+#endif /* O_NONBLOCK */
                errnum = errno_to_WSA (errnum, __func__);
                WSASetLastError (errnum);
                
@@ -1581,3 +1593,5 @@ int WSASend (guint32 fd, WapiWSABuf *buffers, guint32 count, guint32 *sent,
        *sent = ret;
        return 0;
 }
+
+#endif /* ifndef DISABLE_SOCKETS */