Re: Checking for closed/broken connections

Alwin <[email protected]>
Newsgroups gmane.mail.libetpan.user
Message-ID <[email protected]>
> The other solution is to try to run the command and if this fails,
> reconnect to the server.

Hm. As I did (login() will be called before every command).

Next thing, I had look around the connection handling 'cause we have real 
problems wenn the connection get unstable on SmartDevices like Sharp Zaurus 
or IPAQ.

And therefore I found a (possible) problem inside mailstream_socket.c (see 
patch appended)

- on some systems the tcp/ip environment will give a segfault when you try to 
read from a socket not marked as readable or it ends in a endless read 'cause 
you have the socket marked as blocking (why?)
-tcp/ip file-descriptors I think checking for exceptions is a good idea. There 
are such a lot of thing can going wrong...
- on most systems an application crashes trying writing on a socket not 
writeable (there are a lot of reasons for that possible). I think, you should 
check for that. In most times select will return immediately 'cause most 
sockets are writeable. But... its tcp/ip :) Means, I believe it would be 
better to check for write and exceptions via select (as made in the patch).

And last:

Why not using recv/send on tcp/ip sockets? In most cases it should be have a 
little better handling for that as pure read/write.
And why blocking sockets? it is a real problem: on smart devices you can easy 
lose the connection. In that case read/write hangs. forever in blocking mode 
and we have to kill the application. may be, that blocking sockets have a 
better handling to the programmer... but from users point of view.... Or is 
there something I didn't see or not understand the right way?

Ok, enough ideas for the moment.

Bye 

Rajko
libetpan-0.32_socket.patch (text/x-diff, 1.8 KB)
--- tools/mailstream_socket.c.orig	2004-01-19 15:27:25.306626224 +0100
+++ tools/mailstream_socket.c	2004-01-19 15:46:28.101186602 +0100
@@ -158,16 +158,28 @@
   /* timeout */
   {
     fd_set fds_read;
+    /* check for errors! */
+    fd_set fds_excp;
     struct timeval timeout;
     int r;
     
     timeout = mailstream_network_delay;
     
     FD_ZERO(&fds_read);
+    FD_ZERO(&fds_excp);
     FD_SET(socket_data->fd, &fds_read);
-    r = select(socket_data->fd + 1, &fds_read, NULL, NULL, &timeout);
+    FD_SET(socket_data->fd, &fds_excp);
+    r = select(socket_data->fd + 1, &fds_read, NULL, &fds_excp, &timeout);
     if (r == 0)
       return -1;
+    if (FD_ISSET(socket_data->fd,&fds_excp)) {
+      /* houston - we have a problem! */
+      return -1;
+    }
+    if (!FD_ISSET(socket_data->fd,&fds_read)) {
+      /* there is nothing to read! */
+      return 0;
+    }
   }
   
   return read(socket_data->fd, buf, count);
@@ -179,6 +191,32 @@
   struct mailstream_socket_data * socket_data;
 
   socket_data = (struct mailstream_socket_data *) s->data;
+  /* timeout */
+  {
+    fd_set fds_write;
+    /* check for errors! */
+    fd_set fds_excp;
+    struct timeval timeout;
+    int r;
+    
+    timeout = mailstream_network_delay;
+    
+    FD_ZERO(&fds_write);
+    FD_ZERO(&fds_excp);
+    FD_SET(socket_data->fd, &fds_write);
+    FD_SET(socket_data->fd, &fds_excp);
+    r = select(socket_data->fd + 1,NULL, &fds_write, &fds_excp, &timeout);
+    if (r == 0)
+      return -1;
+    if (FD_ISSET(socket_data->fd,&fds_excp)) {
+      /* houston - we have a problem */
+      return -1;
+    }
+    if (!FD_ISSET(socket_data->fd,&fds_write)) {
+      /* we can not write anything this moment */
+      return 0;
+    }
+  }
   return write(socket_data->fd, buf, count);
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.