Fix closing stdin in TestLib.pm
authorAndrew Dunstan <andrew@dunslane.net>
Tue, 26 Nov 2019 21:23:00 +0000 (16:23 -0500)
committerAndrew Dunstan <andrew@dunslane.net>
Tue, 26 Nov 2019 21:32:06 +0000 (16:32 -0500)
Commit 9af34f3c6b naively assumed that all non-windows platforms would
have pseudoterminals and that perl would have IO::Pty. Such is not the
case. Instead of assumung anything, test for the presence of IO::Pty and
only use code that might depend on it if it's present. The test result is
exposed in $TestLib::have_io_pty so that it can be conveniently used in
SKIP tests.

Discussion: https://postgr.es/m/20191126044110.GB5435@paquier.xyz

src/test/perl/TestLib.pm

index 18b4ce35c20f820aed21c8d5f67a93f9f860cb9c..3f89d75310258ea152d29d9b2ca1c78f4d3dd35c 100644 (file)
@@ -21,6 +21,7 @@ TestLib - helper module for writing PostgreSQL's C<prove> tests.
 
   # Miscellanea
   print "on Windows" if $TestLib::windows_os;
+  print "IO::Pty is available" if $TestLib::have_io_pty;
   my $path = TestLib::perl2host($backup_dir);
   ok(check_mode_recursive($stream_dir, 0700, 0600),
     "check stream dir permissions");
@@ -83,9 +84,10 @@ our @EXPORT = qw(
   command_checks_all
 
   $windows_os
+  $have_io_pty
 );
 
-our ($windows_os, $tmp_check, $log_path, $test_logfile);
+our ($windows_os, $tmp_check, $log_path, $test_logfile, $have_io_pty);
 
 my @no_stdin;
 
@@ -119,6 +121,9 @@ BEGIN
        require Win32API::File;
        Win32API::File->import(qw(createFile OsFHandleOpen CloseHandle));
    }
+
+   eval { require IO::Pty; };
+   $have_io_pty = 1 unless $@;
 }
 
 =pod
@@ -133,6 +138,12 @@ Set to true when running under Windows, except on Cygwin.
 
 =back
 
+=item C<$have_io_pty>
+
+Set to true when IO::Pty is available.
+
+=back
+
 =cut
 
 INIT
@@ -182,18 +193,17 @@ INIT
    autoflush $testlog 1;
 
    # Settings to close stdin for certain commands.
-   # On non-Windows, use a pseudo-terminal, so that libraries like openssl
-   # which open the tty if they think stdin isn't one for a password
-   # don't block. Windows doesn't have ptys, so just provide an empty
-   # string for stdin.
-   if ($windows_os)
+   # If IO::Pty is present, use a pseudo-terminal, so that libraries like
+   # openssl which open the tty if they think stdin isn't one for a password
+   # don't block. Elsewhere just provide an empty string for stdin.
+   if ($have_io_pty)
    {
-       @no_stdin = ('<', \"");
+       use charnames ':full';
+       @no_stdin = ('<pty<', \"\N{END OF TRANSMISSION}");
    }
    else
    {
-       use charnames ':full';
-       @no_stdin = ('<pty<', \"\N{END OF TRANSMISSION}");
+       @no_stdin = ('<', \"");
    }
 }