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   872 use v5.12.5;
  58         232  
8 58     58   319 use warnings;
  58         175  
  58         3347  
9              
10             our $VERSION = '1.14.2.3'; # TRIAL VERSION
11              
12 58     58   431 use Rex::Logger;
  58         187  
  58         437  
13 58     58   2226 use Rex::Commands;
  58         386  
  58         1983  
14              
15 58     58   533 use English qw(-no_match_vars);
  58         171  
  58         1349  
16 58     58   38293 use Symbol 'gensym';
  58         197  
  58         5153  
17 58     58   743 use IPC::Open3;
  58         177403  
  58         3478  
18 58     58   826 use IO::Select;
  58         103347  
  58         3232  
19 58     58   819 use Rex::Interface::Exec::IOReader;
  58         210  
  58         806  
20              
21             # Use 'parent' is recommended, but from Perl 5.10.1 its in core
22 58     58   2357 use base qw(Rex::Interface::Exec::Base Rex::Interface::Exec::IOReader);
  58         157  
  58         3184  
23              
24             sub new {
25 2178     2178 0 9826 my $that = shift;
26 2178   33     16002 my $proto = ref($that) || $that;
27 2178         6405 my $self = {@_};
28              
29 2178         5063 bless( $self, $proto );
30              
31 2178         8398 return $self;
32             }
33              
34             sub set_env {
35 10     10 0 29 my ( $self, $env ) = @_;
36 10         36 my $cmd = undef;
37              
38 10 50       55 die("Error: env must be a hash")
39             if ( ref $env ne "HASH" );
40              
41 10         142 while ( my ( $k, $v ) = each(%$env) ) {
42 17         165 $cmd .= "export $k='$v'; ";
43             }
44 10         56 $self->{env} = $cmd;
45             }
46              
47             sub exec {
48 1151     1151 0 7981 my ( $self, $cmd, $path, $option ) = @_;
49              
50 1151         3200 my ( $out, $err, $pid );
51              
52 1151 100       3950 if ( exists $option->{cwd} ) {
53 10 50       120 my $cd_cmd = $OSNAME eq 'MSWin32' ? 'cd /d' : 'cd';
54 10         75 $cmd = "$cd_cmd " . $option->{cwd} . " && $cmd";
55             }
56              
57 1151 50       3014 if ( exists $option->{path} ) {
58 0         0 $path = $option->{path};
59             }
60              
61 1151 100       2967 if ( exists $option->{env} ) {
62 10         45 $self->set_env( $option->{env} );
63             }
64              
65 1151 50       2612 if ( exists $option->{format_cmd} ) {
66 0         0 $option->{format_cmd} =~ s/\{\{CMD\}\}/$cmd/;
67 0         0 $cmd = $option->{format_cmd};
68             }
69              
70 1151         4353 Rex::Commands::profiler()->start("exec: $cmd");
71 1151 50       10693 if ( $^O !~ m/^MSWin/ ) {
72 1151 100       3570 if ($path) { $path = "PATH=$path" }
  920         3050  
73 1151   100     5809 $path ||= "";
74              
75 1151         7741 my $new_cmd = "LC_ALL=C $cmd";
76 1151 100       3627 if ($path) {
77 920         3450 $new_cmd = "export $path ; $new_cmd";
78             }
79              
80 1151 100       3762 if ( $self->{env} ) {
81 9         33 $new_cmd = $self->{env} . " $new_cmd";
82             }
83              
84 1151 50       13750 if ( Rex::Config->get_source_global_profile ) {
85 0         0 $new_cmd = ". /etc/profile >/dev/null 2>&1; $new_cmd";
86             }
87              
88 1151         3139 $cmd = $new_cmd;
89             }
90              
91 1151         10869 Rex::Logger::debug("Executing: $cmd");
92              
93 1151         5922 ( $out, $err ) = $self->_exec( $cmd, $option );
94              
95 1151 100       18061 Rex::Logger::debug($out) if ($out);
96 1151 100       4986 if ($err) {
97 2         21 Rex::Logger::debug("========= ERR ============");
98 2         10 Rex::Logger::debug($err);
99 2         12 Rex::Logger::debug("========= ERR ============");
100             }
101              
102 1151         23009 Rex::Commands::profiler()->end("exec: $cmd");
103              
104 1151 100       4885 if (wantarray) { return ( $out, $err ); }
  921         11502  
105              
106 230         4059 return $out;
107             }
108              
109             sub can_run {
110 555     555 0 2219 my ( $self, $commands_to_check, $check_with_command ) = @_;
111              
112 555 50 33     13624 $check_with_command ||= $^O =~ /^MSWin/i ? 'where' : 'which';
113              
114 555         5000 return $self->SUPER::can_run( $commands_to_check, $check_with_command );
115             }
116              
117             sub _exec {
118 1151     1151   3768 my ( $self, $cmd, $option ) = @_;
119              
120 1151         2606 my ( $pid, $writer, $reader, $error, $out, $err );
121 1151         10764 $error = gensym;
122              
123 1151 100 66     72520 if ( $^O !~ m/^MSWin/ && Rex::Config->get_no_tty ) {
124 2         24 $pid = open3( $writer, $reader, $error, $cmd );
125              
126 2         9055 ( $out, $err ) = $self->io_read( $reader, $error, $pid, $option );
127              
128 2 50       68 waitpid( $pid, 0 ) or die($!);
129             }
130             else {
131 1149 50       3914028 $pid = open( my $fh, "-|", "$cmd 2>&1" ) or die($!);
132 1149         4254111 while (<$fh>) {
133 5993         21205 $out .= $_;
134 5993         13005 chomp;
135             $self->execute_line_based_operation( $_, $option )
136 5993 50       34178 && do { kill( 'KILL', $pid ); last };
  0         0  
  0         0  
137             }
138 1149 50       92574 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 1151         23140 $? >>= 8;
146              
147 1151         42961 return ( $out, $err );
148             }
149              
150             1;