Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Poll: Is your $^X an absolute path?

by xdg (Monsignor)
on Aug 17, 2006 at 13:43 UTC ( [id://567921]=perlmeditation: print w/replies, xml ) Need Help??

Perl 5.9.4 and (hopefuly soon) 5.8.9 will support "relocatable perl" -- meaning that paths to @INC can be set at compile time to be relative to the perl binary instead of hard-coded. The key to making this work reliably appears to be having $^X be an absolute path to the perl binary, which may or may not be true on all platforms and in all situations.

This is an important feature for Vanilla Perl and possibly for others as well, so I'm looking for a quick poll of monks: Is your $^X an absolute path?

It seems to be for me on both linux and win32 -- but I'm looking for results on unusual/old systems (particularly older win32 operating systems) or perls running in some embedded or unusual fashion (e.g. mod_perl, win32 services, etc.).

A tip of the hat, fame and fortune, or at least a ++ vote awaits anyone that can find a situation where $^X isn't absolute.

-xdg

Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Replies are listed 'Best First'.
Re: Poll: Is your $^X an absolute path? (argv[0])
by tye (Sage) on Aug 17, 2006 at 14:04 UTC

    Win32 Perl has always had GetModulePathName() which means that Perl on Win32 will always have an absolute path for $^X. I think that Linux now has similar functionality.

    However, other Unix platforms don't have a reliable way for an executable to figure out its filename. A Unix executable just gets argv[0] which can have absolutely nothing to do with the name of the executable. argv[0] will often be a path string that an algorithm like that used (perversely) by FindBin could be used to find the executable path.

    If you want to know what happens on those platforms, I'd look at Perl's source code rather than try to conduct a poll.

    Update: Here is the best way to prevent Perl from setting $^X to a real path:

    system $^X "notPerl", '-le', 'print $^X'
    which will produce "notPerl" on most non-Linux Unix platforms (and probably even on Linux for not-the-latest releases of Perl) but will produce the full path to your Perl executable on Win32 (even Win95).

    - tye        

      If you want to know what happens on those platforms, I'd look at Perl's source code rather than try to conduct a poll.
      PROCSELFEXE_PATH is /proc/self/exe (Linux) or /proc/curproc/file (BSDish)
      #ifdef HAS_PROCSELFEXE /* This is a function so that we don't hold on to MAXPATHLEN bytes of stack longer than necessary */ STATIC void S_procself_val(pTHX_ SV *sv, const char *arg0) { char buf[MAXPATHLEN]; int len = readlink(PROCSELFEXE_PATH, buf, sizeof(buf) - 1); /* On Playstation2 Linux V1.0 (kernel 2.2.1) readlink(/proc/self/e +xe) includes a spurious NUL which will cause $^X to fail in system or backticks (this will prevent extensions from being built and many tests from working). readlink is not meant to add a NUL. Normal readlink works fine. */ if (len > 0 && buf[len-1] == '\0') { len--; } /* FreeBSD's implementation is acknowledged to be imperfect, somet +imes returning the text "unknown" from the readlink rather than the +path to the executable (or returning an error from the readlink). A +ny valid path has a '/' in it somewhere, so use that to validate the res +ult. See http://www.freebsd.org/cgi/query-pr.cgi?pr=35703 */ if (len > 0 && memchr(buf, '/', len)) { sv_setpvn(sv,buf,len); } else { sv_setpv(sv,arg0); } } #endif /* HAS_PROCSELFEXE */ STATIC void S_set_caret_X(pTHX) { dVAR; GV* tmpgv = gv_fetchpvs("\030", GV_ADD|GV_NOTQUAL, SVt_PV); /* $^X + */ if (tmpgv) { #ifdef HAS_PROCSELFEXE S_procself_val(aTHX_ GvSV(tmpgv), PL_origargv[0]); #else #ifdef OS2 sv_setpv(GvSVn(tmpgv), os2_execname(aTHX)); #else sv_setpv(GvSVn(tmpgv),PL_origargv[0]); #endif #endif } }
      Win32 Perl has always had GetModulePathName()

      At least my cursory grep didn't find that function in the perl source -- but perhaps it's called via some libraries or alias. It looks like it's just getting the name from whatever the compiler sets up as argv[0].

      Based on 'case 3' in this article, I thought it might be possible to spoof the executable name with a bogus argv[0] via CreateProcess, but my experiments with Win32::Process and Win32::Job weren't successful at getting anything other than the absolute path. I didn't try with Win32::API directly as that doesn't (yet) compile for Vanilla Perl.

      -xdg

      Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

        Win32 Perl has always had GetModulePathName()
        At least my cursory grep didn't find that function in the perl source

        Sorry, my transcription error (s/Path/File/):

        perllib.c:171: GetModuleFileName(NULL, szModuleName, sizeof(szModul +eName)); win32.c:135: GetModuleFileName((HMODULE)((w32_perldll_handle == INV +ALID_HANDLE_VALUE) win32.c:136: ? GetModuleHandle(NULL)
        It looks like it's just getting the name from whatever the compiler sets up as argv[0].

        No, Win32 Perl has never figured out $^X based on argv[0] (except before it was released). The function called is os2_execna­me(aTHX) (yes, Win32 is consider OS/2-ish).

        - tye        

Re: Poll: Is your $^X an absolute path?
by Fletch (Bishop) on Aug 17, 2006 at 13:51 UTC

    OS X seems to depend on how it's called.

    $ perl -le 'print $^X' perl $ /usr/bin/perl -le 'print $^X' /usr/bin/perl $ perl -v This is perl, v5.8.6 built for darwin-thread-multi-2level ...

    Update: Unless of course you meant you need this specifically from people running 5.9.4 (which wasn't clear) . . .

Re: Poll: Is your $^X an absolute path?
by derby (Abbot) on Aug 17, 2006 at 13:52 UTC

    Unfortunately not on my solaris box (Solaris 8). There $^X is either relative or absolute depending upon how perl is called.

    > perl -e 'print "$^X\n"' perl > /usr/local/bin/perl -e 'print "$^X\n"' /usr/local/bin/perl > ../../../usr/local/bin/perl -e 'print "$^X\n"' ../../../usr/local/bin/perl

    -derby
      Sad but true; there was a discussion on how to fix this for Solaris, but no changes actually made it in yet.
Re: Poll: Is your $^X an absolute path?
by Hue-Bond (Priest) on Aug 17, 2006 at 14:46 UTC

    I tested four cases:

    perl -le 'print $^X' /usr/bin/perl -le 'print $^X' /usr/bin/../bin/perl -le 'print $^X' ./prrl -le 'print $^X' ## symbolic link

    The path returned by the program was absolute in all cases on:

    • Debian GNU/Linux 3.1r0, perl 5.8.4
    • Red Hat Enterprise Linux ES release 4, perl 5.8.5
    • SuSE Linux Enterprise Server 10.0, perl 5.8.8
    • Windows XP Professional SP2, perl 5.8.8 ActiveState build 817 (symlink not tested)

    In these systems, the program simply returned the same path used for invoking perl:

    • FreeBSD 5.4, perl 5.8.8
    • FreeBSD 6.0, perl 5.8.8
    • HP-UX 11i 11.11, perl 5.005_02
    • HP-UX 11i v2, perl 5.8.3 ActiveState build 809

    Not yet tested for various reasons:

    • NetBSD 3.0
    • HP Tru64 Unix 5.1b

    Update: Added fourth test. Added SuSE Linux.

    --
    David Serrano

Re: Poll: Is your $^X an absolute path?
by Joost (Canon) on Aug 17, 2006 at 15:58 UTC
Re: Poll: Is your $^X an absolute path?
by bluto (Curate) on Aug 17, 2006 at 15:08 UTC
    Perl 5.8.8 on AIX 5.2 just returns whatever path was used to invoke perl.
Re: Poll: Is your $^X an absolute path?
by zentara (Archbishop) on Aug 17, 2006 at 15:44 UTC
    I did a test similar to Hue-Bond's
    perl -le 'print $^X' /usr/bin/perl -le 'print $^X' /usr/bin/../bin/perl -le 'print $^X' env perl -le 'print $^X'
    and all came back absolute, on a roll-your-own system based on Slackware 10.1

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
Re: Poll: Is your $^X an absolute path?
by idsfa (Vicar) on Aug 17, 2006 at 16:26 UTC

    See Re: Using File::Find to find drive (Win32) for some earlier answers to this question ...


    The intelligent reader will judge for himself. Without examining the facts fully and fairly, there is no way of knowing whether vox populi is really vox dei, or merely vox asinorum. — Cyrus H. Gordon

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://567921]
Approved by Hue-Bond
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (6)
As of 2024-04-18 13:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found