-
Notifications
You must be signed in to change notification settings - Fork 40
/
runlock
executable file
·51 lines (46 loc) · 1.28 KB
/
runlock
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#!/usr/bin/perl -w
#
# A simple script that runs the specified command only if the given lockfile
# is not locked. If it *is* locked, we just return 0, considering that
# a success (after all, the command probably is running successfully; it's
# just not us that ran it!)
#
# If it is *not* currently locked, we lock it, run the command, and return
# its result.
#
# We also make an extra effort to handle signals correctly and cleanup our
# subprocess and lock file when we receive one.
#
use strict;
use LockFile::Simple;
if (@ARGV < 2) {
print STDERR "Usage: $0 <lockfile> <command line...>\n";
exit 127;
}
my $lm = LockFile::Simple->make(-stale=>1, -hold=>0)
or die("makelock: $!\n");
my $filename = shift @ARGV;
my $lock = $lm->trylock($filename);
if (defined($lock)) {
my $pid = fork();
if ($pid) {
# parent
local $SIG{INT} = sub { kill 2, $pid; };
local $SIG{TERM} = sub { kill 15, $pid; };
my $newpid = waitpid($pid, 0);
if ($newpid != $pid) {
die("waitpid returned '$newpid', expected '$pid'\n");
}
my $ret = $?;
$lock->release;
exit $ret >> 8;
} else {
# child
exec(@ARGV);
}
# NOTREACHED
}
# didn't obtain lock, so didn't run; call that success, so we don't pop up
# annoying messages in cron.
print STDERR "Still locked.\n";
exit 0;