Blame SOURCES/perl-5.31.0-perl-122112-a-simpler-fix-for-pclose-aborted-by-a-si.patch

7586d2
From 35608a1658fe75c79ca53d96aea6cf7cb2a98615 Mon Sep 17 00:00:00 2001
7586d2
From: Tony Cook <tony@develop-help.com>
7586d2
Date: Thu, 9 May 2019 09:52:30 +1000
7586d2
Subject: [PATCH] (perl #122112) a simpler fix for pclose() aborted by a signal
7586d2
MIME-Version: 1.0
7586d2
Content-Type: text/plain; charset=UTF-8
7586d2
Content-Transfer-Encoding: 8bit
7586d2
7586d2
This change results in a zombie child process for the lifetime of
7586d2
the process, but I think that's the responsibility of the signal
7586d2
handler that aborted pclose().
7586d2
7586d2
We could add some magic to retry (and retry and retry) waiting on
7586d2
child process as we rewind (since there's no other way to remove
7586d2
the zombie), but the program has chosen implicitly to abort the
7586d2
wait() done by pclose() and it's best to honor that.
7586d2
7586d2
If we do choose to retry the wait() we might be blocking an attempt
7586d2
by the process to terminate, whether by exit() or die().
7586d2
7586d2
If a program does need more flexible handling there's always
7586d2
pipe()/fork()/exec() and/or the various event-driven frameworks on
7586d2
CPAN.
7586d2
7586d2
Signed-off-by: Petr Písař <ppisar@redhat.com>
7586d2
---
7586d2
 doio.c      | 12 +++++++++++-
7586d2
 t/io/pipe.t |  2 --
7586d2
 2 files changed, 11 insertions(+), 3 deletions(-)
7586d2
7586d2
diff --git a/doio.c b/doio.c
7586d2
index 0cc4e55404..05a06968dc 100644
7586d2
--- a/doio.c
7586d2
+++ b/doio.c
7586d2
@@ -1779,7 +1779,17 @@ Perl_io_close(pTHX_ IO *io, GV *gv, bool not_implicit, bool warn_on_fail)
7586d2
 
7586d2
     if (IoIFP(io)) {
7586d2
 	if (IoTYPE(io) == IoTYPE_PIPE) {
7586d2
-	    const int status = PerlProc_pclose(IoIFP(io));
7586d2
+            PerlIO *fh = IoIFP(io);
7586d2
+            int status;
7586d2
+
7586d2
+            /* my_pclose() can propagate signals which might bypass any code
7586d2
+               after the call here if the signal handler throws an exception.
7586d2
+               This would leave the handle in the IO object and try to close it again
7586d2
+               when the SV is destroyed on unwind or global destruction.
7586d2
+               So NULL it early.
7586d2
+            */
7586d2
+            IoOFP(io) = IoIFP(io) = NULL;
7586d2
+	    status = PerlProc_pclose(fh);
7586d2
 	    if (not_implicit) {
7586d2
 		STATUS_NATIVE_CHILD_SET(status);
7586d2
 		retval = (STATUS_UNIX == 0);
7586d2
diff --git a/t/io/pipe.t b/t/io/pipe.t
7586d2
index 1d01db6af6..fc3071300d 100644
7586d2
--- a/t/io/pipe.t
7586d2
+++ b/t/io/pipe.t
7586d2
@@ -255,9 +255,7 @@ close \$fh;
7586d2
 PROG
7586d2
     print $prog;
7586d2
     my $out = fresh_perl($prog, {});
7586d2
-    $::TODO = "not fixed yet";
7586d2
     cmp_ok($out, '!~', qr/refcnt/, "no exception from PerlIO");
7586d2
-    undef $::TODO;
7586d2
     # checks that that program did something rather than failing to
7586d2
     # compile
7586d2
     cmp_ok($out, '=~', qr/Died at/, "but we did get the exception from die");
7586d2
-- 
7586d2
2.20.1
7586d2