Looks like a alarm() and groupkill do the same job. Only requires POSIX.
#!/usr/bin/perluse5.014;usewarnings;usePOSIXqw( setpgid );my$USAGE="usage: $0 nsecs command ...\n";@ARGV>=2ordie$USAGE;my($timeout,@command)=@ARGV;$timeout=~/^\d+$/ordie$USAGE;# Create new process group with ourselves as the group leader.setpgid($$,0)ordie"cannot setpgid(): $!\n";# Catch an ALRM signal by sending the TERM signal to the group.$SIG{ALRM}=sub {warn"TIMEOUT\n";kill'TERM'=>-$$;};# Any group kill will also hit us, so exit nicely.$SIG{TERM}=sub {exit(128+14)};alarm($timeout);# Arm the timer.system{$command[0]}@command;# Run the command.alarm(0);# Disarm the timer.exit$?;# Exit with the child status.
This is needlessly restrictive. It should be >= instead of ==. That way you can avoid running the given command through the shell.
system@command;
It may be useful to use system { $command[0] } @command here instead, which will ensure the command is never run under shell. This loses a bit of convenience if the user did want to run the command under shell, but prepending sh -c ... to the arguments is no big deal and this keeps the program from containing a hidden “oops, you got shell when you didn’t mean to” trap.
But this is more subjective than the other change.
Looks like a
alarm()
and groupkill
do the same job. Only requiresPOSIX
.FWIW,
use strict
is redundant given youruse 5.014
. (This applies touse 5.012
and up.)Fixed, including the things you mention below. Thanks.
This is needlessly restrictive. It should be
>=
instead of==
. That way you can avoid running the given command through the shell.It may be useful to use
system { $command[0] } @command
here instead, which will ensure the command is never run under shell. This loses a bit of convenience if the user did want to run the command under shell, but prependingsh -c ...
to the arguments is no big deal and this keeps the program from containing a hidden “oops, you got shell when you didn’t mean to” trap.But this is more subjective than the other change.
Good suggestions, thanks. I quickly threw this together to test the signal mechanism, didn't pay attention to the arguments that much.