Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Use temporary files to store output of the command in perl tesh
authorAugustin Degomme <degomme@idpann.imag.fr>
Tue, 15 Oct 2013 15:33:57 +0000 (17:33 +0200)
committerAugustin Degomme <degomme@idpann.imag.fr>
Tue, 15 Oct 2013 15:33:57 +0000 (17:33 +0200)
Avoids deadlocking when large data is sent to/from pipes (see tesh test IO-bigsize)

buildtools/Cmake/Scripts/tesh.pl

index 07e609e..fae12cd 100755 (executable)
@@ -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=<OUT>)) {
+  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"){