aboutsummaryrefslogtreecommitdiff
path: root/Tools/portbuild/scripts/pnohang
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/portbuild/scripts/pnohang')
-rwxr-xr-xTools/portbuild/scripts/pnohang70
1 files changed, 70 insertions, 0 deletions
diff --git a/Tools/portbuild/scripts/pnohang b/Tools/portbuild/scripts/pnohang
new file mode 100755
index 000000000000..acfeab8a22b1
--- /dev/null
+++ b/Tools/portbuild/scripts/pnohang
@@ -0,0 +1,70 @@
+#!/usr/bin/perl
+# pnohang: executes command ($4-) with output in file ($3)
+# kills command if no output within $1 seconds with message in $2
+# usage: pnohang timeout file command args ...
+
+require "ctime.pl";
+
+if ($#ARGV < 3) {
+ print "usage: pnohang timeout outfile message command [args...]\n";
+ exit 1;
+}
+
+$timeout=$ARGV[0];
+$outfile=$ARGV[1];
+$message=$ARGV[2];
+splice(@ARGV, 0, 3);
+$pid=$$;
+#print "timeout is ", $timeout, "\n";
+#print "outfile is ", $outfile, "\n";
+#print "message is ", $message, "\n";
+#print "arguments are ", "@ARGV", "\n";
+if ($pid1 = fork) {
+ if ($pid2 = fork) {
+ local $SIG{TERM} = 'IGNORE';
+ # parent
+ #print 'child pids are ', $pid1, ' ', $pid2, "\n";
+ $child=wait;
+ $status=$?;
+ #print "exited child is $child, status is $status\n";
+ if ($pid1 = $child) {
+ #print "killing process $pid2 (second child)\n";
+ kill 'TERM', $pid2;
+ }
+ else {
+ #print "killing process $pid1 (first child)\n";
+ kill 'TERM', $pid1;
+ }
+ # exit status in upper 8 bits, killed signal (if any) in lower 8 bits
+ exit (($status >> 8) | ($status & 0xff)) ;
+ }
+ else {
+ # second child
+ for (;;) {
+ #local $^W = 0;
+ $now = time;
+ sleep $timeout;
+ ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks)
+ = stat($outfile);
+ if ($now > $mtime) {
+# system "logger -t pnohang killing @ARGV $message, pid $pid since no output in $timeout seconds";
+ print "pnohang: killing @ARGV ($message, pid $pid1 and $pid) since no output in $timeout seconds since ", &ctime($now);
+ print "ps jgx before the signal\n";
+ system "ps jgxww";
+ sleep 1; # give it a chance to output message
+ kill 'TERM' => -$pid1;
+ sleep 1;
+ kill 'TERM' => -$pid;
+ sleep 1;
+ print "ps jgx after the signal\n";
+ system "ps jgxww";
+ exit 1;
+ }
+ }
+ }
+}
+else {
+ # first child
+ #print "executing @ARGV\n";
+ exec "@ARGV >$outfile 2>&1";
+}