scratchpad
Ranna
<code>
#!/usr/bin/perl
use strict;
use IO::Socket;
use Symbol;
use POSIX;
# Daemon:
chroot("/var/daemon") || die "Couldn't chroot to /var/daemon: $!";
POSIX::setsid() || die "Couldn't POSIX::setsid(): $!";
fork ? exit : die "Fork: $!";
$sock = IO::Socket::INET->new(LocalPort => $ARGV[0],
Type => SOCK_STREAM,
Proto => 'tcp',
Reuse => 1
Listen => SOMAXCONN )
or die "Making socket: $@";
my $PREFORK = 5;
my $MAXCLNT = SOMAXCONN;
my %childrn = ();
my $chidlrn = 0;
my $client;
sub REAP {
$SIG{CHLD} = \&REAPER;
my $pid = wait;
$childrn--;
delete $childrn{$pid};
}
sub STOP {
print $client "Server caught SIGINT or SIGTERM, going down. Bye";
local($SIG{CHLD}) = 'IGNORE';
kill 'INT' => keys %childrn;
exit;
}
sub RESTART {
print $client "Server restarting, going down. Bye.";
local($SIG{CHLD}) = 'IGNORE';
kill 'INT' => keys %childrn;
exec("/path/to/this/prog", "PORT");
exit;
}
for (1 .. $PREFORK) {
makechld();
}
$SIG{CHLD} = \&REAP;
$SIG{TERM} = $SIG{INT} = \&STOP;
$SIG{HUP} = \&RESTART;
while (1) {
sleep;
for (my $i = $childrn; $i < $PREFORK; $i++) {
makechld();
}
}
sub makechld {
my $pid;
my $sigset;
$sigset = POSIX::SigSet->new(SIGINT);
sigprocmask(SIG_BLOCK, $sigset)
or die "Can't block SIGINT for fork $!";
die "Fork: $!" unless defined( $pid = fork );
if ($pid) {
sigprocmask(SIG_UNBLOCK, $sigset)
or die "Can't unblock SIGINT for fork $!";
$childrn{$pid} = 1;
$childrn++;
return;
} else {
$SIG{INT} = 'DEFAULT';
sigprocmask(SIG_UNBLOCK, $sigset)
or die "Can't unblock SIGINT for fork $!";
for (my $i = 0; $i < $MAXCLNT; $i++) {
$client = $sock->accept() or last;
#blah
}
exit;
}
}
</code>