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 groupkilldo the same job. Only requiresPOSIX.FWIW,
use strictis redundant given youruse 5.014. (This applies touse 5.012and 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] } @commandhere 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.