package Cwd;
require 5.000;
use Carp;
$VERSION = '2.01';
require Exporter;
@ISA=qw(Exporter);
@EXPORT=qw(cwd getcwd fastcwd fastgetcwd);
@EXPORT_OK=qw(chdir abs_path fast_abs_path);
sub _backtick_pwd{my$cwd;
chop($cwd=`pwd`);
$cwd;}*cwd=\&_backtick_pwd unless defined&cwd;
sub getcwd{abs_path('.');}my$quoted_shell_meta=quotemeta('$&*(){}[]";\\|?<>~`'."'\n");
sub fastcwd{my($odev,$oino,$cdev,$cino,$tdev,$tino);
my(@path,$path);
local(*DIR);
my($orig_cdev,$orig_cino)=stat('.');
($cdev,$cino)=($orig_cdev,$orig_cino);
for(;;){my$direntry;
($odev,$oino)=($cdev,$cino);
CORE::chdir('..')||return undef;
($cdev,$cino)=stat('.');
last if$odev==$cdev&&$oino==$cino;
opendir(DIR,'.')||return undef;
for(;;){$direntry=readdir(DIR);
last unless defined$direntry;
next if$direntry eq '.';
next if$direntry eq '..';
($tdev,$tino)=lstat($direntry);
last unless$tdev!=$odev||$tino!=$oino;}closedir(DIR);
return undef unless defined$direntry;
unshift(@path,$direntry);}$path='/'.join('/',@path);
$path=$1 if$path=~/^(.*)$/;
CORE::chdir($path)||return undef;
($cdev,$cino)=stat('.');
die"Unstable directory path, current directory changed unexpectedly" if$cdev!=$orig_cdev||$cino!=$orig_cino;
$path;}my$chdir_init=0;
sub chdir_init{if($ENV{'PWD'}and$^O ne 'os2' and$^O ne 'dos'){my($dd,$di)=stat('.');
my($pd,$pi)=stat($ENV{'PWD'});
if(!defined$dd or!defined$pd or$di!=$pi or$dd!=$pd){$ENV{'PWD'}=cwd();}}else{$ENV{'PWD'}=cwd();}if($ENV{'PWD'}=~m|(/[^/]+(/[^/]+/[^/]+))(.*)|){my($pd,$pi)=stat($2);
my($dd,$di)=stat($1);
if(defined$pd and defined$dd and$di==$pi and$dd==$pd){$ENV{'PWD'}="$2$3";}}$chdir_init=1;}sub chdir{my$newdir=shift||'';
$newdir=~s|///*|/|g;
chdir_init()unless$chdir_init;
return 0 unless CORE::chdir$newdir; if($^O eq 'VMS'){return$ENV{'PWD'}=$ENV{'DEFAULT'}}if($newdir=~m#^/#){$ENV{'PWD'}=$newdir;}else{my@curdir=split(m#/#,$ENV{'PWD'});
@curdir=('')unless@curdir;
my$component;
foreach$component(split(m#/#,$newdir)){next if$component eq '.';
pop(@curdir),next if$component eq '..';
push(@curdir,$component);}$ENV{'PWD'}=join('/',@curdir)||'/';}1;}sub abs_path{my$start=@_?shift:'.';
my($dotdots,$cwd,@pst,@cst,$dir,@tst);
unless(@cst=stat($start)){carp"stat($start): $!";
return '';}$cwd='';
$dotdots=$start;
do{$dotdots.='/..';
@pst=@cst;
unless(opendir(PARENT,$dotdots)){carp"opendir($dotdots): $!";
return '';}unless(@cst=stat($dotdots)){carp"stat($dotdots): $!";
closedir(PARENT);
return '';}if($pst[0]==$cst[0]&&$pst[1]==$cst[1]){$dir=undef;}else{do{unless(defined($dir=readdir(PARENT))){carp"readdir($dotdots): $!";
closedir(PARENT);
return '';}$tst[0]=$pst[0]+1 unless(@tst=lstat("$dotdots/$dir"))}while($dir eq '.'||$dir eq '..'||$tst[0]!=$pst[0]||$tst[1]!=$pst[1]);}$cwd=(defined$dir?"$dir":"")."/$cwd";
closedir(PARENT);}while(defined$dir);
chop($cwd)unless$cwd eq '/';
$cwd;}sub fast_abs_path{my$cwd=getcwd();
my$path=shift||'.';
CORE::chdir($path)||croak"Cannot chdir to $path:$!";
my$realpath=getcwd();
CORE::chdir($cwd)||croak"Cannot chdir back to $cwd:$!";
$realpath;}sub _vms_cwd{return$ENV{'DEFAULT'};}sub _vms_abs_path{return$ENV{'DEFAULT'}unless@_;
my$path=VMS::Filespec::pathify($_[0]);
croak("Invalid path name $_[0]")unless defined$path;
return VMS::Filespec::rmsexpand($path);}sub _os2_cwd{$ENV{'PWD'}=`cmd /c cd`;
chop$ENV{'PWD'};
$ENV{'PWD'}=~s:\\:/:g;
return$ENV{'PWD'};}sub _win32_cwd{$ENV{'PWD'}=Win32::GetCwd();
$ENV{'PWD'}=~s:\\:/:g;
return$ENV{'PWD'};}*_NT_cwd=\&_win32_cwd if(!defined&_NT_cwd&&defined&Win32::GetCwd);
*_NT_cwd=\&_os2_cwd unless defined&_NT_cwd;
sub _dos_cwd{if(!defined&Dos::GetCwd){$ENV{'PWD'}=`command /c cd`;
chop$ENV{'PWD'};
$ENV{'PWD'}=~s:\\:/:g;}else{$ENV{'PWD'}=Dos::GetCwd();}return$ENV{'PWD'};}sub _qnx_cwd{$ENV{'PWD'}=`/usr/bin/fullpath -t`;
chop$ENV{'PWD'};
return$ENV{'PWD'};}sub _qnx_abs_path{my$path=shift||'.';
my$realpath=`/usr/bin/fullpath -t $path`;
chop$realpath;
return$realpath;}{local$^W=0;
if($^O eq 'VMS'){*cwd=\&_vms_cwd;
*getcwd=\&_vms_cwd;
*fastcwd=\&_vms_cwd;
*fastgetcwd=\&_vms_cwd;
*abs_path=\&_vms_abs_path;
*fast_abs_path=\&_vms_abs_path;}elsif($^O eq 'NT' or$^O eq 'MSWin32'){*cwd=\&_NT_cwd;
*getcwd=\&_NT_cwd;
*fastcwd=\&_NT_cwd;
*fastgetcwd=\&_NT_cwd;
*abs_path=\&fast_abs_path;}elsif($^O eq 'os2'){*cwd=defined&sys_cwd?\&sys_cwd:\&_os2_cwd;
*getcwd=\&cwd;
*fastgetcwd=\&cwd;
*fastcwd=\&cwd;
*abs_path=\&fast_abs_path;}elsif($^O eq 'dos'){*cwd=\&_dos_cwd;
*getcwd=\&_dos_cwd;
*fastgetcwd=\&_dos_cwd;
*fastcwd=\&_dos_cwd;
*abs_path=\&fast_abs_path;}elsif($^O eq 'qnx'){*cwd=\&_qnx_cwd;
*getcwd=\&_qnx_cwd;
*fastgetcwd=\&_qnx_cwd;
*fastcwd=\&_qnx_cwd;
*abs_path=\&_qnx_abs_path;
*fast_abs_path=\&_qnx_abs_path;}}1;
__END__
BEGIN { import Cwd qw(:DEFAULT chdir); }
print join("\n", cwd, getcwd, fastcwd, "");
chdir('..');
print join("\n", cwd, getcwd, fastcwd, "");
print "$ENV{PWD}\n";
