CPANPLUS
view release on metacpan or search on metacpan
inc/bundle/IPC/Cmd.pm view on Meta::CPAN
The important and distinguishing feature of run_forked
is execution timeout which at first seems to be
quite a simple task but if you think
that the program which you're spawning
might spawn some children itself (which
in their turn could do the same and so on)
it turns out to be not a simple issue.
C<run_forked> is designed to survive and
successfully terminate almost any long running task,
even a fork bomb in case your system has the resources
to survive during given timeout.
This is achieved by creating separate watchdog process
which spawns the specified program in a separate
process session and supervises it: optionally
feeds it with input, stores its exit code,
stdout and stderr, terminates it in case
it runs longer than specified.
Invocation requires the command to be executed or a coderef and optionally a hashref of options:
=over
=item C<timeout>
Specify in seconds how long to run the command before it is killed with SIG_KILL (9),
which effectively terminates it and all of its children (direct or indirect).
=item C<child_stdin>
Specify some text that will be passed into the C<STDIN> of the executed program.
=item C<stdout_handler>
Coderef of a subroutine to call when a portion of data is received on
STDOUT from the executing program.
=item C<stderr_handler>
Coderef of a subroutine to call when a portion of data is received on
STDERR from the executing program.
=item C<wait_loop_callback>
Coderef of a subroutine to call inside of the main waiting loop
(while C<run_forked> waits for the external to finish or fail).
It is useful to stop running external process before it ends
by itself, e.g.
my $r = run_forked("some external command", {
'wait_loop_callback' => sub {
if (condition) {
kill(1, $$);
}
},
'terminate_on_signal' => 'HUP',
});
Combined with C<stdout_handler> and C<stderr_handler> allows terminating
external command based on its output. Could also be used as a timer
without engaging with L<alarm> (signals).
Remember that this code could be called every millisecond (depending
on the output which external command generates), so try to make it
as lightweight as possible.
=item C<discard_output>
Discards the buffering of the standard output and standard errors for return by run_forked().
With this option you have to use the std*_handlers to read what the command outputs.
Useful for commands that send a lot of output.
=item C<terminate_on_parent_sudden_death>
Enable this option if you wish all spawned processes to be killed if the initially spawned
process (the parent) is killed or dies without waiting for child processes.
=back
C<run_forked> will return a HASHREF with the following keys:
=over
=item C<exit_code>
The exit code of the executed program.
=item C<timeout>
The number of seconds the program ran for before being terminated, or 0 if no timeout occurred.
=item C<stdout>
Holds the standard output of the executed command (or empty string if
there was no STDOUT output or if C<discard_output> was used; it's always defined!)
=item C<stderr>
Holds the standard error of the executed command (or empty string if
there was no STDERR output or if C<discard_output> was used; it's always defined!)
=item C<merged>
Holds the standard output and error of the executed command merged into one stream
(or empty string if there was no output at all or if C<discard_output> was used; it's always defined!)
=item C<err_msg>
Holds some explanation in the case of an error.
=back
=cut
sub run_forked {
### container to store things in
my $self = bless {}, __PACKAGE__;
if (!can_use_run_forked()) {
Carp::carp("run_forked is not available: $CAN_USE_RUN_FORKED");
( run in 0.510 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )