'alarm' doesn't yet work usefully, though this may change. I'm sure there are better/more elegant solutions, but here is a sample script, using Win32::Process in stead, to run a (system) command, which times out.
Call like this
perl alarmtest.pl 4 %SYSTEMROOT%\\system32\\ping.exe "ping localhost"
where the paramaters are
a) Number of seconds till timeout
b) Full path to the executable
c) Command line to run.
# alarmtest.pl
use strict;
use Win32::Process;
my @commands = @ARGV;
timeout(@commands);
print "End of test";
sub timeout {
my ($time, $exe, $command) = @_;
my ($obj, $exit, $counter);
Win32::Process::Create($obj,
$exe, $command,
1,NORMAL_PRIORITY_CLASS |
CREATE_NEW_PROCESS_GROUP, '.')
|| die;
{
$obj->GetExitCode( $exit ) ;
# the following constant isn't in
# Win32::Process docs, but seems to
# be true for my system at least.
last unless $exit == 259;
last if $counter++ >= ($time * 4);
select(undef, undef, undef, 0.25);
redo;
};
if ($exit == 259) {
print "Timed out!\n";
$obj->Kill(1);
};
}
If you specify '$ENV{SYSTEMROOT}\system32\cmd.exe' as the application, then this doesn't seem to kill any child processes created by cmd.exe (I thought that adding the
CREATE_NEW_PROCESS_GROUP constand should do this, but it's not very clearly documented in the Win32::Process docs. I think there's more details in Dave Roth's book: I'll check later on. Update: Apparently if you are using Win32::Console, then using $CONSOLE->GenerateCtrlEvent(); on your Console object will send the Ctrl event to all the processes in that group.
Of course, if all you are doing is sleeping, then you could consider just sleeing less... e.g. a little at a time, checking the condition regularly. For example, the following snippet will do pretty much the same as sleep 200 except that it will stop if the specified lockfile is ever created.
sleep_unless_lockfile (200, "$ENV{TEMP}\\lockfile");
sub sleep_unless_lockfile {
my ($sleeptime, $lockfile)=@_;
my $counter;
{
sleep 1;
$counter++; print "$counter.";
last if (-e $lockfile);
last if $counter >= $sleeptime;
redo;
}
}
Hope that's at all helpful.
Osfameron |