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,


In reply to Re: Absolute pathnames from relative? by MarkM
in thread Absolute pathnames from relative? by grantm

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.