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   851 use v5.12.5;
  58         230  
8 58     58   338 use warnings;
  58         184  
  58         2879  
9              
10             our $VERSION = '1.14.3'; # VERSION
11              
12 58     58   419 use Rex::Logger;
  58         156  
  58         393  
13 58     58   1883 use Rex::Commands;
  58         326  
  58         2069  
14              
15 58     58   493 use English qw(-no_match_vars);
  58         153  
  58         1424  
16 58     58   37324 use Symbol 'gensym';
  58         161  
  58         5154  
17 58     58   1049 use IPC::Open3;
  58         170483  
  58         3470  
18 58     58   760 use IO::Select;
  58         98558  
  58         2972  
19 58     58   807 use Rex::Interface::Exec::IOReader;
  58         264  
  58         818  
20              
21             # Use 'parent' is recommended, but from Perl 5.10.1 its in core
22 58     58   2205 use base qw(Rex::Interface::Exec::Base Rex::Interface::Exec::IOReader);
  58         180  
  58         2341  
23              
24             sub new {
25 2178     2178 0 6440 my $that = shift;
26 2178   33     14539 my $proto = ref($that) || $that;
27 2178         5668 my $self = {@_};
28              
29 2178         4311 bless( $self, $proto );
30              
31 2178         7280 return $self;
32             }
33              
34             sub set_env {
35 10     10 0 25 my ( $self, $env ) = @_;
36 10         50 my $cmd = undef;
37              
38 10 50       39 die("Error: env must be a hash")
39             if ( ref $env ne "HASH" );
40              
41 10         96 while ( my ( $k, $v ) = each(%$env) ) {
42 17         147 $cmd .= "export $k='$v'; ";
43             }
44 10         54 $self->{env} = $cmd;
45             }
46              
47             sub exec {
48 1151     1151 0 7170 my ( $self, $cmd, $path, $option ) = @_;
49              
50 1151         2603 my ( $out, $err, $pid );
51              
52 1151 100       3474 if ( exists $option->{cwd} ) {
53 10 50       85 my $cd_cmd = $OSNAME eq 'MSWin32' ? 'cd /d' : 'cd';
54 10         67 $cmd = "$cd_cmd " . $option->{cwd} . " && $cmd";
55             }
56              
57 1151 50       2622 if ( exists $option->{path} ) {
58 0         0 $path = $option->{path};
59             }
60              
61 1151 100       2698 if ( exists $option->{env} ) {
62 10         32 $self->set_env( $option->{env} );
63             }
64              
65 1151 50       2353 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         3720 Rex::Commands::profiler()->start("exec: $cmd");
71 1151 50       9002 if ( $^O !~ m/^MSWin/ ) {
72 1151 100       3229 if ($path) { $path = "PATH=$path" }
  920         2482  
73 1151   100     4600 $path ||= "";
74              
75 1151         5877 my $new_cmd = "LC_ALL=C $cmd";
76 1151 100       3063 if ($path) {
77 920         3619 $new_cmd = "export $path ; $new_cmd";
78             }
79              
80 1151 100       3349 if ( $self->{env} ) {
81 9         25 $new_cmd = $self->{env} . " $new_cmd";
82             }
83              
84 1151 50       11870 if ( Rex::Config->get_source_global_profile ) {
85 0         0 $new_cmd = ". /etc/profile >/dev/null 2>&1; $new_cmd";
86             }
87              
88 1151         2661 $cmd = $new_cmd;
89             }
90              
91 1151         9801 Rex::Logger::debug("Executing: $cmd");
92              
93 1151         5166 ( $out, $err ) = $self->_exec( $cmd, $option );
94              
95 1151 100       15322 Rex::Logger::debug($out) if ($out);
96 1151 100       3998 if ($err) {
97 2         30 Rex::Logger::debug("========= ERR ============");
98 2         11 Rex::Logger::debug($err);
99 2         13 Rex::Logger::debug("========= ERR ============");
100             }
101              
102 1151         19980 Rex::Commands::profiler()->end("exec: $cmd");
103              
104 1151 100       4328 if (wantarray) { return ( $out, $err ); }
  921         8501  
105              
106 230         3851 return $out;
107             }
108              
109             sub can_run {
110 555     555 0 1944 my ( $self, $commands_to_check, $check_with_command ) = @_;
111              
112 555 50 33     12496 $check_with_command ||= $^O =~ /^MSWin/i ? 'where' : 'which';
113              
114 555         3664 return $self->SUPER::can_run( $commands_to_check, $check_with_command );
115             }
116              
117             sub _exec {
118 1151     1151   3287 my ( $self, $cmd, $option ) = @_;
119              
120 1151         2580 my ( $pid, $writer, $reader, $error, $out, $err );
121 1151         9544 $error = gensym;
122              
123 1151 100 66     64151 if ( $^O !~ m/^MSWin/ && Rex::Config->get_no_tty ) {
124 2         20 $pid = open3( $writer, $reader, $error, $cmd );
125              
126 2         6224 ( $out, $err ) = $self->io_read( $reader, $error, $pid, $option );
127              
128 2 50       59 waitpid( $pid, 0 ) or die($!);
129             }
130             else {
131 1149 50       3645589 $pid = open( my $fh, "-|", "$cmd 2>&1" ) or die($!);
132 1149         3691754 while (<$fh>) {
133 5993         17252 $out .= $_;
134 5993         11322 chomp;
135             $self->execute_line_based_operation( $_, $option )
136 5993 50       30351 && do { kill( 'KILL', $pid ); last };
  0         0  
  0         0  
137             }
138 1149 50       81320 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         19278 $? >>= 8;
146              
147 1151         35494 return ( $out, $err );
148             }
149              
150             1;