develooper Front page | perl.perl5.porters | Postings from May 2001

Re: Relocatable perl

Thread Previous | Thread Next
Steve Fink
May 3, 2001 10:44
Re: Relocatable perl
Message ID:
Jarkko Hietaniemi wrote:

> On Thu, May 03, 2001 at 05:35:46PM +0100, Alan Burlison wrote:
>> Graham Barr wrote:
>>>> That's fine, however it is a different mechanism to that used on Solaris
>>>> (and VMS, and Win32...)  Rather than perpetuating a series of
>>>> platform-spefific hacks it would be preferable to have a generic
>>>> get_exe_path() function and then to do all the other path fixups in a
>>> Do we not have that already ? How is $^X set
>> No, that's just set from argv[0] AFAIK.  We need the full path of the
>> executable, even when accessed via a symlink.
> Last time I looked at this (which is admittedly years ago) I found this
> to be one those small things Ritchie et al didn't think of -- and which
> has therefore grown to be a sadly unportable mess.  Chasing $ENV{PATH},
> never mind how fragile and unreliable that is, is about the only portable
> way one can hope to get any reasonable results with.  Various platforms
> may have their own special system calls or other tricks, but then we are
> in the middle of a #ifdef forest.

In my own code, I check at runtime for the existence of /proc/self/exe 
and fall back to $ENV{PATH} chasing and other gunk. The whole thing 
looks like:

1. if /proc/self/exe exists, use it and return;
2. if argv[0] starts with /, use it and return;
3. if argv[0] contains any /'s then getcwd and glue them together
4. else chase getenv(PATH).

Step #1 fails if the proc fs isn't mounted on /proc or doesn't support
the exe symlink (true everywhere but linux?). Step #1 deceives only if
something else happens to be living at /proc/self/exe.

Step #2 never fails, and deceives only if someone has messed with 
argv[0]. Which is not uncommon and apparently already confuses perl:

% perl -e 'exec {"/bin/ls"} ("/usr/bin/perl", "-le", "print \$^X")'

Try `/usr/bin/perl --help' for more information.
% perl -e 'exec {"/usr/bin/perl"} ("/usr/bin/perl", "-le", "print \$^X")'l

% perl -e 'exec {"glub"} ("/usr/bin/perl", "-le", "print \$^X")'
(no output)
% perl -e 'exec {"perl"} ("/usr/bin/perl", "-le", "print \$^X")'

Step #3 fails or deceives if the cwd has changed before $^X is computed, 
or if argv[0] has been mucked with.

Step #4 fails or deceives if PATH has changed before $^X is computed, or 
if argv[0] has been mucked with. (Or if the invoker isn't a shell and 
uses something besides PATH to find binaries...)

The cwd and PATH changes aren't usually much of a problem, because perl 
can do this as soon as it starts up. Unless it's running embedded.

I would argue for runtime checks whenever possible instead of #ifdefs, 
because the whole point of this is relocatability, so it should handle 
being moved between different runtime environments as much as possible. 
(eg compiled on a workstation with /proc and moved to a cell phone 
running the same OS but without the proc fs.)

But there is no 100% solution, so it'll always have to be "relocatable 
from as many and to as many environments as possible."

Seems like there ought to be a GPLd portable FMOA (Find My Own Ass) 
library out there somewhere...

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About