From 3a4c9a16d9a4abdf5acac0f10b92eff037971f69 Mon Sep 17 00:00:00 2001 From: Augustin Degomme Date: Tue, 15 Oct 2013 17:33:57 +0200 Subject: [PATCH] Use temporary files to store output of the command in perl tesh Avoids deadlocking when large data is sent to/from pipes (see tesh test IO-bigsize) --- buildtools/Cmake/Scripts/tesh.pl | 39 ++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/buildtools/Cmake/Scripts/tesh.pl b/buildtools/Cmake/Scripts/tesh.pl index 07e609ee2f..fae12cdae4 100755 --- a/buildtools/Cmake/Scripts/tesh.pl +++ b/buildtools/Cmake/Scripts/tesh.pl @@ -245,7 +245,11 @@ sub exec_cmd { ### # exec the command line ### $line =~ s/\r//g; - $pid = open3(\*CHILD_IN, \*OUT, \*OUT, $cmd{'cmd'} ); + + my $e = IO::File->new_tmpfile; + $e->autoflush(1); + local *E = $e; + $pid = open3(\*CHILD_IN, ">&E", ">&E", $cmd{'cmd'} ); # push all provided input to executing child map { print CHILD_IN "$_\n" } @{$cmd{'in'}}; @@ -264,10 +268,24 @@ sub exec_cmd { } } + + # Cleanup the executing child, and kill the timeouter brother on need + $cmd{'return'} = 0 unless defined($cmd{'return'}); + my $wantret; + if(defined($cmd{'expect'}) and ($cmd{'expect'} ne "")){ + $wantret = "got signal $cmd{'expect'}"; + }else{ + $wantret = "returned code ".(defined($cmd{'return'})? $cmd{'return'} : 0); + $exitcode= 41; + } + my $gotret; + waitpid ($pid, 0); + $gotret = exit_status($?); + seek($e,0,0); # pop all output from executing child my @got; - while(defined(my $got=)) { + while(defined(my $got=<$e>)) { $got =~ s/\r//g; $got =~ s/^( )*//g; chomp $got; @@ -278,8 +296,7 @@ sub exec_cmd { } } } - close OUT; - + if ($cmd{'sort'}){ sub mysort{ $a cmp $b @@ -291,19 +308,7 @@ sub exec_cmd { @{$cmd{'out'}}=sort mysort @{$cmd{'out'}}; } } - - # Cleanup the executing child, and kill the timeouter brother on need - $cmd{'return'} = 0 unless defined($cmd{'return'}); - my $wantret; - if(defined($cmd{'expect'}) and ($cmd{'expect'} ne "")){ - $wantret = "got signal $cmd{'expect'}"; - }else{ - $wantret = "returned code ".(defined($cmd{'return'})? $cmd{'return'} : 0); - $exitcode= 41; - } - my $gotret; - waitpid ($pid, 0); - $gotret = exit_status($?); + #Did we timeout ? If yes, handle it. If not, kill the forked process. if($timeout==-1 and $gotret eq "got signal SIGKILL"){ -- 2.20.1