Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Re: Absolute pathnames from relative?

by MarkM (Curate)
on Jan 22, 2003 at 19:35 UTC ( [id://229113]=note: print w/replies, xml ) Need Help??


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,

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://229113]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (4)
As of 2024-04-18 22:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found