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; }