in reply to Absolute pathnames from relative?
Symbolic links are very odd, and support for conveniently resolving symbolic links is limited.
On a WIN32 based operating system, symbolic links don't really exist, and so, code such as the following will suffice:
use File::Spec; use Win32; my $absolute_path = Win32::GetFullPathName(File::Spec->join("C:\\Perl\ +\bin", "..\\lib\\File\\Spec.pm"));
On UNIX-based operating systems, things get a little strange. The Cwd module itself provides a method of determining the absolute path for a directory.
use File::Spec; use Cwd; my $absolute_path = Cwd::abs_path(File::Spec->join("/usr/bin", "../lib +"));
Cwd in Perl 5.8.0 includes an XS portion that uses advanced code that is able to correctly determine the absolute path for a file as well. (The Perl version of the code, that is used if the XS portion cannot be loaded, still has the directory-only limitation)
The Cwd module uses a frequently used 'trick' that involves recursing backwards from the specified directory through '..' looking for a device/inode match between '..' and the names in '..'. The problem with files is that "/usr/lib/../bin/perl/.." is not a valid accessible path. The normal 'hack' to get around this is to break "/usr/lib/../bin/perl" into "/usr/lib/../bin" and "perl", resolve the "/usr/lib/../bin" to "/usr/bin", and tag "perl" onto the end resulting in "/usr/bin/perl".
The problem with this approach, is that it does not consider the possibility that "/usr/bin/perl" might itself be a symlink to "/opt/perl5.8.0/bin/perl". The solution to this is usually to do readlink() on the file, and if an absolute path is returned, use it, or else if it is a relative path, substitute the last component ("perl") with it, and recurse, performing the entire process over again on the new path.
One could argue that Cwd::abs_path() should use the Win32::GetFullPathName() subroutine on WIN32. Maybe it does in the latest ActiveState Perl Build. I only have build 633 installed (Perl 5.6.1). Perhaps somebody else could verify whether Cwd::abs_path() works correctly on files in build 640?
Good luck,
|
|---|