X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCwd.pm;h=4a263cd5fafdeddb2cd8c6f284718a74a110cc51;hb=1f4f94f54707f6b6f968889b09e1660facfd0c3e;hp=7febb0dde2989d0ce2252030002ebad35c2d6ad0;hpb=e79e61e4622b6e419b9c7736de49bd996a7c7e64;p=p5sagit%2Fp5-mst-13.2.git diff --git a/lib/Cwd.pm b/lib/Cwd.pm index 7febb0d..4a263cd 100644 --- a/lib/Cwd.pm +++ b/lib/Cwd.pm @@ -20,7 +20,7 @@ getcwd - get pathname of current working directory chdir "/tmp"; print $ENV{'PWD'}; - use Cwd 'abs_path'; + use Cwd 'abs_path'; # aka realpath() print abs_path($ENV{'PWD'}); use Cwd 'fast_abs_path'; @@ -32,8 +32,11 @@ The getcwd() function re-implements the getcwd(3) (or getwd(3)) functions in Perl. The abs_path() function takes a single argument and returns the -absolute pathname for that argument. It uses the same algoritm as -getcwd(). (actually getcwd() is abs_path(".")) +absolute pathname for that argument. It uses the same algorithm +as getcwd(). (Actually, getcwd() is abs_path(".")) Symbolic links +and relative-path components ("." and "..") are resolved to return +the canonical pathname, just like realpath(3). Also callable as +realpath(). The fastcwd() function looks the same as getcwd(), but runs faster. It's also more dangerous because it might conceivably chdir() you out @@ -63,31 +66,42 @@ kept up to date if all packages which use chdir import it from Cwd. =cut -## use strict; +use strict; use Carp; -$VERSION = '2.01'; +our $VERSION = '2.04'; -require Exporter; -@ISA = qw(Exporter); -@EXPORT = qw(cwd getcwd fastcwd fastgetcwd); -@EXPORT_OK = qw(chdir abs_path fast_abs_path); +use base qw/ Exporter /; +our @EXPORT = qw(cwd getcwd fastcwd fastgetcwd); +our @EXPORT_OK = qw(chdir abs_path fast_abs_path realpath fast_realpath); # The 'natural and safe form' for UNIX (pwd may be setuid root) sub _backtick_pwd { - my $cwd; - chop($cwd = `pwd`); + my $cwd = `pwd`; + # `pwd` may fail e.g. if the disk is full + chomp($cwd) if defined $cwd; $cwd; } # Since some ports may predefine cwd internally (e.g., NT) # we take care not to override an existing definition for cwd(). -*cwd = \&_backtick_pwd unless defined &cwd; +unless(defined &cwd) { + # The pwd command is not available in some chroot(2)'ed environments + if(grep { -x "$_/pwd" } split(':', $ENV{PATH})) { + *cwd = \&_backtick_pwd; + } + else { + *cwd = \&getcwd; + } +} +# set a reasonable (and very safe) default for fastgetcwd, in case it +# isn't redefined later (20001212 rspier) +*fastgetcwd = \&cwd; # By Brandon S. Allbery # @@ -105,9 +119,6 @@ sub getcwd # This is a faster version of getcwd. It's also more dangerous because # you might chdir out of a directory that you can't chdir back into. -# List of metachars taken from do_exec() in doio.c -my $quoted_shell_meta = quotemeta('$&*(){}[]";\\|?<>~`'."'\n"); - sub fastcwd { my($odev, $oino, $cdev, $cino, $tdev, $tino); my(@path, $path); @@ -136,9 +147,10 @@ sub fastcwd { unshift(@path, $direntry); } $path = '/' . join('/', @path); + if ($^O eq 'apollo') { $path = "/".$path; } # At this point $path may be tainted (if tainting) and chdir would fail. # To be more useful we untaint it then check that we landed where we started. - $path = $1 if $path =~ /^(.*)$/; # untaint + $path = $1 if $path =~ /^(.*)\z/s; # untaint CORE::chdir($path) || return undef; ($cdev, $cino) = stat('.'); die "Unstable directory path, current directory changed unexpectedly" @@ -155,7 +167,7 @@ sub fastcwd { my $chdir_init = 0; sub chdir_init { - if ($ENV{'PWD'} and $^O ne 'os2' and $^O ne 'dos') { + if ($ENV{'PWD'} and $^O ne 'os2' and $^O ne 'dos' and $^O ne 'MSWin32') { my($dd,$di) = stat('.'); my($pd,$pi) = stat($ENV{'PWD'}); if (!defined $dd or !defined $pd or $di != $pi or $dd != $pd) { @@ -163,10 +175,12 @@ sub chdir_init { } } else { - $ENV{'PWD'} = cwd(); + my $wd = cwd(); + $wd = Win32::GetFullPathName($wd) if $^O eq 'MSWin32'; + $ENV{'PWD'} = $wd; } # Strip an automounter prefix (where /tmp_mnt/foo/bar == /foo/bar) - if ($ENV{'PWD'} =~ m|(/[^/]+(/[^/]+/[^/]+))(.*)|) { + if ($^O ne 'MSWin32' and $ENV{'PWD'} =~ m|(/[^/]+(/[^/]+/[^/]+))(.*)|s) { my($pd,$pi) = stat($2); my($dd,$di) = stat($1); if (defined $pd and defined $dd and $di == $pi and $dd == $pd) { @@ -177,13 +191,19 @@ sub chdir_init { } sub chdir { - my $newdir = shift || ''; # allow for no arg (chdir to HOME dir) - $newdir =~ s|///*|/|g; + my $newdir = @_ ? shift : ''; # allow for no arg (chdir to HOME dir) + $newdir =~ s|///*|/|g unless $^O eq 'MSWin32'; chdir_init() unless $chdir_init; return 0 unless CORE::chdir $newdir; - if ($^O eq 'VMS') { return $ENV{'PWD'} = $ENV{'DEFAULT'} } + if ($^O eq 'VMS') { + return $ENV{'PWD'} = $ENV{'DEFAULT'} + } + elsif ($^O eq 'MSWin32') { + $ENV{'PWD'} = Win32::GetFullPathName($newdir); + return 1; + } - if ($newdir =~ m#^/#) { + if ($newdir =~ m#^/#s) { $ENV{'PWD'} = $newdir; } else { my @curdir = split(m#/#,$ENV{'PWD'}); @@ -256,20 +276,28 @@ sub abs_path $cwd; } +# added function alias for those of us more +# used to the libc function. --tchrist 27-Jan-00 +*realpath = \&abs_path; + sub fast_abs_path { my $cwd = getcwd(); - my $path = shift || '.'; + my $path = @_ ? shift : '.'; CORE::chdir($path) || croak "Cannot chdir to $path:$!"; my $realpath = getcwd(); CORE::chdir($cwd) || croak "Cannot chdir back to $cwd:$!"; $realpath; } +# added function alias to follow principle of least surprise +# based on previous aliasing. --tchrist 27-Jan-00 +*fast_realpath = \&fast_abs_path; + # --- PORTING SECTION --- # VMS: $ENV{'DEFAULT'} points to default directory at all times -# 06-Mar-1996 Charles Bailey bailey@genetics.upenn.edu +# 06-Mar-1996 Charles Bailey bailey@newman.upenn.edu # Note: Use of Cwd::chdir() causes the logical name PWD to be defined # in the process logical name table as the default device and directory # seen by Perl. This may not be the same as the default device @@ -323,14 +351,19 @@ sub _qnx_cwd { } sub _qnx_abs_path { - my $path = shift || '.'; + my $path = @_ ? shift : '.'; my $realpath=`/usr/bin/fullpath -t $path`; chop $realpath; return $realpath; } +sub _epoc_cwd { + $ENV{'PWD'} = EPOC::getcwd(); + return $ENV{'PWD'}; +} + { - local $^W = 0; # assignments trigger 'subroutine redefined' warning + no warnings; # assignments trigger 'subroutine redefined' warning if ($^O eq 'VMS') { *cwd = \&_vms_cwd; @@ -371,6 +404,19 @@ sub _qnx_abs_path { *abs_path = \&_qnx_abs_path; *fast_abs_path = \&_qnx_abs_path; } + elsif ($^O eq 'cygwin') { + *getcwd = \&cwd; + *fastgetcwd = \&cwd; + *fastcwd = \&cwd; + *abs_path = \&fast_abs_path; + } + elsif ($^O eq 'epoc') { + *cwd = \&_epoc_cwd; + *getcwd = \&_epoc_cwd; + *fastgetcwd = \&_epoc_cwd; + *fastcwd = \&_epoc_cwd; + *abs_path = \&fast_abs_path; + } } # package main; eval join('',) || die $@; # quick test