Subject: | ".type = writable" check on VMS incorrect: passes or fails by coincidence |
When Euclid checks if an argument is writable (.type = writable), there
is a case where it won't give reliable results on Windows and VMS. It
is currently passing/failing by coincidence.
The problem is that Euclid currently throws away the volume when using
splitpath, and only uses the directory in the if(-w $dir) check. If
you're using Unix, Linux, BSD, etc, this is fine (eg. /home/bob doesn't
contain any volume information, so you can just use the directory part).
However, on Windows and VMS, there is volume information that should be
retained:
Windows:
- C:\home\bob (with volume information)
- \home\bob (without volume information)
VMS:
- some$disk:[home.bob] (with volume information)
- [home.bob] (without volume information)
Due to the behavior of if(-w $dir), the writability test will pass only
if the directory exists and is writable _on the current volume_ that the
script is executed from. This does not appear to be the intended or
correct behavior.
I have included a patch to correct the behavior on VMS. I reran unit
tests on Linux and OpenVMS using Perl 5.8, and they completed without
problem.
Thank you.
Subject: | euclid_v0_2_0_writable_fix.patch |
--- euclid.pm 2007-08-04 16:22:32.000000000 +0900
+++ euclid_patched.pm 2008-08-13 14:44:32.282958900 +0900
@@ -5,7 +5,7 @@
use warnings;
use strict;
use Carp;
-use File::Spec::Functions qw(splitpath);
+use File::Spec::Functions qw(splitpath catpath);
use List::Util qw( first );
# Utility sub to factor out hash key aliasing...
@@ -214,8 +214,14 @@
'+number' => sub { $_[0] > 0 },
'0+number' => sub { $_[0] >= 0 },
'input' => sub { $_[0] eq '-' || -r $_[0] },
- 'output' => sub { my (undef, $dir) = splitpath($_[0]);
- $dir ||= '.';
+ 'output' => sub { my ($vol, $dir) = splitpath($_[0]);
+ if($dir && $vol) {
+ # Reassemble path with volume.
+ $dir = catpath($vol, $dir);
+ }
+ else {
+ $dir = '.';
+ }
$_[0] eq '-' ? 1 : -e $_[0] ? -w $_[0] : -w $dir
},
);