OSSP CVS Repository

ossp - Check-in [4480]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 4480
Date: 2004-Apr-02 20:47:39 (local)
2004-Apr-02 18:47:39 (UTC)
User:rse
Branch:
Comment: In sa_connect() also select(2) on the socket if EINTR was returned similar to what is done already for EINPROGRESS, because one is not allowed to re-start connect(2) according to STEVENS (Unix Network Programming, volume 1, section 5.9) but instead have to perform the same post-processing under EINTR (under both timeout and non-timeout situations) what we already did for EINPROGRESS (in timeout-aware situation).
Tickets:
Inspections:
Files:
ossp-pkg/sa/ChangeLog      1.33 -> 1.34     9 inserted, 0 deleted
ossp-pkg/sa/sa.c      1.80 -> 1.81     57 inserted, 53 deleted

ossp-pkg/sa/ChangeLog 1.33 -> 1.34

--- ChangeLog    2004/04/02 18:21:07     1.33
+++ ChangeLog    2004/04/02 18:47:39     1.34
@@ -13,6 +13,15 @@
 
   Changes between 1.1.0 and 1.2.0 (10-Nov-2003 to xx-Apr-2004)
 
+   o In sa_connect() also select(2) on the socket if EINTR was
+     returned similar to what is done already for EINPROGRESS, because
+     one is not allowed to re-start connect(2) according to STEVENS
+     (Unix Network Programming, volume 1, section 5.9) but instead have
+     to perform the same post-processing under EINTR (under both timeout
+     and non-timeout situations) what we already did for EINPROGRESS (in
+     timeout-aware situation).
+     [Ralf S. Engelschall]
+
    o Adjusted all copyright messages for new year 2004.
      [Ralf S. Engelschall]
 


ossp-pkg/sa/sa.c 1.80 -> 1.81

--- sa.c 2004/04/02 18:21:07     1.80
+++ sa.c 2004/04/02 18:47:39     1.81
@@ -1452,6 +1452,7 @@
     fd_set rset, wset;
     socklen_t len;
     sa_rc_t rv;
+    struct timeval *tv;
 
     /* argument sanity check(s) */
     if (sa == NULL || raddr == NULL)
@@ -1466,72 +1467,75 @@
         if ((rv = sa_socket_init(sa, raddr->nFamily)) != SA_OK)
             return SA_RC(rv);
 
+    /* prepare return code decision */
     rv = SA_OK;
-    if (SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_CONNECT])) {
-        /* standard/non-timeout-aware connect operation */
-        if (SA_SC_CALL_3(sa, connect, sa->fdSocket, raddr->saBuf, raddr->slBuf) < 0)
-            rv = SA_ERR_SYS;
-    }
-    else {
-        /* emulated/timeout-aware connect operation */
-        error = 0;
+    error = 0;
 
-        /* temporarily switch underlying socket to non-blocking mode */
+    /* temporarily switch underlying socket to non-blocking mode
+       (necessary under timeout-aware operation only) */
+    flags = 0;
+    if (!SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_CONNECT])) {
         flags = fcntl(sa->fdSocket, F_GETFL, 0);
         (void)fcntl(sa->fdSocket, F_SETFL, flags|O_NONBLOCK);
+    }
 
-        /* perform the connect operation */
-        if ((n = SA_SC_CALL_3(sa, connect, sa->fdSocket, raddr->saBuf, raddr->slBuf)) < 0) {
-            if (errno != EINPROGRESS) {
-                error = errno;
-                goto done;
-            }
-        }
-
-        /* ok if connect completed immediately */
-        if (n == 0)
-            goto done;
-
-        /* wait for read or write possibility */
-        FD_ZERO(&rset);
-        FD_ZERO(&wset);
-        FD_SET(sa->fdSocket, &rset);
-        FD_SET(sa->fdSocket, &wset);
-        do {
-            n = SA_SC_CALL_5(sa, select, sa->fdSocket+1, &rset, &wset, NULL,
-                             &sa->tvTimeout[SA_TIMEOUT_CONNECT]);
-        } while (n == -1 && errno == EINTR);
-
-        /* decide on return semantic */
-        if (n < 0) {
+    /* perform the connect operation */
+    if ((n = SA_SC_CALL_3(sa, connect, sa->fdSocket, raddr->saBuf, raddr->slBuf)) < 0) {
+        if (errno != EINTR && errno != EINPROGRESS) {
             error = errno;
             goto done;
         }
-        else if (n == 0) {
-            (void)close(sa->fdSocket); /* stop TCP three-way handshake */
-            sa->fdSocket = -1;
-            rv = SA_ERR_TMT;
-            goto done;
-        }
-
-        /* fetch pending error */
-        len = (socklen_t)sizeof(error);
-        if (getsockopt(sa->fdSocket, SOL_SOCKET, SO_ERROR, (void *)&error, &len) < 0)
-            error = errno;
+    }
 
-        done:
+    /* ok if connect completed immediately */
+    if (n == 0)
+        goto done;
+
+    /* wait for read or write possibility */
+    FD_ZERO(&rset);
+    FD_ZERO(&wset);
+    FD_SET(sa->fdSocket, &rset);
+    FD_SET(sa->fdSocket, &wset);
+    if (!SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_CONNECT]))
+        tv = &sa->tvTimeout[SA_TIMEOUT_CONNECT];
+    else
+        tv = NULL;
+    do {
+        n = SA_SC_CALL_5(sa, select, sa->fdSocket+1, &rset, &wset, NULL, tv);
+    } while (n == -1 && errno == EINTR);
+
+    /* decide on return semantic */
+    if (n < 0) {
+        error = errno;
+        goto done;
+    }
+    else if (n == 0) {
+        (void)close(sa->fdSocket); /* stop TCP three-way handshake */
+        sa->fdSocket = -1;
+        rv = SA_ERR_TMT;
+        goto done;
+    }
 
-        /* reset socket flags */
+    /* fetch pending error */
+    len = (socklen_t)sizeof(error);
+    if (getsockopt(sa->fdSocket, SOL_SOCKET, SO_ERROR, (void *)&error, &len) < 0)
+        error = errno;
+
+    done:
+
+    /* reset socket flags
+       (necessary under timeout-aware operation only) */
+    if (!SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_CONNECT]))
         (void)fcntl(sa->fdSocket, F_SETFL, flags);
 
-        /* optionally set errno */
-        if (error != 0) {
-            (void)close(sa->fdSocket); /* just in case */
-            sa->fdSocket = -1;
-            errno = error;
-            rv = SA_ERR_SYS;
-        }
+    /* optionally set errno */
+    if (error != 0) {
+        (void)close(sa->fdSocket); /* just in case */
+        sa->fdSocket = -1;
+        errno = error;
+        rv = SA_ERR_SYS;
     }
+
     return SA_RC(rv);
 }
 

CVSTrac 2.0.1