summaryrefslogtreecommitdiff
path: root/cpan
diff options
context:
space:
mode:
authorChris Williams <chris@bingosnet.co.uk>2009-11-13 16:19:53 +0000
committerChris Williams <chris@bingosnet.co.uk>2009-11-13 16:19:53 +0000
commit635ccb1c96c21c95705df09e6e8425aaf05c1f69 (patch)
tree5eec4d2bea7ea6a43a6ce508204a105abc37d74b /cpan
parent84df657f04b1025e03d7845847755bde20f5a70c (diff)
downloadperl-635ccb1c96c21c95705df09e6e8425aaf05c1f69.tar.gz
Updated IPC::Cmd to cpan release 0.52
Changes for 0.52 Fri Nov 13 16:15:11 GMT 2009 ================================================= * Added documentation for run_forked()
Diffstat (limited to 'cpan')
-rw-r--r--cpan/IPC-Cmd/lib/IPC/Cmd.pm100
1 files changed, 95 insertions, 5 deletions
diff --git a/cpan/IPC-Cmd/lib/IPC/Cmd.pm b/cpan/IPC-Cmd/lib/IPC/Cmd.pm
index 1a5d020a07..b9a23266b6 100644
--- a/cpan/IPC-Cmd/lib/IPC/Cmd.pm
+++ b/cpan/IPC-Cmd/lib/IPC/Cmd.pm
@@ -16,7 +16,7 @@ BEGIN {
$USE_IPC_RUN $USE_IPC_OPEN3 $CAN_USE_RUN_FORKED $WARN
];
- $VERSION = '0.51_01';
+ $VERSION = '0.52';
$VERBOSE = 0;
$DEBUG = 0;
$WARN = 1;
@@ -508,7 +508,91 @@ sub open3_run {
}
}
-=head2 $ok | ($ok, $err, $full_buf, $stdout_buff, $stderr_buff) = run_forked( command => COMMAND, [verbose => BOOL, buffer => \$SCALAR, timeout => DIGIT] );
+=head2 $hashref = run_forked( command => COMMAND, { child_stdin => SCALAR, timeout => DIGIT, stdout_handler => CODEREF, stderr_handler => CODEREF} );
+
+C<run_forked> is used to execute some program,
+optionally feed it with some input, get its return code
+and output (both stdout and stderr into seperate buffers).
+In addition it allows to terminate the program
+which take too long to finish.
+
+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 and optionally a hashref of options:
+
+=over
+
+=item C<timeout>
+
+Specify in seconds how long the command may run for before it is killed with 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 C<STDIN> of the executed program.
+
+=item C<stdout_handler>
+
+You may provide a coderef of a subroutine that will be called a portion of data is received on
+stdout from the executing program.
+
+=item C<stderr_handler>
+
+You may provide a coderef of a subroutine that will be called a portion of data is received on
+stderr from the executing program.
+
+=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 were no stdout output; it's always defined!)
+
+=item C<stderr>
+
+Holds the standard error of the executed command
+(or empty string if there were no stderr output; 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 were no output at all; it's always defined!)
+
+=item C<err_msg>
+
+Holds some explanation in the case of an error.
+
+=back
=cut
@@ -591,8 +675,9 @@ sub run_forked {
# print "child $pid started\n";
my $child_finished = 0;
- my $child_stdout = "";
- my $child_stderr = "";
+ my $child_stdout = '';
+ my $child_stderr = '';
+ my $child_merged = '';
my $child_exit_code = 0;
my $got_sig_child = 0;
@@ -646,6 +731,7 @@ sub run_forked {
while (my $l = <$child_stdout_socket>) {
$child_stdout .= $l;
+ $child_merged .= $l;
if ($opts->{'stdout_handler'} && ref($opts->{'stdout_handler'}) eq 'CODE') {
$opts->{'stdout_handler'}->($l);
@@ -653,6 +739,7 @@ sub run_forked {
}
while (my $l = <$child_stderr_socket>) {
$child_stderr .= $l;
+ $child_merged .= $l;
if ($opts->{'stderr_handler'} && ref($opts->{'stderr_handler'}) eq 'CODE') {
$opts->{'stderr_handler'}->($l);
@@ -687,11 +774,12 @@ sub run_forked {
my $o = {
'stdout' => $child_stdout,
'stderr' => $child_stderr,
+ 'merged' => $child_merged,
'timeout' => $child_timedout ? $opts->{'timeout'} : 0,
'exit_code' => $child_exit_code,
};
- my $err_msg = "";
+ my $err_msg = '';
if ($o->{'exit_code'}) {
$err_msg .= "exited with code [$o->{'exit_code'}]\n";
}
@@ -1541,6 +1629,8 @@ C<IPC::Run>, C<IPC::Open3>
Thanks to James Mastros and Martijn van der Streek for their
help in getting IPC::Open3 to behave nicely.
+Thanks to Petya Kohts for the C<run_forked> code.
+
=head1 BUG REPORTS
Please report bugs or other issues to E<lt>bug-ipc-cmd@rt.cpan.orgE<gt>.