File Coverage

lib/Mojo/IOLoop/ReadWriteProcess.pm
Criterion Covered Total %
statement 345 371 92.9
branch 176 228 77.1
condition 55 103 53.4
subroutine 68 69 98.5
pod 26 28 92.8
total 670 799 83.8


line stmt bran cond sub pod time code
1             package Mojo::IOLoop::ReadWriteProcess;
2              
3             our $VERSION = '0.28';
4              
5 39     39   11454130 use Mojo::Base 'Mojo::EventEmitter';
  39         387651  
  39         359  
  28         438  
  29         126  
  29         272  
6 39     39   71550 use Mojo::File 'path';
  39         61691  
  39         2019  
  29         168  
  2         19  
  2         21  
7 39     39   246 use Mojo::Util qw(b64_decode b64_encode);
  39         77  
  39         3312  
  2         14  
  29         150  
  29         208  
8 39     39   18949 use Mojo::IOLoop::Stream;
  39         5105654  
  39         351  
  29         430  
  29         3160  
  29         11462  
9              
10 39     39   19243 use Mojo::IOLoop::ReadWriteProcess::Exception;
  39         158  
  39         426  
  2         64  
  1         33  
  0            
11 39     39   15836 use Mojo::IOLoop::ReadWriteProcess::Pool;
  39         100  
  39         1991  
  0            
  0            
  0            
12 39     39   15628 use Mojo::IOLoop::ReadWriteProcess::Queue;
  39         105  
  39         321  
  0            
  0            
  0            
13 39     39   1458 use Mojo::IOLoop::ReadWriteProcess::Session;
  39         79  
  39         1452  
  0            
  0            
  0            
14              
15 39     39   16968 use Mojo::IOLoop::ReadWriteProcess::Shared::Lock;
  39         116  
  39         2301  
  0            
16 39     39   16223 use Mojo::IOLoop::ReadWriteProcess::Shared::Memory;
  39         102  
  39         1981  
17 39     39   404 use Mojo::IOLoop::ReadWriteProcess::Shared::Semaphore;
  39         114  
  39         1695  
18              
19 39     39   274 use B::Deparse;
  39         74  
  39         1467  
20 39     39   948 use Carp 'confess';
  39         175  
  39         1976  
21 39     39   268 use IO::Handle;
  39         91  
  39         1494  
22 39     39   19489 use IO::Pipe;
  39         47907  
  39         1380  
23 39     39   18588 use IO::Select;
  39         64513  
  39         1927  
24 39     39   19360 use IPC::Open3;
  39         105372  
  39         2507  
25 39     39   329 use Time::HiRes 'sleep';
  39         57  
  39         398  
26 39     39   4596 use Symbol 'gensym';
  39         78  
  39         1613  
27 39     39   25825 use Storable;
  39         125633  
  39         2475  
28 39     39   310 use POSIX qw( :sys_wait_h :signal_h );
  39         69  
  39         333  
29             our @EXPORT_OK
30             = (qw(parallel batch process pool queue), qw(shared_memory lock semaphore));
31 39     39   14619 use Exporter 'import';
  39         85  
  39         1523  
32              
33 39     39   249 use constant DEBUG => $ENV{MOJO_PROCESS_DEBUG};
  39         92  
  39         221775  
