fork + exec + alarm で、以下のようにやった。
sample.pl
use strict;
use warnings;
use POSIX qw( SIGKILL );
my $TIMEOUT = 10;
my $cmd = "sleep 15";
my $pid = fork();
if (!defined($pid)) { die "failed to fork"; }
if ($pid == 0) {
exec($cmd);
exit;
}
elsif ($pid) {
my $timeout = 0;
eval {
local $SIG{ALRM} = sub {
$timeout = 1;
};
alarm($TIMEOUT);
while(!$timeout) {
last if waitpid($pid, POSIX::WNOHANG);
sleep(1);
}
};
if ($@) {
warn "Error:".$@;
}
if ($timeout) {
kill(SIGKILL, $pid);
warn "TIMEOUT";
}
}