line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Mojo::Run3; |
2
|
10
|
|
|
10
|
|
2126834
|
use Mojo::Base 'Mojo::EventEmitter'; |
|
10
|
|
|
|
|
129
|
|
|
10
|
|
|
|
|
54
|
|
3
|
|
|
|
|
|
|
|
4
|
10
|
|
|
10
|
|
16414
|
use Carp qw(croak); |
|
10
|
|
|
|
|
21
|
|
|
10
|
|
|
|
|
519
|
|
5
|
10
|
|
|
10
|
|
4106
|
use Errno qw(EAGAIN ECONNRESET EINTR EPIPE EWOULDBLOCK EIO); |
|
10
|
|
|
|
|
10735
|
|
|
10
|
|
|
|
|
1002
|
|
6
|
10
|
|
|
10
|
|
66
|
use IO::Handle; |
|
10
|
|
|
|
|
16
|
|
|
10
|
|
|
|
|
375
|
|
7
|
10
|
|
|
10
|
|
4485
|
use IO::Pty; |
|
10
|
|
|
|
|
115413
|
|
|
10
|
|
|
|
|
517
|
|
8
|
10
|
|
|
10
|
|
4940
|
use Mojo::IOLoop::ReadWriteFork::SIGCHLD; |
|
10
|
|
|
|
|
27132
|
|
|
10
|
|
|
|
|
59
|
|
9
|
10
|
|
|
10
|
|
5303
|
use Mojo::IOLoop; |
|
10
|
|
|
|
|
1632301
|
|
|
10
|
|
|
|
|
62
|
|
10
|
10
|
|
|
10
|
|
625
|
use Mojo::Util qw(term_escape); |
|
10
|
|
|
|
|
25
|
|
|
10
|
|
|
|
|
470
|
|
11
|
10
|
|
|
10
|
|
65
|
use Mojo::Promise; |
|
10
|
|
|
|
|
148
|
|
|
10
|
|
|
|
|
58
|
|
12
|
10
|
|
|
10
|
|
297
|
use POSIX qw(sysconf _SC_OPEN_MAX); |
|
10
|
|
|
|
|
24
|
|
|
10
|
|
|
|
|
78
|
|
13
|
10
|
|
|
10
|
|
950
|
use Scalar::Util qw(blessed weaken); |
|
10
|
|
|
|
|
21
|
|
|
10
|
|
|
|
|
585
|
|
14
|
|
|
|
|
|
|
|
15
|
10
|
|
50
|
10
|
|
74
|
use constant DEBUG => $ENV{MOJO_RUN3_DEBUG} && 1; |
|
10
|
|
|
|
|
24
|
|
|
10
|
|
|
|
|
673
|
|
16
|
10
|
|
|
10
|
|
58
|
use constant MAX_OPEN_FDS => sysconf(_SC_OPEN_MAX); |
|
10
|
|
|
|
|
19
|
|
|
10
|
|
|
|
|
36624
|
|
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
our $VERSION = '1.03'; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
our @SAFE_SIG |
21
|
|
|
|
|
|
|
= grep { !m!^(NUM\d+|__[A-Z0-9]+__|ALL|CATCHALL|DEFER|HOLD|IGNORE|MAX|PAUSE|RTMAX|RTMIN|SEGV|SETS)$! } keys %SIG; |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
has driver => sub { +{stdin => 'pipe', stdout => 'pipe', stderr => 'pipe'} }; |
24
|
|
|
|
|
|
|
has ioloop => sub { Mojo::IOLoop->singleton }, weak => 1; |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
sub bytes_waiting { |
27
|
4
|
|
|
4
|
1
|
1711
|
my ($self, $name) = (@_, 'stdin'); |
28
|
4
|
|
100
|
|
|
29
|
return length($self->{buffer}{$name} // ''); |
29
|
|
|
|
|
|
|
} |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
sub close { |
32
|
164
|
|
|
164
|
1
|
7776
|
my ($self, $conduit) = @_; |
33
|
164
|
100
|
|
|
|
634
|
return $self->_close_other if $conduit eq 'other'; |
34
|
163
|
100
|
|
|
|
782
|
return $self->_close_slave if $conduit eq 'slave'; |
35
|
|
|
|
|
|
|
|
36
|
138
|
|
|
|
|
317
|
my $fh = $self->{fh}; |
37
|
138
|
100
|
|
|
|
625
|
return $self unless my $handle = $fh->{$conduit}; |
38
|
|
|
|
|
|
|
|
39
|
72
|
|
|
|
|
145
|
$self->_d('close %s (%s)', $conduit, $fh->{$conduit} // 'undef') if DEBUG; |
40
|
72
|
|
|
|
|
352
|
$self->_remove($handle, 1); |
41
|
72
|
|
|
|
|
529
|
$handle->close; |
42
|
72
|
|
|
|
|
3739
|
return $self; |
43
|
|
|
|
|
|
|
} |
44
|
|
|
|
|
|
|
|
45
|
6
|
|
|
6
|
1
|
15540
|
sub exit_status { shift->status >> 8 } |
46
|
7
|
|
|
7
|
1
|
3890
|
sub handle { $_[0]->{fh}{$_[1]} } |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
sub kill { |
49
|
19
|
|
|
19
|
1
|
5556
|
my ($self, $signal) = (@_, 15); |
50
|
19
|
|
|
|
|
36
|
$self->_d('kill %s %s', $signal, $self->{pid} // 0) if DEBUG; |
51
|
19
|
100
|
|
|
|
1073
|
return $self->{pid} ? kill $signal, $self->{pid} : -1; |
52
|
|
|
|
|
|
|
} |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
sub run_p { |
55
|
24
|
|
|
24
|
1
|
51527
|
my ($self, $cb) = @_; |
56
|
24
|
|
|
|
|
146
|
my $p = Mojo::Promise->new; |
57
|
24
|
|
|
22
|
|
1054
|
$self->once(finish => sub { $p->resolve($_[0]) }); |
|
22
|
|
|
|
|
2157
|
|
58
|
24
|
|
|
|
|
601
|
$self->start($cb); |
59
|
24
|
|
|
|
|
342
|
return $p; |
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
|
62
|
15
|
|
100
|
15
|
1
|
11957
|
sub pid { shift->{pid} // -1 } |
63
|
17
|
|
100
|
17
|
1
|
9318
|
sub status { shift->{status} // -1 } |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
sub start { |
66
|
27
|
|
|
27
|
1
|
7949
|
my ($self, $cb) = @_; |
67
|
27
|
50
|
|
27
|
|
93
|
$self->ioloop->next_tick(sub { $self and $self->_start($cb) }); |
|
27
|
|
|
|
|
13664
|
|
68
|
27
|
|
|
|
|
2267
|
return $self; |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
sub write { |
72
|
10
|
|
66
|
10
|
1
|
21445
|
my $cb = ref $_[-1] eq 'CODE' && pop; |
73
|
10
|
|
|
|
|
58
|
my ($self, $chunk, $conduit) = (@_, 'stdin'); |
74
|
10
|
100
|
|
|
|
65
|
$self->once(drain => $cb) if $cb; |
75
|
10
|
|
|
|
|
271
|
$self->{buffer}{$conduit} .= $chunk; |
76
|
10
|
|
|
|
|
103
|
$self->_write($conduit); |
77
|
10
|
|
|
|
|
111
|
return $self; |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
sub _cleanup { |
81
|
25
|
|
|
25
|
|
122
|
my ($self, $signal) = @_; |
82
|
25
|
100
|
|
|
|
875
|
return unless $self->{pid}; |
83
|
14
|
|
|
|
|
119
|
$self->close($_) for qw(slave pty stdin stderr stdout); |
84
|
14
|
50
|
|
|
|
146
|
$self->kill($signal) if $signal; |
85
|
|
|
|
|
|
|
} |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
sub _close_from_child { |
88
|
75
|
|
|
75
|
|
296
|
my ($self, $conduit) = @_; |
89
|
75
|
|
|
|
|
258
|
delete $self->{watching}{$conduit}; # $conduit can also be "pid" |
90
|
75
|
|
|
|
|
133
|
$self->_d('closed=%s watching="%s"', $conduit, join ' ', sort keys %{$self->{watching}}) if DEBUG; |
91
|
75
|
100
|
|
|
|
145
|
return 0 if keys %{$self->{watching}}; |
|
75
|
|
|
|
|
554
|
|
92
|
|
|
|
|
|
|
|
93
|
24
|
|
|
|
|
104
|
$self->close($_) for keys %{$self->{fh}}; |
|
24
|
|
|
|
|
330
|
|
94
|
24
|
|
|
|
|
351
|
for my $cb (@{$self->subscribers('finish')}) { |
|
24
|
|
|
|
|
316
|
|
95
|
24
|
50
|
|
|
|
459
|
$self->emit(error => $@) unless eval { $self->$cb; 1 }; |
|
24
|
|
|
|
|
282
|
|
|
24
|
|
|
|
|
9432
|
|
96
|
|
|
|
|
|
|
} |
97
|
|
|
|
|
|
|
|
98
|
24
|
|
|
|
|
869
|
return 1; |
99
|
|
|
|
|
|
|
} |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
sub _close_other { |
102
|
1
|
|
|
1
|
|
9
|
my ($self) = @_; |
103
|
1
|
50
|
|
|
|
19
|
croak "Cannot close 'other' in parent process!" if $self->pid != 0; |
104
|
|
|
|
|
|
|
|
105
|
0
|
|
|
|
|
0
|
my $fh = delete $self->{fh}; |
106
|
0
|
|
|
|
|
0
|
$fh->{$_}->close for keys %$fh; |
107
|
|
|
|
|
|
|
|
108
|
0
|
|
|
|
|
0
|
local $!; |
109
|
0
|
|
|
|
|
0
|
for my $fileno (0 .. MAX_OPEN_FDS - 1) { |
110
|
0
|
0
|
|
|
|
0
|
next if fileno(STDIN) == $fileno; |
111
|
0
|
0
|
|
|
|
0
|
next if fileno(STDOUT) == $fileno; |
112
|
0
|
0
|
|
|
|
0
|
next if fileno(STDERR) == $fileno; |
113
|
0
|
|
|
|
|
0
|
POSIX::close($fileno); |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
|
116
|
0
|
|
|
|
|
0
|
return $self; |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
sub _close_slave { |
120
|
25
|
|
|
25
|
|
103
|
my ($self) = @_; |
121
|
25
|
|
|
|
|
90
|
my $pty = $self->{fh}{pty}; |
122
|
25
|
|
|
|
|
64
|
$self->_d('close slave (%s)', $pty && ${*$pty}{io_pty_slave} || 'undef') if DEBUG; |
123
|
25
|
100
|
|
|
|
352
|
$pty->close_slave if $pty; |
124
|
25
|
|
|
|
|
868
|
return $self; |
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
sub _d { |
128
|
0
|
|
|
0
|
|
0
|
my ($self, $format, @val) = @_; |
129
|
0
|
|
|
|
|
0
|
local $!; # Do not reset $! in ex _read() |
130
|
0
|
|
0
|
|
|
0
|
warn sprintf "[run3:%s] $format\n", $self->{pid} // 0, @val; |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
sub _fail { |
134
|
2
|
|
|
2
|
|
46
|
my ($self, $err, $errno) = @_; |
135
|
2
|
|
|
|
|
4
|
$self->_d('finish %s (%s)', $err, $errno) if DEBUG; |
136
|
2
|
|
|
|
|
8
|
$self->{status} = $errno; |
137
|
2
|
|
|
|
|
14
|
$self->emit(error => $err)->emit('finish'); |
138
|
2
|
|
|
|
|
57
|
$self->_cleanup; |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
sub _read { |
142
|
335
|
|
|
335
|
|
10065
|
my ($self, $name, $handle) = @_; |
143
|
|
|
|
|
|
|
|
144
|
335
|
|
|
|
|
1817
|
my $n_bytes = $handle->sysread(my $buf, 131072, 0); |
145
|
335
|
100
|
|
|
|
35545
|
if ($n_bytes) { |
|
|
100
|
|
|
|
|
|
146
|
276
|
|
|
|
|
496
|
$self->_d('%s >>> %s (%i)', $name, term_escape($buf) =~ s!\n!\\n!gr, $n_bytes) if DEBUG; |
147
|
276
|
|
|
|
|
1259
|
return $self->emit($name => $buf); |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
elsif (defined $n_bytes) { |
150
|
41
|
|
|
|
|
293
|
return $self->_remove($handle, 0)->_close_from_child($name); # EOF |
151
|
|
|
|
|
|
|
} |
152
|
|
|
|
|
|
|
else { |
153
|
18
|
|
|
|
|
70
|
$self->_d('op=read conduit=%s errstr="%s" errno=%s', $name, $!, int $!) if DEBUG; |
154
|
18
|
100
|
100
|
|
|
586
|
return undef if $! == EAGAIN || $! == EINTR || $! == EWOULDBLOCK; # Retry |
|
|
|
66
|
|
|
|
|
155
|
14
|
100
|
100
|
|
|
142
|
return $self->kill if $! == ECONNRESET || $! == EPIPE; # Error |
156
|
12
|
100
|
|
|
|
113
|
return $self->_remove($handle, 0)->_close_from_child($name) if $! == EIO; # EOF on PTY raises EIO |
157
|
2
|
|
|
|
|
10
|
return $self->emit(error => $!); |
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
sub _redirect { |
162
|
6
|
|
|
6
|
|
115
|
my ($self, $conduit, $real, $virtual) = @_; |
163
|
6
|
100
|
50
|
|
|
122
|
return $real->close || die "Couldn't close $conduit: $!" unless $virtual; |
164
|
5
|
|
|
|
|
225
|
$real->autoflush(1); |
165
|
5
|
|
50
|
|
|
966
|
return open($real, ($conduit eq 'stdin' ? '<&=' : '>&='), fileno($virtual)) || die "Couldn't dup $conduit: $!"; |
166
|
|
|
|
|
|
|
} |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
sub _remove { |
169
|
123
|
|
|
123
|
|
453
|
my ($self, $handle, $delete) = @_; |
170
|
123
|
|
|
|
|
317
|
my $fh = $self->{fh}; |
171
|
123
|
|
|
|
|
539
|
my $reactor = $self->ioloop->reactor; |
172
|
|
|
|
|
|
|
|
173
|
123
|
|
|
|
|
2146
|
for my $name (keys %$fh) { |
174
|
327
|
100
|
66
|
|
|
2497
|
next unless $fh->{$name} and $fh->{$name} eq $handle; |
175
|
142
|
|
|
|
|
816
|
$reactor->remove($fh->{$name}); |
176
|
142
|
100
|
|
|
|
2447
|
delete $fh->{$name} if $delete; |
177
|
142
|
|
|
|
|
525
|
delete $self->{watching}{$name}; |
178
|
|
|
|
|
|
|
} |
179
|
|
|
|
|
|
|
|
180
|
123
|
|
|
|
|
635
|
return $self; |
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
sub _start { |
184
|
27
|
|
|
27
|
|
80
|
my ($self, $cb) = @_; |
185
|
|
|
|
|
|
|
|
186
|
27
|
|
|
|
|
102
|
my $options = $self->driver; |
187
|
27
|
100
|
|
|
|
160
|
$options = {stdin => $options, stdout => 'pipe', stderr => 'pipe'} unless ref $options; |
188
|
27
|
100
|
|
|
|
101
|
$options->{pty} = 'pty' if $options->{pty}; |
189
|
27
|
100
|
100
|
|
|
133
|
map { $options->{$_} //= 'pipe' } qw(stdin stdout stderr) if $options->{pipe}; |
|
9
|
|
|
|
|
43
|
|
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
# Prepare IPC filehandles |
192
|
27
|
|
|
|
|
70
|
my ($pty, %child, %parent); |
193
|
27
|
|
|
|
|
69
|
for my $conduit (qw(pty stdin stdout stderr)) { |
194
|
106
|
|
100
|
|
|
445
|
my $driver = $options->{$conduit} // 'close'; |
195
|
106
|
100
|
|
|
|
347
|
if ($driver eq 'pty') { |
|
|
100
|
|
|
|
|
|
196
|
13
|
|
66
|
|
|
237
|
$pty ||= IO::Pty->new; |
197
|
13
|
|
|
|
|
8610
|
($child{$conduit}, $parent{$conduit}) = ($pty->slave, $pty); |
198
|
|
|
|
|
|
|
} |
199
|
|
|
|
|
|
|
elsif ($driver eq 'pipe') { |
200
|
65
|
100
|
|
|
|
2330
|
pipe my $read, my $write or return $self->_fail("Can't create pipe: $!", $!); |
201
|
64
|
100
|
|
|
|
505
|
($child{$conduit}, $parent{$conduit}) = $conduit eq 'stdin' ? ($read, $write) : ($write, $read); |
202
|
|
|
|
|
|
|
} |
203
|
|
|
|
|
|
|
|
204
|
105
|
|
|
|
|
489
|
$self->_d('conduit=%s child=%s parent=%s', $conduit, $child{$conduit} // '', $parent{$conduit} // '') if DEBUG; |
205
|
|
|
|
|
|
|
} |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
# Child |
208
|
26
|
100
|
|
|
|
40136
|
unless ($self->{pid} = fork) { |
209
|
3
|
100
|
|
|
|
345
|
return $self->_fail("Can't fork: $!", $!) unless defined $self->{pid}; |
210
|
2
|
|
|
|
|
83
|
$self->{fh} = \%child; |
211
|
2
|
50
|
50
|
|
|
332
|
$pty->make_slave_controlling_terminal if $pty and ($options->{make_slave_controlling_terminal} // 1); |
|
|
|
66
|
|
|
|
|
212
|
2
|
|
|
|
|
1829
|
$_->close for values %parent; |
213
|
|
|
|
|
|
|
|
214
|
2
|
|
|
|
|
231
|
$self->_redirect(stdin => \*STDIN, $child{stdin}); |
215
|
2
|
|
|
|
|
60
|
$self->_redirect(stdout => \*STDOUT, $child{stdout}); |
216
|
2
|
|
|
|
|
79
|
$self->_redirect(stderr => \*STDERR, $child{stderr}); |
217
|
|
|
|
|
|
|
|
218
|
2
|
|
|
|
|
1070
|
@SIG{@SAFE_SIG} = ('DEFAULT') x @SAFE_SIG; |
219
|
2
|
|
|
|
|
98
|
($@, $!) = ('', 0); |
220
|
|
|
|
|
|
|
|
221
|
2
|
|
|
|
|
17
|
eval { $self->$cb }; |
|
2
|
|
|
|
|
78
|
|
222
|
0
|
0
|
0
|
|
|
0
|
my ($err, $errno) = ($@, $@ ? 255 : $! || 0); |
223
|
0
|
0
|
|
|
|
0
|
print STDERR $err if length $err; |
224
|
0
|
0
|
|
|
|
0
|
POSIX::_exit($errno) || exit $errno; |
225
|
|
|
|
|
|
|
} |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
# Parent |
228
|
23
|
|
|
|
|
960
|
$self->{fh} = \%parent; |
229
|
23
|
100
|
|
|
|
657
|
$self->{fh}{pty} = $pty if $pty; |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
# Close child filehandles unless we want to keep the tty open for a bit |
232
|
23
|
|
|
|
|
858
|
for my $fh (values %child) { |
233
|
69
|
100
|
66
|
|
|
3041
|
if (blessed $fh and $fh->can('set_raw')) { |
234
|
11
|
100
|
100
|
|
|
512
|
$self->close('slave') if $options->{close_slave} // 1; |
235
|
|
|
|
|
|
|
} |
236
|
|
|
|
|
|
|
else { |
237
|
58
|
|
|
|
|
1762
|
$fh->close; |
238
|
|
|
|
|
|
|
} |
239
|
|
|
|
|
|
|
} |
240
|
|
|
|
|
|
|
|
241
|
23
|
|
|
|
|
833
|
weaken $self; |
242
|
23
|
|
|
|
|
698
|
my $reactor = $self->ioloop->reactor; |
243
|
23
|
|
|
|
|
1112
|
my %uniq; |
244
|
23
|
|
|
|
|
145
|
for my $conduit (qw(pty stdout stderr)) { |
245
|
69
|
100
|
|
|
|
435
|
next unless my $fh = $parent{$conduit}; |
246
|
55
|
100
|
|
|
|
1057
|
next if $uniq{$fh}++; |
247
|
50
|
50
|
|
324
|
|
1827
|
$reactor->io($fh, sub { $self ? $self->_read($conduit => $fh) : $_[0]->remove($fh) }); |
|
324
|
|
|
|
|
46365610
|
|
248
|
50
|
|
|
|
|
3306
|
$reactor->watch($fh, 1, 0); |
249
|
50
|
|
|
|
|
1100
|
$self->{watching}{$conduit} = 1; |
250
|
|
|
|
|
|
|
} |
251
|
|
|
|
|
|
|
|
252
|
23
|
|
|
|
|
64
|
$self->_d('waitpid %s', $self->{pid}) if DEBUG; |
253
|
23
|
|
|
|
|
91
|
$self->{watching}{pid} = 1; |
254
|
|
|
|
|
|
|
Mojo::IOLoop::ReadWriteFork::SIGCHLD->singleton->waitpid( |
255
|
|
|
|
|
|
|
$self->{pid} => sub { |
256
|
23
|
50
|
|
23
|
|
658025
|
return unless $self; |
257
|
23
|
|
|
|
|
494
|
$self->{status} = $_[0]; |
258
|
23
|
|
|
|
|
192
|
$self->_close_from_child('pid'); |
259
|
|
|
|
|
|
|
} |
260
|
23
|
|
|
|
|
1370
|
); |
261
|
|
|
|
|
|
|
|
262
|
23
|
|
|
|
|
7954
|
$self->emit('spawn'); |
263
|
23
|
|
|
|
|
1421
|
$self->_write($_) for qw(pty stdin); |
264
|
|
|
|
|
|
|
} |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
sub _write { |
267
|
56
|
|
|
56
|
|
452
|
my ($self, $conduit) = @_; |
268
|
56
|
100
|
|
|
|
2196
|
return unless length $self->{buffer}{$conduit}; |
269
|
16
|
100
|
|
|
|
102
|
return unless my $fh = $self->{fh}{$conduit}; |
270
|
|
|
|
|
|
|
|
271
|
8
|
|
|
|
|
264
|
my $n_bytes = $fh->syswrite($self->{buffer}{$conduit}); |
272
|
8
|
50
|
|
|
|
273
|
if (defined $n_bytes) { |
273
|
8
|
|
|
|
|
101
|
my $buf = substr $self->{buffer}{$conduit}, 0, $n_bytes, ''; |
274
|
8
|
|
|
|
|
14
|
$self->_d('%s <<< %s (%i)', $conduit, term_escape($buf) =~ s!\n!\\n!gr, length $buf) if DEBUG; |
275
|
8
|
50
|
|
|
|
80
|
return $self->emit('drain') unless length $self->{buffer}{$conduit}; |
276
|
0
|
|
|
0
|
|
0
|
return $self->ioloop->next_tick(sub { $self->_write }); |
|
0
|
|
|
|
|
0
|
|
277
|
|
|
|
|
|
|
} |
278
|
|
|
|
|
|
|
else { |
279
|
0
|
|
|
|
|
0
|
$self->_d('op=write conduit=%s errstr="%s" errno=%s', $conduit, $!, $!) if DEBUG; |
280
|
0
|
0
|
0
|
|
|
0
|
return if $! == EAGAIN || $! == EINTR || $! == EWOULDBLOCK; |
|
|
|
0
|
|
|
|
|
281
|
0
|
0
|
0
|
|
|
0
|
return $self->kill(9) if $! == ECONNRESET || $! == EPIPE; |
282
|
0
|
|
|
|
|
0
|
return $self->emit(error => $!); |
283
|
|
|
|
|
|
|
} |
284
|
|
|
|
|
|
|
} |
285
|
|
|
|
|
|
|
|
286
|
23
|
50
|
|
23
|
|
132662
|
sub DESTROY { shift->_cleanup(9) unless ${^GLOBAL_PHASE} eq 'DESTRUCT' } |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
1; |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
=encoding utf8 |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
=head1 NAME |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
Mojo::Run3 - Run a subprocess and read/write to it |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
=head1 SYNOPSIS |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
use Mojo::Base -strict, -signatures; |
299
|
|
|
|
|
|
|
use Mojo::Run3; |
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
This example gets "stdout" events when the "ls" command emits output: |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
use IO::Handle; |
304
|
|
|
|
|
|
|
my $run3 = Mojo::Run3->new; |
305
|
|
|
|
|
|
|
$run3->on(stdout => sub ($run3, $bytes) { |
306
|
|
|
|
|
|
|
STDOUT->syswrite($bytes); |
307
|
|
|
|
|
|
|
}); |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
$run3->run_p(sub { exec qw(/usr/bin/ls -l /tmp) })->wait; |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
This example does the same, but on a remote host using ssh: |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
my $run3 = Mojo::Run3->new->driver({pty => 1, pipe => 1}}); |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
$run3->once(pty => sub ($run3, $bytes) { |
316
|
|
|
|
|
|
|
$run3->write("my-secret-password\n", "pty") if $bytes =~ /password:/; |
317
|
|
|
|
|
|
|
}); |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
$run3->on(stdout => sub ($run3, $bytes) { |
320
|
|
|
|
|
|
|
STDOUT->syswrite($bytes); |
321
|
|
|
|
|
|
|
}); |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
$run3->run_p(sub { exec qw(ssh example.com ls -l /tmp) })->wait; |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
=head1 DESCRIPTION |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
L allows you to fork a subprocess which you can write STDIN to, and |
328
|
|
|
|
|
|
|
read STDERR and STDOUT without blocking the the event loop. |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
This module also supports L which allows you to create a |
331
|
|
|
|
|
|
|
pseudoterminal for the child process. This is especially useful for application |
332
|
|
|
|
|
|
|
such as C and L. |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
This module is currently EXPERIMENTAL, but unlikely to change much. |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
=head1 EVENTS |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
=head2 drain |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
$run3->on(drain => sub ($run3) { }); |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
Emitted after L has written the whole buffer to the subprocess. |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
=head2 error |
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
$run3->on(error => sub ($run3, $str) { }); |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
Emitted when something goes wrong. |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
=head2 finish |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
$run3->on(finish => sub ($run3, @) { }); |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
Emitted when the subprocess has ended. L might be emitted before |
355
|
|
|
|
|
|
|
L, but L will always be emitted at some point after L |
356
|
|
|
|
|
|
|
as long as the subprocess actually stops. L will contain C<$!> if the |
357
|
|
|
|
|
|
|
subprocess could not be started or the exit code from the subprocess. |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
=head2 pty |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
$run3->on(pty => sub ($run3, $bytes) { }); |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
Emitted when the subprocess write bytes to L. See L for more |
364
|
|
|
|
|
|
|
details. |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
=head2 stderr |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
$run3->on(stderr => sub ($run3, $bytes) { }); |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
Emitted when the subprocess write bytes to STDERR. |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
=head2 stdout |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
$run3->on(stdout => sub ($run3, $bytes) { }); |
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
Emitted when the subprocess write bytes to STDOUT. |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
=head2 spawn |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
$run3->on(spawn => sub ($run3, @) { }); |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
Emitted in the parent process after the subprocess has been forked. |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
=head1 ATTRIBUTES |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
=head2 driver |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
$hash_ref = $run3->driver; |
389
|
|
|
|
|
|
|
$run3 = $run3->driver({stdin => 'pipe', stdout => 'pipe', stderr => 'pipe'}); |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
Used to set the driver for "pty", "stdin", "stdout" and "stderr". The "pipe" key |
392
|
|
|
|
|
|
|
is a shortcut for setting "stdin", "stdout" and "stderr" to "pipe" unless |
393
|
|
|
|
|
|
|
specified. |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
Examples: |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
# Open pipe for STDIN and STDOUT and close STDERR in child process |
398
|
|
|
|
|
|
|
$run3->driver({pipe => 1, stderr => 'close'}); |
399
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
# Create a PTY and attach STDIN to it and open a pipe for STDOUT and STDERR |
401
|
|
|
|
|
|
|
$run3->driver({stdin => 'pty', stdout => 'pipe', stderr => 'pipe'}); |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
# Create a PTY and pipes for STDIN, STDOUT and STDERR |
404
|
|
|
|
|
|
|
$run3->driver({pty => 1, stdin => 'pipe', stdout => 'pipe', stderr => 'pipe'}); |
405
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
# Create a PTY, and require the slave to to be manually closed |
407
|
|
|
|
|
|
|
$run3->driver({pty => 1, stdout => 'pipe', close_slave => 0}); |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
# Create a PTY, but do not make the PTY slave the controlling terminal |
410
|
|
|
|
|
|
|
$run3->driver({pty => 1, stdout => 'pipe', make_slave_controlling_terminal => 0}); |
411
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
=head2 ioloop |
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
$ioloop = $run3->ioloop; |
415
|
|
|
|
|
|
|
$run3 = $run3->ioloop(Mojo::IOLoop->singleton); |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
Holds a L object. |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
=head1 METHODS |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
=head2 bytes_waiting |
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
$int = $run3->bytes_waiting; |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
Returns how many bytes has been passed on to L buffer, but not yet |
426
|
|
|
|
|
|
|
written to the child process. |
427
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
=head2 close |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
$run3 = $run3->close($conduit); |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
Used to close open filehandles. This method can be called in both parent and |
433
|
|
|
|
|
|
|
child process. C<$conduit> can be: |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
=over 2 |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
=item * stdin, stdout, stderr |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
Close STDIN, STDOUT or STDERR in parent or child process. Closing "stdin" is |
440
|
|
|
|
|
|
|
useful after piping data into a process like C. |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
=item * pty, slave |
443
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
If L opens a "pty", there will be one filehandle opened for the child |
445
|
|
|
|
|
|
|
and one for the parent. The actual "pty" can be closed in both parent and child, |
446
|
|
|
|
|
|
|
while the "slave" can only be closed from the parent process if C |
447
|
|
|
|
|
|
|
was set to "0" (zero) in L. |
448
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
=item * other |
450
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
This is useful in the child process to close every filehandle that is not |
452
|
|
|
|
|
|
|
L, L or L. This is required when opening programs that |
453
|
|
|
|
|
|
|
does not automatically do this for you, like "telnet": |
454
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
$run3->start(sub ($run3, @) { |
456
|
|
|
|
|
|
|
$run3->close('other'); |
457
|
|
|
|
|
|
|
exec telnet => '127.0.0.1'; |
458
|
|
|
|
|
|
|
}); |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
=back |
461
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
=head2 exit_status |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
$int = $run3->exit_status; |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
Returns the exit status part of L, which will should be a number from |
467
|
|
|
|
|
|
|
0 to 255. |
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
=head2 handle |
470
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
$fh = $run3->handle($name); |
472
|
|
|
|
|
|
|
|
473
|
|
|
|
|
|
|
Returns a file handle or undef for C<$name>, which can be "stdin", "stdout", |
474
|
|
|
|
|
|
|
"stderr" or "pty". This method returns the write or read "end" of the file |
475
|
|
|
|
|
|
|
handle depending if it is called from the parent or child process. |
476
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
=head2 kill |
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
$int = $run3->kill($signal); |
480
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
Used to send a C<$signal> to the subprocess. Returns C<-1> if no process |
482
|
|
|
|
|
|
|
exists, C<0> if the process could not be signalled and C<1> if the signal was |
483
|
|
|
|
|
|
|
successfully sent. |
484
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
=head2 pid |
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
$int = $run3->pid; |
488
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
Process ID of the child after L has successfully started. The PID will |
490
|
|
|
|
|
|
|
be "0" in the child process and "-1" before the child process was started. |
491
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
=head2 run_p |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
$p = $run3->run_p(sub ($run3) { ... })->then(sub ($run3) { ... }); |
495
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
Will L the subprocess and the promise will be fulfilled when L |
497
|
|
|
|
|
|
|
is emitted. |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
=head2 start |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
$run3 = $run3->start(sub ($run3, @) { ... }); |
502
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
Will start the subprocess. The code block passed in will be run in the child |
504
|
|
|
|
|
|
|
process. C can be used if you want to run another program. Example: |
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
$run3 = $run3->start(sub { exec @my_other_program_with_args }); |
507
|
|
|
|
|
|
|
$run3 = $run3->start(sub { exec qw(/usr/bin/ls -l /tmp) }); |
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
=head2 status |
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
$int = $run3->status; |
512
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
Holds the exit status of the program or C<$!> if the program failed to start. |
514
|
|
|
|
|
|
|
The value includes signals and coredump flags. L can be used |
515
|
|
|
|
|
|
|
instead to get the exit value from 0 to 255. |
516
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
=head2 write |
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
$run3 = $run3->write($bytes); |
520
|
|
|
|
|
|
|
$run3 = $run3->write($bytes, sub ($run3) { ... }); |
521
|
|
|
|
|
|
|
$run3 = $run3->write($bytes, $conduit); |
522
|
|
|
|
|
|
|
$run3 = $run3->write($bytes, $conduit, sub ($run3) { ... }); |
523
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
Used to write C<$bytes> to the subprocess. C<$conduit> can be "pty" or "stdin", |
525
|
|
|
|
|
|
|
and defaults to "stdin". The optional callback will be called on the next |
526
|
|
|
|
|
|
|
L event. |
527
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
=head1 AUTHOR |
529
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
Jan Henning Thorsen |
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
533
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
This program is free software, you can redistribute it and/or modify it under |
535
|
|
|
|
|
|
|
the terms of the Artistic License version 2.0. |
536
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
=head1 SEE ALSO |
538
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
L, |
540
|
|
|
|
|
|
|
L, L, L. |
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
=cut |