Here is a daemon that does the right things:
#!/usr/bin/perl -w
$|++;
use strict;
use Fcntl;
use POSIX qw(setsid);
my ($PROGRAM) = $0 =~ m!([^\\/:]+)$!;
my $LOCKFILE = "/var/lock/$PROGRAM";
my $LOG = "/var/log/$PROGRAM.error.log";
# use a lockfile to prevent spawning duplicate processes
unless ( sysopen(my $fh, $LOCKFILE, O_CREAT | O_EXCL | O_RDWR, 0600) )
+ {
# the lockfile already exists
print "Lockfile $LOCKFILE aready exists.\nChecking for running $PR
+OGRAM process...";
my @ps = grep{ m/\Q$PROGRAM\E/ } `ps -C $PROGRAM`;
# we expect 1 copy (us) running
# print "@ps\n";
die "\nThere is already a copy of $PROGRAM running!\n" if @ps > 1;
print "None!\n";
}
# now demonize it
defined(my $pid = fork) or die "Can't fork: $!";
exit 0 if $pid;
chdir '/' or die "Can't chdir to /: $!";
umask 0;
setsid() or die "Can't start a new session: $!";
$SIG{INT} = $SIG{TERM} = sub {
unlink $LOCKFILE or warn "Could not unlink $LOCKFILE for $PROGRAM\
+n";
exit;
};
$SIG{HUP} = sub {
warn "Caught HUP " . time() . "\n";
# do reset stuff if required
};
print "Started $0 daemon OK\n\n";
open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!";
#open STDERR, '>/dev/null' or die "Can't write to /dev/null: $!";
open STDERR, ">>$LOG" or die "Can't write to $LOG: $!";
# this is the main loop that runs forever, once every 30 seconds
while (1) {
eval{ ... }; # use eval to exec any code so if it chokes the dae
+mon survives
warn "$@\n" if $@;
sleep 30;
}