This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Term::ReadLine generates empty &STDERR files
authorJames E Keenan <jkeenan@cpan.org>
Fri, 1 Sep 2017 02:57:06 +0000 (22:57 -0400)
committerTony Cook <tony@develop-help.com>
Mon, 18 Sep 2017 05:01:28 +0000 (15:01 +1000)
Revert to 2-arg open in one case.

If /dev/tty is inaccessible, redirecting file handles to STDERR:

       open (my $fh, ">&STDERR))

... cannot be done as a 3 arg open or it'll actually try to write to that
file.

Bump $Term::ReadLine::VERSION.
Add unit test for RT #132008

For: RT #132008
(cherry picked from commit e4dc68d725b19f46c6fca9423e6e7a0eaeff47f4)
Signed-off-by: Nicolas R <atoomic@cpan.org>
xx

MANIFEST
dist/Term-ReadLine/lib/Term/ReadLine.pm
dist/Term-ReadLine/t/ReadLine-STDERR.t [new file with mode: 0644]

index ad24a2d..180fd4f 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -3669,6 +3669,7 @@ dist/Term-ReadLine/lib/Term/ReadLine.pm           Stub readline library
 dist/Term-ReadLine/t/AE.t                      See if Term::ReadLine works
 dist/Term-ReadLine/t/AETk.t                    See if Term::ReadLine works
 dist/Term-ReadLine/t/ReadLine.t                        See if Term::ReadLine works
+dist/Term-ReadLine/t/ReadLine-STDERR.t         See if Term::ReadLine works
 dist/Term-ReadLine/t/Tk.t                      See if Term::ReadLine works
 dist/Test/lib/Test.pm          A simple framework for writing test scripts
 dist/Test/t/05_about_verbose.t See if Test works
index 88d5a75..e00fb37 100644 (file)
@@ -229,12 +229,17 @@ sub readline {
 }
 sub addhistory {}
 
+# used for testing purpose
+sub devtty { return '/dev/tty' }
+
 sub findConsole {
     my $console;
     my $consoleOUT;
 
-    if ($^O ne 'MSWin32' and -e "/dev/tty") {
-       $console = "/dev/tty";
+    my $devtty = devtty();
+
+    if ($^O ne 'MSWin32' and -e $devtty) {
+       $console = $devtty;
     } elsif ($^O eq 'MSWin32' or $^O eq 'msys' or -e "con") {
        $console = 'CONIN$';
        $consoleOUT = 'CONOUT$';
@@ -248,7 +253,7 @@ sub findConsole {
 
     $consoleOUT = $console unless defined $consoleOUT;
     $console = "&STDIN" unless defined $console;
-    if ($console eq "/dev/tty" && !open(my $fh, "<", $console)) {
+    if ($console eq $devtty && !open(my $fh, "<", $console)) {
       $console = "&STDIN";
       undef($consoleOUT);
     }
@@ -266,11 +271,11 @@ sub new {
   if (@_==2) {
     my($console, $consoleOUT) = $_[0]->findConsole;
 
-
     # the Windows CONIN$ needs GENERIC_WRITE mode to allow
     # a SetConsoleMode() if we end up using Term::ReadKey
     open FIN, (( $^O eq 'MSWin32' && $console eq 'CONIN$' ) ? '+<' : '<' ), $console;
-    open FOUT,'>', $consoleOUT;
+    # RT #132008:  Still need 2-arg open here
+    open FOUT,">$consoleOUT";
 
     #OUT->autoflush(1);                # Conflicts with debugger?
     my $sel = select(FOUT);
@@ -319,7 +324,7 @@ sub Features { \%features }
 
 package Term::ReadLine;                # So late to allow the above code be defined?
 
-our $VERSION = '1.16';
+our $VERSION = '1.17';
 
 my ($which) = exists $ENV{PERL_RL} ? split /\s+/, $ENV{PERL_RL} : undef;
 if ($which) {
diff --git a/dist/Term-ReadLine/t/ReadLine-STDERR.t b/dist/Term-ReadLine/t/ReadLine-STDERR.t
new file mode 100644 (file)
index 0000000..f7aa2df
--- /dev/null
@@ -0,0 +1,41 @@
+#!./perl -w
+use strict;
+
+use Test::More;
+
+## unit test for RT 132008 - https://rt.perl.org/Ticket/Display.html?id=132008
+
+if ( $^O eq 'MSWin32' || !-e q{/dev/tty} ) {
+    plan skip_all => "Test not tested on windows or when /dev/tty do not exists";
+}
+else {
+    plan tests => 9;
+}
+
+if ( -e q[&STDERR] ) {
+    note q[Removing existing file &STDERR];
+    unlink q[&STDERR] or die q{Cannot remove existing file &STDERR [probably created from a previous run]};
+}
+
+use_ok('Term::ReadLine');
+can_ok( 'Term::ReadLine::Stub', qw{new devtty findConsole} );
+
+is( Term::ReadLine->devtty(), q{/dev/tty} );
+my @out = Term::ReadLine::Stub::findConsole();
+is_deeply \@out, [ q{/dev/tty}, q{/dev/tty} ], "findConsole is using /dev/tty";
+
+{
+    no warnings 'redefine';
+    my $donotexist = q[/this/should/not/exist/hopefully];
+
+    ok !-e $donotexist, "File $donotexist does not exist";
+    local *Term::ReadLine::Stub::devtty = sub { $donotexist };
+    is( Term::ReadLine->devtty(), $donotexist, "devtty mocked" );
+
+    my @out = Term::ReadLine::Stub::findConsole();
+    is_deeply \@out, [ q{&STDIN}, q{&STDERR} ], "findConsole is using /dev/tty" or diag explain \@out;
+
+    ok !-e q[&STDERR], 'file &STDERR do not exist before Term::ReadLine call';
+    my $tr = Term::ReadLine->new('whatever');
+    ok !-e q[&STDERR], 'file &STDERR was not created by mistake';
+}