34              
35             has [
36             qw(kill_sleeptime sleeptime_during_kill),
37             qw(separate_err autoflush set_pipes verbose),
38             qw(internal_pipes channels)
39             ] => 1;
40              
41             has [qw(blocking_stop serialize quirkiness total_sleeptime_during_kill)] => 0;
42              
43             has [
44             qw(execute code process_id pidfile return_status),
45             qw(channel_in channel_out write_stream read_stream error_stream),
46             qw(_internal_err _internal_return _status)
47             ];
48              
49             has max_kill_attempts => 5;
50             has kill_whole_group => 0;
51              
52             has args => sub { [] };
53             has error => sub { Mojo::Collection->new };
54              
55             has ioloop => sub { Mojo::IOLoop->singleton };
56             has session => sub { Mojo::IOLoop::ReadWriteProcess::Session->singleton };
57              
58             has _deparse => sub { B::Deparse->new }
59             if DEBUG;
60             has _deserialize => sub { \&Storable::thaw };
61             has _serialize => sub { \&Storable::freeze };
62             has _default_kill_signal => POSIX::SIGTERM;
63             has _default_blocking_signal => POSIX::SIGKILL;
64              
65             # Override new() just to support sugar syntax
66             # so it is possible to do : process->new(sub{ print "Hello World\n" })->start->stop; and so on.
67             sub new {
68 385 100   385 1 106722 push(@_, code => splice @_, 1, 1) if ref $_[1] eq "CODE";
    100     1    
69 385         4684 return shift->SUPER::new(@_);
70             }
71              
72             sub to_ioloop {
73 3     3 1 64 my $self = shift;
74 3 50       598 confess 'Pipes needs to be set!' unless $self->read_stream;
    100          
75 2         12 my $stream = Mojo::IOLoop::Stream->new($self->read_stream)->timeout(0);
76 2         620 $self->ioloop->stream($stream);
77 2         448 my $me = $$;
78             $stream->on(
79             close => sub {
80 2 50   2   325 return unless $$ == $me;
    100          
81 2 50       12 $self->_collect->stop unless defined $self->_status;
    100          
82 2         25 });
83 2         13 return $stream;
84             }
85              
86 167     167 1 91354 sub process { __PACKAGE__->new(@_) }
87 6     6 1 6422 sub batch { Mojo::IOLoop::ReadWriteProcess::Pool->new(@_) }
88 6     6 1 16606 sub queue { Mojo::IOLoop::ReadWriteProcess::Queue->new(@_) }
89 1     1 1 15 sub lock { Mojo::IOLoop::ReadWriteProcess::Shared::Lock->new(@_) }
90 1     1 0 40 sub semaphore { Mojo::IOLoop::ReadWriteProcess::Shared::Semaphore->new(@_) }
91 1     1 0 2 sub shared_memory { Mojo::IOLoop::ReadWriteProcess::Shared::Memory->new(@_) }
92              
93             sub parallel {
94 3     3 1 1370 my $c = batch();
95 3         91 $c->add(@_) for 1 .. +pop();
96 3         29 return $c;
97             }
98              
99             sub _diag {
100 10     10   3193 my ($self, @messages) = @_;
101 10         210 my $caller = (caller(1))[3];
102 10 50       125 print STDERR ">> ${caller}(): @messages\n" if (DEBUG || $self->verbose);
    0          
103             }
104              
105             sub _open_collect_status {
106 18     18   2128 my ($self, $pid, $e, $errno) = @_;
107              
108 18 50       138 return unless $self;
    0          
109              
110 18 50 33     121 $self->_status($e // $?) unless defined $self->_status;
    0 100        
111 17         398 $self->_diag("Forked code Process Exit status: " . $self->exit_status)
112             if DEBUG;
113              
114 17         156 $self->_clean_pidfile;
115              
116 17         100 return $self;
117             }
118              
119             # Use open3 to launch external program.
120             sub _open {
121 33     33   422 my ($self, @args) = @_;
122 33         89 $self->_diag('Execute: ' . (join ', ', map { "'$_'" } @args)) if DEBUG;
123              
124 33         144 $self->session->enable;
125              
126 33         228 my ($wtr, $rdr, $err);
127 33         232 $err = gensym;
128 33 100       842 my $pid = open3($wtr, $rdr, ($self->separate_err) ? $err : undef, @args);
129              
130 28 100       148770 die "Cannot create pipe: $!" unless defined $pid;
131 27         6024 $self->process_id($pid);
132              
133             # Defered collect of return status and removal of pidfile
134 27         1223 $self->on(collect_status => \&_open_collect_status);
135              
136 27 100       1469 return $self unless $self->set_pipes();
137              
138 25         1108 $self->read_stream(IO::Handle->new_from_fd($rdr, "r"));
139 25         7553 $self->write_stream(IO::Handle->new_from_fd($wtr, "w"));
140 25 100       3394 $self->error_stream(($self->separate_err)
141             ? IO::Handle->new_from_fd($err, "r")
142             : $self->write_stream);
143              
144 25         2694 return $self;
145             }
146              
147 425 100   434   1906 sub _clean_pidfile { unlink(shift->pidfile) if $_[0]->pidfile }
148              
149             sub _collect {
150 60     50   288 my ($self, $pid) = @_;
151 11   33     21 $pid //= $self->pid;
      66        
152              
153             $self->session->_protect(
154             sub {
155 11     1   84 local $?;
156 11 100       65 waitpid $pid, 0 unless defined $self->_status;
157 11 100       269 return $self->_open_collect_status($pid) if $self->execute;
158 11 100       51073 return $self->_fork_collect_status($pid) if $self->code;
159 11         50 });
160              
161 11         186 $self;
162             }
163              
164             sub _fork_collect_status {
165 248     238   11067 my ($self, $pid, $e, $errno) = @_;
166              
167 248 100       1465 return unless $self;
168              
169 246         1676 my $return_reader;
170             my $internal_err_reader;
171 246         2409 my $rt;
172 246         1269 my @result_error;
173              
174 246 50 100     2301 $self->_status($e // $?) unless defined $self->_status;
      100        
175 237         4142 $self->_diag("Forked code Process Exit status: " . $self->exit_status)
176             if DEBUG;
177              
178 237 100       1080 if ($self->_internal_return) {
179 184 50       1382 $return_reader
180             = $self->_internal_return->isa("IO::Pipe::End")
181             ? $self->_internal_return
182             : $self->_internal_return->reader();
183 184 50 0     24166 $self->_new_err('Cannot read from return code pipe') && return
      33        
184             unless IO::Select->new($return_reader)->can_read(10);
185 184         6345877 $rt = $return_reader->getline();
186 184         10131561 $self->_diag("Forked code Process Returns: " . ($rt ? $rt : 'nothing'))
187             if DEBUG;
188             $self->return_status(
189 184 100       1677 $self->serialize ? eval { $self->_deserialize->(b64_decode($rt)) }
  2 100       93  
190             : $rt ? $rt
191             : ());
192             }
193 237 100       5769 if ($self->_internal_err) {
194 185 100       1751 $internal_err_reader
195             = $self->_internal_err->isa("IO::Pipe::End")
196             ? $self->_internal_err
197             : $self->_internal_err->reader();
198 185 100 50     20902 $self->_new_err('Cannot read from errors code pipe') && return
      66        
199             unless IO::Select->new($internal_err_reader)->can_read(10);
200 183         33845 @result_error = $internal_err_reader->getlines();
201             push(
202 60         430 @{$self->error},
203 183 100       13353 map { Mojo::IOLoop::ReadWriteProcess::Exception->new($_) } @result_error
  60         3348  
204             ) if @result_error;
205 183         400 $self->_diag("Forked code Process Errors: " . join("\n", @result_error))
206             if DEBUG;
207             }
208              
209 235         2008 $self->_clean_pidfile;
210 235         1828 return $self;
211             }
212              
213             # Handle forking of code
214             sub _fork {
215 221     222   1786 my ($self, $code, @args) = @_;
216 221 100       1110 die "Can't spawn child without code" unless ref($code) eq "CODE";
217              
218             # STDIN/STDOUT/STDERR redirect.
219 218         752 my ($input_pipe, $output_pipe, $output_err_pipe);
220              
221             # Separated handles that could be used for internal comunication.
222 218         0 my ($channel_in, $channel_out);
223              
224 218 100       808 if ($self->set_pipes) {
225 168 100       2583 $input_pipe = IO::Pipe->new()
226             or $self->_new_err('Failed creating input pipe');
227 168 100       27188 $output_pipe = IO::Pipe->new()
228             or $self->_new_err('Failed creating output pipe');
229 168 100       16625 $output_err_pipe = IO::Pipe->new()
230             or $self->_new_err('Failed creating output error pipe');
231 168 50       16242 if ($self->channels) {
232 168 100       2509 $channel_in = IO::Pipe->new()
233             or $self->_new_err('Failed creating Channel input pipe');
234 168 100       16173 $channel_out = IO::Pipe->new()
235             or $self->_new_err('Failed creating Channel output pipe');
236             }
237             }
238 218 100       18081 if ($self->internal_pipes) {
239 214 100       3431 my $internal_err = IO::Pipe->new()
240             or $self->_new_err('Failed creating internal error pipe');
241 214 100       25570 my $internal_return = IO::Pipe->new()
242             or $self->_new_err('Failed creating internal return pipe');
243              
244             # Internal pipes to retrieve error/return
245 214         21298 $self->_internal_err($internal_err);
246 214         2478 $self->_internal_return($internal_return);
247             }
248              
249             # Defered collect of return status
250              
251 218         3797 $self->on(collect_status => \&_fork_collect_status);
252              
253 218         2270 $self->_diag("Fork: " . $self->_deparse->coderef2text($code)) if DEBUG;
254              
255 218         314336 my $pid = fork;
256 218 50       7348 die "Cannot fork: $!" unless defined $pid;
257              
258 218 100       3301 if ($pid == 0) {
259 20         3002 local $SIG{CHLD};
260 20     1   2933 local $SIG{TERM} = sub { $self->emit('SIG_TERM')->_exit(1) };
  0         0  
261              
262 20         651 my $return;
263             my $internal_err;
264              
265 20 50       1558 if ($self->internal_pipes) {
266 20 100       1660 if ($self->_internal_err) {
267 19 50       924 $internal_err
268             = $self->_internal_err->isa("IO::Pipe::End")
269             ? $self->_internal_err
270             : $self->_internal_err->writer();
271 19         6600 $internal_err->autoflush(1);
272             }
273              
274 20 100       4788 if ($self->_internal_return) {
275 19 50       904 $return
276             = $self->_internal_return->isa("IO::Pipe::End")
277             ? $self->_internal_return
278             : $self->_internal_return->writer();
279 19         2207 $return->autoflush(1);
280             }
281             else {
282 1         29 eval { $internal_err->write("Can't setup return status pipe") };
  1         28  
283             }
284             }
285              
286             # Set pipes to redirect STDIN/STDOUT/STDERR + channels if desired
287 20 100       1423 if ($self->set_pipes()) {
288 19         510 my $stdout;
289             my $stderr;
290 19         0 my $stdin;
291              
292 19 100       626 $stdout = $output_pipe->writer() if $output_pipe;
293 19 100       1823 $stderr
    100          
294             = (!$self->separate_err) ? $stdout
295             : $output_err_pipe ? $output_err_pipe->writer()
296             : undef;
297 19 100       2500 $stdin = $input_pipe->reader() if $input_pipe;
298 19 50 33     3957 open STDERR, ">&", $stderr
      0        
299             or !!$internal_err->write($!)
300             or $self->_diag($!);
301 18 50 33     928 open STDOUT, ">&", $stdout
302             or !!$internal_err->write($!)
303             or $self->_diag($!);
304 18 50 33     687 open STDIN, ">&", $stdin
305             or !!$internal_err->write($!)
306             or $self->_diag($!);
307              
308 18         284 $self->read_stream($stdin);
309 18         613 $self->error_stream($stderr);
310 18         437 $self->write_stream($stdout);
311 18 50       556 if ($self->channels) {
312              
313 18 50       620 $self->channel_in($channel_in->reader) if $channel_in;
314 18 50       1551 $self->channel_out($channel_out->writer) if $channel_out;
315 36         1552 eval { $self->$_->autoflush($self->autoflush) }
316 18         1605 for qw( channel_in channel_out );
317             }
318 54         1690 eval { $self->$_->autoflush($self->autoflush) }
319 18         790 for qw(read_stream error_stream write_stream );
320             }
321 19         1009 $self->session->reset;
322 19         4237 $self->session->subreaper(0); # Subreaper bit does not persist in fork
323 19         1025 $self->process_id($$);
324 19         596 $! = 0;
325 19         148 my $rt;
326 19         85 eval { $rt = [$code->($self, @args)]; };
  19         193  
327 0 0       0 if ($internal_err) {
328 0 0       0 $internal_err->write($@) if $@;
329 0 0 0     0 $internal_err->write($!) if !$@ && $!;
330             }
331 0 0 0     0 $rt = @$rt[0]
      0        
332             if !$self->serialize && ref $rt eq 'ARRAY' && scalar @$rt == 1;
333 0 0 0     0 $rt = b64_encode(eval { $self->_serialize->($rt) })
  0         0  
334             if $self->serialize && $return;
335 0 0       0 $return->write($rt) if $return;
336 0   0     0 $self->_exit($@ // $!);
337             }
338 198         15007 $self->process_id($pid);
339              
340 198         11436 $self->session->enable;
341              
342 198 100       3252 return $self unless $self->set_pipes();
343              
344 149 100       6066 $self->read_stream($output_pipe->reader) if $output_pipe;
345 149 100       33818 $self->error_stream((!$self->separate_err) ? $self->read_stream()
    100          
346             : $output_err_pipe ? $output_err_pipe->reader()
347             : undef);
348 149 100       15603 $self->write_stream($input_pipe->writer) if $input_pipe;
349              
350 149 50       14985 if ($self->set_pipes) {
351 149 50       2707 if ($self->channels) {
352 149 100       2048 $self->channel_in($channel_in->writer) if $channel_in;
353 149 100       12273 $self->channel_out($channel_out->reader) if $channel_out;
354 298         23127 eval { $self->$_->autoflush($self->autoflush) }
355 149         13493 for qw( channel_in channel_out );
356             }
357 447         11901 eval { $self->$_->autoflush($self->autoflush) }
358 149         6698 for qw(read_stream error_stream write_stream );
359             }
360              
361 149         7878 return $self;
362             }
363              
364             sub _new_err {
365 25     26   240 my $self = shift;
366 25         248 my $err = Mojo::IOLoop::ReadWriteProcess::Exception->new(@_);
367 25         82 push(@{$self->error}, $err);
  25         126  
368              
369             # XXX: Need to switch, we should emit one error at the time, and _shutdown
370             # should emit just the ones wasn't emitted
371 25         276 return $self->emit(process_error => [$err]);
372             }
373              
374             sub _exit {
375 0   0 1   0 my $code = shift // 0;
376 0         0 eval { POSIX::_exit($code); };
  0         0  
377 0         0 exit($code);
378             }
379              
380             sub wait {
381 103     104 1 5386 my $self = shift;
382 103         482 sleep $self->sleeptime_during_kill while ($self->is_running);
383 103         2357 return $self;
384             }
385              
386 84     85 1 4452 sub wait_stop { shift->wait->stop }
387 12 100   12 1 13860 sub errored { !!@{shift->error} ? 1 : 0 }
  12         102  
388              
389             # PPC64: Treat msb on neg (different cpu/perl interpreter version)
390 0 0   0   0 sub _st { my $st = shift >> 8; ($st & 0x80) ? (0x100 - ($st & 0xFF)) : $st }
  0         0  
391              
392             sub exit_status {
393 31 50 33 31 1 15873 defined $_[0]->_status && $_[0]->quirkiness ? _st(shift->_status)
    50          
394             : defined $_[0]->_status ? shift->_status >> 8
395             : undef;
396             }
397              
398             sub restart {
399 15 100   15 1 4719 $_[0]->is_running ? $_[0]->stop->start : $_[0]->start;
400             }
401 1035 100   1035 1 65048767 sub is_running { $_[0]->process_id ? kill 0 => $_[0]->process_id : 0; }
402              
403             sub write_pidfile {
404 531     531 1 1099407 my ($self, $pidfile) = @_;
405 241 100       1006 $self->pidfile($pidfile) if $pidfile;
406 241 100       1335 return unless $self->pid;
407 239 100       2536 return unless $self->pidfile;
408              
409 6         384 path($self->pidfile)->spurt($self->pid);
410 6         2451 return $self;
411             }
412              
413             # Convenience functions
414             sub _syswrite {
415 18     18   156 my $stream = shift;
416 18 50       89 return unless $stream;
417 18         320 $stream->syswrite($_ . "\n") for @_;
418             }
419              
420             sub _getline {
421 74 100   73   1565 return unless IO::Select->new($_[0])->can_read(10);
422 66         47515 shift->getline;
423             }
424              
425             sub _getlines {
426 6 100   6   79 return unless IO::Select->new($_[0])->can_read(10);
427 6 100       1097 wantarray ? shift->getlines : join '\n', @{[shift->getlines]};
  4         133  
428             }
429              
430             # Write to the controlled-process STDIN
431             sub write_stdin {
432 9     9 1 5986 my ($self, @data) = @_;
433 9         57 _syswrite($self->write_stream, @data);
434 9         455 return $self;
435             }
436              
437             sub write_channel {
438 7     7 1 3429 my ($self, @data) = @_;
439 7         58 _syswrite($self->channel_in, @data);
440 7         310 return $self;
441             }
442              
443             # Get all lines from the current process output stream
444 3     3 1 888 sub read_all_stdout { _getlines(shift->read_stream) }
445              
446             # Get all lines from the process channel
447 4     3 1 2581 sub read_all_channel { _getlines(shift->channel_out); }
448 39     38 1 7729 sub read_stdout { _getline(shift->read_stream) }
449 20     20 1 4586 sub read_channel { _getline(shift->channel_out) }
450              
451             sub read_all_stderr {
452 3 100   3 1 728 return $_[0]->getline unless $_[0]->separate_err;
453 1         35 _getlines(shift->error_stream);
454             }
455              
456             # Get a line from the current process output stream
457             sub read_stderr {
458 14 50   14 1 22342 return $_[0]->getline unless $_[0]->separate_err;
459 14         148 _getline(shift->error_stream);
460             }
461              
462             sub start {
463 256     256 1 6677 my $self = shift;
464 256 50       1023 return $self if $self->is_running;
465 256 100 100     2696 die "Nothing to do" unless !!$self->execute || !!$self->code;
466              
467             my @args
468             = $self->args
469             ? ref($self->args) eq "ARRAY"
470 253 100       5116 ? @{$self->args}
  207 50       1646  
471             : $self->args
472             : ();
473              
474 253 100       2758 $self->session->enable_subreaper if $self->subreaper;
475 253         5828 $self->_status(undef);
476              
477 253 100       2695 if ($self->code) {
    50          
478 218         1313 $self->_fork($self->code, @args);
479             }
480             elsif ($self->execute) {
481 35         467 $self->_open($self->execute, @args);
482             }
483              
484 233         6918 $self->write_pidfile;
485 233         3616 $self->emit('start');
486 233         8542 $self->session->register($self->pid() => $self);
487              
488 233         10672 return $self;
489             }
490              
491             sub send_signal {
492 242     242 1 806 my $self = shift;
493 242   33     788 my $signal = shift // $self->_default_kill_signal;
494 242   66     678 my $pid = shift // $self->process_id;
495 242 100 100     699 return unless $self->kill_whole_group || $self->is_running;
496 214         4439 $self->_diag("Sending signal '$signal' to $pid") if DEBUG;
497 214         8512 kill $signal => $pid;
498 214         788 return $self;
499             }
500              
501             sub stop {
502 226     225 1 63756 my $self = shift;
503              
504 225         1845 my $pid = $self->pid;
505 226 100       2113 return $self unless defined $pid;
506 224 100       958 return $self->_shutdown(1) unless $self->is_running;
507 52         1115 $self->_diag("Stopping $pid") if DEBUG;
508              
509 52         163 my $ret;
510 52         158 my $attempt = 1;
511 50   33     169 my $timeout = $self->total_sleeptime_during_kill // 0;
512 50         708 my $sleep_time = $self->sleeptime_during_kill;
513 50         313 my $max_attempts = $self->max_kill_attempts;
514 50         746 my $signal = $self->_default_kill_signal;
515 50 100       661 $pid = -getpgrp($pid) if $self->kill_whole_group;
516 50   66     1302 until ((defined $ret && ($ret == $pid || $ret == -1))
      100        
      100        
      100        
517             || ($attempt > $max_attempts && $timeout <= 0))
518             {
519 226   100     1289 my $send_signal = $attempt == 1 || $timeout <= 0;
520 226         347 $self->_diag(
521             "attempt $attempt/$max_attempts to kill process: $pid, timeout: $timeout")
522             if DEBUG && $send_signal;
523             $self->session->_protect(
524             sub {
525 226     227   1335 local $?;
526 226 100       581 if ($send_signal) {
527 222         824 $self->send_signal($signal, $pid);
528 222         733 ++$attempt;
529             }
530 226         1411 $ret = waitpid($pid, WNOHANG);
531 226 100 66     2558 $self->_status($?) if $ret == $pid || $ret == -1;
532 226         1333 });
533 226 50       1514 if ($sleep_time) {
534 226         2049693 sleep $sleep_time;
535 226         4580 $timeout -= $sleep_time;
536             }
537             }
538 50 100       352 return $self->_shutdown if defined $self->_status;
539              
540 22 50       370 sleep $self->kill_sleeptime if $self->kill_sleeptime;
541              
542 22 100       223269 if ($self->blocking_stop) {
543 16         351 $self->_diag("Could not kill process id: $pid, blocking attempt") if DEBUG;
544 16         132 $self->emit('process_stuck');
545              
546             ### XXX: avoid to protect on blocking.
547 16         309 $self->send_signal($self->_default_blocking_signal, $pid);
548 16         5063 $ret = waitpid($pid, 0);
549 16 100 66     434 $self->_status($?) if $ret == $pid || $ret == -1;
550 16         216 return $self->_shutdown;
551             }
552             else {
553 6         87 $self->_diag("Could not kill process id: $pid") if DEBUG;
554 6         63 $self->_new_err('Could not kill process');
555             }
556 6         138 return $self;
557             }
558              
559             sub _shutdown {
560 190     189   4180 my ($self, $wait) = @_;
561 190 50       788 return $self unless $self->pid;
562              
563 190         1491 $self->_diag("Shutdown " . $self->pid) if DEBUG;
564             $self->session->_protect(
565             sub {
566 56     82   279 local $?;
567 56         226 waitpid $self->pid, 0;
568 56         713 $self->emit('collect_status');
569 190 100 100     1871 }) if $wait && !defined $self->_status;
570              
571 190 100       1920 $self->emit('collect_status') unless defined $self->_status;
572 190         2276 $self->_clean_pidfile;
573 190 100 100     1986 $self->emit('process_error', $self->error)
574             if $self->error && $self->error->size > 0;
575 190         11340 $self->unsubscribe('collect_status');
576              
577 190         3428 return $self->emit('stop');
578             }
579              
580             # General alias
581             *pid = \&process_id;
582             *died = \&_errored;
583             *failed = \&_errored;
584             *diag = \&_diag;
585             *pool = \&batch;
586             *signal = \&send_signal;
587             *prctl = \&Mojo::IOLoop::ReadWriteProcess::Session::_prctl;
588             *subreaper = \&Mojo::IOLoop::ReadWriteProcess::Session::subreaper;
589              
590             *enable_subreaper = \&Mojo::IOLoop::ReadWriteProcess::Session::enable_subreaper;
591             *disable_subreaper
592             = \&Mojo::IOLoop::ReadWriteProcess::Session::disable_subreaper;
593             *_get_prctl_syscall
594             = \&Mojo::IOLoop::ReadWriteProcess::Session::_get_prctl_syscall;
595              
596             # Aliases - write
597             *write = \&write_stdin;
598             *stdin = \&write_stdin;
599             *channel_write = \&write_channel;
600              
601             # Aliases - read
602             *read = \&read_stdout;
603             *stdout = \&read_stdout;
604             *getline = \&read_stdout;
605             *stderr = \&read_stderr;
606             *err_getline = \&read_stderr;
607             *channel_read = \&read_channel;
608             *read_all = \&read_all_stdout;
609             *getlines = \&read_all_stdout;
610             *stderr_all = \&read_all_stderr;
611             *err_getlines = \&read_all_stderr;
612             *channel_read_all = \&read_all_channel;
613              
614             # Aliases - IO::Handle
615             *stdin_handle = \&write_stream;
616             *stdout_handle = \&read_stream;
617             *stderr_handle = \&error_stream;
618             *channe_write_handle = \&channel_in;
619             *channel_read_handle = \&channel_out;
620              
621             1;
622              
623              
624             =encoding utf-8
625              
626             =head1 NAME
627              
628             Mojo::IOLoop::ReadWriteProcess - Execute external programs or internal code blocks as separate process.
629              
630             =head1 SYNOPSIS
631              
632             use Mojo::IOLoop::ReadWriteProcess;
633              
634             # Code fork
635             my $process = Mojo::IOLoop::ReadWriteProcess->new(sub { print "Hello\n" });
636             $process->start();
637             print "Running\n" if $process->is_running();
638             $process->getline(); # Will return "Hello\n"
639             $process->pid(); # Process id
640             $process->stop();
641             $process->wait_stop(); # if you intend to wait its lifespan
642              
643             # Methods can be chained, thus this is valid:
644             use Mojo::IOLoop::ReadWriteProcess qw(process);
645             my $output = process( sub { print "Hello\n" } )->start()->wait_stop->getline;
646              
647             # Handles seamelessy also external processes:
648             my $process = process(execute=> '/path/to/bin' )->args(qw(foo bar baz));
649             $process->start();
650             my $line_output = $process->getline();
651             my $pid = $process->pid();
652             $process->stop();
653             my @errors = $process->error;
654              
655             # Get process return value
656             $process = process( sub { return "256"; } )->start()->wait_stop;
657             # We need to stop it to retrieve the exit status
658             my $return = $process->return_status;
659              
660             # We can access directly to handlers from the object:
661             my $stdout = $process->read_stream;
662             my $stdin = $process->write_stream;
663             my $stderr = $process->error_stream;
664              
665             # So this works:
666             print $stdin "foo bar\n";
667             my @lines = <$stdout>;
668              
669             # There is also an alternative channel of communication (just for forked processes):
670             my $channel_in = $process->channel_in; # write to the child process
671             my $channel_out = $process->channel_out; # read from the child process
672             $process->channel_write("PING"); # convenience function
673              
674             =head1 DESCRIPTION
675              
676             Mojo::IOLoop::ReadWriteProcess is yet another process manager.
677              
678             =head1 EVENTS
679              
680             L inherits all events from L and can emit
681             the following new ones.
682              
683             =head2 start
684              
685             $process->on(start => sub {
686             my ($process) = @_;
687             $process->is_running();
688             });
689              
690             Emitted when the process starts.
691              
692             =head2 stop
693              
694             $process->on(stop => sub {
695             my ($process) = @_;
696             $process->restart();
697             });
698              
699             Emitted when the process stops.
700              
701             =head2 process_error
702              
703             $process->on(process_error => sub {
704             my ($e) = @_;
705             my @errors = @{$e};
706             });
707              
708             Emitted when the process produce errors.
709              
710             =head2 process_stuck
711              
712             $process->on(process_stuck => sub {
713             my ($self) = @_;
714             ...
715             });
716              
717             Emitted when C is set and all attempts for killing the process
718             in C have been exhausted.
719             The event is emitted before attempting to kill it with SIGKILL and becoming blocking.
720              
721             =head2 SIG_CHLD
722              
723             $process->on(SIG_CHLD => sub {
724             my ($self) = @_;
725             ...
726             });
727              
728             Emitted when we receive SIG_CHLD.
729              
730             =head2 SIG_TERM
731              
732             $process->on(SIG_TERM => sub {
733             my ($self) = @_;
734             ...
735             });
736              
737             Emitted when the child forked process receives SIG_TERM, before exiting.
738              
739             =head2 collected
740              
741             $process->on(collected => sub {
742             my ($self) = @_;
743             ...
744             });
745              
746             Emitted right after status collection.
747              
748             =head2 collect_status
749              
750             $process->on(collect_status => sub {
751             my ($self) = @_;
752             ...
753             });
754              
755             Emitted when on child process waitpid.
756             It is used internally to get the child process status.
757             Note: events attached to it are wiped when process has been stopped.
758              
759             =head1 ATTRIBUTES
760              
761             L inherits all attributes from L and implements
762             the following new ones.
763              
764             =head2 execute
765              
766             use Mojo::IOLoop::ReadWriteProcess;
767             my $process = Mojo::IOLoop::ReadWriteProcess->new(execute => "/usr/bin/perl");
768             $process->start();
769             $process->on( stop => sub { print "Process: ".(+shift()->pid)." finished"; } );
770             $process->stop();
771              
772             C should contain the external program that you wish to run.
773              
774             =head2 code
775              
776             use Mojo::IOLoop::ReadWriteProcess;
777             my $process = Mojo::IOLoop::ReadWriteProcess->new(code => sub { print "Hello" } );
778             $process->start();
779             $process->on( stop => sub { print "Process: ".(+shift()->pid)." finished"; } );
780             $process->stop();
781              
782             It represent the code you want to run in background.
783              
784             You do not need to specify C, it is implied if no arguments is given.
785              
786             my $process = Mojo::IOLoop::ReadWriteProcess->new(sub { print "Hello" });
787             $process->start();
788             $process->on( stop => sub { print "Process: ".(+shift()->pid)." finished"; } );
789             $process->stop();
790              
791             =head2 args
792              
793             use Mojo::IOLoop::ReadWriteProcess;
794             my $process = Mojo::IOLoop::ReadWriteProcess->new(code => sub { print "Hello ".$_[1] }, args => "User" );
795             $process->start();
796             $process->on( stop => sub { print "Process: ".(+shift()->pid)." finished"; } );
797             $process->stop();
798              
799             # The process will print "Hello User"
800              
801             Array or arrayref of options to pass by to the external binary or the code block.
802              
803             =head2 blocking_stop
804              
805             use Mojo::IOLoop::ReadWriteProcess;
806             my $process = Mojo::IOLoop::ReadWriteProcess->new(code => sub { print "Hello" }, blocking_stop => 1 );
807             $process->start();
808             $process->on( stop => sub { print "Process: ".(+shift()->pid)." finished"; } );
809             $process->stop(); # Will wait indefinitely until the process is stopped
810              
811             Set it to 1 if you want to do blocking stop of the process.
812              
813              
814             =head2 channels
815              
816             use Mojo::IOLoop::ReadWriteProcess;
817             my $process = Mojo::IOLoop::ReadWriteProcess->new(code => sub { print "Hello" }, channels => 0 );
818             $process->start();
819             $process->on( stop => sub { print "Process: ".(+shift()->pid)." finished"; } );
820             $process->stop(); # Will wait indefinitely until the process is stopped
821              
822             Set it to 0 if you want to disable internal channels.
823              
824             =head2 session
825              
826             use Mojo::IOLoop::ReadWriteProcess;
827             my $process = Mojo::IOLoop::ReadWriteProcess->new(sub { print "Hello" });
828             my $session = $process->session;
829             $session->enable_subreaper;
830              
831             Returns the current L singleton.
832              
833             =head2 subreaper
834              
835             use Mojo::IOLoop::ReadWriteProcess;
836             my $process = Mojo::IOLoop::ReadWriteProcess->new(code => sub { print "Hello ".$_[1] }, args => "User" );
837             $process->subreaper(1)->start();
838             $process->on( stop => sub { shift()->disable_subreaper } );
839             $process->stop();
840              
841             # The process will print "Hello User"
842              
843             Mark the current process (not the child) as subreaper on start.
844             It's on invoker behalf to disable subreaper when process stops, as it marks the current process and not the
845             child.
846              
847             =head2 ioloop
848              
849             my $loop = $process->ioloop;
850             $subprocess = $process->ioloop(Mojo::IOLoop->new);
851              
852             Event loop object to control, defaults to the global L singleton.
853              
854             =head2 max_kill_attempts
855              
856             use Mojo::IOLoop::ReadWriteProcess;
857             my $process = Mojo::IOLoop::ReadWriteProcess->new(code => sub { print "Hello" }, max_kill_attempts => 50 );
858             $process->start();
859             $process->on( stop => sub { print "Process: ".(+shift()->pid)." finished"; } );
860             $process->stop(); # It will attempt to send SIGTERM 50 times.
861              
862             Defaults to C<5>, is the number of attempts before bailing out.
863              
864             It can be used with blocking_stop, so if the number of attempts are exhausted,
865             a SIGKILL and waitpid will be tried at the end.
866              
867             =head2 kill_whole_group
868              
869             use Mojo::IOLoop::ReadWriteProcess;
870             my $process = Mojo::IOLoop::ReadWriteProcess->new(code => sub { setpgrp(0, 0); exec(...); }, kill_whole_group => 1 );
871             $process->start();
872             $process->send_signal(...); # Will skip the usual check whether $process->pid is running
873             $process->stop(); # Kills the entire process group and waits for all processes in the group to finish
874              
875             Defaults to C<0>, whether to send signals (e.g. to stop) to the entire process group.
876              
877             This is useful when the sub process creates further sub processes and creates a new process
878             group as shown in the example. In this case it might be useful to take care of the entire process
879             group when stopping and wait for every process in the group to finish.
880              
881             =head2 collect_status
882              
883             Defaults to C<1>, If enabled it will automatically collect the status of the children process.
884             Disable it in case you want to manage your process child directly, and do not want to rely on
885             automatic collect status. If you won't overwrite your C handler,
886             the C event will be still emitted.
887              
888             =head2 serialize
889              
890             Defaults to C<0>, If enabled data returned from forked process will be serialized with Storable.
891              
892             =head2 kill_sleeptime
893              
894             Defaults to C<1>, it's the seconds to wait before attempting SIGKILL when blocking_stop is setted to 1.
895              
896             =head2 separate_err
897              
898             Defaults to C<1>, it will create a separate channel to intercept process STDERR,
899             otherwise it will be redirected to STDOUT.
900              
901             =head2 verbose
902              
903             Defaults to C<1>, it indicates message verbosity.
904              
905             =head2 set_pipes
906              
907             Defaults to C<1>, If enabled, additional pipes for process communication are automatically set up.
908              
909              
910             =head2 internal_pipes
911              
912             Defaults to C<1>, If enabled, additional pipes for retreiving process return and errors are set up.
913             Note: If you disable that, the only information provided by the process will be the exit_status.
914              
915             =head2 autoflush
916              
917             Defaults to C<1>, If enabled autoflush of handlers is enabled automatically.
918              
919             =head2 error
920              
921             Returns a L of errors.
922             Note: errors that can be captured only at the end of the process
923              
924             =head1 METHODS
925              
926             L inherits all methods from L and implements
927             the following new ones.
928              
929             =head2 start()
930              
931             use Mojo::IOLoop::ReadWriteProcess qw(process);
932             my $p = process(sub {
933             print STDERR "Boo\n"
934             } )->start;
935              
936             Starts the process
937              
938             =head2 stop()
939              
940             use Mojo::IOLoop::ReadWriteProcess qw(process);
941             my $p = process( execute => "/path/to/bin" )->start->stop;
942              
943             Stop the process. Unless you use C, it will attempt to kill the process
944             without waiting the process to finish. By defaults it send C to the child.
945             You can change that by defining the internal attribute C<_default_kill_signal>.
946             Note, if you want to be *sure* that the process gets killed, you can enable the
947             C attribute, that will attempt to send C after C
948             is reached.
949              
950             =head2 restart()
951              
952             use Mojo::IOLoop::ReadWriteProcess qw(process);
953             my $p = process( execute => "/path/to/bin" )->restart;
954              
955             It restarts the process if stopped, or if already running, it stops it first.
956              
957             =head2 is_running()
958              
959             use Mojo::IOLoop::ReadWriteProcess qw(process);
960             my $p = process( execute => "/path/to/bin" )->start;
961             $p->is_running;
962              
963             Boolean, it inspect if the process is currently running or not.
964              
965             =head2 exit_status()
966              
967             use Mojo::IOLoop::ReadWriteProcess qw(process);
968             my $p = process( execute => "/path/to/bin" )->start;
969              
970             $p->wait_stop->exit_status;
971              
972             Inspect the process exit status, it does the shifting magic, to access to the real value
973             call C<_status()>.
974              
975             =head2 return_status()
976              
977             use Mojo::IOLoop::ReadWriteProcess qw(process);
978             my $p = process( sub { return 42 } )->start;
979              
980             my $s = $p->wait_stop->return_status; # 42
981              
982             Inspect the codeblock return.
983              
984             =head2 enable_subreaper()
985              
986             use Mojo::IOLoop::ReadWriteProcess qw(process);
987             my $p = process()->enable_subreaper;
988              
989             Mark the current process (not the child) as subreaper.
990             This is used typically if you want to mark further childs as subreapers inside other forks.
991              
992             my $master_p = process(
993             sub {
994             my $p = shift;
995             $p->enable_subreaper;
996              
997             process(sub { sleep 4; exit 1 })->start();
998             process(
999             sub {
1000             sleep 4;
1001             process(sub { sleep 1; })->start();
1002             })->start();
1003             process(sub { sleep 4; exit 0 })->start();
1004             process(sub { sleep 4; die })->start();
1005             my $manager
1006             = process(sub { sleep 2 })->subreaper(1)->start();
1007             sleep 1 for (0 .. 10);
1008             $manager->stop;
1009             return $manager->session->all->size;
1010             });
1011              
1012             $master_p->subreaper(1);
1013              
1014             $master_p->on(collected => sub { $status++ });
1015              
1016             # On start we setup the current process as subreaper
1017             # So it's up on us to disable it after process is done.
1018             $master_p->on(stop => sub { shift()->disable_subreaper });
1019             $master_p->start();
1020              
1021             =head2 disable_subreaper()
1022              
1023             use Mojo::IOLoop::ReadWriteProcess qw(process);
1024             my $p = process()->disable_subreaper;
1025              
1026             Unset the current process (not the child) as subreaper.
1027              
1028             =head2 prctl()
1029              
1030             use Mojo::IOLoop::ReadWriteProcess qw(process);
1031             my $p = process();
1032             $p->prctl($option, $arg2, $arg3, $arg4, $arg5);
1033              
1034             Internal function to execute and wrap the prctl syscall, accepts the same arguments as prctl.
1035              
1036             =head2 diag()
1037              
1038             use Mojo::IOLoop::ReadWriteProcess qw(process);
1039             my $p = process(sub { print "Hello\n" });
1040             $p->on( stop => sub { shift->diag("Done!") } );
1041             $p->start->wait_stop;
1042              
1043             Internal function to print information to STDERR if verbose attribute is set or either DEBUG mode enabled.
1044             You can use it if you wish to display information on the process status.
1045              
1046             =head2 to_ioloop()
1047              
1048             use Mojo::IOLoop::ReadWriteProcess qw(process);
1049              
1050             my $p = process(sub { print "Hello from first process\n"; sleep 1 });
1051              
1052             $p->start(); # Start and sets the handlers
1053             my $stream = $p->to_ioloop; # Get the stream and demand to IOLoop
1054             my $output;
1055              
1056             # Hook on Mojo::IOLoop::Stream events
1057             $stream->on(read => sub { $output .= pop; $p->is_running ... });
1058              
1059             Mojo::IOLoop->singleton->start() unless Mojo::IOLoop->singleton->is_running;
1060              
1061             Returns a L object and demand the wait operation to L.
1062             It needs C enabled. Default IOLoop can be overridden in C.
1063              
1064             =head2 wait()
1065              
1066             use Mojo::IOLoop::ReadWriteProcess qw(process);
1067             my $p = process(sub { print "Hello\n" })->wait;
1068             # ... here now you can mangle $p handlers and such
1069              
1070             Waits until the process finishes, but does not performs cleanup operations (until stop is called).
1071              
1072             =head2 wait_stop()
1073              
1074             use Mojo::IOLoop::ReadWriteProcess qw(process);
1075             my $p = process(sub { print "Hello\n" })->start->wait_stop;
1076             # $p is not running anymore, and all possible events have been granted to be emitted.
1077              
1078             Waits until the process finishes, and perform cleanup operations.
1079              
1080             =head2 errored()
1081              
1082             use Mojo::IOLoop::ReadWriteProcess qw(process);
1083             my $p = process(sub { die "Nooo" })->start->wait_stop;
1084             $p->errored; # will return "1"
1085              
1086             Returns a boolean indicating if the process had errors or not.
1087              
1088             =head2 write_pidfile()
1089              
1090             use Mojo::IOLoop::ReadWriteProcess qw(process);
1091             my $p = process(sub { die "Nooo" } );
1092             $p->pidfile("foobar");
1093             $p->start();
1094             $p->write_pidfile();
1095              
1096             Forces writing PID of process to specified pidfile in the attributes of the object.
1097             Useful only if the process have been already started, otherwise if a pidfile it's supplied
1098             as attribute, it will be done automatically.
1099              
1100             =head2 write_stdin()
1101              
1102             use Mojo::IOLoop::ReadWriteProcess qw(process);
1103             my $p = process(sub { my $a = ; print STDERR "Hello my name is $a\n"; } )->start;
1104             $p->write_stdin("Larry");
1105             $p->read_stderr; # process STDERR will contain: "Hello my name is Larry\n"
1106              
1107             Write data to process STDIN.
1108              
1109             =head2 write_channel()
1110              
1111             use Mojo::IOLoop::ReadWriteProcess qw(process);
1112             my $p = process(sub {
1113             my $self = shift;
1114             my $parent_output = $self->channel_out;
1115             my $parent_input = $self->channel_in;
1116              
1117             while(defined(my $line = <$parent_input>)) {
1118             print $parent_output "PONG\n" if $line =~ /PING/i;
1119             }
1120             } )->start;
1121             $p->write_channel("PING");
1122             my $out = $p->read_channel;
1123             # $out is PONG
1124             my $child_output = $p->channel_out;
1125             while(defined(my $line = <$child_output>)) {
1126             print "Process is replying back with $line!\n";
1127             $p->write_channel("PING");
1128             }
1129              
1130             Write data to process channel. Note, it's not STDIN, neither STDOUT, it's a complete separate channel
1131             dedicated to parent-child communication.
1132             In the parent process, you can access to the same pipes (but from the opposite direction):
1133              
1134             my $child_output = $self->channel_out;
1135             my $child_input = $self->channel_in;
1136              
1137             =head2 read_stdout()
1138              
1139             use Mojo::IOLoop::ReadWriteProcess qw(process);
1140             my $p = process(sub {
1141             print "Boo\n"
1142             } )->start;
1143             $p->read_stdout;
1144              
1145             Gets a single line from process STDOUT.
1146              
1147             =head2 read_channel()
1148              
1149             use Mojo::IOLoop::ReadWriteProcess qw(process);
1150             my $p = process(sub {
1151             my $self = shift;
1152             my $parent_output = $self->channel_out;
1153             my $parent_input = $self->channel_in;
1154              
1155             print $parent_output "PONG\n";
1156             } )->start;
1157             $p->read_channel;
1158              
1159             Gets a single line from process channel.
1160              
1161             =head2 read_stderr()
1162              
1163             use Mojo::IOLoop::ReadWriteProcess qw(process);
1164             my $p = process(sub {
1165             print STDERR "Boo\n"
1166             } )->start;
1167             $p->read_stderr;
1168              
1169             Gets a single line from process STDERR.
1170              
1171             =head2 read_all_stdout()
1172              
1173             use Mojo::IOLoop::ReadWriteProcess qw(process);
1174             my $p = process(sub {
1175             print "Boo\n"
1176             } )->start;
1177             $p->read_all_stdout;
1178              
1179             Gets all the STDOUT output of the process.
1180              
1181             =head2 read_all_channel()
1182              
1183             use Mojo::IOLoop::ReadWriteProcess qw(process);
1184             my $p = process(sub {
1185             shift->channel_out->write("Ping")
1186             } )->start;
1187             $p->read_all_channel;
1188              
1189             Gets all the channel output of the process.
1190              
1191             =head2 read_all_stderr()
1192              
1193             use Mojo::IOLoop::ReadWriteProcess qw(process);
1194             my $p = process(sub {
1195             print STDERR "Boo\n"
1196             } )->start;
1197             $p->read_all_stderr;
1198              
1199             Gets all the STDERR output of the process.
1200              
1201             =head2 send_signal()
1202              
1203             use Mojo::IOLoop::ReadWriteProcess qw(process);
1204             use POSIX;
1205             my $p = process( execute => "/path/to/bin" )->start;
1206              
1207             $p->send_signal(POSIX::SIGKILL);
1208              
1209             Send a signal to the process
1210              
1211             =head1 EXPORTS
1212              
1213             =head2 parallel()
1214              
1215             use Mojo::IOLoop::ReadWriteProcess qw(parallel);
1216             my $pool = parallel sub { print "Hello\n" } => 5;
1217             $pool->start();
1218             $pool->on( stop => sub { print "Process: ".(+shift()->pid)." finished"; } );
1219             $pool->stop();
1220              
1221             Returns a L object that represent a group of processes.
1222              
1223             It accepts the same arguments as L, and the last one represent the number of processes to generate.
1224              
1225             =head2 batch()
1226              
1227             use Mojo::IOLoop::ReadWriteProcess qw(batch);
1228             my $pool = batch;
1229             $pool->add(sub { print "Hello\n" });
1230             $pool->on(stop => sub { shift->_diag("Done!") })->start->wait_stop;
1231              
1232             Returns a L object generated from supplied arguments.
1233             It accepts as input the same parameter of L constructor ( see parallel() ).
1234              
1235             =head2 process()
1236              
1237             use Mojo::IOLoop::ReadWriteProcess qw(process);
1238             my $p = process sub { print "Hello\n" };
1239             $p->start()->wait_stop;
1240              
1241             or even:
1242              
1243             process(sub { print "Hello\n" })->start->wait_stop;
1244              
1245             Returns a L object that represent a process.
1246              
1247             It accepts the same arguments as L.
1248              
1249             =head2 queue()
1250              
1251             use Mojo::IOLoop::ReadWriteProcess qw(queue);
1252             my $q = queue;
1253             $q->add(sub { return 42 } );
1254             $q->consume;
1255              
1256             Returns a L object that represent a queue.
1257              
1258             =head1 DEBUGGING
1259              
1260             You can set the MOJO_EVENTEMITTER_DEBUG environment variable to get some advanced diagnostics information printed to STDERR.
1261              
1262             MOJO_EVENTEMITTER_DEBUG=1
1263              
1264             Also, you can set MOJO_PROCESS_DEBUG environment variable to get diagnostics about the process execution.
1265              
1266             MOJO_PROCESS_DEBUG=1
1267              
1268             =head1 LICENSE
1269              
1270             Copyright (C) Ettore Di Giacinto.
1271              
1272             This library is free software; you can redistribute it and/or modify
1273             it under the same terms as Perl itself.
1274              
1275             =head1 AUTHOR
1276              
1277             Ettore Di Giacinto Eedigiacinto@suse.comE
1278              
1279             =cut