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

SunOS 5.6 Perl 5.6.1

I have the following:

$SIG{'CHLD'} = 'IGNORE'; open(STDOUT, ">>my.log"); STDOUT->autoflush(1); open(STDERR, ">>my.log"); STDERR->autoflush(1); my $sock = new IO::Socket::INET (LocalHost => 'foo.com', LocalPort => 1234, Proto => 'tcp', Listen => 5, ReuseAddr => 1 ); $sock or die("Failed to create sock: $!."); ONE: while ( 1 ) { my $new_sock = $sock->accept; if (!defined($new_sock)) { print(STDERR "Warning: Bad connect.\n"); next ONE; } if ( ! defined($child = fork) ) { print("Could not fork: $!.\n"); exit(1); } $child && next; <do something as the child> shutdown($new_sock,2); close($new_sock); exit(0); } # End ONE close($sock);

My questions are:

1. For the close($new_sock);, should I be checking the return value for this. I wasn't sure why a close on a socket connection would fail.

2. For the close($sock);, is this necessary/useful and can/should I check for a failure? Also, would shutdown($sock,2); do anything useful? I didn't think so, but I saw it while googling for example code.

3. If the child process is executing a command like system("echo Hello");, I need to reap child processes before closing the forked child process so as not to leave "zombies" right? Or is my handling that via capturing the CHLD signal ($SIG{'CHLD'} = 'IGNORE';) before I even start up the socket sufficient? I wasn't sure I needed to do one of these:

while ( my $child_process = waitpid(-1,WNOHANG) > 0 ) { }

before I close the child each time.

4. In Perl 5.6.1, after each accepted connection do I need to reset STDERR and STDOUT that I set prior creating the socket? Previously in Perl 5.005_02 I was having to reset these with each new connection. If that's the same, can someone tell me why?

I think that's it. I thank you for any help you can offer.

Regards,

NOTE: Updated to remove filehandle comment so we can better focus on the questions. Thanks -sk

Shannon Kerr

2005-10-21 Retitled by planetscape, as per Monastery guidelines
Original title: 'Socket'

Replies are listed 'Best First'.
Re: Handling sockets in a server
by blazar (Canon) on Oct 21, 2005 at 09:11 UTC
    1. For the close($new_sock);, should I be checking the return value for this. I know close doesn't return failure for a file handle, but wasn't sure about a socket connection.
    Huh?!? From perldoc -f close:
    close FILEHANDLE close Closes the file or pipe associated with the file handle, retur +ning true only if IO buffers are success- fully flushed and closes the system file descriptor. Closes t +he currently selected filehandle if the argument is omitted.

    It is true that people normally doesn't check closes for failure on regular files. Well, I don't. But then I generally use lexical filehandles and let perl close them for me. Whatever, this doesn't mean that close can't fail... and definitely (I have very limited experiences with sockets but) I've heard many times experienced hackers claim that sockets should be explicitly closeed and checked for failure in doing so.

      Not to deviate too much from the questions in this post, so you can close a filehandle and you are able to check a return value from the close? I'm sorry I haven't seen this done. I do check success/failure on closing pipes and the man page link you included talks about pipes returning a failure if one of the system calls failed. So, I believe my statement is acurate about no failure returned on a file handle.

      Hopefully, someone can help with the meat of this post.

      Thanks,

      Shannon Kerr
        Not to deviate too much from the questions in this post, so you can close a filehandle and you are able to check a return value from the close?

        "I'll go further than that, I'll get off at the depot." (*) You can use the syntax:

        close FILEHANDLE or die "Could not close FILEHANDLE: $!\n";
        to tell you what the errno varaible was set to when FILEHANDLE could not be closed.

        --

        (*) - This quote stolen with great embarrassment from Groucho Marx.

        --
        tbone1, YAPS (Yet Another Perl Schlub)
        And remember, if he succeeds, so what.
        - Chick McGee

        I have seen someone do, instead. But indeed I've always considered it to be overly paranoid. The point being that a close on a regular filehandle may well fail, but we're confident that it will happen rarely enough no to go mad about it...

      OK, so it appears you are answering question #2 for closing the socket (not a connection). Can someone tell me when doing the close($sock) what are the possible reasons for failing to close the socket? How about possible reasons for failing to close a socket connection close($new_sock)?

      Is shutdown($sock,2) useful? What does it do as it's not communicating with a client?

      How about any answers for questions 3 and 4?

      Thank you

      Shannon Kerr

        close on a socket could fail if the file descriptor has already been reaped [EBADF]. [EINTR] is also possible.

        close is different from shutdown because close only cleans up the file descriptor in the current process, but shutdown will terminate the connection for all processes using it.

        That is to say, if you fork a child process that has an open socket, closing it within either process will free the file descriptor associated with that socket, within that process, but the other process will be free to continue using it's copy of the file descriptor and the socket.

        However, shutdown will terminate the connection for all processes that have a file descriptor associated with it. The file descriptor will remain after shutdown until they are explicitly closed or otherwise GC'd.

        Not having a real fork available, I'll leave questions 3 & 4 to others :)


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.