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).
| [reply] [d/l] [select] |
|
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
}
}
| [reply] [d/l] |
|
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.
| [reply] |
|
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_execname(aTHX) (yes, Win32 is consider OS/2-ish).
| [reply] [d/l] [select] |
|
|
|
Re: Poll: Is your $^X an absolute path?
by Fletch (Bishop) on Aug 17, 2006 at 13:51 UTC
|
$ 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) . . .
| [reply] [d/l] |
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
| [reply] [d/l] |
|
Sad but true; there was a discussion on how to fix this for Solaris, but no changes actually made it in yet.
| [reply] |
Re: Poll: Is your $^X an absolute path?
by Hue-Bond (Priest) on Aug 17, 2006 at 14:46 UTC
|
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.
| [reply] [d/l] |
Re: Poll: Is your $^X an absolute path?
by Joost (Canon) on Aug 17, 2006 at 15:58 UTC
|
| [reply] [d/l] |
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. | [reply] |
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
| [reply] [d/l] |
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
| [reply] |