.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "IO::Async::ChildManager 3pm" .TH IO::Async::ChildManager 3pm "2016-12-27" "perl v5.24.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" "IO::Async::ChildManager" \- facilitates the execution of child processes .SH "SYNOPSIS" .IX Header "SYNOPSIS" This object is used indirectly via an IO::Async::Loop: .PP .Vb 1 \& 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\en"; \& }, \& ); \& \& $loop\->open_child( \& command => [ "/bin/ping", "\-c4", "some.host" ], \& \& stdout => { \& on_read => sub { \& my ( $stream, $buffref, $eof ) = @_; \& while( $$buffref =~ s/^(.*)\en// ) { \& print "PING wrote: $1\en"; \& } \& return 0; \& }, \& }, \& \& on_finish => sub { \& my ( $pid, $exitcode ) = @_; \& my $status = ( $exitcode >> 8 ); \& ... \& }, \& ); \& \& 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\en"; \& }, \& ); \& \& $loop\->spawn_child( \& code => sub { \& do_something; # executes in a child process \& return 1; \& }, \& \& on_exit => sub { \& my ( $pid, $exitcode, $dollarbang, $dollarat ) = @_; \& my $status = ( $exitcode >> 8 ); \& print "Child process exited with status $status\en"; \& print " OS error was $dollarbang, exception was $dollarat\en"; \& }, \& ); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" This module extends the functionality of the containing IO::Async::Loop to manage the execution of child processes. It acts as a central point to store \&\s-1PID\s0 values of currently-running children, and to call the appropriate continuation handler code when the process terminates. It provides useful wrapper methods that set up filehandles and other child process details, and to capture the child process's \s-1STDOUT\s0 and \s-1STDERR\s0 streams. .SH "METHODS" .IX Header "METHODS" When active, the following methods are available on the containing \f(CW\*(C`Loop\*(C'\fR object. .SS "spawn_child" .IX Subsection "spawn_child" .Vb 1 \& $pid = $loop\->spawn_child( %params ) .Ve .PP This method creates a new child process to run a given code block or command. The \f(CW%params\fR hash takes the following keys: .IP "command => \s-1ARRAY\s0 or \s-1STRING\s0" 8 .IX Item "command => ARRAY or STRING" Either a reference to an array containing the command and its arguments, or a plain string containing the command. This value is passed into perl's \&\f(CW\*(C`exec\*(C'\fR function. .IP "code => \s-1CODE\s0" 8 .IX Item "code => CODE" A block of code to execute in the child process. It will be called in scalar context inside an \f(CW\*(C`eval\*(C'\fR block. .IP "setup => \s-1ARRAY\s0" 8 .IX Item "setup => ARRAY" A reference to an array which gives file descriptors to set up in the child process before running the code or command. See below. .IP "on_exit => \s-1CODE\s0" 8 .IX Item "on_exit => CODE" A continuation to be called when the child processes exits. It will be invoked in the following way: .Sp .Vb 1 \& $on_exit\->( $pid, $exitcode, $dollarbang, $dollarat ) .Ve .Sp The second argument is passed the plain perl \f(CW$?\fR value. .PP Exactly one of the \f(CW\*(C`command\*(C'\fR or \f(CW\*(C`code\*(C'\fR keys must be specified. .PP If the \f(CW\*(C`command\*(C'\fR key is used, the given array or string is executed using the \&\f(CW\*(C`exec\*(C'\fR function. .PP If the \f(CW\*(C`code\*(C'\fR key is used, the return value will be used as the \f(CWexit(2)\fR code from the child if it returns (or 255 if it returned \f(CW\*(C`undef\*(C'\fR or thows an exception). .PP .Vb 6 \& Case | ($exitcode >> 8) | $dollarbang | $dollarat \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\- \& exec succeeds | exit code from program | 0 | "" \& exec fails | 255 | $! | "" \& $code returns | return value | $! | "" \& $code dies | 255 | $! | $@ .Ve .PP It is usually more convenient to use the \f(CW\*(C`open_child\*(C'\fR method in simple cases where an external program is being started in order to interact with it via file \s-1IO,\s0 or even \f(CW\*(C`run_child\*(C'\fR when only the final result is required, rather than interaction while it is running. .ie n .SS """setup"" array" .el .SS "\f(CWsetup\fP array" .IX Subsection "setup array" This array gives a list of file descriptor operations to perform in the child process after it has been \f(CWfork(2)\fRed from the parent, before running the code or command. It consists of name/value pairs which are ordered; the operations are performed in the order given. .IP "fd\fIn\fR => \s-1ARRAY\s0" 8 .IX Item "fdn => ARRAY" Gives an operation on file descriptor \fIn\fR. The first element of the array defines the operation to be performed: .RS 8 .IP "[ 'close' ]" 4 .IX Item "[ 'close' ]" The file descriptor will be closed. .ie n .IP "[ 'dup', $io ]" 4 .el .IP "[ 'dup', \f(CW$io\fR ]" 4 .IX Item "[ 'dup', $io ]" The file descriptor will be \f(CWdup2(2)\fRed from the given \s-1IO\s0 handle. .ie n .IP "[ 'open', $mode, $file ]" 4 .el .IP "[ 'open', \f(CW$mode\fR, \f(CW$file\fR ]" 4 .IX Item "[ 'open', $mode, $file ]" The file descriptor will be opened from the named file in the given mode. The \&\f(CW$mode\fR string should be in the form usually given to the \f(CW\*(C`open\*(C'\fR function; such as '<' or '>>'. .IP "[ 'keep' ]" 4 .IX Item "[ 'keep' ]" The file descriptor will not be closed; it will be left as-is. .RE .RS 8 .Sp A non-reference value may be passed as a shortcut, where it would contain the name of the operation with no arguments (i.e. for the \f(CW\*(C`close\*(C'\fR and \f(CW\*(C`keep\*(C'\fR operations). .RE .IP "\s-1IO\s0 => \s-1ARRAY\s0" 8 .IX Item "IO => ARRAY" Shortcut for passing \f(CW\*(C`fd\f(CIn\f(CW\*(C'\fR, where \fIn\fR is the fileno of the \s-1IO\s0 reference. In this case, the key must be a reference that implements the \&\f(CW\*(C`fileno\*(C'\fR method. This is mostly useful for .Sp .Vb 1 \& $handle => \*(Aqkeep\*(Aq .Ve .IP "fd\fIn\fR => \s-1IO\s0" 8 .IX Item "fdn => IO" A shortcut for the \f(CW\*(C`dup\*(C'\fR case given above. .IP "stdin => ..." 8 .IX Item "stdin => ..." .PD 0 .IP "stdout => ..." 8 .IX Item "stdout => ..." .IP "stderr => ..." 8 .IX Item "stderr => ..." .PD Shortcuts for \f(CW\*(C`fd0\*(C'\fR, \f(CW\*(C`fd1\*(C'\fR and \f(CW\*(C`fd2\*(C'\fR respectively. .IP "env => \s-1HASH\s0" 8 .IX Item "env => HASH" A reference to a hash to set as the child process's environment. .Sp 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 \f(CW%ENV\fR into the hash before setting new keys: .Sp .Vb 4 \& env => { \& %ENV, \& ANOTHER => "key here", \& } .Ve .IP "nice => \s-1INT\s0" 8 .IX Item "nice => INT" Change the child process's scheduling priority using \f(CW\*(C`POSIX::nice\*(C'\fR. .IP "chdir => \s-1STRING\s0" 8 .IX Item "chdir => STRING" Change the child process's working directory using \f(CW\*(C`chdir\*(C'\fR. .IP "setuid => \s-1INT\s0" 8 .IX Item "setuid => INT" .PD 0 .IP "setgid => \s-1INT\s0" 8 .IX Item "setgid => INT" .PD Change the child process's effective \s-1UID\s0 or \s-1GID.\s0 .IP "setgroups => \s-1ARRAY\s0" 8 .IX Item "setgroups => ARRAY" Change the child process's groups list, to those groups whose numbers are given in the \s-1ARRAY\s0 reference. .Sp On most systems, only the privileged superuser change user or group IDs. IO::Async will \fB\s-1NOT\s0\fR check before detaching the child process whether this is the case. .Sp If setting both the primary \s-1GID\s0 and the supplementary groups list, it is suggested to set the primary \s-1GID\s0 first. Moreover, some operating systems may require that the supplementary groups list contains the primary \s-1GID.\s0 .PP If no directions for what to do with \f(CW\*(C`stdin\*(C'\fR, \f(CW\*(C`stdout\*(C'\fR and \f(CW\*(C`stderr\*(C'\fR are given, a default of \f(CW\*(C`keep\*(C'\fR is implied. All other file descriptors will be closed, unless a \f(CW\*(C`keep\*(C'\fR operation is given for them. .PP If \f(CW\*(C`setuid\*(C'\fR is used, be sure to place it after any other operations that might require superuser privileges, such as \f(CW\*(C`setgid\*(C'\fR or opening special files. .SH "AUTHOR" .IX Header "AUTHOR" Paul Evans