[xiph-cvs] cvs commit: net sock.c

Karl Heyes karl at xiph.org
Thu Feb 12 13:28:35 PST 2004



karl        04/02/12 16:28:35

  Modified:    .        sock.c
  Log:
  a few cleanups and a fix for async connects

Revision  Changes    Path
1.37      +77 -33    net/sock.c

Index: sock.c
===================================================================
RCS file: /usr/local/cvsroot/net/sock.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -r1.36 -r1.37
--- sock.c	20 Oct 2003 03:08:45 -0000	1.36
+++ sock.c	12 Feb 2004 21:28:35 -0000	1.37
@@ -120,6 +120,15 @@
 #endif
 }
 
+static void sock_set_error(int val)
+{
+#ifdef _WIN32
+     WSASetLastError (val);
+#else
+     errno = val;
+#endif
+}
+
 /* sock_recoverable
 **
 ** determines if the socket error is recoverable
@@ -127,23 +136,43 @@
 */
 int sock_recoverable(int error)
 {
-    return (error == 0 || error == EAGAIN || error == EINTR || 
-            error == EINPROGRESS || error == EWOULDBLOCK);
+    switch (error)
+    {
+    case 0:
+    case EAGAIN:
+    case EINTR:
+    case EINPROGRESS:
+#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
+    case EWOULDBLOCK:
+#endif
+#ifdef ERESTART
+    case ERESTART:
+#endif
+        return 1;
+    default:
+        return 0;
+    }
 }
 
 int sock_stalled (int error)
 {
-    return error == EAGAIN || error == EINPROGRESS || error == EWOULDBLOCK || 
-        error == EALREADY;
+    switch (error)
+    {
+    case EAGAIN:
+    case EINPROGRESS:
+    case EALREADY:
+#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
+    case EWOULDBLOCK:
+#endif
+#ifdef ERESTART
+    case ERESTART:
+#endif
+        return 1;
+    default:
+        return 0;
+    }
 }
 
-#if 0
-/* what is this??? */
-static int sock_success (int error)
-{
-    return error == 0;
-}
-#endif
 
 static int sock_connect_pending (int error)
 {
@@ -420,7 +449,7 @@
 }
 
 /* see if a connection can be written to
-** return -1 unable to check
+** return -1 for failure
 ** return 0 for not yet
 ** return 1 for ok 
 */
@@ -429,24 +458,33 @@
     fd_set wfds;
     int val = SOCK_ERROR;
     socklen_t size = sizeof val;
-    struct timeval tv;
+    struct timeval tv, *timeval = NULL;
 
-    tv.tv_sec = timeout;
-    tv.tv_usec = 0;
+    if (timeout)
+    {
+        tv.tv_sec = timeout;
+        tv.tv_usec = 0;
+        timeval = &tv;
+    }
 
     FD_ZERO(&wfds);
     FD_SET(sock, &wfds);
 
-    switch (select(sock + 1, NULL, &wfds, NULL, &tv))
+    switch (select(sock + 1, NULL, &wfds, NULL, timeval))
     {
         case 0:
-	    return SOCK_TIMEOUT;
+            return SOCK_TIMEOUT;
         default:
-	    /* on windows getsockopt.val is defined as char* */
-	    if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*) &val, &size) < 0)
-		val = SOCK_ERROR;
+            /* on windows getsockopt.val is defined as char* */
+            if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*) &val, &size) == 0)
+            {
+                if (val == 0)
+                    return 1;
+            }
         case -1:
-	    return val;
+            if (sock_recoverable (sock_error()))
+                return 0;
+            return SOCK_ERROR;
     }
 }
 
@@ -508,31 +546,37 @@
     ai = head;
     while (ai)
     {
-        if ((sock = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol)) > -1)
+        if ((sock = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol)) >= 0)
         {
             if (timeout)
-            {
                 sock_set_blocking (sock, SOCK_NONBLOCK);
-                if (connect (sock, ai->ai_addr, ai->ai_addrlen) < 0)
+
+            if (connect (sock, ai->ai_addr, ai->ai_addrlen) == 0)
+                break;
+
+            /* loop as the connect maybe async */
+            while (sock != SOCK_ERROR)
+            {
+                if (sock_recoverable (sock_error()))
                 {
                     if (sock_connected (sock, timeout) > 0)
                     {
-                        sock_set_blocking(sock, SOCK_BLOCK);
+                        if (timeout) /* really wants to reset to what it was before */
+                            sock_set_blocking(sock, SOCK_BLOCK);
                         break;
                     }
+                    continue;
                 }
+                sock_close (sock);
+                sock = SOCK_ERROR;
             }
-            else
-            {
-                if (connect (sock, ai->ai_addr, ai->ai_addrlen) == 0)
-                    break;
-            }
-            sock_close (sock);
+            if (sock != SOCK_ERROR)
+                break;
         }
-        sock = SOCK_ERROR;
         ai = ai->ai_next;
     }
-    if (head) freeaddrinfo (head);
+    if (head)
+        freeaddrinfo (head);
 
     return sock;
 }

<p><p>--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list