B<tesh> [I<options>] I<tesh_file>
=cut
-my($bindir)=".";
-my($srcdir)=".";
my($timeout)=0;
my($time_to_wait)=0;
my $path = $0;
use Text::ParseWords;
use IPC::Open3;
use IO::File;
+use English;
##
## Portability bits for windows
##
-use constant RUNNING_ON_WINDOWS => ($^O =~ /^(?:mswin|dos|os2)/oi);
+use constant RUNNING_ON_WINDOWS => ($OSNAME =~ /^(?:mswin|dos|os2)/oi);
use POSIX qw(:sys_wait_h WIFEXITED WIFSIGNALED WIFSTOPPED WEXITSTATUS WTERMSIG WSTOPSIG
:signal_h SIGINT SIGTERM SIGKILL SIGABRT SIGSEGV);
-# These are not implemented on windows (see bug 6798 and 6470)
+# These are not implemented on windows
BEGIN {
if (RUNNING_ON_WINDOWS) {
*WIFEXITED = sub { not $_[0] & 127 };
## Command line option handling
##
+if ($ARGV[0] eq "--internal-killer-process") {
+ # We fork+exec a waiter process in charge of killing the command after timeout
+ # If the command stops earlier, that's fine: the killer sends a signal to an already stopped process, fails, and quits.
+ # Nobody cares about the killer issues.
+ # The only problem could arise if another process is given the same PID than cmd. We bet it won't happen :)
+ my $time_to_wait = $ARGV[1];
+ my $pid = $ARGV[2];
+ sleep $time_to_wait;
+ kill('TERM', $pid);
+ sleep 1;
+ kill('KILL', $pid);
+ exit $time_to_wait;
+}
+
+
sub var_subst {
my ($text, $name, $value) = @_;
if ($value) {
$tesh_file = pop @ARGV;
# temporary arrays for GetOption
- my @verbose = ();
my @cfg;
my $log; # ignored
my %opt = (
"help" => 0,
"debug" => 0,
- "verbose" => 0
);
Getopt::Long::config('bundling', 'no_getopt_compat', 'no_auto_abbrev');
GetOptions(
'help|h' => \$opt{'help'},
- 'verbose|v' => \@verbose,
'debug|d' => \$opt{"debug"},
'difftool=s' => \$diff_tool,
print "Test suite `$tesh_name'\n";
}
- $opt{'verbose'} = scalar @verbose;
foreach (@cfg) {
$opt{'cfg'} .= " --cfg=$_";
}
##
## File parsing
##
-my($nb_arg)=0;
-my($old_buffer);
-my($linebis);
-my($SIGABRT)=0;
-my($verbose)=0;
my($return)=-1;
-my($pid);
-my($result);
-my($result_err);
my($forked);
my($config)="";
-my($tesh_command)=0;
my(@buffer_tesh)=();
###########################################################################
close CHILD_IN;
# if timeout specified, fork and kill executing child at the end of timeout
- if (defined($cmd{'timeout'}) or defined($opts{'timeout'})){
+ if (not $cmd{'background'} and (defined($cmd{'timeout'}) or defined($opts{'timeout'}))){
$time_to_wait= defined($cmd{'timeout'}) ? $cmd{'timeout'} : $opts{'timeout'};
$forked = fork();
$timeout=-1;
die "fork() failed: $!" unless defined $forked;
if ( $forked == 0 ) { # child
- sleep $time_to_wait;
-# if (RUNNING_ON_WINDOWS) {
-# system("TASKKILL /F /T /PID $cmd{'pid'}");
-# # /F: Forcefully
-# # /T: Tree kill
-# # /PID: poor soul
-# } else {
- kill('TERM', $cmd{'pid'});
- sleep 1;
- kill('KILL', $cmd{'pid'});
-# }
- exit $time_to_wait;
+ exec("$PROGRAM_NAME --internal-killer-process $time_to_wait $cmd{'pid'}");
}
}
-
# Cleanup the executing child, and kill the timeouter brother on need
$cmd{'return'} = 0 unless defined($cmd{'return'});
- if($cmd{'background'} != 1){
+ if ($cmd{'background'} != 1) {
waitpid ($cmd{'pid'}, 0);
$cmd{'gotret'} = exit_status($?);
parse_out(\%cmd);
- }else{
+ } else {
# & commands, which will be handled at the end
push @bg_cmds, \%cmd;
- # no timeout for background commands
- if($forked){
- kill(SIGKILL, $forked);
- $timeout=0;
- $forked=0;
- }
}
}
die "[TESH/CRITICAL] parse error: $line\n";
}
if($forked){
- kill(SIGKILL, $forked);
+ kill('KILL', $forked);
$timeout=0;
}
if($forked){
- kill(SIGKILL, $forked);
+ kill('KILL', $forked);
$timeout=0;
}