1b8851fccSafresh1package FilePathTest; 2b8851fccSafresh1use strict; 3b8851fccSafresh1use warnings; 4b8851fccSafresh1use base 'Exporter'; 5b8851fccSafresh1use SelectSaver; 6b8851fccSafresh1use Cwd; 7b8851fccSafresh1use File::Spec::Functions; 8b8851fccSafresh1 9*c0dd97bfSafresh1our @EXPORT = qw(_run_for_warning _run_for_verbose _basedir 10b8851fccSafresh1 _cannot_delete_safe_mode 11*c0dd97bfSafresh1 _verbose_expected); 12de18eedbSafresh1 13014083a1Safresh1sub _basedir { 14*c0dd97bfSafresh1 return catdir( curdir(), 15014083a1Safresh1 sprintf( 'test-%x-%x-%x', time, $$, rand(99999) ), 16014083a1Safresh1 ); 17*c0dd97bfSafresh1 18b8851fccSafresh1} 19b8851fccSafresh1 20b8851fccSafresh1sub _run_for_warning { 21b8851fccSafresh1 my $coderef = shift; 22b8851fccSafresh1 my $warn = ''; 23b8851fccSafresh1 local $SIG{__WARN__} = sub { $warn .= shift }; 24b8851fccSafresh1 &$coderef; 25b8851fccSafresh1 return $warn; 26b8851fccSafresh1} 27b8851fccSafresh1 28b8851fccSafresh1sub _run_for_verbose { 29b8851fccSafresh1 my $coderef = shift; 30b8851fccSafresh1 my $stdout = ''; 31b8851fccSafresh1 { 32b8851fccSafresh1 my $guard = SelectSaver->new(_ref_to_fh(\$stdout)); 33b8851fccSafresh1 &$coderef; 34b8851fccSafresh1 } 35b8851fccSafresh1 return $stdout; 36b8851fccSafresh1} 37b8851fccSafresh1 38b8851fccSafresh1sub _ref_to_fh { 39b8851fccSafresh1 my $output = shift; 40b8851fccSafresh1 open my $fh, '>', $output; 41b8851fccSafresh1 return $fh; 42b8851fccSafresh1} 43b8851fccSafresh1 44b8851fccSafresh1# Whether a directory can be deleted without modifying permissions varies 45b8851fccSafresh1# by platform and by current privileges, so we really have to do the same 46b8851fccSafresh1# check the module does in safe mode to determine that. 47b8851fccSafresh1 48b8851fccSafresh1sub _cannot_delete_safe_mode { 49b8851fccSafresh1 my $path = shift; 50b8851fccSafresh1 return $^O eq 'VMS' 51b8851fccSafresh1 ? !&VMS::Filespec::candelete($path) 52b8851fccSafresh1 : !-w $path; 53b8851fccSafresh1} 54b8851fccSafresh1 55b8851fccSafresh1# What verbose mode reports depends on what it can do in safe mode. 56b8851fccSafresh1# Plus on VMS, mkpath may report what it's operating on in a 57b8851fccSafresh1# different format from the format of the path passed to it. 58b8851fccSafresh1 59b8851fccSafresh1sub _verbose_expected { 60b8851fccSafresh1 my ($function, $path, $safe_mode, $base) = @_; 61b8851fccSafresh1 my $expected; 62b8851fccSafresh1 63b8851fccSafresh1 if ($function =~ m/^(mkpath|make_path)$/) { 64b8851fccSafresh1 # On VMS, mkpath reports in Unix format. Maddeningly, it 65b8851fccSafresh1 # reports the top-level directory without a trailing slash 66b8851fccSafresh1 # and everything else with. 67b8851fccSafresh1 if ($^O eq 'VMS') { 68b8851fccSafresh1 $path = VMS::Filespec::unixify($path); 69b8851fccSafresh1 $path =~ s/\/$// if defined $base && $base; 70b8851fccSafresh1 } 71b8851fccSafresh1 $expected = "mkdir $path\n"; 72b8851fccSafresh1 } 73b8851fccSafresh1 elsif ($function =~ m/^(rmtree|remove_tree)$/) { 74b8851fccSafresh1 # N.B. Directories must still/already exist for this to work. 75b8851fccSafresh1 $expected = $safe_mode && _cannot_delete_safe_mode($path) 76b8851fccSafresh1 ? "skipped $path\n" 77b8851fccSafresh1 : "rmdir $path\n"; 78b8851fccSafresh1 } 79b8851fccSafresh1 elsif ($function =~ m/^(unlink)$/) { 80b8851fccSafresh1 $expected = "unlink $path\n"; 81b8851fccSafresh1 $expected =~ s/\n\z/\.\n/ if $^O eq 'VMS'; 82b8851fccSafresh1 } 83b8851fccSafresh1 else { 84b8851fccSafresh1 die "Unknown function $function in _verbose_expected"; 85b8851fccSafresh1 } 86b8851fccSafresh1 return $expected; 87b8851fccSafresh1} 88b8851fccSafresh1 89b8851fccSafresh1BEGIN { 90b8851fccSafresh1 if ($] < 5.008000) { 91b8851fccSafresh1 eval qq{#line @{[__LINE__+1]} "@{[__FILE__]}"\n} . <<'END' or die $@; 92b8851fccSafresh1 no warnings 'redefine'; 93b8851fccSafresh1 use Symbol (); 94b8851fccSafresh1 95b8851fccSafresh1 sub _ref_to_fh { 96b8851fccSafresh1 my $output = shift; 97b8851fccSafresh1 my $fh = Symbol::gensym(); 98b8851fccSafresh1 tie *$fh, 'StringIO', $output; 99b8851fccSafresh1 return $fh; 100b8851fccSafresh1 } 101b8851fccSafresh1 102b8851fccSafresh1 package StringIO; 103b8851fccSafresh1 sub TIEHANDLE { bless [ $_[1] ], $_[0] } 104b8851fccSafresh1 sub CLOSE { @{$_[0]} = (); 1 } 105b8851fccSafresh1 sub PRINT { ${ $_[0][0] } .= $_[1] } 106b8851fccSafresh1 sub PRINTF { ${ $_[0][0] } .= sprintf $_[1], @_[2..$#_] } 107b8851fccSafresh1 1; 108b8851fccSafresh1END 109b8851fccSafresh1 } 110b8851fccSafresh1} 111b8851fccSafresh1 112b8851fccSafresh11; 113