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