diff options
author | Chris Williams <chris@bingosnet.co.uk> | 2009-11-13 16:19:53 +0000 |
---|---|---|
committer | Chris Williams <chris@bingosnet.co.uk> | 2009-11-13 16:19:53 +0000 |
commit | 635ccb1c96c21c95705df09e6e8425aaf05c1f69 (patch) | |
tree | 5eec4d2bea7ea6a43a6ce508204a105abc37d74b /cpan/IPC-Cmd | |
parent | 84df657f04b1025e03d7845847755bde20f5a70c (diff) | |
download | perl-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/IPC-Cmd')
-rw-r--r-- | cpan/IPC-Cmd/lib/IPC/Cmd.pm | 100 |
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>. |