#!/usr/bin/perl -w $|++; use strict; use Fcntl; use POSIX qw(setsid); my $PROGRAM = 'cleaner.pl'; my $LOCKFILE = "/var/lock/$PROGRAM"; # use a lockfile to prevent spawning duplicate processes unless ( sysopen(my $fh, $LOCKFILE, O_CREAT | O_EXCL | O_RDWR, 0600) ) { close $fh; # the lockfile already exists print "Lockfile $LOCKFILE aready exists.\nChecking for running $PROGRAM process..."; # sleep for a couple of seconds to make sure we don't race # by this time the process should be in the process table sleep 2; 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"; $dbh->disconnect if $dbh; exit; }; $SIG{HUP} = sub { warn "Caught HUP " . time() . "\n"; }; 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: $!"; # this is the main loop that runs forever, once every 30 seconds # we don't want to die so we eval our function in case it chokes # we have closed STDERR so we won't know if it is choking # but we can change the code as required for debugging. while (1) { eval{ blah() }; sleep 30; }