* clientsocket.c: implement socket timeouts for read operations
authorArt Cancro <ajc@citadel.org>
Sat, 1 Dec 2001 19:23:27 +0000 (19:23 +0000)
committerArt Cancro <ajc@citadel.org>
Sat, 1 Dec 2001 19:23:27 +0000 (19:23 +0000)
citadel/ChangeLog
citadel/clientsocket.c
citadel/clientsocket.h
citadel/sysdep.c

index 559e733df3ed9a58e2d0c73ed5af0ee80ce14a6e..f5512c297dc56ec6b83b8808d2bd44a5d522a304 100644 (file)
@@ -1,4 +1,7 @@
  $Log$
+ Revision 580.83  2001/12/01 19:23:26  ajc
+ * clientsocket.c: implement socket timeouts for read operations
+
  Revision 580.82  2001/12/01 17:00:23  ajc
  * serv_smtp.c: when multiple MX's are the same preference, randomize them
 
@@ -2889,4 +2892,3 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant <bryant@cs.usm.maine.edu>
 
 Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
        * Initial CVS import 
-
index f096cdb345d26dfd0ad664f105525d42e0a14e34..b1ad7f05e38ff13111a08cdfb642d5d2d1631189 100644 (file)
@@ -18,6 +18,7 @@
 #include <stdio.h>
 #include <signal.h>
 #include <sys/types.h>
+#include <sys/time.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -33,6 +34,7 @@
 #include "snprintf.h"
 #endif
 #include "sysdep_decls.h"
+#include <clientsocket.h>
 
 #ifndef INADDR_NONE
 #define INADDR_NONE 0xffffffff
@@ -91,23 +93,52 @@ int sock_connect(char *host, char *service, char *protocol)
        return (s);
 }
 
+
+
 /*
- * sock_read() - input binary data from socket.
+ * sock_read_to() - input binary data from socket, with a settable timeout.
  * Returns the number of bytes read, or -1 for error.
  */
-int sock_read(int sock, char *buf, int bytes)
+int sock_read_to(int sock, char *buf, int bytes, int timeout)
 {
-       int len, rlen;
+       int len,rlen;
+       fd_set rfds;
+       struct timeval tv;
+       int retval;
 
        len = 0;
-       while (len < bytes) {
-               rlen = read(sock, &buf[len], bytes - len);
-               if (rlen < 1) {
-                       return (-1);
+       while(len<bytes) {
+               FD_ZERO(&rfds);
+               FD_SET(sock, &rfds);
+               tv.tv_sec = timeout;
+               tv.tv_usec = 0;
+
+               retval = select(sock+1, &rfds, NULL, NULL, &tv);
+
+               if (FD_ISSET(sock, &rfds) == 0) {       /* timed out */
+                       lprintf(9, "sock_read() timed out.\n");
+                       return(-1);
+               }
+
+               rlen = read(sock, &buf[len], bytes-len);
+               if (rlen<1) {
+                       lprintf(2, "sock_read() failed: %s\n",
+                               strerror(errno));
+                       return(-1);
                }
                len = len + rlen;
        }
-       return (len);
+       return(bytes);
+}
+
+
+/*
+ * sock_read() - input binary data from socket.
+ * Returns the number of bytes read, or -1 for error.
+ */
+inline int sock_read(int sock, char *buf, int bytes)
+{
+       return sock_read_to(sock, buf, bytes, CLIENT_TIMEOUT);
 }
 
 
index 6bbe88db57eadd2aefe7908bea23004e874d2cf5..ead4c907d9d642d3596de3964f1612e68e3f3b9a 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 int sock_connect(char *host, char *service, char *protocol);
+int sock_read_to(int sock, char *buf, int bytes, int timeout);
 int sock_read(int sock, char *buf, int bytes);
 int sock_write(int sock, char *buf, int nbytes);
 int ml_sock_gets(int sock, char *buf);
@@ -15,3 +16,8 @@ int sock_puts(int sock, char *buf);
  * This looks dumb, but it's being done for future portability
  */
 #define sock_close(sock)       close(sock)
+
+/* 
+ * Default timeout for client sessions
+ */
+#define CLIENT_TIMEOUT         90
index 86534cf078d9b916d07e4b99f689996f825ce8a6..80427374c1dee14e5fe1ba20e15fb5ed43c15748 100644 (file)
@@ -567,7 +567,7 @@ int client_read_to(char *buf, int bytes, int timeout)
  * (This is implemented in terms of client_read_to() and could be
  * justifiably moved out of sysdep.c)
  */
-int client_read(char *buf, int bytes)
+inline int client_read(char *buf, int bytes)
 {
        return(client_read_to(buf, bytes, config.c_sleeping));
 }