--- 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;
|