use Carp;
use Symbol qw(gensym qualify);
-$VERSION = '1.11';
+$VERSION = '1.16';
@ISA = qw(Exporter);
@EXPORT = qw(open3);
open3() returns the process ID of the child process. It doesn't return on
failure: it just raises an exception matching C</^open3:/>. However,
C<exec> failures in the child (such as no such file or permission denied),
-are just reported to CHLD_ERR, as it is not possible to trap them.
+are just reported to CHLD_ERR under Windows and OS/2, as it is not possible
+to trap them.
If the child process dies for any reason, the next write to CHLD_IN is
likely to generate a SIGPIPE in the parent, which is fatal by default.
=item L<IPC::Open2>
-Like Open3 but without STDERR catpure.
+Like Open3 but without STDERR capture.
=item L<IPC::Run>
}
sub xclose {
- $_[0] =~ /\A=?(\d+)\z/ ? eval { require POSIX; POSIX::close($1); } : close $_[0]
+ $_[0] =~ /\A=?(\d+)\z/
+ ? do { my $fh; open($fh, $_[1] . '&=' . $1) and close($fh); }
+ : close $_[0]
or croak "$Me: close($_[0]) failed: $!";
}
# it's too ugly to use @_ throughout to make perl do it for us
# tchrist 5-Mar-00
+ # Historically, open3(undef...) has silently worked, so keep
+ # it working.
+ splice @_, 0, 1, undef if \$_[0] == \undef;
+ splice @_, 1, 1, undef if \$_[1] == \undef;
unless (eval {
$_[0] = gensym unless defined $_[0] && length $_[0];
$_[1] = gensym unless defined $_[1] && length $_[1];
xopen $_->{handle}, $_->{mode} . '&', $_->{parent}
if fileno $_->{handle} != xfileno($_->{parent});
} else {
- xclose $_->{parent};
+ xclose $_->{parent}, $_->{mode};
xopen $_->{handle}, $_->{mode} . '&=',
fileno $_->{open_as};
}
if ($bytes_read) {
(my $bang, $to_read) = unpack('II', $buf);
read($stat_r, my $err = '', $to_read);
+ waitpid $kidpid, 0; # Reap child which should have exited
if ($err) {
utf8::decode $err if $] >= 5.008;
} else {
foreach (@handles) {
next if $_->{dup} or $_->{dup_of_out};
- xclose $_->{open_as};
+ xclose $_->{open_as}, $_->{mode};
}
# If the write handle is a dup give it away entirely, close my copy
# of it.
- xclose $handles[0]{parent} if $handles[0]{dup};
+ xclose $handles[0]{parent}, $handles[0]{mode} if $handles[0]{dup};
select((select($handles[0]{parent}), $| = 1)[0]); # unbuffer pipe
$kidpid;