This is a bit simpler than yours, a lot simpler than the CPAN 'solutions', and it works even if the program produces a lot of output:
#! perl -slw
use strict;
use IPC::Open3;
use threads stack_size => 4096;
## Kill 0,pid does appear to work properly,
## It return true even after the executable is dead & gone
sub checkPid{
scalar( `tasklist /nh /fi "pid eq $_[0]"` !~ m[INFO]sm );
}
sub execute {
my( $timeout, @command, ) = @_;
my( $err, $in, $out ) = do{ local *FH; \*FH };
my $pid = open3( $in, $out, $err, @command )
or die "@command : $!/$@/$^E";
my( $Tout ) = threads->create( sub{
my( $Terr ) = threads->create( sub{ my @in = <$err>; return \@
+in } );
my @in = <$out>;
return \@in, $Terr->join;
} );
sleep 1 while checkPid( $pid ) and --$timeout;
kill 3, $pid unless $timeout;
return $Tout->join, $timeout == 0;
}
my @cmd = (
'perl.exe',
q[-le"$|++; print($_), warn( $_), Win32::Sleep 250 for 1 .. 12" ]
);
my( $out, $err, $timeout ) = execute( 2, @cmd );
print 'Command ', $timeout ? 'timed out' : 'completed';
print "From stdout:[\n @$out ]" if @$out;
print "From stderr:[\n @$err ]\n" if @$err;
( $out, $err, $timeout ) = execute( 5, @cmd );
print 'Command ', $timeout ? 'timed out' : 'completed';
print "From stdout:[\n @$out ]" if @$out;
print "From stderr:[\n @$err ]" if @$err;
Produces:
C:\test>869942
Command timed out
From stdout:[
1
2
3
4
5
]
From stderr:[
1 at -e line 1.
2 at -e line 1.
3 at -e line 1.
4 at -e line 1.
5 at -e line 1.
]
Command completed
From stdout:[
1
2
3
4
5
6
7
8
9
10
11
12
]
From stderr:[
1 at -e line 1.
2 at -e line 1.
3 at -e line 1.
4 at -e line 1.
5 at -e line 1.
6 at -e line 1.
7 at -e line 1.
8 at -e line 1.
9 at -e line 1.
10 at -e line 1.
11 at -e line 1.
12 at -e line 1.
]
The discrepancy between the 1 1/4 seconds of output gathered and the 2 second timeout in the first run, is down to pipe buffering.
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.