70 lines
2.4 KiB
Diff
70 lines
2.4 KiB
Diff
|
From cccbbce940ea952c4c236049e98d21a011475cb1 Mon Sep 17 00:00:00 2001
|
||
|
From: Philip Boulain <philip.boulain@smoothwall.net>
|
||
|
Date: Mon, 3 Sep 2012 15:16:26 +0100
|
||
|
Subject: [PATCH] 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).
|
||
|
---
|
||
|
ext/IPC-Open3/lib/IPC/Open3.pm | 4 +++-
|
||
|
ext/IPC-Open3/t/IPC-Open3.t | 7 ++++++-
|
||
|
2 files changed, 9 insertions(+), 2 deletions(-)
|
||
|
|
||
|
diff --git a/ext/IPC-Open3/lib/IPC/Open3.pm b/ext/IPC-Open3/lib/IPC/Open3.pm
|
||
|
index 989c2f6..f50146f 100644
|
||
|
--- a/ext/IPC-Open3/lib/IPC/Open3.pm
|
||
|
+++ b/ext/IPC-Open3/lib/IPC/Open3.pm
|
||
|
@@ -57,7 +57,8 @@ as file descriptors.
|
||
|
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.
|
||
|
@@ -297,6 +298,7 @@ sub _open3 {
|
||
|
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 {
|
||
|
diff --git a/ext/IPC-Open3/t/IPC-Open3.t b/ext/IPC-Open3/t/IPC-Open3.t
|
||
|
index 7b85b82..6ab519d 100644
|
||
|
--- a/ext/IPC-Open3/t/IPC-Open3.t
|
||
|
+++ b/ext/IPC-Open3/t/IPC-Open3.t
|
||
|
@@ -14,10 +14,11 @@ BEGIN {
|
||
|
}
|
||
|
|
||
|
use strict;
|
||
|
-use Test::More tests => 37;
|
||
|
+use Test::More tests => 38;
|
||
|
|
||
|
use IO::Handle;
|
||
|
use IPC::Open3;
|
||
|
+use POSIX ":sys_wait_h";
|
||
|
|
||
|
my $perl = $^X;
|
||
|
|
||
|
@@ -154,6 +155,10 @@ $TB->current_test($test);
|
||
|
isnt($@, '',
|
||
|
'open3 of a non existent program fails with an exception in the parent')
|
||
|
or do {waitpid $pid, 0};
|
||
|
+ SKIP: {
|
||
|
+ skip 'open3 returned, our responsibility to reap', 1 unless $@;
|
||
|
+ is(waitpid(-1, WNOHANG), -1, 'failed exec child is reaped');
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
$pid = eval { open3 'WRITE', '', 'ERROR', '/non/existent/program'; };
|
||
|
--
|
||
|
1.8.3.1
|
||
|
|