| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package AnyEvent::Subprocess; |
|
2
|
|
|
|
|
|
|
BEGIN { |
|
3
|
17
|
|
|
17
|
|
1163814
|
$AnyEvent::Subprocess::VERSION = '1.102912'; |
|
4
|
|
|
|
|
|
|
} |
|
5
|
|
|
|
|
|
|
# ABSTRACT: flexible, OO, asynchronous process spawning and management |
|
6
|
17
|
|
|
17
|
|
31901
|
use Moose; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
with 'AnyEvent::Subprocess::Job'; |
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
our $VERSION; |
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
use AnyEvent::Subprocess::DefaultDelegates; |
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
use namespace::autoclean; |
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
__PACKAGE__->meta->make_immutable; |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
1; |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
=pod |
|
22
|
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
=head1 NAME |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
AnyEvent::Subprocess - flexible, OO, asynchronous process spawning and management |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
=head1 VERSION |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
version 1.102912 |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
32
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
use AnyEvent::Subprocess; |
|
34
|
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
# prepare the job |
|
36
|
|
|
|
|
|
|
my $job = AnyEvent::Subprocess->new( |
|
37
|
|
|
|
|
|
|
delegates => ['StandardHandles'], |
|
38
|
|
|
|
|
|
|
on_completion => sub { die 'bad exit status' unless $_[0]->is_success }, |
|
39
|
|
|
|
|
|
|
code => sub { |
|
40
|
|
|
|
|
|
|
my %args = %{$_[0]}; |
|
41
|
|
|
|
|
|
|
while(<>){ |
|
42
|
|
|
|
|
|
|
print "Got line: $_"; |
|
43
|
|
|
|
|
|
|
} |
|
44
|
|
|
|
|
|
|
exit 0; |
|
45
|
|
|
|
|
|
|
}, |
|
46
|
|
|
|
|
|
|
); |
|
47
|
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
# start the child |
|
49
|
|
|
|
|
|
|
my $run = $job->run; |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
# add watcher to print the next line we see on the child's stdout |
|
52
|
|
|
|
|
|
|
$run->delegate('stdout')->handle->push_read( line => sub { |
|
53
|
|
|
|
|
|
|
my ($h, $line) = @_; |
|
54
|
|
|
|
|
|
|
say "The child said: $line"; |
|
55
|
|
|
|
|
|
|
}); |
|
56
|
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
# write to the child's stdin |
|
58
|
|
|
|
|
|
|
$run->delegate('stdin')->handle->push_write("Hello, world!\n"); |
|
59
|
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
# close stdin after it has been written to the child |
|
61
|
|
|
|
|
|
|
$run->delegate('stdin')->handle->on_drain(sub { $_[0]->close_fh }); |
|
62
|
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
# kill the child if it takes too long to produce a result |
|
64
|
|
|
|
|
|
|
my $killer = AnyEvent->timer( after => 42, interval => 0, cb => sub { |
|
65
|
|
|
|
|
|
|
$run->kill(2); # SIGINT. |
|
66
|
|
|
|
|
|
|
}); |
|
67
|
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
# ensure the event loop runs until the on_completion handler dies |
|
69
|
|
|
|
|
|
|
EV::loop(); # you can use any AnyEvent-compatible event loop, including POE |
|
70
|
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
# eventually prints "The child said: Got line: Hello, world!", or |
|
72
|
|
|
|
|
|
|
# perhaps dies if your system is really really overloaded. |
|
73
|
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
There are so many possible ways to use this module that a tutorial |
|
77
|
|
|
|
|
|
|
would take me months to write. You should definitely read the test |
|
78
|
|
|
|
|
|
|
suite to see what possibilities exist. (There is also an examples |
|
79
|
|
|
|
|
|
|
directory in the dist.) |
|
80
|
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
The basic "flow" is like in the SYNOPSIS section; create a job, call |
|
82
|
|
|
|
|
|
|
run, wait for your callback to be called with the exit status of the |
|
83
|
|
|
|
|
|
|
subprocess. |
|
84
|
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
The fun comes when you add delegates. |
|
86
|
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
Delegates are technically instances of classes. Typing: |
|
88
|
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
my $stdin = AnyEvent::Subprocess::Job::Delegate::Handle->new( |
|
90
|
|
|
|
|
|
|
name => 'stdin', |
|
91
|
|
|
|
|
|
|
direction => 'w', |
|
92
|
|
|
|
|
|
|
replace => \*STDIN, |
|
93
|
|
|
|
|
|
|
); |
|
94
|
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
Every time you want to be able to write to STDIN is going to become |
|
96
|
|
|
|
|
|
|
tiring after a while. When you load C<AnyEvent::Subprocess>, you also |
|
97
|
|
|
|
|
|
|
load |
|
98
|
|
|
|
|
|
|
L<AnyEvent::Subprocess::DefaultDelegate|AnyEvent::Subprocess::DefaultDelegates>. |
|
99
|
|
|
|
|
|
|
This registers short names for each delegate and will cause |
|
100
|
|
|
|
|
|
|
C<AnyEvent::Subprocess::Job> to build the actual instances |
|
101
|
|
|
|
|
|
|
automatically. This means you can say C<'StandardHandles'> to get a |
|
102
|
|
|
|
|
|
|
delegate for each of STDIN, STDOUT, and STDERR. If you want to know |
|
103
|
|
|
|
|
|
|
how all the sugary names work, just open C<DefaultDelegates.pm> and |
|
104
|
|
|
|
|
|
|
take a look. (The documentation for that module also covers that, as |
|
105
|
|
|
|
|
|
|
well as how to define your own delegate builders.) |
|
106
|
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
If you are too lazy to look -- there are delegates for giving the |
|
108
|
|
|
|
|
|
|
child arbitrary sockets or pipes opened to arbitrary file descriptors |
|
109
|
|
|
|
|
|
|
(so you can deal with more than stdin/stdout/stderr and communicate |
|
110
|
|
|
|
|
|
|
bidirectionally between the parent and child), there is a delegate for |
|
111
|
|
|
|
|
|
|
giving the child a pseudo-tty (which can run complicatged programs, |
|
112
|
|
|
|
|
|
|
like emacs!), there is a delegate for capturing any input |
|
113
|
|
|
|
|
|
|
automatically, and passing it back to the parent via the C<Done> |
|
114
|
|
|
|
|
|
|
object, and there is a delegate for calling functions in the parent |
|
115
|
|
|
|
|
|
|
when certain events are received. |
|
116
|
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
Once you have decided what delegates your job needs, you need to |
|
118
|
|
|
|
|
|
|
create a job object: |
|
119
|
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
my $proc = AnyEvent::Subprocess->new( |
|
121
|
|
|
|
|
|
|
delegates => [qw/List them here/], |
|
122
|
|
|
|
|
|
|
code => sub { code to run in the child }, |
|
123
|
|
|
|
|
|
|
on_completion => sub { code to run in the parent when the child is done }, |
|
124
|
|
|
|
|
|
|
); |
|
125
|
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
Then you can run it: |
|
127
|
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
my $running = $proc->run; |
|
129
|
|
|
|
|
|
|
my $another = $proc->run({ with => 'args' }); # a separate process |
|
130
|
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
The C<code> coderef receives a hashref as an argument; delegates |
|
132
|
|
|
|
|
|
|
typically populate this for you, but you can also pass a hashref of |
|
133
|
|
|
|
|
|
|
args to run (that will be merged with any arguments the delegates |
|
134
|
|
|
|
|
|
|
create; the delegates' arguments "win" if there is a conflict). The |
|
135
|
|
|
|
|
|
|
code then runs in a child process until it stops running for some |
|
136
|
|
|
|
|
|
|
reason. The C<on_completion> hook is then run in the parent, with the |
|
137
|
|
|
|
|
|
|
L<AnyEvent::Subprocess::Done|AnyEvent::Subprocess::Done> object passed |
|
138
|
|
|
|
|
|
|
in as an argument. |
|
139
|
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
You can, of course, have as many children running concurrently as you |
|
141
|
|
|
|
|
|
|
desire. The event loop handles managing the any IO with the child, |
|
142
|
|
|
|
|
|
|
and the notifications of the child dying. (You don't need to deal |
|
143
|
|
|
|
|
|
|
with SIGCHLD or anything like that.) |
|
144
|
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
=head1 OVERVIEW |
|
146
|
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
C<AnyEvent::Subprocess> is a set of modules for running external |
|
148
|
|
|
|
|
|
|
processes, and interacting with them in the context of an event-driven |
|
149
|
|
|
|
|
|
|
program. It is similar to L<POE::Wheel::Run|POE::Wheel::Run>, but |
|
150
|
|
|
|
|
|
|
much more customizable (and Moose-based). It is also similar to |
|
151
|
|
|
|
|
|
|
modules that really want to be event-based, but aren't for some |
|
152
|
|
|
|
|
|
|
reason; this includes L<IPC::Run|IPC::Run> and |
|
153
|
|
|
|
|
|
|
L<IPC::Open3|IPC::Open3>, L<Expect|Expect>, and even the built-in |
|
154
|
|
|
|
|
|
|
C<qx//> operator. You can replace all those modules with this one, |
|
155
|
|
|
|
|
|
|
and have the ability to write much more flexible applications and |
|
156
|
|
|
|
|
|
|
libraries. |
|
157
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
AnyEvent::Subprocess is based on three classes; |
|
159
|
|
|
|
|
|
|
C<AnyEvent::Subprocess::Job>, which represents a job that can be run |
|
160
|
|
|
|
|
|
|
at a later time, C<AnyEvent::Subprocess::Running>, which represents a |
|
161
|
|
|
|
|
|
|
running child process, and C<AnyEvent::Subprocess::Done>, which |
|
162
|
|
|
|
|
|
|
represents a completed job. The C<Job> object contains the command to |
|
163
|
|
|
|
|
|
|
run, information about its environment (which handles to capture, |
|
164
|
|
|
|
|
|
|
which plugins to run, what to do when the job is done, etc.). Then |
|
165
|
|
|
|
|
|
|
C<Run> object is returned by C<< $job->run >>, and lets you interact |
|
166
|
|
|
|
|
|
|
with the running subprocess. This includes things like writing to its |
|
167
|
|
|
|
|
|
|
pipes/sockets, reading from its pipes, sending it signals, and so on. |
|
168
|
|
|
|
|
|
|
When the running job exits, the C<on_completion> handler provided by |
|
169
|
|
|
|
|
|
|
the Job object is called with a C<Done> object. This contains the |
|
170
|
|
|
|
|
|
|
exit status, output that the process produced (if requested), and so |
|
171
|
|
|
|
|
|
|
on. |
|
172
|
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
What makes this more interesting is the ability to add delegates to |
|
174
|
|
|
|
|
|
|
any of these classes. These delegates are called into at various |
|
175
|
|
|
|
|
|
|
points and allow you to add more features. By default, you just get a |
|
176
|
|
|
|
|
|
|
callback when the process exits. You can also kill the running |
|
177
|
|
|
|
|
|
|
process. That's it. From there, you can add delegates to add more |
|
178
|
|
|
|
|
|
|
features. You can add a pipe to share between the parent and the |
|
179
|
|
|
|
|
|
|
child. Instead of sharing a pipe, you can have an fd opened to an |
|
180
|
|
|
|
|
|
|
arbitrary file descriptor number in the child. You have an infinite |
|
181
|
|
|
|
|
|
|
number of these, so you can capture the child's stdout and stderr, |
|
182
|
|
|
|
|
|
|
write to its stdin, and also share a socket for out-of-band |
|
183
|
|
|
|
|
|
|
communication. You can also open a pipe to the child's fd #5 and |
|
184
|
|
|
|
|
|
|
write to it. (This is nice if you are invoking something like C<gpg> |
|
185
|
|
|
|
|
|
|
that wants the password written on an arbitrary fd other than 1.) |
|
186
|
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
(This is all done with the included C<Handle> delegate. See |
|
188
|
|
|
|
|
|
|
L<AnyEvent::Subprocess::Job::Delegate::Handle>.) |
|
189
|
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
You can then build upon this; instead of writing your own code to |
|
191
|
|
|
|
|
|
|
reading the handles when they become readable and accumulate input, |
|
192
|
|
|
|
|
|
|
you can write a delegate that saves all the data coming from a given |
|
193
|
|
|
|
|
|
|
handle and gives it to your program after the child exits (via the |
|
194
|
|
|
|
|
|
|
C<Done> instance). |
|
195
|
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
(This is also included via the C<CaptureHandle> delegate. See |
|
197
|
|
|
|
|
|
|
L<AnyEvent::Subprocess::Job::Delegate::CaptureHandle>.) |
|
198
|
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
All of this integrates into your existing event-based app; waiting for |
|
200
|
|
|
|
|
|
|
IO from the child (or waiting for the child to exit) is asynchronous, |
|
201
|
|
|
|
|
|
|
and lets your app do other work while waiting for the child. (It can |
|
202
|
|
|
|
|
|
|
integrate nicely into Coro, for example, unlike the default C<qx//>.) |
|
203
|
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
=head1 BUGS |
|
205
|
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
The parent's event loop still exists in the child process, which means |
|
207
|
|
|
|
|
|
|
you can't safely use it in the child. I have tried to work around |
|
208
|
|
|
|
|
|
|
this in a few event loops; my C<AnyEventX::Cancel> module on github is |
|
209
|
|
|
|
|
|
|
an early attempt. When that becomes stable, I will remove this |
|
210
|
|
|
|
|
|
|
restriction. |
|
211
|
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
In the mean time, YOU MUST NOT USE ANY EVENT-LOOP FUNCTIONS IN THE |
|
213
|
|
|
|
|
|
|
CHILD. |
|
214
|
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
This is not a problem if you are running external processes, but is a |
|
216
|
|
|
|
|
|
|
problem if you are running a code block and you want to do event-ful |
|
217
|
|
|
|
|
|
|
things in there. (Note that EV is designed to allow the child to |
|
218
|
|
|
|
|
|
|
handle events that the parent created watchers for. You can do that |
|
219
|
|
|
|
|
|
|
just fine. It's if you want a fresh event loop with no existing |
|
220
|
|
|
|
|
|
|
watchers that doesn't work well yet.) |
|
221
|
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
=head1 AUTHOR |
|
223
|
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
Jonathan Rockway <jrockway@cpan.org> |
|
225
|
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
|
227
|
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
This software is copyright (c) 2011 by Jonathan Rockway. |
|
229
|
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
|
231
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
|
232
|
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
=cut |
|
234
|
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
__END__ |
|
237
|
|
|
|
|
|
|
|