use IO::Socket;
# optional stuff to make init.d calling work
my $pidFile = '/var/run/something.pid';
my $pid = fork;
if ($pid) # parent: save PID
{
open PIDFILE, ">$pidFile" or die "Can't open PID file: $!\n";
print PIDFILE $pid;
close PIDFILE;
exit 0;
}
# end of optional init.d stuff
my $port = 8000;
my $proto = 'tcp';
my %kids = ();
# do stuff when we are forced to exit
$SIG{"TERM"} = "cleanup_and_exit";
sub cleanup_and_exit {
my $sig = @_;
foreach my $kid (keys %kids) {
# attempt to reap the kiddies
warn ("Failed to reap child pid: $kid") unless kill 9, $kid;
}
# it's a good idea to exit when you are told to
exit(0);
}
# set up a socket
my $listen_socket = IO::Socket::INET->new(LocalPort => $port,
Listen => 10,
Proto => $proto,
Reuse => 1);
while (my $connection = $listen_socket->accept)
{
my $child;
# perform the fork or exit
die "Can't fork: $!" unless defined ($child = fork());
if ($child == 0) { # i'm the child!
# close the child's listen socket, we dont need it.
$listen_socket->close;
# call the main child rountine
&some_routine($connection);
# if the child returns, then record and exit;
undef $kids{$child};
exit 0;
} else { # i'm the parent!
# remember the pid of any children for later reaping
$kids{$child} = 1;
# close the connection, the parent has already passed
# it off to a child.
$connection->close();
}
# go back and listen for the next connection!
}
sub some_routine {
my $socket = shift;
# go for it here ...
# but don't forget to exit
exit(0);
}
|