On Wed, Nov 6, 2019 at 4:38 PM Alvaro Herrera <alvhe...@2ndquadrant.com>
wrote:

> On 2019-Nov-05, Michael Paquier wrote:
>
> > On Sun, Nov 03, 2019 at 10:53:00PM -0500, Tom Lane wrote:
> > > That is, TestLib::slurp_file is failing to read a file.  Almost
> > > certainly, "permission denied" doesn't really mean a permissions
> > > problem, but failure to specify the file-opening flags needed to
> > > allow concurrent access on Windows.  We fixed this in pg_ctl
> > > itself in commit 0ba06e0bf ... but we didn't fix the TAP
> > > infrastructure.  Is there an easy way to get Perl on board
> > > with that?
> >
> > If we were to use Win32API::File so as the file is opened in shared
> > mode, we would do the same as what our frontend/backend code does (see
> > $uShare):
> > https://metacpan.org/pod/Win32API::File
>
> Compatibility-wise, that should be okay, since that module appears to
> have been distributed with Perl core early on.
>
>
Please find attached a patch that adds the FILE_SHARE options to
TestLib::slurp_file using Win32API::File.

Regards,

Juan José Santamaría Flecha
diff --git a/src/test/perl/TestLib.pm b/src/test/perl/TestLib.pm
index 905d0d1..25ab1f2 100644
--- a/src/test/perl/TestLib.pm
+++ b/src/test/perl/TestLib.pm
@@ -112,6 +112,22 @@ BEGIN
 
 	# Must be set early
 	$windows_os = $Config{osname} eq 'MSWin32' || $Config{osname} eq 'msys';
+	if ($windows_os)
+	{
+		require Win32::API;
+		Win32::API->import;
+
+		require Win32API::File;
+		Win32API::File->import(qw(
+			:Func
+			:Misc
+			:FILE_
+			:FILE_FLAG_
+			:FILE_SHARE_
+			:FILE_ATTRIBUTE_
+			:GENERIC_
+		));
+	}
 }
 
 =pod
@@ -394,10 +410,25 @@ sub slurp_file
 {
 	my ($filename) = @_;
 	local $/;
-	open(my $in, '<', $filename)
-	  or die "could not read \"$filename\": $!";
-	my $contents = <$in>;
-	close $in;
+	my $contents;
+	if (!$windows_os)
+	{
+		open(my $in, '<', $filename)
+		  or die "could not read \"$filename\": $!";
+		$contents = <$in>;
+		close $in;
+	}
+	else
+	{
+		my $fHandle = CreateFile($filename, GENERIC_READ(),
+		  FILE_SHARE_DELETE()|FILE_SHARE_READ()|FILE_SHARE_WRITE(), [], OPEN_EXISTING(), 0, [])
+		  or die "could not read \"$filename\": $^E";
+		OsFHandleOpen(my $fh = IO::Handle->new(), $fHandle, 'r')
+		  or die "OsFHandleOpen: $^E\n";
+		$contents = <$fh>;
+		CloseHandle($fHandle)
+		  or die "CloseHandle: $^E\n";
+	}
 	$contents =~ s/\r//g if $Config{osname} eq 'msys';
 	return $contents;
 }

Reply via email to