xref: /openbsd-src/gnu/usr.bin/perl/cpan/IPC-Cmd/lib/IPC/Cmd.pm (revision 56d68f1e19ff848c889ecfa71d3a06340ff64892)
1b39c5158Smillertpackage IPC::Cmd;
2b39c5158Smillert
3b39c5158Smillertuse strict;
4b39c5158Smillert
5b39c5158SmillertBEGIN {
6b39c5158Smillert
7b39c5158Smillert    use constant IS_VMS         => $^O eq 'VMS'                       ? 1 : 0;
8b39c5158Smillert    use constant IS_WIN32       => $^O eq 'MSWin32'                   ? 1 : 0;
9b46d8ef2Safresh1    use constant IS_HPUX        => $^O eq 'hpux'                      ? 1 : 0;
10b39c5158Smillert    use constant IS_WIN98       => (IS_WIN32 and !Win32::IsWinNT())   ? 1 : 0;
11b39c5158Smillert    use constant ALARM_CLASS    => __PACKAGE__ . '::TimeOut';
12b39c5158Smillert    use constant SPECIAL_CHARS  => qw[< > | &];
13b39c5158Smillert    use constant QUOTE          => do { IS_WIN32 ? q["] : q['] };
14b39c5158Smillert
15b39c5158Smillert    use Exporter    ();
16b39c5158Smillert    use vars        qw[ @ISA $VERSION @EXPORT_OK $VERBOSE $DEBUG
17b39c5158Smillert                        $USE_IPC_RUN $USE_IPC_OPEN3 $CAN_USE_RUN_FORKED $WARN
18898184e3Ssthen                        $INSTANCES $ALLOW_NULL_ARGS
196fb12b70Safresh1                        $HAVE_MONOTONIC
20b39c5158Smillert                    ];
21b39c5158Smillert
22*56d68f1eSafresh1    $VERSION        = '1.04';
23b39c5158Smillert    $VERBOSE        = 0;
24b39c5158Smillert    $DEBUG          = 0;
25b39c5158Smillert    $WARN           = 1;
26b39c5158Smillert    $USE_IPC_RUN    = IS_WIN32 && !IS_WIN98;
27b39c5158Smillert    $USE_IPC_OPEN3  = not IS_VMS;
28898184e3Ssthen    $ALLOW_NULL_ARGS = 0;
29b39c5158Smillert
30b39c5158Smillert    $CAN_USE_RUN_FORKED = 0;
31b39c5158Smillert    eval {
32b39c5158Smillert        require POSIX; POSIX->import();
33b39c5158Smillert        require IPC::Open3; IPC::Open3->import();
34b39c5158Smillert        require IO::Select; IO::Select->import();
35b39c5158Smillert        require IO::Handle; IO::Handle->import();
36b39c5158Smillert        require FileHandle; FileHandle->import();
376fb12b70Safresh1        require Socket;
38b39c5158Smillert        require Time::HiRes; Time::HiRes->import();
39898184e3Ssthen        require Win32 if IS_WIN32;
40b39c5158Smillert    };
41b39c5158Smillert    $CAN_USE_RUN_FORKED = $@ || !IS_VMS && !IS_WIN32;
42b39c5158Smillert
436fb12b70Safresh1    eval {
446fb12b70Safresh1        my $wait_start_time = Time::HiRes::clock_gettime(&Time::HiRes::CLOCK_MONOTONIC);
456fb12b70Safresh1    };
466fb12b70Safresh1    if ($@) {
476fb12b70Safresh1        $HAVE_MONOTONIC = 0;
486fb12b70Safresh1    }
496fb12b70Safresh1    else {
506fb12b70Safresh1        $HAVE_MONOTONIC = 1;
516fb12b70Safresh1    }
526fb12b70Safresh1
53b39c5158Smillert    @ISA            = qw[Exporter];
54b39c5158Smillert    @EXPORT_OK      = qw[can_run run run_forked QUOTE];
55b39c5158Smillert}
56b39c5158Smillert
57b39c5158Smillertrequire Carp;
58b39c5158Smillertuse File::Spec;
59b39c5158Smillertuse Params::Check               qw[check];
60b39c5158Smillertuse Text::ParseWords            ();             # import ONLY if needed!
61b39c5158Smillertuse Module::Load::Conditional   qw[can_load];
62b39c5158Smillertuse Locale::Maketext::Simple    Style => 'gettext';
63b39c5158Smillert
649f11ffb7Safresh1local $Module::Load::Conditional::FORCE_SAFE_INC = 1;
659f11ffb7Safresh1
66b39c5158Smillert=pod
67b39c5158Smillert
68b39c5158Smillert=head1 NAME
69b39c5158Smillert
70b39c5158SmillertIPC::Cmd - finding and running system commands made easy
71b39c5158Smillert
72b39c5158Smillert=head1 SYNOPSIS
73b39c5158Smillert
74b39c5158Smillert    use IPC::Cmd qw[can_run run run_forked];
75b39c5158Smillert
76b39c5158Smillert    my $full_path = can_run('wget') or warn 'wget is not installed!';
77b39c5158Smillert
78b39c5158Smillert    ### commands can be arrayrefs or strings ###
79b39c5158Smillert    my $cmd = "$full_path -b theregister.co.uk";
80b39c5158Smillert    my $cmd = [$full_path, '-b', 'theregister.co.uk'];
81b39c5158Smillert
82b39c5158Smillert    ### in scalar context ###
83b39c5158Smillert    my $buffer;
84b39c5158Smillert    if( scalar run( command => $cmd,
85b39c5158Smillert                    verbose => 0,
86b39c5158Smillert                    buffer  => \$buffer,
87b39c5158Smillert                    timeout => 20 )
88b39c5158Smillert    ) {
89b39c5158Smillert        print "fetched webpage successfully: $buffer\n";
90b39c5158Smillert    }
91b39c5158Smillert
92b39c5158Smillert
93b39c5158Smillert    ### in list context ###
94898184e3Ssthen    my( $success, $error_message, $full_buf, $stdout_buf, $stderr_buf ) =
95b39c5158Smillert            run( command => $cmd, verbose => 0 );
96b39c5158Smillert
97b39c5158Smillert    if( $success ) {
98b39c5158Smillert        print "this is what the command printed:\n";
99b39c5158Smillert        print join "", @$full_buf;
100b39c5158Smillert    }
101b39c5158Smillert
1026fb12b70Safresh1    ### run_forked example ###
1036fb12b70Safresh1    my $result = run_forked("$full_path -q -O - theregister.co.uk", {'timeout' => 20});
1046fb12b70Safresh1    if ($result->{'exit_code'} eq 0 && !$result->{'timeout'}) {
1056fb12b70Safresh1        print "this is what wget returned:\n";
1066fb12b70Safresh1        print $result->{'stdout'};
1076fb12b70Safresh1    }
1086fb12b70Safresh1
109b39c5158Smillert    ### check for features
110b39c5158Smillert    print "IPC::Open3 available: "  . IPC::Cmd->can_use_ipc_open3;
111b39c5158Smillert    print "IPC::Run available: "    . IPC::Cmd->can_use_ipc_run;
112b39c5158Smillert    print "Can capture buffer: "    . IPC::Cmd->can_capture_buffer;
113b39c5158Smillert
114b39c5158Smillert    ### don't have IPC::Cmd be verbose, ie don't print to stdout or
115b39c5158Smillert    ### stderr when running commands -- default is '0'
116b39c5158Smillert    $IPC::Cmd::VERBOSE = 0;
117b39c5158Smillert
118b39c5158Smillert
119b39c5158Smillert=head1 DESCRIPTION
120b39c5158Smillert
121898184e3SsthenIPC::Cmd allows you to run commands platform independently,
122898184e3Sstheninteractively if desired, but have them still work.
123b39c5158Smillert
124b39c5158SmillertThe C<can_run> function can tell you if a certain binary is installed
125b39c5158Smillertand if so where, whereas the C<run> function can actually execute any
126b39c5158Smillertof the commands you give it and give you a clear return value, as well
127b39c5158Smillertas adhere to your verbosity settings.
128b39c5158Smillert
129b39c5158Smillert=head1 CLASS METHODS
130b39c5158Smillert
131b39c5158Smillert=head2 $ipc_run_version = IPC::Cmd->can_use_ipc_run( [VERBOSE] )
132b39c5158Smillert
133b39c5158SmillertUtility function that tells you if C<IPC::Run> is available.
134898184e3SsthenIf the C<verbose> flag is passed, it will print diagnostic messages
135898184e3Ssthenif L<IPC::Run> can not be found or loaded.
136b39c5158Smillert
137b39c5158Smillert=cut
138b39c5158Smillert
139b39c5158Smillert
140b39c5158Smillertsub can_use_ipc_run     {
141b39c5158Smillert    my $self    = shift;
142b39c5158Smillert    my $verbose = shift || 0;
143b39c5158Smillert
144898184e3Ssthen    ### IPC::Run doesn't run on win98
145b39c5158Smillert    return if IS_WIN98;
146b39c5158Smillert
1476fb12b70Safresh1    ### if we don't have ipc::run, we obviously can't use it.
148b39c5158Smillert    return unless can_load(
149b39c5158Smillert                        modules => { 'IPC::Run' => '0.55' },
150b39c5158Smillert                        verbose => ($WARN && $verbose),
151b39c5158Smillert                    );
152b39c5158Smillert
153b39c5158Smillert    ### otherwise, we're good to go
154b39c5158Smillert    return $IPC::Run::VERSION;
155b39c5158Smillert}
156b39c5158Smillert
157b39c5158Smillert=head2 $ipc_open3_version = IPC::Cmd->can_use_ipc_open3( [VERBOSE] )
158b39c5158Smillert
159b39c5158SmillertUtility function that tells you if C<IPC::Open3> is available.
160b39c5158SmillertIf the verbose flag is passed, it will print diagnostic messages
161b39c5158Smillertif C<IPC::Open3> can not be found or loaded.
162b39c5158Smillert
163b39c5158Smillert=cut
164b39c5158Smillert
165b39c5158Smillert
166b39c5158Smillertsub can_use_ipc_open3   {
167b39c5158Smillert    my $self    = shift;
168b39c5158Smillert    my $verbose = shift || 0;
169b39c5158Smillert
170898184e3Ssthen    ### IPC::Open3 is not working on VMS because of a lack of fork.
171b39c5158Smillert    return if IS_VMS;
172b39c5158Smillert
1736fb12b70Safresh1    ### IPC::Open3 works on every non-VMS platform, but it can't
174b39c5158Smillert    ### capture buffers on win32 :(
175b39c5158Smillert    return unless can_load(
176b39c5158Smillert        modules => { map {$_ => '0.0'} qw|IPC::Open3 IO::Select Symbol| },
177b39c5158Smillert        verbose => ($WARN && $verbose),
178b39c5158Smillert    );
179b39c5158Smillert
180b39c5158Smillert    return $IPC::Open3::VERSION;
181b39c5158Smillert}
182b39c5158Smillert
183b39c5158Smillert=head2 $bool = IPC::Cmd->can_capture_buffer
184b39c5158Smillert
185b39c5158SmillertUtility function that tells you if C<IPC::Cmd> is capable of
186b39c5158Smillertcapturing buffers in it's current configuration.
187b39c5158Smillert
188b39c5158Smillert=cut
189b39c5158Smillert
190b39c5158Smillertsub can_capture_buffer {
191b39c5158Smillert    my $self    = shift;
192b39c5158Smillert
193b39c5158Smillert    return 1 if $USE_IPC_RUN    && $self->can_use_ipc_run;
194898184e3Ssthen    return 1 if $USE_IPC_OPEN3  && $self->can_use_ipc_open3;
195b39c5158Smillert    return;
196b39c5158Smillert}
197b39c5158Smillert
198b39c5158Smillert=head2 $bool = IPC::Cmd->can_use_run_forked
199b39c5158Smillert
200b39c5158SmillertUtility function that tells you if C<IPC::Cmd> is capable of
201b39c5158Smillertproviding C<run_forked> on the current platform.
202b39c5158Smillert
203b39c5158Smillert=head1 FUNCTIONS
204b39c5158Smillert
205b39c5158Smillert=head2 $path = can_run( PROGRAM );
206b39c5158Smillert
207898184e3SsthenC<can_run> takes only one argument: the name of a binary you wish
208b39c5158Smillertto locate. C<can_run> works much like the unix binary C<which> or the bash
209b39c5158Smillertcommand C<type>, which scans through your path, looking for the requested
210b39c5158Smillertbinary.
211b39c5158Smillert
212b39c5158SmillertUnlike C<which> and C<type>, this function is platform independent and
213b39c5158Smillertwill also work on, for example, Win32.
214b39c5158Smillert
215898184e3SsthenIf called in a scalar context it will return the full path to the binary
216898184e3Ssthenyou asked for if it was found, or C<undef> if it was not.
217898184e3Ssthen
218898184e3SsthenIf called in a list context and the global variable C<$INSTANCES> is a true
219898184e3Ssthenvalue, it will return a list of the full paths to instances
220898184e3Ssthenof the binary where found in C<PATH>, or an empty list if it was not found.
221b39c5158Smillert
222b39c5158Smillert=cut
223b39c5158Smillert
224b39c5158Smillertsub can_run {
225b39c5158Smillert    my $command = shift;
226b39c5158Smillert
227b39c5158Smillert    # a lot of VMS executables have a symbol defined
228b39c5158Smillert    # check those first
229b39c5158Smillert    if ( $^O eq 'VMS' ) {
230b39c5158Smillert        require VMS::DCLsym;
231b39c5158Smillert        my $syms = VMS::DCLsym->new;
232b39c5158Smillert        return $command if scalar $syms->getsym( uc $command );
233b39c5158Smillert    }
234b39c5158Smillert
235b39c5158Smillert    require File::Spec;
236b39c5158Smillert    require ExtUtils::MakeMaker;
237b39c5158Smillert
238898184e3Ssthen    my @possibles;
239898184e3Ssthen
240b39c5158Smillert    if( File::Spec->file_name_is_absolute($command) ) {
241b39c5158Smillert        return MM->maybe_command($command);
242b39c5158Smillert
243b39c5158Smillert    } else {
244b39c5158Smillert        for my $dir (
24591f110e0Safresh1            File::Spec->path,
2469f11ffb7Safresh1            ( IS_WIN32 ? File::Spec->curdir : () )
247b39c5158Smillert        ) {
248898184e3Ssthen            next if ! $dir || ! -d $dir;
249898184e3Ssthen            my $abs = File::Spec->catfile( IS_WIN32 ? Win32::GetShortPathName( $dir ) : $dir, $command);
250898184e3Ssthen            push @possibles, $abs if $abs = MM->maybe_command($abs);
251b39c5158Smillert        }
252b39c5158Smillert    }
253898184e3Ssthen    return @possibles if wantarray and $INSTANCES;
254898184e3Ssthen    return shift @possibles;
255b39c5158Smillert}
256b39c5158Smillert
257b39c5158Smillert=head2 $ok | ($ok, $err, $full_buf, $stdout_buff, $stderr_buff) = run( command => COMMAND, [verbose => BOOL, buffer => \$SCALAR, timeout => DIGIT] );
258b39c5158Smillert
259b39c5158SmillertC<run> takes 4 arguments:
260b39c5158Smillert
261b39c5158Smillert=over 4
262b39c5158Smillert
263b39c5158Smillert=item command
264b39c5158Smillert
265b39c5158SmillertThis is the command to execute. It may be either a string or an array
266b39c5158Smillertreference.
267b39c5158SmillertThis is a required argument.
268b39c5158Smillert
269898184e3SsthenSee L<"Caveats"> for remarks on how commands are parsed and their
270b39c5158Smillertlimitations.
271b39c5158Smillert
272b39c5158Smillert=item verbose
273b39c5158Smillert
274b39c5158SmillertThis controls whether all output of a command should also be printed
275b39c5158Smillertto STDOUT/STDERR or should only be trapped in buffers (NOTE: buffers
276898184e3Ssthenrequire L<IPC::Run> to be installed, or your system able to work with
277898184e3SsthenL<IPC::Open3>).
278b39c5158Smillert
279b39c5158SmillertIt will default to the global setting of C<$IPC::Cmd::VERBOSE>,
280b39c5158Smillertwhich by default is 0.
281b39c5158Smillert
282b39c5158Smillert=item buffer
283b39c5158Smillert
284b39c5158SmillertThis will hold all the output of a command. It needs to be a reference
285b39c5158Smillertto a scalar.
286b39c5158SmillertNote that this will hold both the STDOUT and STDERR messages, and you
287b39c5158Smillerthave no way of telling which is which.
288b39c5158SmillertIf you require this distinction, run the C<run> command in list context
289b39c5158Smillertand inspect the individual buffers.
290b39c5158Smillert
291b39c5158SmillertOf course, this requires that the underlying call supports buffers. See
292898184e3Ssthenthe note on buffers above.
293b39c5158Smillert
294b39c5158Smillert=item timeout
295b39c5158Smillert
296b39c5158SmillertSets the maximum time the command is allowed to run before aborting,
297b39c5158Smillertusing the built-in C<alarm()> call. If the timeout is triggered, the
298b39c5158SmillertC<errorcode> in the return value will be set to an object of the
299898184e3SsthenC<IPC::Cmd::TimeOut> class. See the L<"error message"> section below for
300b39c5158Smillertdetails.
301b39c5158Smillert
302b39c5158SmillertDefaults to C<0>, meaning no timeout is set.
303b39c5158Smillert
304b39c5158Smillert=back
305b39c5158Smillert
306b39c5158SmillertC<run> will return a simple C<true> or C<false> when called in scalar
307b39c5158Smillertcontext.
308b39c5158SmillertIn list context, you will be returned a list of the following items:
309b39c5158Smillert
310b39c5158Smillert=over 4
311b39c5158Smillert
312b39c5158Smillert=item success
313b39c5158Smillert
314b39c5158SmillertA simple boolean indicating if the command executed without errors or
315b39c5158Smillertnot.
316b39c5158Smillert
317b39c5158Smillert=item error message
318b39c5158Smillert
319898184e3SsthenIf the first element of the return value (C<success>) was 0, then some
320b39c5158Smillerterror occurred. This second element is the error message the command
321b39c5158Smillertyou requested exited with, if available. This is generally a pretty
322b39c5158Smillertprinted value of C<$?> or C<$@>. See C<perldoc perlvar> for details on
323b39c5158Smillertwhat they can contain.
324b39c5158SmillertIf the error was a timeout, the C<error message> will be prefixed with
325b39c5158Smillertthe string C<IPC::Cmd::TimeOut>, the timeout class.
326b39c5158Smillert
327b39c5158Smillert=item full_buffer
328b39c5158Smillert
329b39c5158SmillertThis is an array reference containing all the output the command
330b39c5158Smillertgenerated.
331898184e3SsthenNote that buffers are only available if you have L<IPC::Run> installed,
332898184e3Ssthenor if your system is able to work with L<IPC::Open3> -- see below).
333898184e3SsthenOtherwise, this element will be C<undef>.
334b39c5158Smillert
335b39c5158Smillert=item out_buffer
336b39c5158Smillert
337b39c5158SmillertThis is an array reference containing all the output sent to STDOUT the
338898184e3Ssthencommand generated. The notes from L<"full_buffer"> apply.
339b39c5158Smillert
340b39c5158Smillert=item error_buffer
341b39c5158Smillert
342b39c5158SmillertThis is an arrayreference containing all the output sent to STDERR the
343898184e3Ssthencommand generated. The notes from L<"full_buffer"> apply.
344898184e3Ssthen
345b39c5158Smillert
346b39c5158Smillert=back
347b39c5158Smillert
348898184e3SsthenSee the L<"HOW IT WORKS"> section below to see how C<IPC::Cmd> decides
349b39c5158Smillertwhat modules or function calls to use when issuing a command.
350b39c5158Smillert
351b39c5158Smillert=cut
352b39c5158Smillert
353b39c5158Smillert{   my @acc = qw[ok error _fds];
354b39c5158Smillert
355b39c5158Smillert    ### autogenerate accessors ###
356b39c5158Smillert    for my $key ( @acc ) {
357b39c5158Smillert        no strict 'refs';
358b39c5158Smillert        *{__PACKAGE__."::$key"} = sub {
359b39c5158Smillert            $_[0]->{$key} = $_[1] if @_ > 1;
360b39c5158Smillert            return $_[0]->{$key};
361b39c5158Smillert        }
362b39c5158Smillert    }
363b39c5158Smillert}
364b39c5158Smillert
365b39c5158Smillertsub can_use_run_forked {
366b39c5158Smillert    return $CAN_USE_RUN_FORKED eq "1";
367b39c5158Smillert}
368b39c5158Smillert
3696fb12b70Safresh1sub get_monotonic_time {
3706fb12b70Safresh1    if ($HAVE_MONOTONIC) {
3716fb12b70Safresh1        return Time::HiRes::clock_gettime(&Time::HiRes::CLOCK_MONOTONIC);
3726fb12b70Safresh1    }
3736fb12b70Safresh1    else {
3746fb12b70Safresh1        return time();
3756fb12b70Safresh1    }
3766fb12b70Safresh1}
3776fb12b70Safresh1
3786fb12b70Safresh1sub adjust_monotonic_start_time {
3796fb12b70Safresh1    my ($ref_vars, $now, $previous) = @_;
3806fb12b70Safresh1
3816fb12b70Safresh1    # workaround only for those systems which don't have
3826fb12b70Safresh1    # Time::HiRes::CLOCK_MONOTONIC (Mac OSX in particular)
3836fb12b70Safresh1    return if $HAVE_MONOTONIC;
3846fb12b70Safresh1
3856fb12b70Safresh1    # don't have previous monotonic value (only happens once
3866fb12b70Safresh1    # in the beginning of the program execution)
3876fb12b70Safresh1    return unless $previous;
3886fb12b70Safresh1
3896fb12b70Safresh1    my $time_diff = $now - $previous;
3906fb12b70Safresh1
3916fb12b70Safresh1    # adjust previously saved time with the skew value which is
3926fb12b70Safresh1    # either negative when clock moved back or more than 5 seconds --
3936fb12b70Safresh1    # assuming that event loop does happen more often than once
3946fb12b70Safresh1    # per five seconds, which might not be always true (!) but
3956fb12b70Safresh1    # hopefully that's ok, because it's just a workaround
3966fb12b70Safresh1    if ($time_diff > 5 || $time_diff < 0) {
3976fb12b70Safresh1        foreach my $ref_var (@{$ref_vars}) {
3986fb12b70Safresh1            if (defined($$ref_var)) {
3996fb12b70Safresh1                $$ref_var = $$ref_var + $time_diff;
4006fb12b70Safresh1            }
4016fb12b70Safresh1        }
4026fb12b70Safresh1    }
4036fb12b70Safresh1}
4046fb12b70Safresh1
4059f11ffb7Safresh1sub uninstall_signals {
4069f11ffb7Safresh1		return unless defined($IPC::Cmd::{'__old_signals'});
4079f11ffb7Safresh1
4089f11ffb7Safresh1		foreach my $sig_name (keys %{$IPC::Cmd::{'__old_signals'}}) {
4099f11ffb7Safresh1				$SIG{$sig_name} = $IPC::Cmd::{'__old_signals'}->{$sig_name};
4109f11ffb7Safresh1		}
4119f11ffb7Safresh1}
4129f11ffb7Safresh1
413898184e3Ssthen# incompatible with POSIX::SigAction
414898184e3Ssthen#
415898184e3Ssthensub install_layered_signal {
416898184e3Ssthen  my ($s, $handler_code) = @_;
417898184e3Ssthen
418898184e3Ssthen  my %available_signals = map {$_ => 1} keys %SIG;
419898184e3Ssthen
4206fb12b70Safresh1  Carp::confess("install_layered_signal got nonexistent signal name [$s]")
421898184e3Ssthen    unless defined($available_signals{$s});
4226fb12b70Safresh1  Carp::confess("install_layered_signal expects coderef")
423898184e3Ssthen    if !ref($handler_code) || ref($handler_code) ne 'CODE';
424898184e3Ssthen
4259f11ffb7Safresh1  $IPC::Cmd::{'__old_signals'} = {}
4269f11ffb7Safresh1  		unless defined($IPC::Cmd::{'__old_signals'});
4279f11ffb7Safresh1	$IPC::Cmd::{'__old_signals'}->{$s} = $SIG{$s};
4289f11ffb7Safresh1
429898184e3Ssthen  my $previous_handler = $SIG{$s};
430898184e3Ssthen
431898184e3Ssthen  my $sig_handler = sub {
432898184e3Ssthen    my ($called_sig_name, @sig_param) = @_;
433898184e3Ssthen
434898184e3Ssthen    # $s is a closure referring to real signal name
435898184e3Ssthen    # for which this handler is being installed.
436898184e3Ssthen    # it is used to distinguish between
437898184e3Ssthen    # real signal handlers and aliased signal handlers
438898184e3Ssthen    my $signal_name = $s;
439898184e3Ssthen
440898184e3Ssthen    # $called_sig_name is a signal name which
441898184e3Ssthen    # was passed to this signal handler;
442898184e3Ssthen    # it doesn't equal $signal_name in case
443898184e3Ssthen    # some signal handlers in %SIG point
444898184e3Ssthen    # to other signal handler (CHLD and CLD,
445898184e3Ssthen    # ABRT and IOT)
446898184e3Ssthen    #
447898184e3Ssthen    # initial signal handler for aliased signal
448898184e3Ssthen    # calls some other signal handler which
449898184e3Ssthen    # should not execute the same handler_code again
450898184e3Ssthen    if ($called_sig_name eq $signal_name) {
451898184e3Ssthen      $handler_code->($signal_name);
452898184e3Ssthen    }
453898184e3Ssthen
454898184e3Ssthen    # run original signal handler if any (including aliased)
455898184e3Ssthen    #
456898184e3Ssthen    if (ref($previous_handler)) {
457898184e3Ssthen      $previous_handler->($called_sig_name, @sig_param);
458898184e3Ssthen    }
459898184e3Ssthen  };
460898184e3Ssthen
461898184e3Ssthen  $SIG{$s} = $sig_handler;
462898184e3Ssthen}
463898184e3Ssthen
464b39c5158Smillert# give process a chance sending TERM,
465b39c5158Smillert# waiting for a while (2 seconds)
466b39c5158Smillert# and killing it with KILL
467b39c5158Smillertsub kill_gently {
468898184e3Ssthen  my ($pid, $opts) = @_;
469b39c5158Smillert
470898184e3Ssthen  require POSIX;
471898184e3Ssthen
472898184e3Ssthen  $opts = {} unless $opts;
473898184e3Ssthen  $opts->{'wait_time'} = 2 unless defined($opts->{'wait_time'});
474898184e3Ssthen  $opts->{'first_kill_type'} = 'just_process' unless $opts->{'first_kill_type'};
475898184e3Ssthen  $opts->{'final_kill_type'} = 'just_process' unless $opts->{'final_kill_type'};
476898184e3Ssthen
477898184e3Ssthen  if ($opts->{'first_kill_type'} eq 'just_process') {
478b39c5158Smillert    kill(15, $pid);
479898184e3Ssthen  }
480898184e3Ssthen  elsif ($opts->{'first_kill_type'} eq 'process_group') {
481898184e3Ssthen    kill(-15, $pid);
482898184e3Ssthen  }
483b39c5158Smillert
4846fb12b70Safresh1  my $do_wait = 1;
485b39c5158Smillert  my $child_finished = 0;
486b39c5158Smillert
4876fb12b70Safresh1  my $wait_start_time = get_monotonic_time();
4886fb12b70Safresh1  my $now;
4896fb12b70Safresh1  my $previous_monotonic_value;
4906fb12b70Safresh1
4916fb12b70Safresh1  while ($do_wait) {
4926fb12b70Safresh1    $previous_monotonic_value = $now;
4936fb12b70Safresh1    $now = get_monotonic_time();
4946fb12b70Safresh1
4956fb12b70Safresh1    adjust_monotonic_start_time([\$wait_start_time], $now, $previous_monotonic_value);
4966fb12b70Safresh1
4976fb12b70Safresh1    if ($now > $wait_start_time + $opts->{'wait_time'}) {
4986fb12b70Safresh1        $do_wait = 0;
4996fb12b70Safresh1        next;
5006fb12b70Safresh1    }
5016fb12b70Safresh1
502898184e3Ssthen    my $waitpid = waitpid($pid, POSIX::WNOHANG);
5036fb12b70Safresh1
504b39c5158Smillert    if ($waitpid eq -1) {
505b39c5158Smillert        $child_finished = 1;
5066fb12b70Safresh1        $do_wait = 0;
5076fb12b70Safresh1        next;
508b39c5158Smillert    }
5096fb12b70Safresh1
510898184e3Ssthen    Time::HiRes::usleep(250000); # quarter of a second
511898184e3Ssthen  }
512b39c5158Smillert
513898184e3Ssthen  if (!$child_finished) {
514898184e3Ssthen    if ($opts->{'final_kill_type'} eq 'just_process') {
515898184e3Ssthen      kill(9, $pid);
516898184e3Ssthen    }
517898184e3Ssthen    elsif ($opts->{'final_kill_type'} eq 'process_group') {
518898184e3Ssthen      kill(-9, $pid);
519898184e3Ssthen    }
520b39c5158Smillert  }
521b39c5158Smillert}
522b39c5158Smillert
523b39c5158Smillertsub open3_run {
524b39c5158Smillert    my ($cmd, $opts) = @_;
525b39c5158Smillert
526b39c5158Smillert    $opts = {} unless $opts;
527b39c5158Smillert
528b39c5158Smillert    my $child_in = FileHandle->new;
529b39c5158Smillert    my $child_out = FileHandle->new;
530b39c5158Smillert    my $child_err = FileHandle->new;
531b39c5158Smillert    $child_out->autoflush(1);
532b39c5158Smillert    $child_err->autoflush(1);
533b39c5158Smillert
534b39c5158Smillert    my $pid = open3($child_in, $child_out, $child_err, $cmd);
535b46d8ef2Safresh1    Time::HiRes::usleep(1) if IS_HPUX;
536b46d8ef2Safresh1
537b46d8ef2Safresh1    # will consider myself orphan if my ppid changes
538b46d8ef2Safresh1    # from this one:
539b46d8ef2Safresh1    my $original_ppid = $opts->{'original_ppid'};
540b39c5158Smillert
541b39c5158Smillert    # push my child's pid to our parent
542b39c5158Smillert    # so in case i am killed parent
543b39c5158Smillert    # could stop my child (search for
544b39c5158Smillert    # child_child_pid in parent code)
545b39c5158Smillert    if ($opts->{'parent_info'}) {
546b39c5158Smillert      my $ps = $opts->{'parent_info'};
547b39c5158Smillert      print $ps "spawned $pid\n";
548b39c5158Smillert    }
549b39c5158Smillert
550b39c5158Smillert    if ($child_in && $child_out->opened && $opts->{'child_stdin'}) {
551b39c5158Smillert        # If the child process dies for any reason,
552b39c5158Smillert        # the next write to CHLD_IN is likely to generate
553b39c5158Smillert        # a SIGPIPE in the parent, which is fatal by default.
554b39c5158Smillert        # So you may wish to handle this signal.
555b39c5158Smillert        #
556b39c5158Smillert        # from http://perldoc.perl.org/IPC/Open3.html,
557b39c5158Smillert        # absolutely needed to catch piped commands errors.
558b39c5158Smillert        #
559898184e3Ssthen        local $SIG{'PIPE'} = sub { 1; };
560b39c5158Smillert
561b39c5158Smillert        print $child_in $opts->{'child_stdin'};
562b39c5158Smillert    }
563b39c5158Smillert    close($child_in);
564b39c5158Smillert
565b39c5158Smillert    my $child_output = {
566b39c5158Smillert        'out' => $child_out->fileno,
567b39c5158Smillert        'err' => $child_err->fileno,
568b39c5158Smillert        $child_out->fileno => {
569b39c5158Smillert            'parent_socket' => $opts->{'parent_stdout'},
570b39c5158Smillert            'scalar_buffer' => "",
571b39c5158Smillert            'child_handle' => $child_out,
572b39c5158Smillert            'block_size' => ($child_out->stat)[11] || 1024,
573b39c5158Smillert          },
574b39c5158Smillert        $child_err->fileno => {
575b39c5158Smillert            'parent_socket' => $opts->{'parent_stderr'},
576b39c5158Smillert            'scalar_buffer' => "",
577b39c5158Smillert            'child_handle' => $child_err,
578b39c5158Smillert            'block_size' => ($child_err->stat)[11] || 1024,
579b39c5158Smillert          },
580b39c5158Smillert        };
581b39c5158Smillert
582b39c5158Smillert    my $select = IO::Select->new();
583b39c5158Smillert    $select->add($child_out, $child_err);
584b39c5158Smillert
585b39c5158Smillert    # pass any signal to the child
586b39c5158Smillert    # effectively creating process
587b39c5158Smillert    # strongly attached to the child:
588b39c5158Smillert    # it will terminate only after child
589b39c5158Smillert    # has terminated (except for SIGKILL,
590b39c5158Smillert    # which is specially handled)
5919f11ffb7Safresh1    SIGNAL: foreach my $s (keys %SIG) {
5929f11ffb7Safresh1        next SIGNAL if $s eq '__WARN__' or $s eq '__DIE__'; # Skip and don't clobber __DIE__ & __WARN__
593b39c5158Smillert        my $sig_handler;
594b39c5158Smillert        $sig_handler = sub {
595b39c5158Smillert            kill("$s", $pid);
596b39c5158Smillert            $SIG{$s} = $sig_handler;
597b39c5158Smillert        };
598b39c5158Smillert        $SIG{$s} = $sig_handler;
599b39c5158Smillert    }
600b39c5158Smillert
601b39c5158Smillert    my $child_finished = 0;
602b39c5158Smillert
6036fb12b70Safresh1    my $real_exit;
6046fb12b70Safresh1    my $exit_value;
605b39c5158Smillert
6066fb12b70Safresh1    while(!$child_finished) {
607b39c5158Smillert
608b39c5158Smillert        # parent was killed otherwise we would have got
609b39c5158Smillert        # the same signal as parent and process it same way
610b46d8ef2Safresh1        if (getppid() != $original_ppid) {
611898184e3Ssthen
612898184e3Ssthen          # end my process group with all the children
613898184e3Ssthen          # (i am the process group leader, so my pid
614898184e3Ssthen          # equals to the process group id)
615898184e3Ssthen          #
616898184e3Ssthen          # same thing which is done
617898184e3Ssthen          # with $opts->{'clean_up_children'}
618898184e3Ssthen          # in run_forked
619898184e3Ssthen          #
620898184e3Ssthen          kill(-9, $$);
621898184e3Ssthen
62291f110e0Safresh1          POSIX::_exit 1;
623b39c5158Smillert        }
624b39c5158Smillert
6256fb12b70Safresh1        my $waitpid = waitpid($pid, POSIX::WNOHANG);
6266fb12b70Safresh1
6276fb12b70Safresh1        # child finished, catch it's exit status
6286fb12b70Safresh1        if ($waitpid ne 0 && $waitpid ne -1) {
6296fb12b70Safresh1          $real_exit = $?;
6306fb12b70Safresh1          $exit_value = $? >> 8;
6316fb12b70Safresh1        }
6326fb12b70Safresh1
6336fb12b70Safresh1        if ($waitpid eq -1) {
634b39c5158Smillert          $child_finished = 1;
635b39c5158Smillert        }
636b39c5158Smillert
637b39c5158Smillert
6386fb12b70Safresh1        my $ready_fds = [];
6396fb12b70Safresh1        push @{$ready_fds}, $select->can_read(1/100);
6406fb12b70Safresh1
6416fb12b70Safresh1        READY_FDS: while (scalar(@{$ready_fds})) {
6426fb12b70Safresh1            my $fd = shift @{$ready_fds};
6436fb12b70Safresh1            $ready_fds = [grep {$_ ne $fd} @{$ready_fds}];
6446fb12b70Safresh1
645b39c5158Smillert            my $str = $child_output->{$fd->fileno};
6466fb12b70Safresh1            Carp::confess("child stream not found: $fd") unless $str;
647b39c5158Smillert
648b39c5158Smillert            my $data;
649b39c5158Smillert            my $count = $fd->sysread($data, $str->{'block_size'});
650b39c5158Smillert
651b39c5158Smillert            if ($count) {
652b39c5158Smillert                if ($str->{'parent_socket'}) {
653b39c5158Smillert                    my $ph = $str->{'parent_socket'};
654b39c5158Smillert                    print $ph $data;
655b39c5158Smillert                }
656b39c5158Smillert                else {
657b39c5158Smillert                    $str->{'scalar_buffer'} .= $data;
658b39c5158Smillert                }
659b39c5158Smillert            }
660b39c5158Smillert            elsif ($count eq 0) {
661b39c5158Smillert                $select->remove($fd);
662b39c5158Smillert                $fd->close();
663b39c5158Smillert            }
664b39c5158Smillert            else {
6656fb12b70Safresh1                Carp::confess("error during sysread: " . $!);
666b39c5158Smillert            }
667b39c5158Smillert
6686fb12b70Safresh1            push @{$ready_fds}, $select->can_read(1/100) if $child_finished;
6696fb12b70Safresh1        }
6706fb12b70Safresh1
6716fb12b70Safresh1        Time::HiRes::usleep(1);
6726fb12b70Safresh1    }
673b39c5158Smillert
674898184e3Ssthen    # since we've successfully reaped the child,
675898184e3Ssthen    # let our parent know about this.
676898184e3Ssthen    #
677b39c5158Smillert    if ($opts->{'parent_info'}) {
678b39c5158Smillert        my $ps = $opts->{'parent_info'};
679898184e3Ssthen
680898184e3Ssthen        # child was killed, inform parent
681898184e3Ssthen        if ($real_exit & 127) {
682898184e3Ssthen          print $ps "$pid killed with " . ($real_exit & 127) . "\n";
683898184e3Ssthen        }
684898184e3Ssthen
685b39c5158Smillert        print $ps "reaped $pid\n";
686b39c5158Smillert    }
687b39c5158Smillert
688b39c5158Smillert    if ($opts->{'parent_stdout'} || $opts->{'parent_stderr'}) {
689b39c5158Smillert        return $exit_value;
690b39c5158Smillert    }
691b39c5158Smillert    else {
692b39c5158Smillert        return {
693b39c5158Smillert            'stdout' => $child_output->{$child_output->{'out'}}->{'scalar_buffer'},
694b39c5158Smillert            'stderr' => $child_output->{$child_output->{'err'}}->{'scalar_buffer'},
695b39c5158Smillert            'exit_code' => $exit_value,
696b39c5158Smillert            };
697b39c5158Smillert    }
698b39c5158Smillert}
699b39c5158Smillert
700898184e3Ssthen=head2 $hashref = run_forked( COMMAND, { child_stdin => SCALAR, timeout => DIGIT, stdout_handler => CODEREF, stderr_handler => CODEREF} );
701b39c5158Smillert
702898184e3SsthenC<run_forked> is used to execute some program or a coderef,
703b39c5158Smillertoptionally feed it with some input, get its return code
704898184e3Ssthenand output (both stdout and stderr into separate buffers).
705898184e3SsthenIn addition, it allows to terminate the program
706898184e3Ssthenif it takes too long to finish.
707b39c5158Smillert
708b39c5158SmillertThe important and distinguishing feature of run_forked
709b39c5158Smillertis execution timeout which at first seems to be
710b39c5158Smillertquite a simple task but if you think
711b39c5158Smillertthat the program which you're spawning
712b39c5158Smillertmight spawn some children itself (which
713b39c5158Smillertin their turn could do the same and so on)
714b39c5158Smillertit turns out to be not a simple issue.
715b39c5158Smillert
716b39c5158SmillertC<run_forked> is designed to survive and
717b39c5158Smillertsuccessfully terminate almost any long running task,
718b39c5158Smillerteven a fork bomb in case your system has the resources
719b39c5158Smillertto survive during given timeout.
720b39c5158Smillert
721b39c5158SmillertThis is achieved by creating separate watchdog process
722b39c5158Smillertwhich spawns the specified program in a separate
723b39c5158Smillertprocess session and supervises it: optionally
724b39c5158Smillertfeeds it with input, stores its exit code,
725b39c5158Smillertstdout and stderr, terminates it in case
726b39c5158Smillertit runs longer than specified.
727b39c5158Smillert
728898184e3SsthenInvocation requires the command to be executed or a coderef and optionally a hashref of options:
729b39c5158Smillert
730b39c5158Smillert=over
731b39c5158Smillert
732b39c5158Smillert=item C<timeout>
733b39c5158Smillert
7346fb12b70Safresh1Specify in seconds how long to run the command before it is killed with SIG_KILL (9),
735b39c5158Smillertwhich effectively terminates it and all of its children (direct or indirect).
736b39c5158Smillert
737b39c5158Smillert=item C<child_stdin>
738b39c5158Smillert
739898184e3SsthenSpecify some text that will be passed into the C<STDIN> of the executed program.
740b39c5158Smillert
741b39c5158Smillert=item C<stdout_handler>
742b39c5158Smillert
743898184e3SsthenCoderef of a subroutine to call when a portion of data is received on
744898184e3SsthenSTDOUT from the executing program.
745b39c5158Smillert
746b39c5158Smillert=item C<stderr_handler>
747b39c5158Smillert
748898184e3SsthenCoderef of a subroutine to call when a portion of data is received on
749898184e3SsthenSTDERR from the executing program.
750898184e3Ssthen
7519f11ffb7Safresh1=item C<wait_loop_callback>
7529f11ffb7Safresh1
7539f11ffb7Safresh1Coderef of a subroutine to call inside of the main waiting loop
7549f11ffb7Safresh1(while C<run_forked> waits for the external to finish or fail).
7559f11ffb7Safresh1It is useful to stop running external process before it ends
7569f11ffb7Safresh1by itself, e.g.
7579f11ffb7Safresh1
7589f11ffb7Safresh1  my $r = run_forked("some external command", {
7599f11ffb7Safresh1	  'wait_loop_callback' => sub {
7609f11ffb7Safresh1          if (condition) {
7619f11ffb7Safresh1              kill(1, $$);
7629f11ffb7Safresh1          }
7639f11ffb7Safresh1	  },
7649f11ffb7Safresh1	  'terminate_on_signal' => 'HUP',
7659f11ffb7Safresh1	  });
7669f11ffb7Safresh1
7679f11ffb7Safresh1Combined with C<stdout_handler> and C<stderr_handler> allows terminating
7689f11ffb7Safresh1external command based on its output. Could also be used as a timer
7699f11ffb7Safresh1without engaging with L<alarm> (signals).
7709f11ffb7Safresh1
7719f11ffb7Safresh1Remember that this code could be called every millisecond (depending
7729f11ffb7Safresh1on the output which external command generates), so try to make it
7739f11ffb7Safresh1as lightweight as possible.
774898184e3Ssthen
775898184e3Ssthen=item C<discard_output>
776898184e3Ssthen
777898184e3SsthenDiscards the buffering of the standard output and standard errors for return by run_forked().
778898184e3SsthenWith this option you have to use the std*_handlers to read what the command outputs.
779898184e3SsthenUseful for commands that send a lot of output.
780898184e3Ssthen
781898184e3Ssthen=item C<terminate_on_parent_sudden_death>
782898184e3Ssthen
783898184e3SsthenEnable this option if you wish all spawned processes to be killed if the initially spawned
784898184e3Ssthenprocess (the parent) is killed or dies without waiting for child processes.
785b39c5158Smillert
786b39c5158Smillert=back
787b39c5158Smillert
788b39c5158SmillertC<run_forked> will return a HASHREF with the following keys:
789b39c5158Smillert
790b39c5158Smillert=over
791b39c5158Smillert
792b39c5158Smillert=item C<exit_code>
793b39c5158Smillert
794b39c5158SmillertThe exit code of the executed program.
795b39c5158Smillert
796b39c5158Smillert=item C<timeout>
797b39c5158Smillert
798b39c5158SmillertThe number of seconds the program ran for before being terminated, or 0 if no timeout occurred.
799b39c5158Smillert
800b39c5158Smillert=item C<stdout>
801b39c5158Smillert
802898184e3SsthenHolds the standard output of the executed command (or empty string if
803898184e3Ssthenthere was no STDOUT output or if C<discard_output> was used; it's always defined!)
804b39c5158Smillert
805b39c5158Smillert=item C<stderr>
806b39c5158Smillert
807898184e3SsthenHolds the standard error of the executed command (or empty string if
808898184e3Ssthenthere was no STDERR output or if C<discard_output> was used; it's always defined!)
809b39c5158Smillert
810b39c5158Smillert=item C<merged>
811b39c5158Smillert
812b39c5158SmillertHolds the standard output and error of the executed command merged into one stream
813898184e3Ssthen(or empty string if there was no output at all or if C<discard_output> was used; it's always defined!)
814b39c5158Smillert
815b39c5158Smillert=item C<err_msg>
816b39c5158Smillert
817b39c5158SmillertHolds some explanation in the case of an error.
818b39c5158Smillert
819b39c5158Smillert=back
820b39c5158Smillert
821b39c5158Smillert=cut
822b39c5158Smillert
823b39c5158Smillertsub run_forked {
824b39c5158Smillert    ### container to store things in
825b39c5158Smillert    my $self = bless {}, __PACKAGE__;
826b39c5158Smillert
827b39c5158Smillert    if (!can_use_run_forked()) {
828b39c5158Smillert        Carp::carp("run_forked is not available: $CAN_USE_RUN_FORKED");
829b39c5158Smillert        return;
830b39c5158Smillert    }
831b39c5158Smillert
8326fb12b70Safresh1    require POSIX;
8336fb12b70Safresh1
834b39c5158Smillert    my ($cmd, $opts) = @_;
8356fb12b70Safresh1    if (ref($cmd) eq 'ARRAY') {
8366fb12b70Safresh1        $cmd = join(" ", @{$cmd});
8376fb12b70Safresh1    }
838b39c5158Smillert
839b39c5158Smillert    if (!$cmd) {
840b39c5158Smillert        Carp::carp("run_forked expects command to run");
841b39c5158Smillert        return;
842b39c5158Smillert    }
843b39c5158Smillert
844b39c5158Smillert    $opts = {} unless $opts;
845b39c5158Smillert    $opts->{'timeout'} = 0 unless $opts->{'timeout'};
846898184e3Ssthen    $opts->{'terminate_wait_time'} = 2 unless defined($opts->{'terminate_wait_time'});
847898184e3Ssthen
848898184e3Ssthen    # turned on by default
849898184e3Ssthen    $opts->{'clean_up_children'} = 1 unless defined($opts->{'clean_up_children'});
850b39c5158Smillert
851b39c5158Smillert    # sockets to pass child stdout to parent
852b39c5158Smillert    my $child_stdout_socket;
853b39c5158Smillert    my $parent_stdout_socket;
854b39c5158Smillert
855b39c5158Smillert    # sockets to pass child stderr to parent
856b39c5158Smillert    my $child_stderr_socket;
857b39c5158Smillert    my $parent_stderr_socket;
858b39c5158Smillert
859b39c5158Smillert    # sockets for child -> parent internal communication
860b39c5158Smillert    my $child_info_socket;
861b39c5158Smillert    my $parent_info_socket;
862b39c5158Smillert
8636fb12b70Safresh1    socketpair($child_stdout_socket, $parent_stdout_socket, &Socket::AF_UNIX, &Socket::SOCK_STREAM, &Socket::PF_UNSPEC) ||
8646fb12b70Safresh1      Carp::confess ("socketpair: $!");
8656fb12b70Safresh1    socketpair($child_stderr_socket, $parent_stderr_socket, &Socket::AF_UNIX, &Socket::SOCK_STREAM, &Socket::PF_UNSPEC) ||
8666fb12b70Safresh1      Carp::confess ("socketpair: $!");
8676fb12b70Safresh1    socketpair($child_info_socket, $parent_info_socket, &Socket::AF_UNIX, &Socket::SOCK_STREAM, &Socket::PF_UNSPEC) ||
8686fb12b70Safresh1      Carp::confess ("socketpair: $!");
869b39c5158Smillert
870b39c5158Smillert    $child_stdout_socket->autoflush(1);
871b39c5158Smillert    $parent_stdout_socket->autoflush(1);
872b39c5158Smillert    $child_stderr_socket->autoflush(1);
873b39c5158Smillert    $parent_stderr_socket->autoflush(1);
874b39c5158Smillert    $child_info_socket->autoflush(1);
875b39c5158Smillert    $parent_info_socket->autoflush(1);
876b39c5158Smillert
8776fb12b70Safresh1    my $start_time = get_monotonic_time();
878b39c5158Smillert
879b39c5158Smillert    my $pid;
880b46d8ef2Safresh1    my $ppid = $$;
881b39c5158Smillert    if ($pid = fork) {
882b39c5158Smillert
883b39c5158Smillert      # we are a parent
884b39c5158Smillert      close($parent_stdout_socket);
885b39c5158Smillert      close($parent_stderr_socket);
886b39c5158Smillert      close($parent_info_socket);
887b39c5158Smillert
888b39c5158Smillert      my $flags;
889b39c5158Smillert
890b39c5158Smillert      # prepare sockets to read from child
891b39c5158Smillert
8929f11ffb7Safresh1      $flags = fcntl($child_stdout_socket, POSIX::F_GETFL, 0) || Carp::confess "can't fnctl F_GETFL: $!";
893898184e3Ssthen      $flags |= POSIX::O_NONBLOCK;
8946fb12b70Safresh1      fcntl($child_stdout_socket, POSIX::F_SETFL, $flags) || Carp::confess "can't fnctl F_SETFL: $!";
895b39c5158Smillert
8969f11ffb7Safresh1      $flags = fcntl($child_stderr_socket, POSIX::F_GETFL, 0) || Carp::confess "can't fnctl F_GETFL: $!";
897898184e3Ssthen      $flags |= POSIX::O_NONBLOCK;
8986fb12b70Safresh1      fcntl($child_stderr_socket, POSIX::F_SETFL, $flags) || Carp::confess "can't fnctl F_SETFL: $!";
899b39c5158Smillert
9009f11ffb7Safresh1      $flags = fcntl($child_info_socket, POSIX::F_GETFL, 0) || Carp::confess "can't fnctl F_GETFL: $!";
901898184e3Ssthen      $flags |= POSIX::O_NONBLOCK;
9026fb12b70Safresh1      fcntl($child_info_socket, POSIX::F_SETFL, $flags) || Carp::confess "can't fnctl F_SETFL: $!";
903b39c5158Smillert
904b39c5158Smillert  #    print "child $pid started\n";
905b39c5158Smillert
9066fb12b70Safresh1      my $child_output = {
9076fb12b70Safresh1        $child_stdout_socket->fileno => {
9086fb12b70Safresh1          'scalar_buffer' => "",
9096fb12b70Safresh1          'child_handle' => $child_stdout_socket,
9106fb12b70Safresh1          'block_size' => ($child_stdout_socket->stat)[11] || 1024,
9116fb12b70Safresh1          'protocol' => 'stdout',
9126fb12b70Safresh1          },
9136fb12b70Safresh1        $child_stderr_socket->fileno => {
9146fb12b70Safresh1          'scalar_buffer' => "",
9156fb12b70Safresh1          'child_handle' => $child_stderr_socket,
9166fb12b70Safresh1          'block_size' => ($child_stderr_socket->stat)[11] || 1024,
9176fb12b70Safresh1          'protocol' => 'stderr',
9186fb12b70Safresh1          },
9196fb12b70Safresh1        $child_info_socket->fileno => {
9206fb12b70Safresh1          'scalar_buffer' => "",
9216fb12b70Safresh1          'child_handle' => $child_info_socket,
9226fb12b70Safresh1          'block_size' => ($child_info_socket->stat)[11] || 1024,
9236fb12b70Safresh1          'protocol' => 'info',
9246fb12b70Safresh1          },
9256fb12b70Safresh1        };
9266fb12b70Safresh1
9276fb12b70Safresh1      my $select = IO::Select->new();
9286fb12b70Safresh1      $select->add($child_stdout_socket, $child_stderr_socket, $child_info_socket);
9296fb12b70Safresh1
930898184e3Ssthen      my $child_timedout = 0;
931b39c5158Smillert      my $child_finished = 0;
932b39c5158Smillert      my $child_stdout = '';
933b39c5158Smillert      my $child_stderr = '';
934b39c5158Smillert      my $child_merged = '';
935b39c5158Smillert      my $child_exit_code = 0;
936898184e3Ssthen      my $child_killed_by_signal = 0;
937898184e3Ssthen      my $parent_died = 0;
938b39c5158Smillert
9396fb12b70Safresh1      my $last_parent_check = 0;
940b39c5158Smillert      my $got_sig_child = 0;
941898184e3Ssthen      my $got_sig_quit = 0;
942898184e3Ssthen      my $orig_sig_child = $SIG{'CHLD'};
943898184e3Ssthen
9446fb12b70Safresh1      $SIG{'CHLD'} = sub { $got_sig_child = get_monotonic_time(); };
945b39c5158Smillert
946898184e3Ssthen      if ($opts->{'terminate_on_signal'}) {
947898184e3Ssthen        install_layered_signal($opts->{'terminate_on_signal'}, sub { $got_sig_quit = time(); });
948898184e3Ssthen      }
949898184e3Ssthen
950b39c5158Smillert      my $child_child_pid;
9516fb12b70Safresh1      my $now;
9526fb12b70Safresh1      my $previous_monotonic_value;
953b39c5158Smillert
954b39c5158Smillert      while (!$child_finished) {
9556fb12b70Safresh1        $previous_monotonic_value = $now;
9566fb12b70Safresh1        $now = get_monotonic_time();
9576fb12b70Safresh1
9586fb12b70Safresh1        adjust_monotonic_start_time([\$start_time, \$last_parent_check, \$got_sig_child], $now, $previous_monotonic_value);
959898184e3Ssthen
960898184e3Ssthen        if ($opts->{'terminate_on_parent_sudden_death'}) {
961898184e3Ssthen          # check for parent once each five seconds
9626fb12b70Safresh1          if ($now > $last_parent_check + 5) {
963898184e3Ssthen            if (getppid() eq "1") {
964898184e3Ssthen              kill_gently ($pid, {
965898184e3Ssthen                'first_kill_type' => 'process_group',
966898184e3Ssthen                'final_kill_type' => 'process_group',
967898184e3Ssthen                'wait_time' => $opts->{'terminate_wait_time'}
968898184e3Ssthen                });
969898184e3Ssthen              $parent_died = 1;
970898184e3Ssthen            }
971898184e3Ssthen
9726fb12b70Safresh1            $last_parent_check = $now;
973898184e3Ssthen          }
974898184e3Ssthen        }
975898184e3Ssthen
976b39c5158Smillert        # user specified timeout
977b39c5158Smillert        if ($opts->{'timeout'}) {
9786fb12b70Safresh1          if ($now > $start_time + $opts->{'timeout'}) {
979898184e3Ssthen            kill_gently ($pid, {
980898184e3Ssthen              'first_kill_type' => 'process_group',
981898184e3Ssthen              'final_kill_type' => 'process_group',
982898184e3Ssthen              'wait_time' => $opts->{'terminate_wait_time'}
983898184e3Ssthen              });
984b39c5158Smillert            $child_timedout = 1;
985b39c5158Smillert          }
986b39c5158Smillert        }
987b39c5158Smillert
988b39c5158Smillert        # give OS 10 seconds for correct return of waitpid,
989b39c5158Smillert        # kill process after that and finish wait loop;
990b39c5158Smillert        # shouldn't ever happen -- remove this code?
991b39c5158Smillert        if ($got_sig_child) {
9926fb12b70Safresh1          if ($now > $got_sig_child + 10) {
993b39c5158Smillert            print STDERR "waitpid did not return -1 for 10 seconds after SIG_CHLD, killing [$pid]\n";
994b39c5158Smillert            kill (-9, $pid);
995b39c5158Smillert            $child_finished = 1;
996b39c5158Smillert          }
997b39c5158Smillert        }
998b39c5158Smillert
999898184e3Ssthen        if ($got_sig_quit) {
1000898184e3Ssthen          kill_gently ($pid, {
1001898184e3Ssthen            'first_kill_type' => 'process_group',
1002898184e3Ssthen            'final_kill_type' => 'process_group',
1003898184e3Ssthen            'wait_time' => $opts->{'terminate_wait_time'}
1004898184e3Ssthen            });
1005898184e3Ssthen          $child_finished = 1;
1006898184e3Ssthen        }
1007898184e3Ssthen
1008898184e3Ssthen        my $waitpid = waitpid($pid, POSIX::WNOHANG);
1009b39c5158Smillert
1010b39c5158Smillert        # child finished, catch it's exit status
1011b39c5158Smillert        if ($waitpid ne 0 && $waitpid ne -1) {
1012b39c5158Smillert          $child_exit_code = $? >> 8;
1013b39c5158Smillert        }
1014b39c5158Smillert
1015b39c5158Smillert        if ($waitpid eq -1) {
1016b39c5158Smillert          $child_finished = 1;
1017b39c5158Smillert        }
1018b39c5158Smillert
10196fb12b70Safresh1        my $ready_fds = [];
10206fb12b70Safresh1        push @{$ready_fds}, $select->can_read(1/100);
10216fb12b70Safresh1
10226fb12b70Safresh1        READY_FDS: while (scalar(@{$ready_fds})) {
10236fb12b70Safresh1          my $fd = shift @{$ready_fds};
10246fb12b70Safresh1          $ready_fds = [grep {$_ ne $fd} @{$ready_fds}];
10256fb12b70Safresh1
10266fb12b70Safresh1          my $str = $child_output->{$fd->fileno};
10276fb12b70Safresh1          Carp::confess("child stream not found: $fd") unless $str;
10286fb12b70Safresh1
10296fb12b70Safresh1          my $data = "";
10306fb12b70Safresh1          my $count = $fd->sysread($data, $str->{'block_size'});
10316fb12b70Safresh1
10326fb12b70Safresh1          if ($count) {
10336fb12b70Safresh1              # extract all the available lines and store the rest in temporary buffer
10346fb12b70Safresh1              if ($data =~ /(.+\n)([^\n]*)/so) {
10356fb12b70Safresh1                  $data = $str->{'scalar_buffer'} . $1;
10366fb12b70Safresh1                  $str->{'scalar_buffer'} = $2 || "";
10376fb12b70Safresh1              }
10386fb12b70Safresh1              else {
10396fb12b70Safresh1                  $str->{'scalar_buffer'} .= $data;
10406fb12b70Safresh1                  $data = "";
10416fb12b70Safresh1              }
10426fb12b70Safresh1          }
10436fb12b70Safresh1          elsif ($count eq 0) {
10446fb12b70Safresh1            $select->remove($fd);
10456fb12b70Safresh1            $fd->close();
10466fb12b70Safresh1            if ($str->{'scalar_buffer'}) {
10476fb12b70Safresh1                $data = $str->{'scalar_buffer'} . "\n";
10486fb12b70Safresh1            }
10496fb12b70Safresh1          }
10506fb12b70Safresh1          else {
10516fb12b70Safresh1            Carp::confess("error during sysread on [$fd]: " . $!);
10526fb12b70Safresh1          }
10536fb12b70Safresh1
10546fb12b70Safresh1          # $data contains only full lines (or last line if it was unfinished read
10556fb12b70Safresh1          # or now new-line in the output of the child); dat is processed
10566fb12b70Safresh1          # according to the "protocol" of socket
10576fb12b70Safresh1          if ($str->{'protocol'} eq 'info') {
10586fb12b70Safresh1            if ($data =~ /^spawned ([0-9]+?)\n(.*?)/so) {
1059b39c5158Smillert              $child_child_pid = $1;
10606fb12b70Safresh1              $data = $2;
1061b39c5158Smillert            }
10626fb12b70Safresh1            if ($data =~ /^reaped ([0-9]+?)\n(.*?)/so) {
1063b39c5158Smillert              $child_child_pid = undef;
10646fb12b70Safresh1              $data = $2;
1065b39c5158Smillert            }
10666fb12b70Safresh1            if ($data =~ /^[\d]+ killed with ([0-9]+?)\n(.*?)/so) {
1067898184e3Ssthen              $child_killed_by_signal = $1;
10686fb12b70Safresh1              $data = $2;
1069b39c5158Smillert            }
1070b39c5158Smillert
10716fb12b70Safresh1            # we don't expect any other data in info socket, so it's
10726fb12b70Safresh1            # some strange violation of protocol, better know about this
10736fb12b70Safresh1            if ($data) {
10746fb12b70Safresh1              Carp::confess("info protocol violation: [$data]");
10756fb12b70Safresh1            }
10766fb12b70Safresh1          }
10776fb12b70Safresh1          if ($str->{'protocol'} eq 'stdout') {
1078898184e3Ssthen            if (!$opts->{'discard_output'}) {
10796fb12b70Safresh1              $child_stdout .= $data;
10806fb12b70Safresh1              $child_merged .= $data;
1081898184e3Ssthen            }
1082b39c5158Smillert
1083b39c5158Smillert            if ($opts->{'stdout_handler'} && ref($opts->{'stdout_handler'}) eq 'CODE') {
10846fb12b70Safresh1              $opts->{'stdout_handler'}->($data);
1085b39c5158Smillert            }
1086b39c5158Smillert          }
10876fb12b70Safresh1          if ($str->{'protocol'} eq 'stderr') {
1088898184e3Ssthen            if (!$opts->{'discard_output'}) {
10896fb12b70Safresh1              $child_stderr .= $data;
10906fb12b70Safresh1              $child_merged .= $data;
1091898184e3Ssthen            }
10926fb12b70Safresh1
1093b39c5158Smillert            if ($opts->{'stderr_handler'} && ref($opts->{'stderr_handler'}) eq 'CODE') {
10946fb12b70Safresh1              $opts->{'stderr_handler'}->($data);
1095b39c5158Smillert            }
1096b39c5158Smillert          }
1097b39c5158Smillert
10986fb12b70Safresh1          # process may finish (waitpid returns -1) before
10996fb12b70Safresh1          # we've read all of its output because of buffering;
11006fb12b70Safresh1          # so try to read all the way it is possible to read
11016fb12b70Safresh1          # in such case - this shouldn't be too much (unless
11026fb12b70Safresh1          # the buffer size is HUGE -- should introduce
11036fb12b70Safresh1          # another counter in such case, maybe later)
11046fb12b70Safresh1          #
11056fb12b70Safresh1          push @{$ready_fds}, $select->can_read(1/100) if $child_finished;
11066fb12b70Safresh1        }
11076fb12b70Safresh1
11089f11ffb7Safresh1        if ($opts->{'wait_loop_callback'} && ref($opts->{'wait_loop_callback'}) eq 'CODE') {
11099f11ffb7Safresh1          $opts->{'wait_loop_callback'}->();
11109f11ffb7Safresh1        }
11119f11ffb7Safresh1
1112b39c5158Smillert        Time::HiRes::usleep(1);
1113b39c5158Smillert      }
1114b39c5158Smillert
1115b39c5158Smillert      # $child_pid_pid is not defined in two cases:
1116b39c5158Smillert      #  * when our child was killed before
1117b39c5158Smillert      #    it had chance to tell us the pid
1118b39c5158Smillert      #    of the child it spawned. we can do
1119b39c5158Smillert      #    nothing in this case :(
1120b39c5158Smillert      #  * our child successfully reaped its child,
1121b39c5158Smillert      #    we have nothing left to do in this case
1122b39c5158Smillert      #
1123b39c5158Smillert      # defined $child_pid_pid means child's child
1124b39c5158Smillert      # has not died but nobody is waiting for it,
1125898184e3Ssthen      # killing it brutally.
1126b39c5158Smillert      #
1127b39c5158Smillert      if ($child_child_pid) {
1128b39c5158Smillert        kill_gently($child_child_pid);
1129b39c5158Smillert      }
1130b39c5158Smillert
1131898184e3Ssthen      # in case there are forks in child which
1132898184e3Ssthen      # do not forward or process signals (TERM) correctly
1133898184e3Ssthen      # kill whole child process group, effectively trying
1134898184e3Ssthen      # not to return with some children or their parts still running
1135898184e3Ssthen      #
1136898184e3Ssthen      # to be more accurate -- we need to be sure
1137898184e3Ssthen      # that this is process group created by our child
1138898184e3Ssthen      # (and not some other process group with the same pgid,
1139898184e3Ssthen      # created just after death of our child) -- fortunately
1140898184e3Ssthen      # this might happen only when process group ids
1141898184e3Ssthen      # are reused quickly (there are lots of processes
1142898184e3Ssthen      # spawning new process groups for example)
1143898184e3Ssthen      #
1144898184e3Ssthen      if ($opts->{'clean_up_children'}) {
1145898184e3Ssthen        kill(-9, $pid);
1146898184e3Ssthen      }
1147898184e3Ssthen
1148b39c5158Smillert  #    print "child $pid finished\n";
1149b39c5158Smillert
1150b39c5158Smillert      close($child_stdout_socket);
1151b39c5158Smillert      close($child_stderr_socket);
1152b39c5158Smillert      close($child_info_socket);
1153b39c5158Smillert
1154b39c5158Smillert      my $o = {
1155b39c5158Smillert        'stdout' => $child_stdout,
1156b39c5158Smillert        'stderr' => $child_stderr,
1157b39c5158Smillert        'merged' => $child_merged,
1158b39c5158Smillert        'timeout' => $child_timedout ? $opts->{'timeout'} : 0,
1159b39c5158Smillert        'exit_code' => $child_exit_code,
1160898184e3Ssthen        'parent_died' => $parent_died,
1161898184e3Ssthen        'killed_by_signal' => $child_killed_by_signal,
1162898184e3Ssthen        'child_pgid' => $pid,
11636fb12b70Safresh1        'cmd' => $cmd,
1164b39c5158Smillert        };
1165b39c5158Smillert
1166b39c5158Smillert      my $err_msg = '';
1167b39c5158Smillert      if ($o->{'exit_code'}) {
1168b39c5158Smillert        $err_msg .= "exited with code [$o->{'exit_code'}]\n";
1169b39c5158Smillert      }
1170b39c5158Smillert      if ($o->{'timeout'}) {
1171b39c5158Smillert        $err_msg .= "ran more than [$o->{'timeout'}] seconds\n";
1172b39c5158Smillert      }
1173898184e3Ssthen      if ($o->{'parent_died'}) {
1174898184e3Ssthen        $err_msg .= "parent died\n";
1175898184e3Ssthen      }
11766fb12b70Safresh1      if ($o->{'stdout'} && !$opts->{'non_empty_stdout_ok'}) {
1177b39c5158Smillert        $err_msg .= "stdout:\n" . $o->{'stdout'} . "\n";
1178b39c5158Smillert      }
1179b39c5158Smillert      if ($o->{'stderr'}) {
1180b39c5158Smillert        $err_msg .= "stderr:\n" . $o->{'stderr'} . "\n";
1181b39c5158Smillert      }
1182898184e3Ssthen      if ($o->{'killed_by_signal'}) {
1183898184e3Ssthen        $err_msg .= "killed by signal [" . $o->{'killed_by_signal'} . "]\n";
1184898184e3Ssthen      }
1185b39c5158Smillert      $o->{'err_msg'} = $err_msg;
1186b39c5158Smillert
1187898184e3Ssthen      if ($orig_sig_child) {
1188898184e3Ssthen        $SIG{'CHLD'} = $orig_sig_child;
1189898184e3Ssthen      }
1190898184e3Ssthen      else {
1191898184e3Ssthen        delete($SIG{'CHLD'});
1192898184e3Ssthen      }
1193898184e3Ssthen
11949f11ffb7Safresh1      uninstall_signals();
11959f11ffb7Safresh1
1196b39c5158Smillert      return $o;
1197b39c5158Smillert    }
1198b39c5158Smillert    else {
11996fb12b70Safresh1      Carp::confess("cannot fork: $!") unless defined($pid);
1200b39c5158Smillert
1201b39c5158Smillert      # create new process session for open3 call,
1202b39c5158Smillert      # so we hopefully can kill all the subprocesses
1203b39c5158Smillert      # which might be spawned in it (except for those
1204b39c5158Smillert      # which do setsid theirselves -- can't do anything
1205b39c5158Smillert      # with those)
1206b39c5158Smillert
1207*56d68f1eSafresh1      POSIX::setsid() == -1 and Carp::confess("Error running setsid: " . $!);
1208b39c5158Smillert
1209898184e3Ssthen      if ($opts->{'child_BEGIN'} && ref($opts->{'child_BEGIN'}) eq 'CODE') {
1210898184e3Ssthen        $opts->{'child_BEGIN'}->();
1211898184e3Ssthen      }
1212898184e3Ssthen
1213b39c5158Smillert      close($child_stdout_socket);
1214b39c5158Smillert      close($child_stderr_socket);
1215b39c5158Smillert      close($child_info_socket);
1216b39c5158Smillert
1217898184e3Ssthen      my $child_exit_code;
1218898184e3Ssthen
1219898184e3Ssthen      # allow both external programs
1220898184e3Ssthen      # and internal perl calls
1221898184e3Ssthen      if (!ref($cmd)) {
1222898184e3Ssthen        $child_exit_code = open3_run($cmd, {
1223b39c5158Smillert          'parent_info' => $parent_info_socket,
1224b39c5158Smillert          'parent_stdout' => $parent_stdout_socket,
1225b39c5158Smillert          'parent_stderr' => $parent_stderr_socket,
1226b39c5158Smillert          'child_stdin' => $opts->{'child_stdin'},
1227b46d8ef2Safresh1          'original_ppid' => $ppid,
1228b39c5158Smillert          });
1229898184e3Ssthen      }
1230898184e3Ssthen      elsif (ref($cmd) eq 'CODE') {
12316fb12b70Safresh1        # reopen STDOUT and STDERR for child code:
12326fb12b70Safresh1        # https://rt.cpan.org/Ticket/Display.html?id=85912
12336fb12b70Safresh1        open STDOUT, '>&', $parent_stdout_socket || Carp::confess("Unable to reopen STDOUT: $!\n");
12346fb12b70Safresh1        open STDERR, '>&', $parent_stderr_socket || Carp::confess("Unable to reopen STDERR: $!\n");
12356fb12b70Safresh1
1236898184e3Ssthen        $child_exit_code = $cmd->({
1237898184e3Ssthen          'opts' => $opts,
1238898184e3Ssthen          'parent_info' => $parent_info_socket,
1239898184e3Ssthen          'parent_stdout' => $parent_stdout_socket,
1240898184e3Ssthen          'parent_stderr' => $parent_stderr_socket,
1241898184e3Ssthen          'child_stdin' => $opts->{'child_stdin'},
1242898184e3Ssthen          });
1243898184e3Ssthen      }
1244898184e3Ssthen      else {
1245898184e3Ssthen        print $parent_stderr_socket "Invalid command reference: " . ref($cmd) . "\n";
1246898184e3Ssthen        $child_exit_code = 1;
1247898184e3Ssthen      }
1248b39c5158Smillert
1249b39c5158Smillert      close($parent_stdout_socket);
1250b39c5158Smillert      close($parent_stderr_socket);
1251b39c5158Smillert      close($parent_info_socket);
1252b39c5158Smillert
1253898184e3Ssthen      if ($opts->{'child_END'} && ref($opts->{'child_END'}) eq 'CODE') {
1254898184e3Ssthen        $opts->{'child_END'}->();
1255898184e3Ssthen      }
1256898184e3Ssthen
12576fb12b70Safresh1      $| = 1;
125891f110e0Safresh1      POSIX::_exit $child_exit_code;
1259b39c5158Smillert    }
1260b39c5158Smillert}
1261b39c5158Smillert
1262b39c5158Smillertsub run {
1263b39c5158Smillert    ### container to store things in
1264b39c5158Smillert    my $self = bless {}, __PACKAGE__;
1265b39c5158Smillert
1266b39c5158Smillert    my %hash = @_;
1267b39c5158Smillert
1268b39c5158Smillert    ### if the user didn't provide a buffer, we'll store it here.
1269b39c5158Smillert    my $def_buf = '';
1270b39c5158Smillert
1271b39c5158Smillert    my($verbose,$cmd,$buffer,$timeout);
1272b39c5158Smillert    my $tmpl = {
1273b39c5158Smillert        verbose => { default  => $VERBOSE,  store => \$verbose },
1274b39c5158Smillert        buffer  => { default  => \$def_buf, store => \$buffer },
1275b39c5158Smillert        command => { required => 1,         store => \$cmd,
1276b39c5158Smillert                     allow    => sub { !ref($_[0]) or ref($_[0]) eq 'ARRAY' },
1277b39c5158Smillert        },
1278b39c5158Smillert        timeout => { default  => 0,         store => \$timeout },
1279b39c5158Smillert    };
1280b39c5158Smillert
1281b39c5158Smillert    unless( check( $tmpl, \%hash, $VERBOSE ) ) {
1282b39c5158Smillert        Carp::carp( loc( "Could not validate input: %1",
1283b39c5158Smillert                         Params::Check->last_error ) );
1284b39c5158Smillert        return;
1285b39c5158Smillert    };
1286b39c5158Smillert
1287b39c5158Smillert    $cmd = _quote_args_vms( $cmd ) if IS_VMS;
1288b39c5158Smillert
1289b39c5158Smillert    ### strip any empty elements from $cmd if present
1290898184e3Ssthen    if ( $ALLOW_NULL_ARGS ) {
1291898184e3Ssthen      $cmd = [ grep { defined } @$cmd ] if ref $cmd;
1292898184e3Ssthen    }
1293898184e3Ssthen    else {
1294b39c5158Smillert      $cmd = [ grep { defined && length } @$cmd ] if ref $cmd;
1295898184e3Ssthen    }
1296b39c5158Smillert
1297b39c5158Smillert    my $pp_cmd = (ref $cmd ? "@$cmd" : $cmd);
1298b39c5158Smillert    print loc("Running [%1]...\n", $pp_cmd ) if $verbose;
1299b39c5158Smillert
1300b39c5158Smillert    ### did the user pass us a buffer to fill or not? if so, set this
1301b39c5158Smillert    ### flag so we know what is expected of us
1302b39c5158Smillert    ### XXX this is now being ignored. in the future, we could add diagnostic
1303b39c5158Smillert    ### messages based on this logic
1304b39c5158Smillert    #my $user_provided_buffer = $buffer == \$def_buf ? 0 : 1;
1305b39c5158Smillert
1306b39c5158Smillert    ### buffers that are to be captured
1307b39c5158Smillert    my( @buffer, @buff_err, @buff_out );
1308b39c5158Smillert
1309b39c5158Smillert    ### capture STDOUT
1310b39c5158Smillert    my $_out_handler = sub {
1311b39c5158Smillert        my $buf = shift;
1312b39c5158Smillert        return unless defined $buf;
1313b39c5158Smillert
1314b39c5158Smillert        print STDOUT $buf if $verbose;
1315b39c5158Smillert        push @buffer,   $buf;
1316b39c5158Smillert        push @buff_out, $buf;
1317b39c5158Smillert    };
1318b39c5158Smillert
1319b39c5158Smillert    ### capture STDERR
1320b39c5158Smillert    my $_err_handler = sub {
1321b39c5158Smillert        my $buf = shift;
1322b39c5158Smillert        return unless defined $buf;
1323b39c5158Smillert
1324b39c5158Smillert        print STDERR $buf if $verbose;
1325b39c5158Smillert        push @buffer,   $buf;
1326b39c5158Smillert        push @buff_err, $buf;
1327b39c5158Smillert    };
1328b39c5158Smillert
1329b39c5158Smillert
1330b39c5158Smillert    ### flag to indicate we have a buffer captured
1331b39c5158Smillert    my $have_buffer = $self->can_capture_buffer ? 1 : 0;
1332b39c5158Smillert
1333b39c5158Smillert    ### flag indicating if the subcall went ok
1334b39c5158Smillert    my $ok;
1335b39c5158Smillert
13366fb12b70Safresh1    ### don't look at previous errors:
1337b39c5158Smillert    local $?;
1338b39c5158Smillert    local $@;
1339b39c5158Smillert    local $!;
1340b39c5158Smillert
1341b39c5158Smillert    ### we might be having a timeout set
1342b39c5158Smillert    eval {
1343b39c5158Smillert        local $SIG{ALRM} = sub { die bless sub {
1344b39c5158Smillert            ALARM_CLASS .
1345b39c5158Smillert            qq[: Command '$pp_cmd' aborted by alarm after $timeout seconds]
1346b39c5158Smillert        }, ALARM_CLASS } if $timeout;
1347b39c5158Smillert        alarm $timeout || 0;
1348b39c5158Smillert
1349b39c5158Smillert        ### IPC::Run is first choice if $USE_IPC_RUN is set.
1350898184e3Ssthen        if( !IS_WIN32 and $USE_IPC_RUN and $self->can_use_ipc_run( 1 ) ) {
1351b39c5158Smillert            ### ipc::run handlers needs the command as a string or an array ref
1352b39c5158Smillert
1353b39c5158Smillert            $self->_debug( "# Using IPC::Run. Have buffer: $have_buffer" )
1354b39c5158Smillert                if $DEBUG;
1355b39c5158Smillert
1356b39c5158Smillert            $ok = $self->_ipc_run( $cmd, $_out_handler, $_err_handler );
1357b39c5158Smillert
1358b39c5158Smillert        ### since IPC::Open3 works on all platforms, and just fails on
1359b39c5158Smillert        ### win32 for capturing buffers, do that ideally
1360b39c5158Smillert        } elsif ( $USE_IPC_OPEN3 and $self->can_use_ipc_open3( 1 ) ) {
1361b39c5158Smillert
1362b39c5158Smillert            $self->_debug("# Using IPC::Open3. Have buffer: $have_buffer")
1363b39c5158Smillert                if $DEBUG;
1364b39c5158Smillert
1365b39c5158Smillert            ### in case there are pipes in there;
1366b39c5158Smillert            ### IPC::Open3 will call exec and exec will do the right thing
1367898184e3Ssthen
1368898184e3Ssthen            my $method = IS_WIN32 ? '_open3_run_win32' : '_open3_run';
1369898184e3Ssthen
1370898184e3Ssthen            $ok = $self->$method(
1371b39c5158Smillert                                    $cmd, $_out_handler, $_err_handler, $verbose
1372b39c5158Smillert                                );
1373b39c5158Smillert
1374b39c5158Smillert        ### if we are allowed to run verbose, just dispatch the system command
1375b39c5158Smillert        } else {
1376b39c5158Smillert            $self->_debug( "# Using system(). Have buffer: $have_buffer" )
1377b39c5158Smillert                if $DEBUG;
1378b39c5158Smillert            $ok = $self->_system_run( $cmd, $verbose );
1379b39c5158Smillert        }
1380b39c5158Smillert
1381b39c5158Smillert        alarm 0;
1382b39c5158Smillert    };
1383b39c5158Smillert
1384b39c5158Smillert    ### restore STDIN after duping, or STDIN will be closed for
1385b39c5158Smillert    ### this current perl process!
1386b39c5158Smillert    $self->__reopen_fds( @{ $self->_fds} ) if $self->_fds;
1387b39c5158Smillert
1388b39c5158Smillert    my $err;
1389b39c5158Smillert    unless( $ok ) {
1390b39c5158Smillert        ### alarm happened
1391b39c5158Smillert        if ( $@ and ref $@ and $@->isa( ALARM_CLASS ) ) {
1392b39c5158Smillert            $err = $@->();  # the error code is an expired alarm
1393b39c5158Smillert
1394b39c5158Smillert        ### another error happened, set by the dispatchub
1395b39c5158Smillert        } else {
1396b39c5158Smillert            $err = $self->error;
1397b39c5158Smillert        }
1398b39c5158Smillert    }
1399b39c5158Smillert
1400b39c5158Smillert    ### fill the buffer;
1401b39c5158Smillert    $$buffer = join '', @buffer if @buffer;
1402b39c5158Smillert
1403b39c5158Smillert    ### return a list of flags and buffers (if available) in list
1404b39c5158Smillert    ### context, or just a simple 'ok' in scalar
1405b39c5158Smillert    return wantarray
1406b39c5158Smillert                ? $have_buffer
1407b39c5158Smillert                    ? ($ok, $err, \@buffer, \@buff_out, \@buff_err)
1408b39c5158Smillert                    : ($ok, $err )
1409b39c5158Smillert                : $ok
1410b39c5158Smillert
1411b39c5158Smillert
1412b39c5158Smillert}
1413b39c5158Smillert
1414898184e3Ssthensub _open3_run_win32 {
1415898184e3Ssthen  my $self    = shift;
1416898184e3Ssthen  my $cmd     = shift;
1417898184e3Ssthen  my $outhand = shift;
1418898184e3Ssthen  my $errhand = shift;
1419898184e3Ssthen
14206fb12b70Safresh1  require Socket;
14216fb12b70Safresh1
1422898184e3Ssthen  my $pipe = sub {
14236fb12b70Safresh1    socketpair($_[0], $_[1], &Socket::AF_UNIX, &Socket::SOCK_STREAM, &Socket::PF_UNSPEC)
1424898184e3Ssthen        or return undef;
1425898184e3Ssthen    shutdown($_[0], 1);  # No more writing for reader
1426898184e3Ssthen    shutdown($_[1], 0);  # No more reading for writer
1427898184e3Ssthen    return 1;
1428898184e3Ssthen  };
1429898184e3Ssthen
1430898184e3Ssthen  my $open3 = sub {
1431898184e3Ssthen    local (*TO_CHLD_R,     *TO_CHLD_W);
1432898184e3Ssthen    local (*FR_CHLD_R,     *FR_CHLD_W);
1433898184e3Ssthen    local (*FR_CHLD_ERR_R, *FR_CHLD_ERR_W);
1434898184e3Ssthen
1435898184e3Ssthen    $pipe->(*TO_CHLD_R,     *TO_CHLD_W    ) or die $^E;
1436898184e3Ssthen    $pipe->(*FR_CHLD_R,     *FR_CHLD_W    ) or die $^E;
1437898184e3Ssthen    $pipe->(*FR_CHLD_ERR_R, *FR_CHLD_ERR_W) or die $^E;
1438898184e3Ssthen
1439898184e3Ssthen    my $pid = IPC::Open3::open3('>&TO_CHLD_R', '<&FR_CHLD_W', '<&FR_CHLD_ERR_W', @_);
1440898184e3Ssthen
1441898184e3Ssthen    return ( $pid, *TO_CHLD_W, *FR_CHLD_R, *FR_CHLD_ERR_R );
1442898184e3Ssthen  };
1443898184e3Ssthen
1444898184e3Ssthen  $cmd = [ grep { defined && length } @$cmd ] if ref $cmd;
1445898184e3Ssthen  $cmd = $self->__fix_cmd_whitespace_and_special_chars( $cmd );
1446898184e3Ssthen
1447898184e3Ssthen  my ($pid, $to_chld, $fr_chld, $fr_chld_err) =
1448898184e3Ssthen    $open3->( ( ref $cmd ? @$cmd : $cmd ) );
1449898184e3Ssthen
1450898184e3Ssthen  my $in_sel  = IO::Select->new();
1451898184e3Ssthen  my $out_sel = IO::Select->new();
1452898184e3Ssthen
1453898184e3Ssthen  my %objs;
1454898184e3Ssthen
1455898184e3Ssthen  $objs{ fileno( $fr_chld ) } = $outhand;
1456898184e3Ssthen  $objs{ fileno( $fr_chld_err ) } = $errhand;
1457898184e3Ssthen  $in_sel->add( $fr_chld );
1458898184e3Ssthen  $in_sel->add( $fr_chld_err );
1459898184e3Ssthen
1460898184e3Ssthen  close($to_chld);
1461898184e3Ssthen
1462898184e3Ssthen  while ($in_sel->count() + $out_sel->count()) {
1463898184e3Ssthen    my ($ins, $outs) = IO::Select::select($in_sel, $out_sel, undef);
1464898184e3Ssthen
1465898184e3Ssthen    for my $fh (@$ins) {
1466898184e3Ssthen        my $obj = $objs{ fileno($fh) };
1467898184e3Ssthen        my $buf;
1468898184e3Ssthen        my $bytes_read = sysread($fh, $buf, 64*1024 ); #, length($buf));
1469898184e3Ssthen        if (!$bytes_read) {
1470898184e3Ssthen            $in_sel->remove($fh);
1471898184e3Ssthen        }
1472898184e3Ssthen        else {
1473898184e3Ssthen            $obj->( "$buf" );
1474898184e3Ssthen        }
1475898184e3Ssthen      }
1476898184e3Ssthen
1477898184e3Ssthen      for my $fh (@$outs) {
1478898184e3Ssthen      }
1479898184e3Ssthen  }
1480898184e3Ssthen
1481898184e3Ssthen  waitpid($pid, 0);
1482898184e3Ssthen
1483898184e3Ssthen  ### some error occurred
1484898184e3Ssthen  if( $? ) {
1485898184e3Ssthen        $self->error( $self->_pp_child_error( $cmd, $? ) );
1486898184e3Ssthen        $self->ok( 0 );
1487898184e3Ssthen        return;
1488898184e3Ssthen  } else {
1489898184e3Ssthen        return $self->ok( 1 );
1490898184e3Ssthen  }
1491898184e3Ssthen}
1492898184e3Ssthen
1493b39c5158Smillertsub _open3_run {
1494b39c5158Smillert    my $self            = shift;
1495b39c5158Smillert    my $cmd             = shift;
1496b39c5158Smillert    my $_out_handler    = shift;
1497b39c5158Smillert    my $_err_handler    = shift;
1498b39c5158Smillert    my $verbose         = shift || 0;
1499b39c5158Smillert
1500b39c5158Smillert    ### Following code are adapted from Friar 'abstracts' in the
1501b39c5158Smillert    ### Perl Monastery (http://www.perlmonks.org/index.pl?node_id=151886).
1502b39c5158Smillert    ### XXX that code didn't work.
1503b39c5158Smillert    ### we now use the following code, thanks to theorbtwo
1504b39c5158Smillert
1505b39c5158Smillert    ### define them beforehand, so we always have defined FH's
1506b39c5158Smillert    ### to read from.
1507b39c5158Smillert    use Symbol;
1508b39c5158Smillert    my $kidout      = Symbol::gensym();
1509b39c5158Smillert    my $kiderror    = Symbol::gensym();
1510b39c5158Smillert
1511b39c5158Smillert    ### Dup the filehandle so we can pass 'our' STDIN to the
1512b39c5158Smillert    ### child process. This stops us from having to pump input
1513b39c5158Smillert    ### from ourselves to the childprocess. However, we will need
1514b39c5158Smillert    ### to revive the FH afterwards, as IPC::Open3 closes it.
1515b39c5158Smillert    ### We'll do the same for STDOUT and STDERR. It works without
1516b39c5158Smillert    ### duping them on non-unix derivatives, but not on win32.
1517b39c5158Smillert    my @fds_to_dup = ( IS_WIN32 && !$verbose
1518b39c5158Smillert                            ? qw[STDIN STDOUT STDERR]
1519b39c5158Smillert                            : qw[STDIN]
1520b39c5158Smillert                        );
1521b39c5158Smillert    $self->_fds( \@fds_to_dup );
1522b39c5158Smillert    $self->__dup_fds( @fds_to_dup );
1523b39c5158Smillert
1524b39c5158Smillert    ### pipes have to come in a quoted string, and that clashes with
1525b39c5158Smillert    ### whitespace. This sub fixes up such commands so they run properly
1526b39c5158Smillert    $cmd = $self->__fix_cmd_whitespace_and_special_chars( $cmd );
1527b39c5158Smillert
15286fb12b70Safresh1    ### don't stringify @$cmd, so spaces in filenames/paths are
1529b39c5158Smillert    ### treated properly
1530b39c5158Smillert    my $pid = eval {
1531b39c5158Smillert        IPC::Open3::open3(
1532b39c5158Smillert                    '<&STDIN',
1533b39c5158Smillert                    (IS_WIN32 ? '>&STDOUT' : $kidout),
1534b39c5158Smillert                    (IS_WIN32 ? '>&STDERR' : $kiderror),
1535b39c5158Smillert                    ( ref $cmd ? @$cmd : $cmd ),
1536b39c5158Smillert                );
1537b39c5158Smillert    };
1538b39c5158Smillert
1539b39c5158Smillert    ### open3 error occurred
1540b39c5158Smillert    if( $@ and $@ =~ /^open3:/ ) {
1541b39c5158Smillert        $self->ok( 0 );
1542b39c5158Smillert        $self->error( $@ );
1543b39c5158Smillert        return;
1544b39c5158Smillert    };
1545b39c5158Smillert
1546b39c5158Smillert    ### use OUR stdin, not $kidin. Somehow,
1547b39c5158Smillert    ### we never get the input.. so jump through
1548b39c5158Smillert    ### some hoops to do it :(
1549b39c5158Smillert    my $selector = IO::Select->new(
1550b39c5158Smillert                        (IS_WIN32 ? \*STDERR : $kiderror),
1551b39c5158Smillert                        \*STDIN,
1552b39c5158Smillert                        (IS_WIN32 ? \*STDOUT : $kidout)
1553b39c5158Smillert                    );
1554b39c5158Smillert
1555b39c5158Smillert    STDOUT->autoflush(1);   STDERR->autoflush(1);   STDIN->autoflush(1);
1556b39c5158Smillert    $kidout->autoflush(1)   if UNIVERSAL::can($kidout,   'autoflush');
1557b39c5158Smillert    $kiderror->autoflush(1) if UNIVERSAL::can($kiderror, 'autoflush');
1558b39c5158Smillert
1559898184e3Ssthen    ### add an explicit break statement
1560b39c5158Smillert    ### code courtesy of theorbtwo from #london.pm
1561b39c5158Smillert    my $stdout_done = 0;
1562b39c5158Smillert    my $stderr_done = 0;
1563b39c5158Smillert    OUTER: while ( my @ready = $selector->can_read ) {
1564b39c5158Smillert
1565b39c5158Smillert        for my $h ( @ready ) {
1566b39c5158Smillert            my $buf;
1567b39c5158Smillert
1568b39c5158Smillert            ### $len is the amount of bytes read
1569b39c5158Smillert            my $len = sysread( $h, $buf, 4096 );    # try to read 4096 bytes
1570b39c5158Smillert
1571b39c5158Smillert            ### see perldoc -f sysread: it returns undef on error,
1572b39c5158Smillert            ### so bail out.
1573b39c5158Smillert            if( not defined $len ) {
1574b39c5158Smillert                warn(loc("Error reading from process: %1", $!));
1575b39c5158Smillert                last OUTER;
1576b39c5158Smillert            }
1577b39c5158Smillert
1578b39c5158Smillert            ### check for $len. it may be 0, at which point we're
1579b39c5158Smillert            ### done reading, so don't try to process it.
1580b39c5158Smillert            ### if we would print anyway, we'd provide bogus information
1581b39c5158Smillert            $_out_handler->( "$buf" ) if $len && $h == $kidout;
1582b39c5158Smillert            $_err_handler->( "$buf" ) if $len && $h == $kiderror;
1583b39c5158Smillert
1584b39c5158Smillert            ### Wait till child process is done printing to both
1585b39c5158Smillert            ### stdout and stderr.
1586b39c5158Smillert            $stdout_done = 1 if $h == $kidout   and $len == 0;
1587b39c5158Smillert            $stderr_done = 1 if $h == $kiderror and $len == 0;
1588b39c5158Smillert            last OUTER if ($stdout_done && $stderr_done);
1589b39c5158Smillert        }
1590b39c5158Smillert    }
1591b39c5158Smillert
1592b39c5158Smillert    waitpid $pid, 0; # wait for it to die
1593b39c5158Smillert
1594b39c5158Smillert    ### restore STDIN after duping, or STDIN will be closed for
1595b39c5158Smillert    ### this current perl process!
1596b39c5158Smillert    ### done in the parent call now
1597b39c5158Smillert    # $self->__reopen_fds( @fds_to_dup );
1598b39c5158Smillert
1599b39c5158Smillert    ### some error occurred
1600b39c5158Smillert    if( $? ) {
1601b39c5158Smillert        $self->error( $self->_pp_child_error( $cmd, $? ) );
1602b39c5158Smillert        $self->ok( 0 );
1603b39c5158Smillert        return;
1604b39c5158Smillert    } else {
1605b39c5158Smillert        return $self->ok( 1 );
1606b39c5158Smillert    }
1607b39c5158Smillert}
1608b39c5158Smillert
1609898184e3Ssthen### Text::ParseWords::shellwords() uses unix semantics. that will break
1610b39c5158Smillert### on win32
1611b39c5158Smillert{   my $parse_sub = IS_WIN32
1612b39c5158Smillert                        ? __PACKAGE__->can('_split_like_shell_win32')
1613b39c5158Smillert                        : Text::ParseWords->can('shellwords');
1614b39c5158Smillert
1615b39c5158Smillert    sub _ipc_run {
1616b39c5158Smillert        my $self            = shift;
1617b39c5158Smillert        my $cmd             = shift;
1618b39c5158Smillert        my $_out_handler    = shift;
1619b39c5158Smillert        my $_err_handler    = shift;
1620b39c5158Smillert
1621b39c5158Smillert        STDOUT->autoflush(1); STDERR->autoflush(1);
1622b39c5158Smillert
1623b39c5158Smillert        ### a command like:
1624b39c5158Smillert        # [
1625b39c5158Smillert        #     '/usr/bin/gzip',
1626b39c5158Smillert        #     '-cdf',
1627b39c5158Smillert        #     '/Users/kane/sources/p4/other/archive-extract/t/src/x.tgz',
1628b39c5158Smillert        #     '|',
1629b39c5158Smillert        #     '/usr/bin/tar',
1630b39c5158Smillert        #     '-tf -'
1631b39c5158Smillert        # ]
1632b39c5158Smillert        ### needs to become:
1633b39c5158Smillert        # [
1634b39c5158Smillert        #     ['/usr/bin/gzip', '-cdf',
1635b39c5158Smillert        #       '/Users/kane/sources/p4/other/archive-extract/t/src/x.tgz']
1636b39c5158Smillert        #     '|',
1637b39c5158Smillert        #     ['/usr/bin/tar', '-tf -']
1638b39c5158Smillert        # ]
1639b39c5158Smillert
1640b39c5158Smillert
1641b39c5158Smillert        my @command;
1642b39c5158Smillert        my $special_chars;
1643b39c5158Smillert
1644b39c5158Smillert        my $re = do { my $x = join '', SPECIAL_CHARS; qr/([$x])/ };
1645b39c5158Smillert        if( ref $cmd ) {
1646b39c5158Smillert            my $aref = [];
1647b39c5158Smillert            for my $item (@$cmd) {
1648b39c5158Smillert                if( $item =~ $re ) {
1649b39c5158Smillert                    push @command, $aref, $item;
1650b39c5158Smillert                    $aref = [];
1651b39c5158Smillert                    $special_chars .= $1;
1652b39c5158Smillert                } else {
1653b39c5158Smillert                    push @$aref, $item;
1654b39c5158Smillert                }
1655b39c5158Smillert            }
1656b39c5158Smillert            push @command, $aref;
1657b39c5158Smillert        } else {
1658b39c5158Smillert            @command = map { if( $_ =~ $re ) {
1659b39c5158Smillert                                $special_chars .= $1; $_;
1660b39c5158Smillert                             } else {
1661b39c5158Smillert#                                [ split /\s+/ ]
1662b39c5158Smillert                                 [ map { m/[ ]/ ? qq{'$_'} : $_ } $parse_sub->($_) ]
1663b39c5158Smillert                             }
1664b39c5158Smillert                        } split( /\s*$re\s*/, $cmd );
1665b39c5158Smillert        }
1666b39c5158Smillert
1667b39c5158Smillert        ### if there's a pipe in the command, *STDIN needs to
1668b39c5158Smillert        ### be inserted *BEFORE* the pipe, to work on win32
1669b39c5158Smillert        ### this also works on *nix, so we should do it when possible
1670b39c5158Smillert        ### this should *also* work on multiple pipes in the command
1671b39c5158Smillert        ### if there's no pipe in the command, append STDIN to the back
1672b39c5158Smillert        ### of the command instead.
1673b39c5158Smillert        ### XXX seems IPC::Run works it out for itself if you just
16746fb12b70Safresh1        ### don't pass STDIN at all.
1675b39c5158Smillert        #     if( $special_chars and $special_chars =~ /\|/ ) {
1676b39c5158Smillert        #         ### only add STDIN the first time..
1677b39c5158Smillert        #         my $i;
1678b39c5158Smillert        #         @command = map { ($_ eq '|' && not $i++)
1679b39c5158Smillert        #                             ? ( \*STDIN, $_ )
1680b39c5158Smillert        #                             : $_
1681b39c5158Smillert        #                         } @command;
1682b39c5158Smillert        #     } else {
1683b39c5158Smillert        #         push @command, \*STDIN;
1684b39c5158Smillert        #     }
1685b39c5158Smillert
1686b39c5158Smillert        # \*STDIN is already included in the @command, see a few lines up
1687b39c5158Smillert        my $ok = eval { IPC::Run::run(   @command,
1688b39c5158Smillert                                fileno(STDOUT).'>',
1689b39c5158Smillert                                $_out_handler,
1690b39c5158Smillert                                fileno(STDERR).'>',
1691b39c5158Smillert                                $_err_handler
1692b39c5158Smillert                            )
1693b39c5158Smillert                        };
1694b39c5158Smillert
1695b39c5158Smillert        ### all is well
1696b39c5158Smillert        if( $ok ) {
1697b39c5158Smillert            return $self->ok( $ok );
1698b39c5158Smillert
1699b39c5158Smillert        ### some error occurred
1700b39c5158Smillert        } else {
1701b39c5158Smillert            $self->ok( 0 );
1702b39c5158Smillert
1703b39c5158Smillert            ### if the eval fails due to an exception, deal with it
1704b39c5158Smillert            ### unless it's an alarm
1705b39c5158Smillert            if( $@ and not UNIVERSAL::isa( $@, ALARM_CLASS ) ) {
1706b39c5158Smillert                $self->error( $@ );
1707b39c5158Smillert
1708b39c5158Smillert            ### if it *is* an alarm, propagate
1709b39c5158Smillert            } elsif( $@ ) {
1710b39c5158Smillert                die $@;
1711b39c5158Smillert
1712b39c5158Smillert            ### some error in the sub command
1713b39c5158Smillert            } else {
1714b39c5158Smillert                $self->error( $self->_pp_child_error( $cmd, $? ) );
1715b39c5158Smillert            }
1716b39c5158Smillert
1717b39c5158Smillert            return;
1718b39c5158Smillert        }
1719b39c5158Smillert    }
1720b39c5158Smillert}
1721b39c5158Smillert
1722b39c5158Smillertsub _system_run {
1723b39c5158Smillert    my $self    = shift;
1724b39c5158Smillert    my $cmd     = shift;
1725b39c5158Smillert    my $verbose = shift || 0;
1726b39c5158Smillert
1727b39c5158Smillert    ### pipes have to come in a quoted string, and that clashes with
1728b39c5158Smillert    ### whitespace. This sub fixes up such commands so they run properly
1729b39c5158Smillert    $cmd = $self->__fix_cmd_whitespace_and_special_chars( $cmd );
1730b39c5158Smillert
1731b39c5158Smillert    my @fds_to_dup = $verbose ? () : qw[STDOUT STDERR];
1732b39c5158Smillert    $self->_fds( \@fds_to_dup );
1733b39c5158Smillert    $self->__dup_fds( @fds_to_dup );
1734b39c5158Smillert
1735b39c5158Smillert    ### system returns 'true' on failure -- the exit code of the cmd
1736b39c5158Smillert    $self->ok( 1 );
1737b39c5158Smillert    system( ref $cmd ? @$cmd : $cmd ) == 0 or do {
1738b39c5158Smillert        $self->error( $self->_pp_child_error( $cmd, $? ) );
1739b39c5158Smillert        $self->ok( 0 );
1740b39c5158Smillert    };
1741b39c5158Smillert
1742b39c5158Smillert    ### done in the parent call now
1743b39c5158Smillert    #$self->__reopen_fds( @fds_to_dup );
1744b39c5158Smillert
1745b39c5158Smillert    return unless $self->ok;
1746b39c5158Smillert    return $self->ok;
1747b39c5158Smillert}
1748b39c5158Smillert
1749b39c5158Smillert{   my %sc_lookup = map { $_ => $_ } SPECIAL_CHARS;
1750b39c5158Smillert
1751b39c5158Smillert
1752b39c5158Smillert    sub __fix_cmd_whitespace_and_special_chars {
1753b39c5158Smillert        my $self = shift;
1754b39c5158Smillert        my $cmd  = shift;
1755b39c5158Smillert
1756b39c5158Smillert        ### command has a special char in it
1757b39c5158Smillert        if( ref $cmd and grep { $sc_lookup{$_} } @$cmd ) {
1758b39c5158Smillert
1759b39c5158Smillert            ### since we have special chars, we have to quote white space
1760b39c5158Smillert            ### this *may* conflict with the parsing :(
1761b39c5158Smillert            my $fixed;
1762b39c5158Smillert            my @cmd = map { / / ? do { $fixed++; QUOTE.$_.QUOTE } : $_ } @$cmd;
1763b39c5158Smillert
1764b39c5158Smillert            $self->_debug( "# Quoted $fixed arguments containing whitespace" )
1765b39c5158Smillert                    if $DEBUG && $fixed;
1766b39c5158Smillert
1767b39c5158Smillert            ### stringify it, so the special char isn't escaped as argument
1768b39c5158Smillert            ### to the program
1769b39c5158Smillert            $cmd = join ' ', @cmd;
1770b39c5158Smillert        }
1771b39c5158Smillert
1772b39c5158Smillert        return $cmd;
1773b39c5158Smillert    }
1774b39c5158Smillert}
1775b39c5158Smillert
1776b39c5158Smillert### Command-line arguments (but not the command itself) must be quoted
1777b39c5158Smillert### to ensure case preservation. Borrowed from Module::Build with adaptations.
1778b39c5158Smillert### Patch for this supplied by Craig Berry, see RT #46288: [PATCH] Add argument
1779b39c5158Smillert### quoting for run() on VMS
1780b39c5158Smillertsub _quote_args_vms {
1781b39c5158Smillert  ### Returns a command string with proper quoting so that the subprocess
1782b39c5158Smillert  ### sees this same list of args, or if we get a single arg that is an
1783b39c5158Smillert  ### array reference, quote the elements of it (except for the first)
1784b39c5158Smillert  ### and return the reference.
1785b39c5158Smillert  my @args = @_;
1786b39c5158Smillert  my $got_arrayref = (scalar(@args) == 1
1787b39c5158Smillert                      && UNIVERSAL::isa($args[0], 'ARRAY'))
1788b39c5158Smillert                   ? 1
1789b39c5158Smillert                   : 0;
1790b39c5158Smillert
1791b39c5158Smillert  @args = split(/\s+/, $args[0]) unless $got_arrayref || scalar(@args) > 1;
1792b39c5158Smillert
1793b39c5158Smillert  my $cmd = $got_arrayref ? shift @{$args[0]} : shift @args;
1794b39c5158Smillert
1795b39c5158Smillert  ### Do not quote qualifiers that begin with '/' or previously quoted args.
1796b39c5158Smillert  map { if (/^[^\/\"]/) {
1797b39c5158Smillert          $_ =~ s/\"/""/g;     # escape C<"> by doubling
1798b39c5158Smillert          $_ = q(").$_.q(");
1799b39c5158Smillert        }
1800b39c5158Smillert  }
1801b39c5158Smillert    ($got_arrayref ? @{$args[0]}
1802b39c5158Smillert                   : @args
1803b39c5158Smillert    );
1804b39c5158Smillert
1805b39c5158Smillert  $got_arrayref ? unshift(@{$args[0]}, $cmd) : unshift(@args, $cmd);
1806b39c5158Smillert
1807b39c5158Smillert  return $got_arrayref ? $args[0]
1808b39c5158Smillert                       : join(' ', @args);
1809b39c5158Smillert}
1810b39c5158Smillert
1811b39c5158Smillert
1812b39c5158Smillert### XXX this is cribbed STRAIGHT from M::B 0.30 here:
1813b39c5158Smillert### http://search.cpan.org/src/KWILLIAMS/Module-Build-0.30/lib/Module/Build/Platform/Windows.pm:split_like_shell
1814b39c5158Smillert### XXX this *should* be integrated into text::parsewords
1815b39c5158Smillertsub _split_like_shell_win32 {
1816b39c5158Smillert  # As it turns out, Windows command-parsing is very different from
1817b39c5158Smillert  # Unix command-parsing.  Double-quotes mean different things,
1818b39c5158Smillert  # backslashes don't necessarily mean escapes, and so on.  So we
1819b39c5158Smillert  # can't use Text::ParseWords::shellwords() to break a command string
1820b39c5158Smillert  # into words.  The algorithm below was bashed out by Randy and Ken
1821b39c5158Smillert  # (mostly Randy), and there are a lot of regression tests, so we
1822b39c5158Smillert  # should feel free to adjust if desired.
1823b39c5158Smillert
1824b39c5158Smillert  local $_ = shift;
1825b39c5158Smillert
1826b39c5158Smillert  my @argv;
1827b39c5158Smillert  return @argv unless defined() && length();
1828b39c5158Smillert
1829b39c5158Smillert  my $arg = '';
1830b39c5158Smillert  my( $i, $quote_mode ) = ( 0, 0 );
1831b39c5158Smillert
1832b39c5158Smillert  while ( $i < length() ) {
1833b39c5158Smillert
1834b39c5158Smillert    my $ch      = substr( $_, $i  , 1 );
1835b39c5158Smillert    my $next_ch = substr( $_, $i+1, 1 );
1836b39c5158Smillert
1837b39c5158Smillert    if ( $ch eq '\\' && $next_ch eq '"' ) {
1838b39c5158Smillert      $arg .= '"';
1839b39c5158Smillert      $i++;
1840b39c5158Smillert    } elsif ( $ch eq '\\' && $next_ch eq '\\' ) {
1841b39c5158Smillert      $arg .= '\\';
1842b39c5158Smillert      $i++;
1843b39c5158Smillert    } elsif ( $ch eq '"' && $next_ch eq '"' && $quote_mode ) {
1844b39c5158Smillert      $quote_mode = !$quote_mode;
1845b39c5158Smillert      $arg .= '"';
1846b39c5158Smillert      $i++;
1847b39c5158Smillert    } elsif ( $ch eq '"' && $next_ch eq '"' && !$quote_mode &&
1848b39c5158Smillert          ( $i + 2 == length()  ||
1849b39c5158Smillert        substr( $_, $i + 2, 1 ) eq ' ' )
1850b39c5158Smillert        ) { # for cases like: a"" => [ 'a' ]
1851b39c5158Smillert      push( @argv, $arg );
1852b39c5158Smillert      $arg = '';
1853b39c5158Smillert      $i += 2;
1854b39c5158Smillert    } elsif ( $ch eq '"' ) {
1855b39c5158Smillert      $quote_mode = !$quote_mode;
1856b39c5158Smillert    } elsif ( $ch eq ' ' && !$quote_mode ) {
1857898184e3Ssthen      push( @argv, $arg ) if defined( $arg ) && length( $arg );
1858b39c5158Smillert      $arg = '';
1859b39c5158Smillert      ++$i while substr( $_, $i + 1, 1 ) eq ' ';
1860b39c5158Smillert    } else {
1861b39c5158Smillert      $arg .= $ch;
1862b39c5158Smillert    }
1863b39c5158Smillert
1864b39c5158Smillert    $i++;
1865b39c5158Smillert  }
1866b39c5158Smillert
1867b39c5158Smillert  push( @argv, $arg ) if defined( $arg ) && length( $arg );
1868b39c5158Smillert  return @argv;
1869b39c5158Smillert}
1870b39c5158Smillert
1871b39c5158Smillert
1872b39c5158Smillert
1873b39c5158Smillert{   use File::Spec;
1874b39c5158Smillert    use Symbol;
1875b39c5158Smillert
1876b39c5158Smillert    my %Map = (
1877b39c5158Smillert        STDOUT => [qw|>&|, \*STDOUT, Symbol::gensym() ],
1878b39c5158Smillert        STDERR => [qw|>&|, \*STDERR, Symbol::gensym() ],
1879b39c5158Smillert        STDIN  => [qw|<&|, \*STDIN,  Symbol::gensym() ],
1880b39c5158Smillert    );
1881b39c5158Smillert
1882b39c5158Smillert    ### dups FDs and stores them in a cache
1883b39c5158Smillert    sub __dup_fds {
1884b39c5158Smillert        my $self    = shift;
1885b39c5158Smillert        my @fds     = @_;
1886b39c5158Smillert
1887b39c5158Smillert        __PACKAGE__->_debug( "# Closing the following fds: @fds" ) if $DEBUG;
1888b39c5158Smillert
1889b39c5158Smillert        for my $name ( @fds ) {
1890b39c5158Smillert            my($redir, $fh, $glob) = @{$Map{$name}} or (
1891b39c5158Smillert                Carp::carp(loc("No such FD: '%1'", $name)), next );
1892b39c5158Smillert
1893b39c5158Smillert            ### MUST use the 2-arg version of open for dup'ing for
1894898184e3Ssthen            ### 5.6.x compatibility. 5.8.x can use 3-arg open
1895b39c5158Smillert            ### see perldoc5.6.2 -f open for details
1896b39c5158Smillert            open $glob, $redir . fileno($fh) or (
1897b39c5158Smillert                        Carp::carp(loc("Could not dup '$name': %1", $!)),
1898b39c5158Smillert                        return
1899b39c5158Smillert                    );
1900b39c5158Smillert
1901b39c5158Smillert            ### we should re-open this filehandle right now, not
1902b39c5158Smillert            ### just dup it
1903b39c5158Smillert            ### Use 2-arg version of open, as 5.5.x doesn't support
1904b39c5158Smillert            ### 3-arg version =/
1905b39c5158Smillert            if( $redir eq '>&' ) {
1906b39c5158Smillert                open( $fh, '>' . File::Spec->devnull ) or (
1907b39c5158Smillert                    Carp::carp(loc("Could not reopen '$name': %1", $!)),
1908b39c5158Smillert                    return
1909b39c5158Smillert                );
1910b39c5158Smillert            }
1911b39c5158Smillert        }
1912b39c5158Smillert
1913b39c5158Smillert        return 1;
1914b39c5158Smillert    }
1915b39c5158Smillert
1916b39c5158Smillert    ### reopens FDs from the cache
1917b39c5158Smillert    sub __reopen_fds {
1918b39c5158Smillert        my $self    = shift;
1919b39c5158Smillert        my @fds     = @_;
1920b39c5158Smillert
1921b39c5158Smillert        __PACKAGE__->_debug( "# Reopening the following fds: @fds" ) if $DEBUG;
1922b39c5158Smillert
1923b39c5158Smillert        for my $name ( @fds ) {
1924b39c5158Smillert            my($redir, $fh, $glob) = @{$Map{$name}} or (
1925b39c5158Smillert                Carp::carp(loc("No such FD: '%1'", $name)), next );
1926b39c5158Smillert
1927b39c5158Smillert            ### MUST use the 2-arg version of open for dup'ing for
1928898184e3Ssthen            ### 5.6.x compatibility. 5.8.x can use 3-arg open
1929b39c5158Smillert            ### see perldoc5.6.2 -f open for details
1930b39c5158Smillert            open( $fh, $redir . fileno($glob) ) or (
1931b39c5158Smillert                    Carp::carp(loc("Could not restore '$name': %1", $!)),
1932b39c5158Smillert                    return
1933b39c5158Smillert                );
1934b39c5158Smillert
1935b39c5158Smillert            ### close this FD, we're not using it anymore
1936b39c5158Smillert            close $glob;
1937b39c5158Smillert        }
1938b39c5158Smillert        return 1;
1939b39c5158Smillert
1940b39c5158Smillert    }
1941b39c5158Smillert}
1942b39c5158Smillert
1943b39c5158Smillertsub _debug {
1944b39c5158Smillert    my $self    = shift;
1945b39c5158Smillert    my $msg     = shift or return;
1946b39c5158Smillert    my $level   = shift || 0;
1947b39c5158Smillert
1948b39c5158Smillert    local $Carp::CarpLevel += $level;
1949b39c5158Smillert    Carp::carp($msg);
1950b39c5158Smillert
1951b39c5158Smillert    return 1;
1952b39c5158Smillert}
1953b39c5158Smillert
1954b39c5158Smillertsub _pp_child_error {
1955b39c5158Smillert    my $self    = shift;
1956b39c5158Smillert    my $cmd     = shift or return;
1957b39c5158Smillert    my $ce      = shift or return;
1958b39c5158Smillert    my $pp_cmd  = ref $cmd ? "@$cmd" : $cmd;
1959b39c5158Smillert
1960b39c5158Smillert
1961b39c5158Smillert    my $str;
1962b39c5158Smillert    if( $ce == -1 ) {
1963b39c5158Smillert        ### Include $! in the error message, so that the user can
1964b39c5158Smillert        ### see 'No such file or directory' versus 'Permission denied'
1965b39c5158Smillert        ### versus 'Cannot fork' or whatever the cause was.
1966b39c5158Smillert        $str = "Failed to execute '$pp_cmd': $!";
1967b39c5158Smillert
1968b39c5158Smillert    } elsif ( $ce & 127 ) {
1969b39c5158Smillert        ### some signal
19706fb12b70Safresh1        $str = loc( "'%1' died with signal %2, %3 coredump",
1971b39c5158Smillert               $pp_cmd, ($ce & 127), ($ce & 128) ? 'with' : 'without');
1972b39c5158Smillert
1973b39c5158Smillert    } else {
1974b39c5158Smillert        ### Otherwise, the command run but gave error status.
1975b39c5158Smillert        $str = "'$pp_cmd' exited with value " . ($ce >> 8);
1976b39c5158Smillert    }
1977b39c5158Smillert
1978b39c5158Smillert    $self->_debug( "# Child error '$ce' translated to: $str" ) if $DEBUG;
1979b39c5158Smillert
1980b39c5158Smillert    return $str;
1981b39c5158Smillert}
1982b39c5158Smillert
1983b39c5158Smillert1;
1984b39c5158Smillert
19859f11ffb7Safresh1__END__
19869f11ffb7Safresh1
1987b39c5158Smillert=head2 $q = QUOTE
1988b39c5158Smillert
1989b39c5158SmillertReturns the character used for quoting strings on this platform. This is
1990b39c5158Smillertusually a C<'> (single quote) on most systems, but some systems use different
1991b39c5158Smillertquotes. For example, C<Win32> uses C<"> (double quote).
1992b39c5158Smillert
1993b39c5158SmillertYou can use it as follows:
1994b39c5158Smillert
1995b39c5158Smillert  use IPC::Cmd qw[run QUOTE];
1996b39c5158Smillert  my $cmd = q[echo ] . QUOTE . q[foo bar] . QUOTE;
1997b39c5158Smillert
1998b39c5158SmillertThis makes sure that C<foo bar> is treated as a string, rather than two
1999898184e3Ssthenseparate arguments to the C<echo> function.
2000b39c5158Smillert
2001b39c5158Smillert=head1 HOW IT WORKS
2002b39c5158Smillert
2003b39c5158SmillertC<run> will try to execute your command using the following logic:
2004b39c5158Smillert
2005b39c5158Smillert=over 4
2006b39c5158Smillert
2007b39c5158Smillert=item *
2008b39c5158Smillert
2009b39c5158SmillertIf you have C<IPC::Run> installed, and the variable C<$IPC::Cmd::USE_IPC_RUN>
2010898184e3Ssthenis set to true (See the L<"Global Variables"> section) use that to execute
2011898184e3Ssthenthe command. You will have the full output available in buffers, interactive commands
2012898184e3Ssthenare sure to work  and you are guaranteed to have your verbosity
2013b39c5158Smillertsettings honored cleanly.
2014b39c5158Smillert
2015b39c5158Smillert=item *
2016b39c5158Smillert
2017b39c5158SmillertOtherwise, if the variable C<$IPC::Cmd::USE_IPC_OPEN3> is set to true
2018898184e3Ssthen(See the L<"Global Variables"> section), try to execute the command using
2019898184e3SsthenL<IPC::Open3>. Buffers will be available on all platforms,
2020b39c5158Smillertinteractive commands will still execute cleanly, and also your verbosity
2021b39c5158Smillertsettings will be adhered to nicely;
2022b39c5158Smillert
2023b39c5158Smillert=item *
2024b39c5158Smillert
2025898184e3SsthenOtherwise, if you have the C<verbose> argument set to true, we fall back
2026898184e3Ssthento a simple C<system()> call. We cannot capture any buffers, but
2027b39c5158Smillertinteractive commands will still work.
2028b39c5158Smillert
2029b39c5158Smillert=item *
2030b39c5158Smillert
2031b39c5158SmillertOtherwise we will try and temporarily redirect STDERR and STDOUT, do a
2032898184e3SsthenC<system()> call with your command and then re-open STDERR and STDOUT.
2033b39c5158SmillertThis is the method of last resort and will still allow you to execute
2034b39c5158Smillertyour commands cleanly. However, no buffers will be available.
2035b39c5158Smillert
2036b39c5158Smillert=back
2037b39c5158Smillert
2038b39c5158Smillert=head1 Global Variables
2039b39c5158Smillert
2040b39c5158SmillertThe behaviour of IPC::Cmd can be altered by changing the following
2041b39c5158Smillertglobal variables:
2042b39c5158Smillert
2043b39c5158Smillert=head2 $IPC::Cmd::VERBOSE
2044b39c5158Smillert
2045b39c5158SmillertThis controls whether IPC::Cmd will print any output from the
2046898184e3Ssthencommands to the screen or not. The default is 0.
2047b39c5158Smillert
2048b39c5158Smillert=head2 $IPC::Cmd::USE_IPC_RUN
2049b39c5158Smillert
2050b39c5158SmillertThis variable controls whether IPC::Cmd will try to use L<IPC::Run>
2051898184e3Ssthenwhen available and suitable.
2052b39c5158Smillert
2053b39c5158Smillert=head2 $IPC::Cmd::USE_IPC_OPEN3
2054b39c5158Smillert
2055b39c5158SmillertThis variable controls whether IPC::Cmd will try to use L<IPC::Open3>
2056b39c5158Smillertwhen available and suitable. Defaults to true.
2057b39c5158Smillert
2058b39c5158Smillert=head2 $IPC::Cmd::WARN
2059b39c5158Smillert
2060898184e3SsthenThis variable controls whether run-time warnings should be issued, like
2061b39c5158Smillertthe failure to load an C<IPC::*> module you explicitly requested.
2062b39c5158Smillert
2063b39c5158SmillertDefaults to true. Turn this off at your own risk.
2064b39c5158Smillert
2065898184e3Ssthen=head2 $IPC::Cmd::INSTANCES
2066898184e3Ssthen
2067898184e3SsthenThis variable controls whether C<can_run> will return all instances of
2068898184e3Ssthenthe binary it finds in the C<PATH> when called in a list context.
2069898184e3Ssthen
2070898184e3SsthenDefaults to false, set to true to enable the described behaviour.
2071898184e3Ssthen
2072898184e3Ssthen=head2 $IPC::Cmd::ALLOW_NULL_ARGS
2073898184e3Ssthen
2074898184e3SsthenThis variable controls whether C<run> will remove any empty/null arguments
2075898184e3Ssthenit finds in command arguments.
2076898184e3Ssthen
2077898184e3SsthenDefaults to false, so it will remove null arguments. Set to true to allow
2078898184e3Ssthenthem.
2079898184e3Ssthen
2080b39c5158Smillert=head1 Caveats
2081b39c5158Smillert
2082b39c5158Smillert=over 4
2083b39c5158Smillert
2084b39c5158Smillert=item Whitespace and IPC::Open3 / system()
2085b39c5158Smillert
2086b39c5158SmillertWhen using C<IPC::Open3> or C<system>, if you provide a string as the
2087b39c5158SmillertC<command> argument, it is assumed to be appropriately escaped. You can
2088b39c5158Smillertuse the C<QUOTE> constant to use as a portable quote character (see above).
2089898184e3SsthenHowever, if you provide an array reference, special rules apply:
2090b39c5158Smillert
2091898184e3SsthenIf your command contains B<special characters> (< > | &), it will
2092b39c5158Smillertbe internally stringified before executing the command, to avoid that these
2093b39c5158Smillertspecial characters are escaped and passed as arguments instead of retaining
2094b39c5158Smillerttheir special meaning.
2095b39c5158Smillert
2096b39c5158SmillertHowever, if the command contained arguments that contained whitespace,
209791f110e0Safresh1stringifying the command would lose the significance of the whitespace.
2098898184e3SsthenTherefore, C<IPC::Cmd> will quote any arguments containing whitespace in your
2099b39c5158Smillertcommand if the command is passed as an arrayref and contains special characters.
2100b39c5158Smillert
2101b39c5158Smillert=item Whitespace and IPC::Run
2102b39c5158Smillert
2103b39c5158SmillertWhen using C<IPC::Run>, if you provide a string as the C<command> argument,
2104b39c5158Smillertthe string will be split on whitespace to determine the individual elements
2105b39c5158Smillertof your command. Although this will usually just Do What You Mean, it may
2106b39c5158Smillertbreak if you have files or commands with whitespace in them.
2107b39c5158Smillert
2108b39c5158SmillertIf you do not wish this to happen, you should provide an array
2109b39c5158Smillertreference, where all parts of your command are already separated out.
2110898184e3SsthenNote however, if there are extra or spurious whitespaces in these parts,
2111b39c5158Smillertthe parser or underlying code may not interpret it correctly, and
2112b39c5158Smillertcause an error.
2113b39c5158Smillert
2114b39c5158SmillertExample:
2115b39c5158SmillertThe following code
2116b39c5158Smillert
2117b39c5158Smillert    gzip -cdf foo.tar.gz | tar -xf -
2118b39c5158Smillert
2119b39c5158Smillertshould either be passed as
2120b39c5158Smillert
2121b39c5158Smillert    "gzip -cdf foo.tar.gz | tar -xf -"
2122b39c5158Smillert
2123b39c5158Smillertor as
2124b39c5158Smillert
2125b39c5158Smillert    ['gzip', '-cdf', 'foo.tar.gz', '|', 'tar', '-xf', '-']
2126b39c5158Smillert
2127b39c5158SmillertBut take care not to pass it as, for example
2128b39c5158Smillert
2129b39c5158Smillert    ['gzip -cdf foo.tar.gz', '|', 'tar -xf -']
2130b39c5158Smillert
2131b39c5158SmillertSince this will lead to issues as described above.
2132b39c5158Smillert
2133b39c5158Smillert
2134b39c5158Smillert=item IO Redirect
2135b39c5158Smillert
2136b39c5158SmillertCurrently it is too complicated to parse your command for IO
2137898184e3Ssthenredirections. For capturing STDOUT or STDERR there is a work around
2138b39c5158Smillerthowever, since you can just inspect your buffers for the contents.
2139b39c5158Smillert
2140b39c5158Smillert=item Interleaving STDOUT/STDERR
2141b39c5158Smillert
2142b39c5158SmillertNeither IPC::Run nor IPC::Open3 can interleave STDOUT and STDERR. For short
2143898184e3Ssthenbursts of output from a program, e.g. this sample,
2144b39c5158Smillert
2145b39c5158Smillert    for ( 1..4 ) {
2146b39c5158Smillert        $_ % 2 ? print STDOUT $_ : print STDERR $_;
2147b39c5158Smillert    }
2148b39c5158Smillert
2149b39c5158SmillertIPC::[Run|Open3] will first read all of STDOUT, then all of STDERR, meaning
2150898184e3Ssthenthe output looks like '13' on STDOUT and '24' on STDERR, instead of
2151b39c5158Smillert
2152898184e3Ssthen    1
2153898184e3Ssthen    2
2154898184e3Ssthen    3
2155898184e3Ssthen    4
2156b39c5158Smillert
2157b39c5158SmillertThis has been recorded in L<rt.cpan.org> as bug #37532: Unable to interleave
2158898184e3SsthenSTDOUT and STDERR.
2159b39c5158Smillert
2160b39c5158Smillert=back
2161b39c5158Smillert
2162b39c5158Smillert=head1 See Also
2163b39c5158Smillert
2164898184e3SsthenL<IPC::Run>, L<IPC::Open3>
2165b39c5158Smillert
2166b39c5158Smillert=head1 ACKNOWLEDGEMENTS
2167b39c5158Smillert
2168b39c5158SmillertThanks to James Mastros and Martijn van der Streek for their
2169898184e3Ssthenhelp in getting L<IPC::Open3> to behave nicely.
2170b39c5158Smillert
2171b39c5158SmillertThanks to Petya Kohts for the C<run_forked> code.
2172b39c5158Smillert
2173b39c5158Smillert=head1 BUG REPORTS
2174b39c5158Smillert
2175b39c5158SmillertPlease report bugs or other issues to E<lt>bug-ipc-cmd@rt.cpan.orgE<gt>.
2176b39c5158Smillert
2177b39c5158Smillert=head1 AUTHOR
2178b39c5158Smillert
2179898184e3SsthenOriginal author: Jos Boumans E<lt>kane@cpan.orgE<gt>.
2180898184e3SsthenCurrent maintainer: Chris Williams E<lt>bingos@cpan.orgE<gt>.
2181b39c5158Smillert
2182b39c5158Smillert=head1 COPYRIGHT
2183b39c5158Smillert
2184b39c5158SmillertThis library is free software; you may redistribute and/or modify it
2185b39c5158Smillertunder the same terms as Perl itself.
2186b39c5158Smillert
2187b39c5158Smillert=cut
2188