[PATCH] ftpfs socket timeout



Hello,

the following patch imposes send and receive timeouts on the command and data socket. I also changed the vfs_s_select_on_two function so that it can wait for only one descriptor if the second parameter is < 0. Actually it's unclear to me why there was a select on both data socket and stdin performed in both ftpfs and FISH. When I changed it to wait only for the socket, it's now possible to abort the stalled downloads. Previously, mc tried to read from the socket even after pressing a key, which caused a lockup.

--
Jindrich Makovicka

diff -ur --exclude-from dontdiff vanilla/mc/vfs/direntry.c mc/vfs/direntry.c
--- vanilla/mc/vfs/direntry.c	2002-10-07 13:57:57.000000000 +0200
+++ mc/vfs/direntry.c	2002-10-26 10:54:19.000000000 +0200
@@ -1121,18 +1121,19 @@
     int v;
     int maxfd = (fd1 > fd2 ? fd1 : fd2) + 1;
 
-    timeout.tv_sec  = 1;
-    timeout.tv_usec = 0;
+    timeout.tv_sec  = 0;
+    timeout.tv_usec = 200000;
     FD_ZERO (&set);
     FD_SET (fd1, &set);
-    FD_SET (fd2, &set);
+    if (fd2 >= 0) FD_SET (fd2, &set);
     v = select (maxfd, &set, 0, 0, &timeout);
     if (v <= 0)
 	return v;
     if (FD_ISSET (fd1, &set))
 	return 1;
-    if (FD_ISSET (fd2, &set))
-	return 2;
+    if (fd2 >= 0)
+	if (FD_ISSET (fd2, &set))
+	    return 2;
     return -1;
 }
 
diff -ur --exclude-from dontdiff vanilla/mc/vfs/fish.c mc/vfs/fish.c
--- vanilla/mc/vfs/fish.c	2002-10-06 17:12:09.000000000 +0200
+++ mc/vfs/fish.c	2002-10-26 10:54:19.000000000 +0200
@@ -653,7 +653,7 @@
 		if (FH->linear == LS_LINEAR_CLOSED)
 		    return 0;
 
-		v = vfs_s_select_on_two (FH_SUPER->u.fish.sockr, 0);
+		v = vfs_s_select_on_two (FH_SUPER->u.fish.sockr, -1);
 		if (((v < 0) && (errno == EINTR)) || v == 0)
 		    return 1;
 		return 0;
diff -ur --exclude-from dontdiff vanilla/mc/vfs/ftpfs.c mc/vfs/ftpfs.c
--- vanilla/mc/vfs/ftpfs.c	2002-10-26 09:56:53.000000000 +0200
+++ mc/vfs/ftpfs.c	2002-10-26 10:58:03.000000000 +0200
@@ -81,6 +81,9 @@
 #    define MAXHOSTNAMELEN 64
 #endif
 
+#define COMMAND_SOCKET_TIMEOUT 5
+#define DATA_SOCKET_TIMEOUT 15
+
 #define UPLOAD_ZERO_LENGTH_FILE
 #define SUP super->u.ftp
 #define FH_SOCK fh->u.ftp.sock
@@ -624,6 +627,22 @@
     g_free (dir);
 }
 
+static void
+ftpfs_set_socket_timeout (int socket, int timeout)
+{
+    struct timeval tv;
+#ifdef SO_SNDTIMEO
+    tv.tv_sec = timeout;
+    tv.tv_usec = 0;
+    setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
+#endif
+#ifdef SO_RCVTIMEO
+    tv.tv_sec = timeout;
+    tv.tv_usec = 0;
+    setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
+#endif
+}
+
 static int
 ftpfs_open_socket (vfs *me, vfs_s_super *super)
 {
@@ -633,7 +652,7 @@
     char     *host;
     int      port = SUP.port;
     int      free_host = 0;
-    
+
     /* Use a proxy host? */
     host = SUP.host;
 
@@ -699,6 +718,7 @@
 	close (my_socket);
 	return -1;
     }
+    ftpfs_set_socket_timeout(my_socket, COMMAND_SOCKET_TIMEOUT);
     disable_interrupt_key();
     return my_socket;
 }
@@ -900,6 +920,7 @@
     struct sockaddr_in data_addr;
     int data, len = sizeof(data_addr);
     struct protoent *pe;
+    struct timeval tv;
 
     getsockname(SUP.sock, (struct sockaddr *) &data_addr, &len);
     data_addr.sin_port = 0;
@@ -911,6 +932,8 @@
     if (data < 0)
 	    ERRNOR (EIO, -1);
 
+    ftpfs_set_socket_timeout(data, DATA_SOCKET_TIMEOUT);
+
     if (SUP.use_passive_connection){
 	if ((SUP.use_passive_connection = setup_passive (me, super, data, &data_addr)))
 	    return data;
@@ -1003,9 +1026,12 @@
 	return;
     }
     if (dsock != -1) {
+	struct timeval timeout;
+	timeout.tv_sec = 5;
+	timeout.tv_usec = 0;
 	FD_ZERO (&mask);
 	FD_SET (dsock, &mask);
-	if (select (dsock + 1, &mask, NULL, NULL, NULL) > 0) {
+	if (select (dsock + 1, &mask, NULL, NULL, &timeout) > 0) {
 	    struct timeval start_tim, tim;
 	    gettimeofday (&start_tim, NULL);
 	    /* flush the remaining data */
@@ -1476,7 +1502,7 @@
 		if (FH->linear == LS_LINEAR_CLOSED)
 		    return 0;
 
-		v = vfs_s_select_on_two (FH->u.ftp.sock, 0);
+		v = vfs_s_select_on_two (FH->u.ftp.sock, -1);
 		if (((v < 0) && (errno == EINTR)) || v == 0)
 		    return 1;
 		return 0;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]