File Coverage

lib/Rex/Interface/Exec/Local.pm
Criterion Covered Total %
statement 90 96 93.7
branch 29 40 72.5
condition 6 11 54.5
subroutine 15 15 100.0
pod 0 4 0.0
total 140 166 84.3


line stmt bran cond sub pod time code
1             #
2             # (c) Jan Gehring
3             #
4              
5             package Rex::Interface::Exec::Local;
6              
7 58     58   964 use v5.12.5;
  58         266  
8 58     58   376 use warnings;
  58         169  
  58         3065  
9              
10             our $VERSION = '1.14.2.2'; # TRIAL VERSION
11              
12 58     58   406 use Rex::Logger;
  58         195  
  58         440  
13 58     58   2142 use Rex::Commands;
  58         311  
  58         2025  
14              
15 58     58   481 use English qw(-no_match_vars);
  58         213  
  58         1207  
16 58     58   39832 use Symbol 'gensym';
  58         151  
  58         5204  
17 58     58   742 use IPC::Open3;
  58         178417  
  58         3679  
18 58     58   814 use IO::Select;
  58         106514  
  58         3194  
19 58     58   850 use Rex::Interface::Exec::IOReader;
  58         218  
  58         879  
20              
21             # Use 'parent' is recommended, but from Perl 5.10.1 its in core
22 58     58   2330 use base qw(Rex::Interface::Exec::Base Rex::Interface::Exec::IOReader);
  58         168  
  58         3425  
23              
24             sub new {
25 2179     2179 0 10489 my $that = shift;
26 2179   33     18498 my $proto = ref($that) || $that;
27 2179         6448 my $self = {@_};
28              
29 2179         4986 bless( $self, $proto );
30              
31 2179         8896 return $self;
32             }
33              
34             sub set_env {
35 10     10 0 26 my ( $self, $env ) = @_;
36 10         49 my $cmd = undef;
37              
38 10 50       42 die("Error: env must be a hash")
39             if ( ref $env ne "HASH" );
40              
41 10         107 while ( my ( $k, $v ) = each(%$env) ) {
42 17         160 $cmd .= "export $k='$v'; ";
43             }
44 10         48 $self->{env} = $cmd;
45             }
46              
47             sub exec {
48 1152     1152 0 8369 my ( $self, $cmd, $path, $option ) = @_;
49              
50 1152         3261 my ( $out, $err, $pid );
51              
52 1152 100       5215 if ( exists $option->{cwd} ) {
53 10 50       108 my $cd_cmd = $OSNAME eq 'MSWin32' ? 'cd /d' : 'cd';
54 10         144 $cmd = "$cd_cmd " . $option->{cwd} . " && $cmd";
55             }
56              
57 1152 50       3232 if ( exists $option->{path} ) {
58 0         0 $path = $option->{path};
59             }
60              
61 1152 100       4047 if ( exists $option->{env} ) {
62 10         73 $self->set_env( $option->{env} );
63             }
64              
65 1152 50       2906 if ( exists $option->{format_cmd} ) {
66 0         0 $option->{format_cmd} =~ s/\{\{CMD\}\}/$cmd/;
67 0         0 $cmd = $option->{format_cmd};
68             }
69              
70 1152         4507 Rex::Commands::profiler()->start("exec: $cmd");
71 1152 50       11341 if ( $^O !~ m/^MSWin/ ) {
72 1152 100       3698 if ($path) { $path = "PATH=$path" }
  921         3102  
73 1152   100     5647 $path ||= "";
74              
75 1152         6710 my $new_cmd = "LC_ALL=C $cmd";
76 1152 100       3549 if ($path) {
77 921         3466 $new_cmd = "export $path ; $new_cmd";
78             }
79              
80 1152 100       3686 if ( $self->{env} ) {
81 9         31 $new_cmd = $self->{env} . " $new_cmd";
82             }
83              
84 1152 50       13932 if ( Rex::Config->get_source_global_profile ) {
85 0         0 $new_cmd = ". /etc/profile >/dev/null 2>&1; $new_cmd";
86             }
87              
88 1152         3311 $cmd = $new_cmd;
89             }
90              
91 1152         11165 Rex::Logger::debug("Executing: $cmd");
92              
93 1152         4507 ( $out, $err ) = $self->_exec( $cmd, $option );
94              
95 1152 100       19332 Rex::Logger::debug($out) if ($out);
96 1152 100       3889 if ($err) {
97 2         23 Rex::Logger::debug("========= ERR ============");
98 2         12 Rex::Logger::debug($err);
99 2         5 Rex::Logger::debug("========= ERR ============");
100             }
101              
102 1152         23887 Rex::Commands::profiler()->end("exec: $cmd");
103              
104 1152 100       5175 if (wantarray) { return ( $out, $err ); }
  922         10484  
105              
106 230         4710 return $out;
107             }
108              
109             sub can_run {
110 555     555 0 2426 my ( $self, $commands_to_check, $check_with_command ) = @_;
111              
112 555 50 33     14562 $check_with_command ||= $^O =~ /^MSWin/i ? 'where' : 'which';
113              
114 555         4639 return $self->SUPER::can_run( $commands_to_check, $check_with_command );
115             }
116              
117             sub _exec {
118 1152     1152   3368 my ( $self, $cmd, $option ) = @_;
119              
120 1152         3301 my ( $pid, $writer, $reader, $error, $out, $err );
121 1152         11418 $error = gensym;
122              
123 1152 100 66     76783 if ( $^O !~ m/^MSWin/ && Rex::Config->get_no_tty ) {
124 2         24 $pid = open3( $writer, $reader, $error, $cmd );
125              
126 2         10210 ( $out, $err ) = $self->io_read( $reader, $error, $pid, $option );
127              
128 2 50       66 waitpid( $pid, 0 ) or die($!);
129             }
130             else {
131 1150 50       4732602 $pid = open( my $fh, "-|", "$cmd 2>&1" ) or die($!);
132 1150         4552487 while (<$fh>) {
133 5994         21018 $out .= $_;
134 5994         13556 chomp;
135             $self->execute_line_based_operation( $_, $option )
136 5994 50       35017 && do { kill( 'KILL', $pid ); last };
  0         0  
  0         0  
137             }
138 1150 50       97178 waitpid( $pid, 0 ) or die($!);
139              
140             }
141              
142             # we need to bitshift $? so that $? contains the right (and for all
143             # connection methods the same) exit code after a run()/i_run() call.
144             # this is for the user, so that he can query $? in his task.
145 1152         22974 $? >>= 8;
146              
147 1152         45381 return ( $out, $err );
148             }
149              
150             1;