#!/usr/bin/perl
# locking example david mcanulty 2006
# This is my attempt to make a robust locking system. Over the years i've used dirty tricks
# Like 'ps auxw', etc, to do my nasty work. I figured i'd write this once and recycle it
# Everywhere. I invite everyone to look and comment on how to improve it, i really want it
# to be a robust code snippet.
#
# Here is an example cron entry you can make to eliminate "impossible" stale lock files :D
# if your program takes more then 10 minutes to run change the "+10" to whatever is logical for your app
#*/10 * * * * /usr/bin/find /tmp/ -name "locktest.lock" -mmin +10 -exec /bin/rm {} \;

#locking code
use Fcntl qw(:DEFAULT :flock);
sub clean_close();

my $lockfile="/tmp/locktest.lock";   #It is a good idea to put the lockfile on the same filesystem as your app.

if (-e $lockfile) {
   print "$lockfile exists, exiting!\n";
   exit 1;
}

#grab signals so lock files don't get left around
$SIG{'TERM'} = 'clean_close';
$SIG{'INT'} = 'clean_close';
$SIG{'HUP'} = 'clean_close';
$SIG{'KILL'} = 'clean_close';
$SIG{'QUIT'} = 'clean_close';
$SIG{'ABRT'} = 'clean_close';
$SIG{__DIE__} = 'clean_close';   #this traps the perl die command, incase you use it

sysopen(LOCKFILE, "$lockfile", O_WRONLY|O_NDELAY|O_CREAT) or die "can't open lockfile: $lockfile ($!)";
flock(LOCKFILE, LOCK_EX|LOCK_NB) or die "can't flock lockfile: $lockfile ($!)";

#### Your code goes here, live it up a little!!
if ($hell eq $frozen) {
   print "oh no!\n";
   clean_close();    #If you have another exit point make sure to use clean_close()
   exit 1;
} else {
   print "all is well\n";
}
clean_close();
exit 0; #this should never run
####END (of your code, back to mine!)



#Don't forget the sub!
sub clean_close() {
   close LOCKFILE or die "can't close lockfile: $lockfile ($!)";
   unlink($lockfile) or die "can't remove lockfile: $lockfile ($!)";
   exit;
}

Email me with suggestions/complaints/praise/etc