Network socket disconnect unreliable

From: Richard B. Johnson (root@chaos.analogic.com)
Date: Fri Feb 18 2000 - 11:57:20 EST


When a network socket disconnects, this fact can't presently be
reliably detected when using select. The exception bit is set, but this
gets set occasionly even though there was not a disconnect. This gets
set everytime somebody performs an ioctl() on the file discriptor or
otherwise changes the mode of the file discriptor.

I tried to use fstat() to see if the file-descriptor was still valid
when the exception occurs. It turns out to always be valid even though
the socket has been closed!

Code snippet......

The ERRORS() macro logs events and then calls exit(EXIT_FAILURE);
The rest of the stuff is standard.

                sfd = MAX(fd, ma) +1;
                FD_ZERO(&mem->rfds);
                FD_ZERO(&mem->efds);
                FD_SET(fd, &mem->rfds);
                FD_SET(ma, &mem->rfds);
                FD_SET(fd, &mem->efds);
                FD_SET(ma, &mem->efds);
                while(select(sfd, &mem->rfds, NULL, &mem->efds, NULL) > 0)
                {
                    if(FD_ISSET(ma, &mem->efds))
                        if(fstat(ma, &mem->stat) < 0)
                            ERRORS(Fstat);
                    if(FD_ISSET(fd, &mem->efds))
                        if(fstat(fd, &mem->stat) < 0)
                            ERRORS(Fstat);
                    if(FD_ISSET(fd, &mem->rfds))

                    [Snipped standard R/W stuff]
                    {...............}

                    FD_ZERO(&mem->rfds);
                    FD_ZERO(&mem->efds);
                    FD_SET(fd, &mem->rfds);
                    FD_SET(ma, &mem->rfds);
                    FD_SET(fd, &mem->efds);
                    FD_SET(ma, &mem->efds);
                }

So, when a socket fd disconnects, this just spins <forever>. The
fd is still considered valid! Of course if I read or write to
the socket, it will return an error, but I can't just abitrarily
do this or I will corrupt data if the socket has not been disconnected.

So, how am I supposed to know if the socket was disconnected?
There are of course hacks. I can just count the number of times
that this thing looped without finding anything to do and then
exit if it's obvious that it's hung.

FYI on my Sun, fstat() on a closed network socket returns -1 and
errno is set to EBADF. On Linux, the network socket is still "good"
even though the client has disconnected.
 

Cheers,
Dick Johnson

Penguin : Linux version 2.3.41 on an i686 machine (800.63 BogoMips).

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed Feb 23 2000 - 21:00:21 EST