view release on metacpan or search on metacpan
local/lib/perl5/IO/Async/ChildManager.pm view on Meta::CPAN
use IO::Async::Loop;
my $loop = IO::Async::Loop->new;
...
$loop->run_child(
command => "/bin/ps",
on_finish => sub {
my ( $pid, $exitcode, $stdout, $stderr ) = @_;
my $status = ( $exitcode >> 8 );
print "ps [PID $pid] exited with status $status\n";
},
);
$loop->open_child(
command => [ "/bin/ping", "-c4", "some.host" ],
stdout => {
on_read => sub {
local/lib/perl5/IO/Async/ChildManager.pm view on Meta::CPAN
},
);
my ( $pipeRd, $pipeWr ) = IO::Async::OS->pipepair;
$loop->spawn_child(
command => "/usr/bin/my-command",
setup => [
stdin => [ "open", "<", "/dev/null" ],
stdout => $pipeWr,
stderr => [ "open", ">>", "/var/log/mycmd.log" ],
chdir => "/",
]
on_exit => sub {
my ( $pid, $exitcode ) = @_;
my $status = ( $exitcode >> 8 );
print "Command exited with status $status\n";
},
);
local/lib/perl5/IO/Async/ChildManager.pm view on Meta::CPAN
$handle => 'keep'
=item fdI<n> => IO
A shortcut for the C<dup> case given above.
=item stdin => ...
=item stdout => ...
=item stderr => ...
Shortcuts for C<fd0>, C<fd1> and C<fd2> respectively.
=item env => HASH
A reference to a hash to set as the child process's environment.
Note that this will entirely set a new environment, completely replacing the
existing one. If you want to simply add new keys or change the values of some
keys without removing the other existing ones, you can simply copy C<%ENV>
local/lib/perl5/IO/Async/ChildManager.pm view on Meta::CPAN
On most systems, only the privileged superuser change user or group IDs.
L<IO::Async> will B<NOT> check before detaching the child process whether
this is the case.
If setting both the primary GID and the supplementary groups list, it is
suggested to set the primary GID first. Moreover, some operating systems may
require that the supplementary groups list contains the primary GID.
=back
If no directions for what to do with C<stdin>, C<stdout> and C<stderr> are
given, a default of C<keep> is implied. All other file descriptors will be
closed, unless a C<keep> operation is given for them.
If C<setuid> is used, be sure to place it after any other operations that
might require superuser privileges, such as C<setgid> or opening special
files.
=cut
sub _check_setup_and_canonicise
local/lib/perl5/IO/Async/ChildManager.pm view on Meta::CPAN
return () if !@$setup;
my @setup;
my $has_setgroups;
foreach my $i ( 0 .. $#$setup / 2 ) {
my ( $key, $value ) = @$setup[$i*2, $i*2 + 1];
# Rewrite stdin/stdout/stderr
$key eq "stdin" and $key = "fd0";
$key eq "stdout" and $key = "fd1";
$key eq "stderr" and $key = "fd2";
# Rewrite other filehandles
ref $key and eval { $key->fileno; 1 } and $key = "fd" . $key->fileno;
if( $key =~ m/^fd(\d+)$/ ) {
my $fd = $1;
my $ref = ref $value;
if( !$ref ) {
$value = [ $value ];
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
The child will be given the reading end of a pipe. The string given by the
C<from> parameter will be written to the child. When all of the data has been
written the pipe will be closed.
=back
=item stdin => ...
=item stdout => ...
=item stderr => ...
Shortcuts for C<fd0>, C<fd1> and C<fd2> respectively.
=back
=cut
sub open_child
{
my $self = shift;
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
=item code => CODE
The command or code to run in the child process (as per the C<spawn_child>
method)
=item on_finish => CODE
A continuation to be called when the child process exits and closed its STDOUT
and STDERR streams. It will be invoked in the following way:
$on_finish->( $pid, $exitcode, $stdout, $stderr )
The second argument is passed the plain perl C<$?> value.
=item stdin => STRING
Optional. String to pass in to the child process's STDIN stream.
=item setup => ARRAY
Optional reference to an array to pass to the underlying C<spawn> method.
local/lib/perl5/IO/Async/Loop.pm view on Meta::CPAN
sub run_child
{
my $self = shift;
my %params = @_;
my $on_finish = delete $params{on_finish};
ref $on_finish or croak "Expected 'on_finish' to be a reference";
my $stdout;
my $stderr;
my %subparams;
if( my $child_stdin = delete $params{stdin} ) {
ref $child_stdin and croak "Expected 'stdin' not to be a reference";
$subparams{stdin} = { from => $child_stdin };
}
$subparams{code} = delete $params{code};
$subparams{command} = delete $params{command};
$subparams{setup} = delete $params{setup};
croak "Unrecognised parameters " . join( ", ", keys %params ) if keys %params;
require IO::Async::Process;
my $process = IO::Async::Process->new(
%subparams,
stdout => { into => \$stdout },
stderr => { into => \$stderr },
on_finish => sub {
my ( $process, $exitcode ) = @_;
$on_finish->( $process->pid, $exitcode, $stdout, $stderr );
},
);
$self->add( $process );
return $process->pid;
}
=head2 resolver
local/lib/perl5/IO/Async/Process.pm view on Meta::CPAN
given the other. The family of this socket may be given by the extra key
called C<family>; defaulting to C<unix>. The socktype of this socket may be
given by the extra key called C<socktype>; defaulting to C<stream>. If the
type is not C<SOCK_STREAM> then a L<IO::Async::Socket> object will be
constructed for the parent side of the handle, rather than
L<IO::Async::Stream>.
=back
Once the filehandle is set up, the C<fd> method (or its shortcuts of C<stdin>,
C<stdout> or C<stderr>) may be used to access the
L<IO::Async::Handle>-subclassed object wrapped around it.
The value of this argument is implied by any of the following alternatives.
=item on_read => CODE
The child will be given the writing end of a pipe. The reading end will be
wrapped by an L<IO::Async::Stream> using this C<on_read> callback function.
=item into => SCALAR
local/lib/perl5/IO/Async/Process.pm view on Meta::CPAN
The child will be given the reading end of a pipe. The string given by the
C<from> parameter will be written to the child. When all of the data has been
written the pipe will be closed.
=back
=head2 stdin => ...
=head2 stdout => ...
=head2 stderr => ...
Shortcuts for C<fd0>, C<fd1> and C<fd2> respectively.
=head2 stdio => ...
Special filehandle to affect STDIN and STDOUT at the same time. This
filehandle supports being configured for both reading and writing at the same
time.
=cut
local/lib/perl5/IO/Async/Process.pm view on Meta::CPAN
my $self = shift;
my %params = @_;
foreach (qw( on_finish on_exception )) {
$self->{$_} = delete $params{$_} if exists $params{$_};
}
# All these parameters can only be configured while the process isn't
# running
my %setup_params;
foreach (qw( code command setup stdin stdout stderr stdio ), grep { m/^fd\d+$/ } keys %params ) {
$setup_params{$_} = delete $params{$_} if exists $params{$_};
}
if( $self->is_running ) {
keys %setup_params and croak "Cannot configure a running Process with " . join ", ", keys %setup_params;
}
defined( exists $setup_params{code} ? $setup_params{code} : $self->{code} ) +
defined( exists $setup_params{command} ? $setup_params{command} : $self->{command} ) <= 1 or
croak "Cannot have both 'code' and 'command'";
foreach (qw( code command setup )) {
$self->{$_} = delete $setup_params{$_} if exists $setup_params{$_};
}
$self->configure_fd( 0, %{ delete $setup_params{stdin} } ) if $setup_params{stdin};
$self->configure_fd( 1, %{ delete $setup_params{stdout} } ) if $setup_params{stdout};
$self->configure_fd( 2, %{ delete $setup_params{stderr} } ) if $setup_params{stderr};
$self->configure_fd( 'io', %{ delete $setup_params{stdio} } ) if $setup_params{stdio};
# All the rest are fd\d+
foreach ( keys %setup_params ) {
my ( $fd ) = m/^fd(\d+)$/ or croak "Expected 'fd\\d+'";
$self->configure_fd( $fd, %{ $setup_params{$_} } );
}
$self->SUPER::configure( %params );
local/lib/perl5/IO/Async/Process.pm view on Meta::CPAN
$handle_class = "IO::Async::Socket";
}
else {
require IO::Async::Stream;
$handle_class = "IO::Async::Stream";
}
my $handle = $handle_class->new(
notifier_name => $fd eq "0" ? "stdin" :
$fd eq "1" ? "stdout" :
$fd eq "2" ? "stderr" :
$fd eq "io" ? "stdio" : "fd$fd",
%{ $opts->{handle} },
);
if( defined $opts->{from} ) {
$handle->write( $opts->{from},
on_flush => sub {
my ( $handle ) = @_;
$handle->close_write;
},
local/lib/perl5/IO/Async/Process.pm view on Meta::CPAN
}
$handle
};
}
=head2 stdin
=head2 stdout
=head2 stderr
=head2 stdio
$stream = $process->stdin
$stream = $process->stdout
$stream = $process->stderr
$stream = $process->stdio
Shortcuts for calling C<fd> with 0, 1, 2 or C<io> respectively, to obtain the
L<IO::Async::Stream> representing the standard input, output, error, or
combined input/output streams of the child process.
=cut
sub stdin { shift->fd( 0 ) }
sub stdout { shift->fd( 1 ) }
sub stderr { shift->fd( 2 ) }
sub stdio { shift->fd( 'io' ) }
=head1 EXAMPLES
=head2 Capturing the STDOUT stream of a process
By configuring the C<stdout> filehandle of the process using the C<into> key,
data written by the process can be captured.
my $stdout;