Fixes for ext/compress
[p5sagit/p5-mst-13.2.git] / lib / Cwd.pm
index 21cc263..83239bf 100644 (file)
@@ -171,7 +171,9 @@ use strict;
 use Exporter;
 use vars qw(@ISA @EXPORT @EXPORT_OK $VERSION);
 
-$VERSION = '3.17';
+$VERSION = '3.29_01';
+my $xs_version = $VERSION;
+$VERSION = eval $VERSION;
 
 @ISA = qw/ Exporter /;
 @EXPORT = qw(cwd getcwd fastcwd fastgetcwd);
@@ -200,15 +202,54 @@ if ($^O eq 'os2') {
     return 1;
 }
 
+# Need to look up the feature settings on VMS.  The preferred way is to use the
+# VMS::Feature module, but that may not be available to dual life modules.
+
+my $use_vms_feature;
+BEGIN {
+    if ($^O eq 'VMS') {
+        if (eval { local $SIG{__DIE__}; require VMS::Feature; }) {
+            $use_vms_feature = 1;
+        }
+    }
+}
+
+# Need to look up the UNIX report mode.  This may become a dynamic mode
+# in the future.
+sub _vms_unix_rpt {
+    my $unix_rpt;
+    if ($use_vms_feature) {
+        $unix_rpt = VMS::Feature::current("filename_unix_report");
+    } else {
+        my $env_unix_rpt = $ENV{'DECC$FILENAME_UNIX_REPORT'} || '';
+        $unix_rpt = $env_unix_rpt =~ /^[ET1]/i; 
+    }
+    return $unix_rpt;
+}
+
+# Need to look up the EFS character set mode.  This may become a dynamic
+# mode in the future.
+sub _vms_efs {
+    my $efs;
+    if ($use_vms_feature) {
+        $efs = VMS::Feature::current("efs_charset");
+    } else {
+        my $env_efs = $ENV{'DECC$EFS_CHARSET'} || '';
+        $efs = $env_efs =~ /^[ET1]/i; 
+    }
+    return $efs;
+}
+
+
 # If loading the XS stuff doesn't work, we can fall back to pure perl
 eval {
   if ( $] >= 5.006 ) {
     require XSLoader;
-    XSLoader::load( __PACKAGE__, $VERSION );
+    XSLoader::load( __PACKAGE__, $xs_version);
   } else {
     require DynaLoader;
     push @ISA, 'DynaLoader';
-    __PACKAGE__->bootstrap( $VERSION );
+    __PACKAGE__->bootstrap( $xs_version );
   }
 };
 
@@ -370,10 +411,8 @@ if ($^O eq 'cygwin') {
 # isn't redefined later (20001212 rspier)
 *fastgetcwd = \&cwd;
 
-# By Brandon S. Allbery
-#
-# Usage: $cwd = getcwd();
-
+# A non-XS version of getcwd() - also used to bootstrap the perl build
+# process, when miniperl is running and no XS loading happens.
 sub _perl_getcwd
 {
     abs_path('.');
@@ -481,7 +520,9 @@ sub chdir {
        return 1;
     }
 
-    if ($newdir =~ m#^/#s) {
+    if (ref $newdir eq 'GLOB') { # in case a file/dir handle is passed in
+       $ENV{'PWD'} = cwd();
+    } elsif ($newdir =~ m#^/#s) {
        $ENV{'PWD'} = $newdir;
     } else {
        my @curdir = split(m#/#,$ENV{'PWD'});
@@ -540,8 +581,8 @@ sub _perl_abs_path
        local *PARENT;
        unless (opendir(PARENT, $dotdots))
        {
-           _carp("opendir($dotdots): $!");
-           return '';
+           # probably a permissions issue.  Try the native command.
+           return File::Spec->rel2abs( $start, _backtick_pwd() );
        }
        unless (@cst = stat($dotdots))
        {
@@ -644,11 +685,58 @@ sub _vms_cwd {
 
 sub _vms_abs_path {
     return $ENV{'DEFAULT'} unless @_;
+    my $path = shift;
+
+    my $efs = _vms_efs;
+    my $unix_rpt = _vms_unix_rpt;
+
+    if (defined &VMS::Filespec::vmsrealpath) {
+        my $path_unix = 0;
+        my $path_vms = 0;
+
+        $path_unix = 1 if ($path =~ m#(?<=\^)/#);
+        $path_unix = 1 if ($path =~ /^\.\.?$/);
+        $path_vms = 1 if ($path =~ m#[\[<\]]#);
+        $path_vms = 1 if ($path =~ /^--?$/);
+
+        my $unix_mode = $path_unix;
+        if ($efs) {
+            # In case of a tie, the Unix report mode decides.
+            if ($path_vms == $path_unix) {
+                $unix_mode = $unix_rpt;
+            } else {
+                $unix_mode = 0 if $path_vms;
+            }
+        }
+
+        if ($unix_mode) {
+            # Unix format
+            return VMS::Filespec::unixrealpath($path);
+        }
+
+       # VMS format
+
+       my $new_path = VMS::Filespec::vmsrealpath($path);
+
+       # Perl expects directories to be in directory format
+       $new_path = VMS::Filespec::pathify($new_path) if -d $path;
+       return $new_path;
+    }
 
-    # may need to turn foo.dir into [.foo]
-    my $path = VMS::Filespec::pathify($_[0]);
-    $path = $_[0] unless defined $path;
+    # Fallback to older algorithm if correct ones are not
+    # available.
+
+    if (-l $path) {
+        my $link_target = readlink($path);
+        die "Can't resolve link $path: $!" unless defined $link_target;
 
+        return _vms_abs_path($link_target);
+    }
+
+    # may need to turn foo.dir into [.foo]
+    my $pathified = VMS::Filespec::pathify($path);
+    $path = $pathified if defined $pathified;
+       
     return VMS::Filespec::rmsexpand($path);
 }
 
@@ -660,7 +748,12 @@ sub _os2_cwd {
 }
 
 sub _win32_cwd {
-    $ENV{'PWD'} = Win32::GetCwd();
+    if (defined &DynaLoader::boot_DynaLoader) {
+       $ENV{'PWD'} = Win32::GetCwd();
+    }
+    else { # miniperl
+       chomp($ENV{'PWD'} = `cd`);
+    }
     $ENV{'PWD'} =~ s:\\:/:g ;
     return $ENV{'PWD'};
 }