Blob Blame History Raw
From e57cc2468d765872b20810478b94ead3906f1912 Mon Sep 17 00:00:00 2001
From: Stepan Kasal <skasal@redhat.com>
Date: Wed, 3 Jun 2009 12:03:55 +0200
Subject: [PATCH] fix RT 39060, errno incorrectly set in perlio

---
 MANIFEST     |    1 +
 perlio.c     |   12 +++++++-----
 t/io/errno.t |   26 ++++++++++++++++++++++++++
 3 files changed, 34 insertions(+), 5 deletions(-)
 create mode 100644 t/io/errno.t

diff --git a/MANIFEST b/MANIFEST
index b7c9341..be3be43 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -3899,6 +3899,7 @@ t/io/binmode.t			See if binmode() works
 t/io/crlf.t			See if :crlf works
 t/io/crlf_through.t		See if pipe passes data intact with :crlf
 t/io/dup.t			See if >& works right
+t/io/errno.t			See if $! is correctly set
 t/io/fflush.t			See if auto-flush on fork/exec/system/qx works
 t/io/fs.t			See if directory manipulations work
 t/io/inplace.t			See if inplace editing works
diff --git a/perlio.c b/perlio.c
index 0a086a8..e92a32a 100644
--- a/perlio.c
+++ b/perlio.c
@@ -1784,12 +1784,14 @@ PerlIO_has_base(PerlIO *f)
 int
 PerlIO_fast_gets(PerlIO *f)
 {
-    if (PerlIOValid(f) && (PerlIOBase(f)->flags & PERLIO_F_FASTGETS)) {
-	 const PerlIO_funcs * const tab = PerlIOBase(f)->tab;
+    if (PerlIOValid(f)) {
+	 if (PerlIOBase(f)->flags & PERLIO_F_FASTGETS) {
+	     const PerlIO_funcs * const tab = PerlIOBase(f)->tab;
 
-	 if (tab)
-	      return (tab->Set_ptrcnt != NULL);
-	 SETERRNO(EINVAL, LIB_INVARG);
+	     if (tab)
+		  return (tab->Set_ptrcnt != NULL);
+	     SETERRNO(EINVAL, LIB_INVARG);
+	 }
     }
     else
 	 SETERRNO(EBADF, SS_IVCHAN);
diff --git a/t/io/errno.t b/t/io/errno.t
new file mode 100644
index 0000000..b55e3db
--- /dev/null
+++ b/t/io/errno.t
@@ -0,0 +1,26 @@
+#!./perl
+# vim: ts=4 sts=4 sw=4:
+
+# $! may not be set if EOF was reached without any error.
+# http://rt.perl.org/rt3/Ticket/Display.html?id=39060
+
+use strict;
+require './test.pl';
+
+plan( tests => 16 );
+
+my $test_prog = 'while(<>){print}; print $!';
+
+for my $perlio ('perlio', 'stdio') {
+    $ENV{PERLIO} = $perlio;
+    for my $test_in ("test\n", "test") {
+		my $test_in_esc = $test_in;
+		$test_in_esc =~ s/\n/\\n/g;
+		for my $rs_code ('', '$/=undef', '$/=\2', '$/=\1024') {
+			is( runperl( prog => "$rs_code; $test_prog",
+						 stdin => $test_in, stderr => 1),
+				$test_in,
+				"Wrong errno, PERLIO=$ENV{PERLIO} stdin='$test_in_esc'");
+		}
+	}
+}
-- 
1.6.2