kingkongrevenge has asked for the wisdom of the Perl Monks concerning the following question:

If you close a unix domain socket from the client, is there a reason the "IO::Socket::UNIX::connected()" method never detects the close? See the comment over the while loop below.
use IO::Socket::UNIX; my $sockfile = "/tmp/testsocket"; if (fork) { my $server_sock = IO::Socket::UNIX->new( Type => SOCK_STREAM, Local => $sockfile, Listen => SOMAXCONN ); my $req = $server_sock->accept; # This loop never exits. # The close done from the client is never detected. while ($req->connected) { print STDERR "connected\n"; } print STDERR "disconnected\n"; } else { sleep 1; my $client = IO::Socket::UNIX->new( Type => SOCK_STREAM, Peer => $sockfile ); close $client; exit; }

Replies are listed 'Best First'.
Re: server doesn't detect closed sockets?
by Anno (Deacon) on Aug 02, 2007 at 11:26 UTC
    Thanks for providing runnable test code. I can reproduce the behavior you are seeing.

    I'm not sure what the ->connected method is supposed to detect. Testing for not eof instead achieves the expected behavior. In the parent, change

    while ($req->connected) {
    to
    until ( $req->eof ) {
    Anno
      eof $req is always false until the client has written to the socket and the data is unread, so that doesn't work.

      I looked at the source of IO::Socket::connected and it's just calling peername on the socket. So I inserted these lines into the while loop code to see what's going on:

      print "peername: " . $req->peername . "\n"; print "peerpath: " . $req->peerpath . "\n";

      peername is always a string of one space, regardless of whether data has been written or read from the socket, or whether the socket has been closed in the client. How do I set the peername from the client side on a unix domain socket?

      Peerpath displays as binarygiberish1 the first call, binarygiberish2, the second, then binarygiberish3, and then the binarygiberish2 and binarygiberish3 alternate forever. What is the binary giberish and how can I unpack it? Maybe this is a useful testable value?