I'm writing a perl script that needs to work in windows and linux that will run a process, timeout if it takes too long, return the exit code assuming it didn't timeout, and return stdout assuming the exitcode was zero and it didn't timeout. I don't need STDIN or STDERR. I've tried to use IPC::run
but couldn't get it to work.
The closest I got is with IPC::Open3
and waitpid($pid, WNOHANG)
. But I've hit a snag. I'm seeing different results on windows and linux. In the code below I give open3
a command that will fail (ping doesn't have any argument -z
). On linux the code immediately returns a negative exit code. On windows the command times out. Running ping google.com -z
on the windows command line immediately returns telling me there is no such argument. Why does ``waitpid` return a zero?
use strict;
use warnings;
use POSIX ":sys_wait_h";
use IPC::Open3;
my $inFH;
my $outFH;
my @cmd = ("ping", "google.com", "-z");
my $pid = open3( $inFH, $outFH, 0, @cmd);
my $counter=0;
my $waitret;
my $exitcode;
do{
$counter++;
$waitret = waitpid($pid,WNOHANG);
$exitcode = $?;
}while( !$waitret and ($counter < 4_000_000));
if ($counter >= 4_000_000) {
print "Command timed out\n";
kill(9, $pid);
} else {
print "Exit Code: $exitcode\n";
}
Other solutions are welcome. The only reason I use waitpid with nohang is to kill the process if it takes too long. I dont have any other processing I need to do in the meantime. I'm using windows 10 strawberry perl 5.28 portable on windows. My debian machine has perl 5.24.