#!/usr/bin/perl $sendmailpath = '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:' . '/usr/lib:/sbin:/bin'; # safe - run a command but kill or report it after the given amount of time # Steve Kinzler, kinzler@cs.indiana.edu, Jun 08/Mar 11 # ported/enhanced from safe(1) in C by Mike Blackwell, ihnp4!aicchi!mdb, Aug 86 # http://www.cs.indiana.edu/~kinzler/home.html#unix # Tests: safe -d 3 -v /bin/csh -fc : && echo ok # safe -d 3 -v sleep 1 && echo ok # safe -d 3 -v sleep 6 || echo ok # safe -d 3 -v -n sleep 1 && echo ok # safe -d 3 -v -n sleep 6 && echo ok # NOTE: This seems to mostly work, but I'm not entirely confident with it # since I've seen it fail strangely on occasion on RH9 and RHEL3. $dflt_d = 60; use Getopt::Std; $usage = < 0) { $opt_b ? print(STDERR "\a\a") : &msg($opt_n ? "$0: $proc overruns in $opt_w sec$cmd" : "$0: killing $proc in $opt_w sec$cmd"); sleep $opt_w; } $opt_n ? &over() : &maim(); } sub maim { $SIG{'CHLD'} = 'IGNORE'; kill(15, $pid); sleep(2) if kill(0, $pid); kill( 9, $pid) if kill(0, $pid); sleep(2) if kill(0, $pid); if (kill(0, $pid)) { &msg("$0: $proc will not die after $opt_d sec$cmd"); } else { &msg("$0: $proc killed after $opt_d sec$cmd") unless $opt_q; } exit 1; } sub over { &msg("$0: $proc has run $opt_d sec$cmd"); $opt_v = 1; wait; } sub done { &msg("$0: $proc self-terminated after ", time - $start, " sec$cmd") if $opt_v; exit 0; } ############################################################################### sub msg { warn(@_, "\n"), return unless defined $opt_m; warn("$0: cannot open sendmail ($!)\n"), return unless open(SENDMAIL, '| sendmail -t -oi'); print SENDMAIL 'To: ', $opt_m || $ENV{'USER'} || $ENV{'LOGNAME'}, "\n", "Subject: $0 message\n\n", @_, "\n"; $SIG{'CHLD'} = 'IGNORE'; close SENDMAIL; $SIG{'CHLD'} = 'done'; }