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