OSSP CVS Repository

ossp - Difference in ossp-pkg/sa/sa.c versions 1.24 and 1.25
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [History

ossp-pkg/sa/sa.c 1.24 -> 1.25

--- sa.c 2001/10/09 19:58:46     1.24
+++ sa.c 2001/10/09 20:19:58     1.25
@@ -163,7 +163,7 @@
 struct sa_st {
     sa_type_t        eType;            /* socket type (stream or datagram) */
     int              fdSocket;         /* socket file descriptor */
-    struct timeval   tvTimeout[6];     /* timeout values (sec, usec) */
+    struct timeval   tvTimeout[4];     /* timeout values (sec, usec) */
     int              nReadLen;         /* read  buffer current length */
     int              nReadSize;        /* read  buffer current size */
     char            *cpReadBuf;        /* read  buffer memory chunk */
@@ -796,6 +796,28 @@
     return SA_OK;
 }
 
+/* set timeouts if timeouts or done in kernel */
+static sa_rc_t sa_socket_settimeouts(sa_t *sa)
+{
+#if defined(SO_RCVTIMEO) && defined(SO_SNDTIMEO)
+    if (sa->fdSocket != -1) {
+        if (SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_READ])) {
+            if (setsockopt(sa->fdSocket, SOL_SOCKET, SO_RCVTIMEO,
+                           &sa->tvTimeout[SA_TIMEOUT_READ],
+                           sizeof(sa->tvTimeout[SA_TIMEOUT_READ])) < 0)
+                return SA_ERR_SYS;
+        }
+        if (SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_WRITE])) {
+            if (setsockopt(sa->fdSocket, SOL_SOCKET, SO_SNDTIMEO,
+                           &sa->tvTimeout[SA_TIMEOUT_WRITE],
+                           sizeof(sa->tvTimeout[SA_TIMEOUT_WRITE])) < 0)
+                return SA_ERR_SYS;
+        }
+    }
+#endif
+    return SA_OK;
+}
+
 /* internal lazy/delayed initialization of underlying socket */
 static sa_rc_t sa_socket_init(sa_t *sa, int nFamily)
 {
@@ -845,6 +867,9 @@
     if ((sa->fdSocket = socket(nFamily, nType, nProto)) == -1)
         return SA_ERR_SYS;
 
+    /* optionally set kernel timeouts */
+    sa_socket_settimeouts(sa);
+
     return SA_OK;
 }
 
@@ -973,6 +998,9 @@
         sa->tvTimeout[id].tv_usec = usec;
     }
 
+    /* optionally set kernel timeouts */
+    sa_socket_settimeouts(sa);
+
     return SA_OK;
 }
 
@@ -1369,10 +1397,13 @@
 static int sa_read_raw(sa_t *sa, char *cpBuf, int nBufLen)
 {
     int rv;
+#if !(defined(SO_RCVTIMEO) && defined(SO_SNDTIMEO))
     fd_set fds;
+#endif
 
     /* if timeout is enabled, perform explicit/smart blocking instead 
        of implicitly/hard blocking in the read(2) system call */
+#if !(defined(SO_RCVTIMEO) && defined(SO_SNDTIMEO))
     if (!SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_READ])) {
         FD_ZERO(&fds);
         FD_SET(sa->fdSocket, &fds);
@@ -1385,12 +1416,18 @@
             return -1;
         }
     }
+#endif
 
     /* perform read operation on underlying socket */
     do {
         rv = SA_SC_CALL_3(sa, read, sa->fdSocket, cpBuf, nBufLen);
     } while (rv == -1 && errno == EINTR);
 
+#if defined(SO_RCVTIMEO) && defined(SO_SNDTIMEO)
+    if (rv == -1 && errno == EWOULDBLOCK)
+        errno = ETIMEDOUT;
+#endif
+
     return rv;
 }
 
@@ -1535,10 +1572,13 @@
 static int sa_write_raw(sa_t *sa, const char *cpBuf, int nBufLen)
 {
     int rv;
+#if !(defined(SO_RCVTIMEO) && defined(SO_SNDTIMEO))
     fd_set fds;
+#endif
 
     /* if timeout is enabled, perform explicit/smart blocking instead 
        of implicitly/hard blocking in the write(2) system call */
+#if !(defined(SO_RCVTIMEO) && defined(SO_SNDTIMEO))
     if (!SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_WRITE])) {
         FD_ZERO(&fds);
         FD_SET(sa->fdSocket, &fds);
@@ -1551,12 +1591,18 @@
             return -1;
         }
     }
+#endif
 
     /* perform write operation on underlying socket */
     do {
         rv = SA_SC_CALL_3(sa, write, sa->fdSocket, cpBuf, nBufLen);
     } while (rv == -1 && errno == EINTR);
 
+#if defined(SO_RCVTIMEO) && defined(SO_SNDTIMEO)
+    if (rv == -1 && errno == EWOULDBLOCK)
+        errno = ETIMEDOUT;
+#endif
+
     return rv;
 }
 
@@ -1756,12 +1802,12 @@
 
     /* if timeout is enabled, perform explicit/smart blocking instead 
        of implicitly/hard blocking in the recvfrom(2) system call */
-    if (!SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_RECV])) {
+    if (!SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_READ])) {
         FD_ZERO(&fds);
         FD_SET(sa->fdSocket, &fds);
         do {
             n = SA_SC_CALL_5(sa, select, sa->fdSocket+1, &fds, NULL, NULL, 
-                             &sa->tvTimeout[SA_TIMEOUT_RECV]);
+                             &sa->tvTimeout[SA_TIMEOUT_READ]);
         } while (n == -1 && errno == EINTR);
         if (n == 0) 
             errno = ETIMEDOUT;
@@ -1812,12 +1858,12 @@
 
     /* if timeout is enabled, perform explicit/smart blocking instead 
        of implicitly/hard blocking in the sendto(2) system call */
-    if (!SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_SEND])) {
+    if (!SA_TVISZERO(sa->tvTimeout[SA_TIMEOUT_WRITE])) {
         FD_ZERO(&fds);
         FD_SET(sa->fdSocket, &fds);
         do {
             n = SA_SC_CALL_5(sa, select, sa->fdSocket+1, NULL, &fds, NULL, 
-                             &sa->tvTimeout[SA_TIMEOUT_SEND]);
+                             &sa->tvTimeout[SA_TIMEOUT_WRITE]);
         } while (n == -1 && errno == EINTR);
         if (n == 0) 
             errno = ETIMEDOUT;

CVSTrac 2.0.1