[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Possible bug (perl server spawns zombies)



The server below, written in perl, accepts connections on port 4242
and sends a cliche to the client.  Some of you may recognize it as the
server in appendix B of 'learning perl', modified to fork a child to
handle each incoming connection.

The subroutine 'wait_on_kid' should get rid of these children; indeed,
it does so under SunOS.  However, on my machine runing Debian 0.91, it
leaves one zombie for each connection accepted.

Is this a peculiarity of Debian, or of Linux in general?  I'd
appreciate it if someone would run the server, telnet to it a few
times, and let me know if it leaves zombies on your machine as well.
It would be even more informative if someone who has access to a
machine running another distribution could do the same.

Thanks.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Ted Hajek      Distributed Computing Services     University of Minnesota
=-=-=-=-=-=-=-=-=-=-= CUT HERE -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

# require 'sys/socket.ph';
$AF_INET = 2;
$SOCK_STREAM = 1;
$sockaddr = "S n a4 x8";

$SIG{'CHLD'} = "wait_on_kid";
sub wait_on_kid {
  wait;
}

chop($hostname = `hostname`);
($name, $aliases, $proto) = getprotobyname("tcp");
$port = 4242;
$thisport = pack($sockaddr, $AF_INET, $port, "\0\0\0\0");  #wildcard addr
socket(S, $AF_INET, $SOCK_STREAM, $proto) || die "socket: $!";
bind(S, $thisport) || die "bind: $!";
listen(S, 5) || die "listen: $!";

GET_CONNECTION:
for (;;) {
  # We run the accept() in an eval() to trap the fatal error of
  # an interrupted accept call.  This is a solution to a problem
  # which shouldn't really even exist :-(
  eval { accept(NS, S) || die "accept: $!"; };
  if($@) {
    next GET_CONNECTION if($@ =~ /^accept: Interrupted system call/);
    print "Server exiting: $@\n";
    die "$@";
  }
  unless ($child = fork()) {
    srand;
    print NS &fortune;
    close(NS);
    exit;
  }
  close(NS);
}

sub fortune {
  @fortunes = split(/\n%%\n/, <<"END") unless @fortunes;
A bird in the hand is worth two in the bush.
%%
A penny saved is a penny earned.
%%
Ask not what your country can do for you;
ask what you can do for your country.
%%
Moderation in most things.
%%
END
  splice(@fortunes, int(rand(@fortunes)), 1) . "\n";
}


Reply to: