package Cwd;
-require 5.6.0;
+use 5.006;
=head1 NAME
most systems it is identical to `pwd` (but without the trailing line
terminator).
-Unfortunately, cwd() tends to break if called under taint mode.
-
=item fastcwd
my $cwd = fastcwd();
=head2 abs_path and friends
These functions are exported only on request. They each take a single
-argument and return the absolute pathname for it.
+argument and return the absolute pathname for it. If no argument is
+given they'll use the current working directory.
=over 4
=item fast_abs_path
- my $abs_path = abs_path($file);
+ my $abs_path = fast_abs_path($file);
A more dangerous, but potentially faster version of abs_path.
use strict;
-use Carp;
-
-our $VERSION = '2.06';
+our $VERSION = '2.08';
use base qw/ Exporter /;
our @EXPORT = qw(cwd getcwd fastcwd fastgetcwd);
eval {
require XSLoader;
+ local $^W = 0;
XSLoader::load('Cwd');
};
last;
}
}
-$pwd_cmd ||= 'pwd';
+unless ($pwd_cmd) {
+ if (-x '/QOpenSys/bin/pwd') { # OS/400 PASE.
+ $pwd_cmd = '/QOpenSys/bin/pwd' ;
+ } else {
+ # Isn't this wrong? _backtick_pwd() will fail if somenone has
+ # pwd in their path but it is not /bin/pwd or /usr/bin/pwd?
+ # See [perl #16774]. --jhi
+ $pwd_cmd = 'pwd';
+ }
+}
# The 'natural and safe form' for UNIX (pwd may be setuid root)
sub _backtick_pwd {
+ local @ENV{qw(PATH IFS CDPATH ENV BASH_ENV)};
my $cwd = `$pwd_cmd`;
+ # Belt-and-suspenders in case someone said "undef $/".
+ local $/ = "\n";
# `pwd` may fail e.g. if the disk is full
chomp($cwd) if defined $cwd;
$cwd;
unless(defined &cwd) {
# The pwd command is not available in some chroot(2)'ed environments
- if($^O eq 'MacOS' || grep { -x "$_/pwd" } split(':', $ENV{PATH})) {
+ if( $^O eq 'MacOS' || (defined $ENV{PATH} &&
+ grep { -x "$_/pwd" } split(':', $ENV{PATH})) )
+ {
*cwd = \&_backtick_pwd;
}
else {
$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 =~ /^(.*)\z/s; # untaint
- CORE::chdir($path) || return undef;
+ # Untaint it then check that we landed where we started.
+ $path =~ /^(.*)\z/s # untaint
+ && CORE::chdir($1) or return undef;
($cdev, $cino) = stat('.');
die "Unstable directory path, current directory changed unexpectedly"
if $cdev != $orig_cdev || $cino != $orig_cino;
unless (@cst = stat( $start ))
{
- carp "stat($start): $!";
+ require Carp;
+ Carp::carp ("stat($start): $!");
return '';
}
$cwd = '';
{
$dotdots .= '/..';
@pst = @cst;
+ local *PARENT;
unless (opendir(PARENT, $dotdots))
{
- carp "opendir($dotdots): $!";
+ require Carp;
+ Carp::carp ("opendir($dotdots): $!");
return '';
}
unless (@cst = stat($dotdots))
{
- carp "stat($dotdots): $!";
+ require Carp;
+ Carp::carp ("stat($dotdots): $!");
closedir(PARENT);
return '';
}
{
unless (defined ($dir = readdir(PARENT)))
{
- carp "readdir($dotdots): $!";
+ require Carp;
+ Carp::carp ("readdir($dotdots): $!");
closedir(PARENT);
return '';
}
# used to the libc function. --tchrist 27-Jan-00
*realpath = \&abs_path;
+my $Curdir;
sub fast_abs_path {
my $cwd = getcwd();
require File::Spec;
- my $path = @_ ? shift : File::Spec->curdir;
- CORE::chdir($path) || croak "Cannot chdir to $path:$!";
+ my $path = @_ ? shift : ($Curdir ||= File::Spec->curdir);
+
+ # Detaint else we'll explode in taint mode. This is safe because
+ # we're not doing anything dangerous with it.
+ ($path) = $path =~ /(.*)/;
+ ($cwd) = $cwd =~ /(.*)/;
+
+ if (!CORE::chdir($path)) {
+ require Carp;
+ Carp::croak ("Cannot chdir to $path: $!");
+ }
my $realpath = getcwd();
- CORE::chdir($cwd) || croak "Cannot chdir back to $cwd:$!";
+ if (! ((-d $cwd) && (CORE::chdir($cwd)))) {
+ require Carp;
+ Carp::croak ("Cannot chdir back to $cwd: $!");
+ }
$realpath;
}
sub _vms_abs_path {
return $ENV{'DEFAULT'} unless @_;
my $path = VMS::Filespec::pathify($_[0]);
- croak("Invalid path name $_[0]") unless defined $path;
+ if (! defined $path)
+ {
+ require Carp;
+ Carp::croak("Invalid path name $_[0]")
+ }
return VMS::Filespec::rmsexpand($path);
}
}
sub _qnx_cwd {
+ local $ENV{PATH} = '';
+ local $ENV{CDPATH} = '';
+ local $ENV{ENV} = '';
$ENV{'PWD'} = `/usr/bin/fullpath -t`;
chop $ENV{'PWD'};
return $ENV{'PWD'};
}
sub _qnx_abs_path {
+ local $ENV{PATH} = '';
+ local $ENV{CDPATH} = '';
+ local $ENV{ENV} = '';
my $path = @_ ? shift : '.';
my $realpath=`/usr/bin/fullpath -t $path`;
chop $realpath;
*fastcwd = \&_NT_cwd;
*fastgetcwd = \&_NT_cwd;
*abs_path = \&fast_abs_path;
+ *realpath = \&fast_abs_path;
}
elsif ($^O eq 'os2') {
# sys_cwd may keep the builtin command