3f1b01
From 89341f87f9fc65c4d7133e497bb04586e86b8052 Mon Sep 17 00:00:00 2001
3f1b01
From: Tony Cook <tony@develop-help.com>
3f1b01
Date: Tue, 12 May 2020 10:29:17 +1000
3f1b01
Subject: [PATCH 1/2] make $fh->error report errors from both input and output
3f1b01
MIME-Version: 1.0
3f1b01
Content-Type: text/plain; charset=UTF-8
3f1b01
Content-Transfer-Encoding: 8bit
3f1b01
3f1b01
For character devices and sockets perl uses separate PerlIO objects
3f1b01
for input and output so they can be buffered separately.
3f1b01
3f1b01
The IO::Handle::error() method only checked the input stream, so
3f1b01
if a write error occurs error() would still returned false.
3f1b01
3f1b01
Change this so both the input and output streams are checked.
3f1b01
3f1b01
fixes #6799
3f1b01
3f1b01
Signed-off-by: Petr Písař <ppisar@redhat.com>
3f1b01
---
3f1b01
 dist/IO/IO.xs     | 12 ++++++++----
3f1b01
 dist/IO/t/io_xs.t | 19 ++++++++++++++++++-
3f1b01
 2 files changed, 26 insertions(+), 5 deletions(-)
3f1b01
3f1b01
diff --git a/dist/IO/IO.xs b/dist/IO/IO.xs
3f1b01
index 68b7352c38..99d523d2c1 100644
3f1b01
--- a/dist/IO/IO.xs
3f1b01
+++ b/dist/IO/IO.xs
3f1b01
@@ -389,13 +389,17 @@ ungetc(handle, c)
3f1b01
 
3f1b01
 int
3f1b01
 ferror(handle)
3f1b01
-	InputStream	handle
3f1b01
+	SV *	handle
3f1b01
+    PREINIT:
3f1b01
+        IO *io = sv_2io(handle);
3f1b01
+        InputStream in = IoIFP(io);
3f1b01
+        OutputStream out = IoOFP(io);
3f1b01
     CODE:
3f1b01
-	if (handle)
3f1b01
+	if (in)
3f1b01
 #ifdef PerlIO
3f1b01
-	    RETVAL = PerlIO_error(handle);
3f1b01
+	    RETVAL = PerlIO_error(in) || (in != out && PerlIO_error(out));
3f1b01
 #else
3f1b01
-	    RETVAL = ferror(handle);
3f1b01
+	    RETVAL = ferror(in) || (in != out && ferror(out));
3f1b01
 #endif
3f1b01
 	else {
3f1b01
 	    RETVAL = -1;
3f1b01
diff --git a/dist/IO/t/io_xs.t b/dist/IO/t/io_xs.t
3f1b01
index 1e3c49a4a7..f890e92558 100644
3f1b01
--- a/dist/IO/t/io_xs.t
3f1b01
+++ b/dist/IO/t/io_xs.t
3f1b01
@@ -11,7 +11,7 @@ BEGIN {
3f1b01
     }
3f1b01
 }
3f1b01
 
3f1b01
-use Test::More tests => 5;
3f1b01
+use Test::More tests => 7;
3f1b01
 use IO::File;
3f1b01
 use IO::Seekable;
3f1b01
 
3f1b01
@@ -50,3 +50,20 @@ SKIP:
3f1b01
     ok($fh->sync, "sync to a read only handle")
3f1b01
 	or diag "sync(): ", $!;
3f1b01
 }
3f1b01
+
3f1b01
+
3f1b01
+SKIP: {
3f1b01
+    # gh 6799
3f1b01
+    #
3f1b01
+    # This isn't really a Linux/BSD specific test, but /dev/full is (I
3f1b01
+    # hope) reasonably well defined on these.  Patches welcome if your platform
3f1b01
+    # also supports it (or something like it)
3f1b01
+    skip "no /dev/full or not a /dev/full platform", 2
3f1b01
+      unless $^O =~ /^(linux|netbsd|freebsd)$/ && -c "/dev/full";
3f1b01
+    open my $fh, ">", "/dev/full"
3f1b01
+      or skip "Could not open /dev/full: $!", 2;
3f1b01
+    $fh->print("a" x 1024);
3f1b01
+    ok(!$fh->flush, "should fail to flush");
3f1b01
+    ok($fh->error, "stream should be in error");
3f1b01
+    close $fh; # silently ignore the error
3f1b01
+}
3f1b01
-- 
3f1b01
2.25.4
3f1b01