Blame SOURCES/0001-test-and-fix-for-RT-52317-Calling-run3-garbles-STDIN.patch

ed21a8
From 8ebe48760cfdc78fbf4fc46413dde9470121b99e Mon Sep 17 00:00:00 2001
ed21a8
From: Roderich Schupp <roderich.schupp@gmail.com>
ed21a8
Date: Sun, 29 Sep 2013 18:12:03 +0200
ed21a8
Subject: [PATCH 5/5] test and fix for RT #52317: Calling run3 garbles STDIN
ed21a8
ed21a8
---
ed21a8
 lib/IPC/Run3.pm    | 26 ++++++-------------------
ed21a8
 t/preserve_stdin.t | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
ed21a8
 2 files changed, 63 insertions(+), 20 deletions(-)
ed21a8
 create mode 100644 t/preserve_stdin.t
ed21a8
ed21a8
diff --git a/lib/IPC/Run3.pm b/lib/IPC/Run3.pm
ed21a8
index 12c9d8a..777e290 100644
ed21a8
--- a/lib/IPC/Run3.pm
ed21a8
+++ b/lib/IPC/Run3.pm
ed21a8
@@ -363,14 +363,12 @@ sub run3 {
ed21a8
             $options if defined $stderr;
ed21a8
 
ed21a8
     # this should make perl close these on exceptions
ed21a8
-#    local *STDIN_SAVE;
ed21a8
+    local *STDIN_SAVE;
ed21a8
     local *STDOUT_SAVE;
ed21a8
     local *STDERR_SAVE;
ed21a8
 
ed21a8
-    my $saved_fd0 = dup( 0 ) if defined $in_fh;
ed21a8
-
ed21a8
-#    open STDIN_SAVE,  "<&STDIN"#  or croak "run3(): $! saving STDIN"
ed21a8
-#        if defined $in_fh;
ed21a8
+    open STDIN_SAVE,  "<&STDIN"  or croak "run3(): $! saving STDIN"
ed21a8
+        if defined $in_fh;
ed21a8
     open STDOUT_SAVE, ">&STDOUT" or croak "run3(): $! saving STDOUT"
ed21a8
         if defined $out_fh;
ed21a8
     open STDERR_SAVE, ">&STDERR" or croak "run3(): $! saving STDERR"
ed21a8
@@ -378,17 +376,10 @@ sub run3 {
ed21a8
 
ed21a8
     my $errno;
ed21a8
     my $ok = eval {
ed21a8
-        # The open() call here seems to not force fd 0 in some cases;
ed21a8
-        # I ran in to trouble when using this in VCP, not sure why.
ed21a8
-        # the dup2() seems to work.
ed21a8
-        dup2( fileno $in_fh, 0 )
ed21a8
-#        open STDIN,  "<&=" . fileno $in_fh
ed21a8
+        open STDIN,  "<&=" . fileno $in_fh
ed21a8
             or croak "run3(): $! redirecting STDIN"
ed21a8
             if defined $in_fh;
ed21a8
 
ed21a8
-#        close $in_fh or croak "$! closing STDIN temp file"
ed21a8
-#            if ref $stdin;
ed21a8
-
ed21a8
         open STDOUT, ">&" . fileno $out_fh
ed21a8
             or croak "run3(): $! redirecting STDOUT"
ed21a8
             if defined $out_fh;
ed21a8
@@ -428,13 +419,8 @@ sub run3 {
ed21a8
 
ed21a8
     my @errs;
ed21a8
 
ed21a8
-    if ( defined $saved_fd0 ) {
ed21a8
-        dup2( $saved_fd0, 0 );
ed21a8
-        POSIX::close( $saved_fd0 );
ed21a8
-    }
ed21a8
-
ed21a8
-#    open STDIN,  "<&STDIN_SAVE"#  or push @errs, "run3(): $! restoring STDIN"
ed21a8
-#        if defined $in_fh;
ed21a8
+    open STDIN,  "<&STDIN_SAVE"  or push @errs, "run3(): $! restoring STDIN"
ed21a8
+        if defined $in_fh;
ed21a8
     open STDOUT, ">&STDOUT_SAVE" or push @errs, "run3(): $! restoring STDOUT"
ed21a8
         if defined $out_fh;
ed21a8
     open STDERR, ">&STDERR_SAVE" or push @errs, "run3(): $! restoring STDERR"
ed21a8
diff --git a/t/preserve_stdin.t b/t/preserve_stdin.t
ed21a8
new file mode 100644
ed21a8
index 0000000..8e090ee
ed21a8
--- /dev/null
ed21a8
+++ b/t/preserve_stdin.t
ed21a8
@@ -0,0 +1,57 @@
ed21a8
+#!perl -w
ed21a8
+
ed21a8
+## test whether reading from STDIN is preserved when
ed21a8
+## run3 is called in between reads
ed21a8
+
ed21a8
+use Test::More;
ed21a8
+use IPC::Run3;
ed21a8
+use File::Temp qw(tempfile);
ed21a8
+use strict;
ed21a8
+
ed21a8
+# call run3 at different lines (problems might manifest itself 
ed21a8
+# on different lines, probably due to different buffering of input)
ed21a8
+my @check_at = (5, 10, 50, 100, 200, 500);
ed21a8
+plan tests => @check_at * 3;
ed21a8
+
ed21a8
+# create a test file for input containing 1000 lines
ed21a8
+my $nlines = 1000;
ed21a8
+my @exp_lines;
ed21a8
+my ($fh, $file) = tempfile(UNLINK => 1);
ed21a8
+for (my $i = 1; $i <= $nlines; $i++)
ed21a8
+{
ed21a8
+    my $line = "this is line $i";
ed21a8
+    push @exp_lines, $line;
ed21a8
+    print $fh $line, "\n";
ed21a8
+}
ed21a8
+close $fh;
ed21a8
+
ed21a8
+
ed21a8
+my ( $in, $out, $err );
ed21a8
+
ed21a8
+foreach my $n (@check_at)
ed21a8
+{
ed21a8
+    my $nread = 0;
ed21a8
+    my $unexpected;
ed21a8
+    open STDIN, "<", $file or die "can't open file $file: $!";
ed21a8
+    while (<STDIN>)
ed21a8
+    {
ed21a8
+	chomp;
ed21a8
+	$unexpected = qq[line $nread: expected "$exp_lines[$nread]", got "$_"\n]
ed21a8
+	    unless $exp_lines[$nread] eq $_ || $unexpected;
ed21a8
+	$nread++;
ed21a8
+
ed21a8
+	if ($nread == $n)
ed21a8
+	{
ed21a8
+            $in = "checking at line $n";
ed21a8
+	    run3 [ $^X, '-e', 'print uc $_ while <>' ], \$in, \$out, \$err;
ed21a8
+	    die "command failed" unless $? == 0;
ed21a8
+            is($out, uc $in);
ed21a8
+	}
ed21a8
+    }
ed21a8
+    close STDIN;
ed21a8
+
ed21a8
+    is($nread, $nlines, "STDIN was read completely");
ed21a8
+    ok(!$unexpected, "STDIN as expected") or diag($unexpected);
ed21a8
+}
ed21a8
+
ed21a8
+
ed21a8
-- 
ed21a8
1.8.5.3
ed21a8