+ else{
+ $cmd{'cmd'} =~ s/\${EXEEXT:=}//g;
+ }
+ $cmd{'cmd'} =~ s/\${bindir:=}/$bindir/g;
+ $cmd{'cmd'} =~ s/\${srcdir:=}/$srcdir/g;
+ $cmd{'cmd'} =~ s/\${bindir:=.}/$bindir/g;
+ $cmd{'cmd'} =~ s/\${srcdir:=.}/$srcdir/g;
+ $cmd{'cmd'} =~ s/\${bindir}/$bindir/g;
+ $cmd{'cmd'} =~ s/\${srcdir}/$srcdir/g;
+# $cmd{'cmd'} =~ s|^\./||g;
+# $cmd{'cmd'} =~ s|tesh|tesh.pl|g;
+ $cmd{'cmd'} =~ s/\(%i:%P@%h\)/\\\(%i:%P@%h\\\)/g;
+ $cmd{'cmd'} .= " $opts{'cfg'}" if (defined($opts{'cfg'}) && length($opts{'cfg'}));
+
+ print "[$tesh_name:$cmd{'line'}] $cmd{'cmd'}\n" ;
+
+ ###
+ # exec the command line
+ ### $line =~ s/\r//g;
+
+ $cmd{'got'} = IO::File->new_tmpfile;
+ $cmd{'got'}->autoflush(1);
+ local *E = $cmd{'got'};
+ $cmd{'pid'} = open3(\*CHILD_IN, ">&E", ">&E", $cmd{'cmd'} );
+
+ # push all provided input to executing child
+ map { print CHILD_IN "$_\n"; } @{$cmd{'in'}};
+ close CHILD_IN;
+
+ # if timeout specified, fork and kill executing child at the end of timeout
+ if (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;
+ kill(SIGKILL, $cmd{'pid'});
+ exit $time_to_wait;
+ }
+ }
+
+
+ # Cleanup the executing child, and kill the timeouter brother on need
+ $cmd{'return'} = 0 unless defined($cmd{'return'});
+ if($cmd{'background'} != 1){
+ waitpid ($cmd{'pid'}, 0);
+ $cmd{'gotret'} = exit_status($?);
+ parse_out(\%cmd);
+ }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;
+ }
+ }
+}
+