Skip to content

Commit cccbbce

Browse files
philipboulainsmoothwalltonycoz
authored andcommitted
Reap child in case where exception has been thrown
If open3 throws due to an issue such as an exec failure, the caller cannot know the child PID to wait for. Therefore it is our responsibility to reap it. Also update POD, since on some platforms exec failures now ARE raised as exceptions (since perlbug #72016).
1 parent 748cc03 commit cccbbce

File tree

2 files changed

+9
-2
lines changed

2 files changed

+9
-2
lines changed

ext/IPC-Open3/lib/IPC/Open3.pm

+3-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ as file descriptors.
5757
open3() returns the process ID of the child process. It doesn't return on
5858
failure: it just raises an exception matching C</^open3:/>. However,
5959
C<exec> failures in the child (such as no such file or permission denied),
60-
are just reported to CHLD_ERR, as it is not possible to trap them.
60+
are just reported to CHLD_ERR under Windows and OS/2, as it is not possible
61+
to trap them.
6162
6263
If the child process dies for any reason, the next write to CHLD_IN is
6364
likely to generate a SIGPIPE in the parent, which is fatal by default.
@@ -297,6 +298,7 @@ sub _open3 {
297298
if ($bytes_read) {
298299
(my $bang, $to_read) = unpack('II', $buf);
299300
read($stat_r, my $err = '', $to_read);
301+
waitpid $kidpid, 0; # Reap child which should have exited
300302
if ($err) {
301303
utf8::decode $err if $] >= 5.008;
302304
} else {

ext/IPC-Open3/t/IPC-Open3.t

+6-1
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ BEGIN {
1414
}
1515

1616
use strict;
17-
use Test::More tests => 37;
17+
use Test::More tests => 38;
1818

1919
use IO::Handle;
2020
use IPC::Open3;
21+
use POSIX ":sys_wait_h";
2122

2223
my $perl = $^X;
2324

@@ -154,6 +155,10 @@ $TB->current_test($test);
154155
isnt($@, '',
155156
'open3 of a non existent program fails with an exception in the parent')
156157
or do {waitpid $pid, 0};
158+
SKIP: {
159+
skip 'open3 returned, our responsibility to reap', 1 unless $@;
160+
is(waitpid(-1, WNOHANG), -1, 'failed exec child is reaped');
161+
}
157162
}
158163

159164
$pid = eval { open3 'WRITE', '', 'ERROR', '/non/existent/program'; };

0 commit comments

Comments
 (0)