| 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; |