Open p5pRT opened 13 years ago
If I compile perl 5.14.0 with -Duserelocatableinc\, and then relocate it afterward and add that to the PATH\, "perl -V" doesn't find Config.pm and thus dies.
$ perl -v
This is perl 5\, version 14\, subversion 0 (v5.14.0) built for aix-thread-multi-64all
Copyright 1987-2011\, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the GNU General Public License\, which may be found in the Perl 5 source kit.
Complete documentation for Perl\, including FAQ lists\, should be found on this system using "man perl" or "perldoc perl". If you have access to the Internet\, point your browser at http://www.perl.org/\, the Perl Home Page.
$ perl -V Can't locate Config.pm in @INC (@INC contains: ../lib/site_perl/5.14.0/aix-thread-multi-64all ../lib/site_perl/5.14.0 ../lib/5.14.0/aix-thread-multi-64all ../lib/5.14.0 .).
When I try this on Linux\, it works. I suspect it has something to do with:
$ perl -le 'print $^X' perl
whereas if I do the same thing on Linux\, I get a full path to perl in the relocated directory (not where it was compiled to install to). If I call the perl on AIX with a full or relative path\, it works fine.
Note that if I run perlbug\, whether on AIX or Linux\, it fails. The #! line combined with the eval 'exec ...' simply fail to find the perl it's associated with\, e.g.\, on Linux:
$ perlbug bash: /home/dmcbride/perl/tmp/foo/usr/opt/perl/bin/perlbug: /usr/opt/perl/bin/perl: bad interpreter: No such file or directory
On Mon\, 20 Jun 2011\, via RT wrote:
If I compile perl 5.14.0 with -Duserelocatableinc\, and then relocate it afterward and add that to the PATH\, "perl -V" doesn't find Config.pm and thus dies.
[...]
When I try this on Linux\, it works. I suspect it has something to do with:
$ perl -le 'print $^X' perl
whereas if I do the same thing on Linux\, I get a full path to perl in the relocated directory (not where it was compiled to install to). If I call the perl on AIX with a full or relative path\, it works fine.
That is indeed the problem: -Duserelocatableinc really only works on Linux where $^X is set from /proc/self/exe. On other systems it just relies on the value of argv[0]\, which is typically not fully qualified.
I know how to make things work on OS X and Solaris as well\, but for AIX and HP-UX I don't know of any secure/reliable mechanism to determine the full path of the currently running executable.
On Windows this is not an issue as there @INC is always determined at runtime relative to the location of the perl5xx.dll file.
Cheers\, -Jan
The RT System itself - Status changed from 'new' to 'open'
You mention that you don't know how on HPUX (which I don't care about right now)\, but searching for the AIX solution popped this up - the "pstat" answer looks most promising. I'm still searching for AIX.
http://stackoverflow.com/questions/200737/get-full-path-of- executable-of-running-process-on-hpux
On Mon\, Jun 20\, 2011 at 04:59:33PM -0700\, Jan Dubois wrote:
On Mon\, 20 Jun 2011\, via RT wrote:
If I compile perl 5.14.0 with -Duserelocatableinc\, and then relocate it afterward and add that to the PATH\, "perl -V" doesn't find Config.pm and thus dies.
[...]
When I try this on Linux\, it works. I suspect it has something to do with:
$ perl -le 'print $^X' perl
whereas if I do the same thing on Linux\, I get a full path to perl in the relocated directory (not where it was compiled to install to). If I call the perl on AIX with a full or relative path\, it works fine.
That is indeed the problem: -Duserelocatableinc really only works on Linux where $^X is set from /proc/self/exe. On other systems it just relies on the value of argv[0]\, which is typically not fully qualified.
I know how to make things work on OS X and Solaris as well\, but for AIX and HP-UX I don't know of any secure/reliable mechanism to determine the full path of the currently running executable.
With commit 6f31bef90fda3b9a I've merged code to make $^X absolute on OS X\, Solaris 10 and 11\, and FreeBSD without needing /proc mounted.
It would be possible to use getexecname() along with realpath() on earlier Solaris\, but I'm not sure if it's worth adding.
perl already uses /proc on Linux and NetBSD to convert $^X to an absolute path.
Like Jan\, I'm not aware of a reliable way to do this on any other platform. Likely it's not possible.
Nicholas Clark
On Wed\, Sep 28\, 2011 at 5:43 AM\, Nicholas Clark \nick@​ccl4\.org wrote:
Like Jan\, I'm not aware of a reliable way to do this on any other platform. Likely it's not possible.
The following code snippet (found via stackoverflow)\, appears to work as advertised on HP-UX 11.23 and 11.31:
#include \<stdio.h> #include \<stdlib.h> #include \<limits.h> #include \<unistd.h>
#define _PSTAT64 #include \<sys/pstat.h>
int main(int argc\, char *argv[]) { char filename[PATH_MAX]; struct pst_status s;
if (pstat_getproc(&s\,sizeof(s)\,0\,getpid()) == -1) { perror("pstat_getproc"); return EXIT_FAILURE; }
if (pstat_getpathname(filename\,sizeof(filename)\,&s.pst_fid_text) == -1) { perror("pstat_getpathname"); return EXIT_FAILURE; }
printf("filename: %s\n"\,filename);
return EXIT_SUCCESS; }
--Phil
On Wed\, Sep 28\, 2011 at 12:13:49PM -0500\, Philip Monsen wrote:
On Wed\, Sep 28\, 2011 at 5:43 AM\, Nicholas Clark \nick@​ccl4\.org wrote:
Like Jan\, I'm not aware of a reliable way to do this on any other platform. Likely it's not possible.
Good. Proven wrong on another platform. Are the rest "impossible" too? :-)
The following code snippet (found via stackoverflow)\, appears to work as advertised on HP-UX 11.23 and 11.31:
#include \<stdio.h> #include \<stdlib.h> #include \<limits.h> #include \<unistd.h>
#define _PSTAT64 #include \<sys/pstat.h>
int main(int argc\, char *argv[]) { char filename[PATH_MAX]; struct pst_status s;
if (pstat_getproc(&s\,sizeof(s)\,0\,getpid()) == -1) { perror("pstat_getproc"); return EXIT_FAILURE; }
I don't have access to any HP-UX system\, so can't write code to test any of this. I think that the right approach would be a Configure probe\, perl.c change analogous to those for sysctl() and _NSGetExecutablePath()
http://perl5.git.perl.org/perl.git/commit/2982a345b7a1edb6 http://perl5.git.perl.org/perl.git/commit/ae60cb464cebf895
[the second patch was based on the first]
From searching online I find this piece of documentation:
On success\, the function returns the length of the pathname copied starting at the location specified by buf. If the pathname is not available in the system cache\, 0 is returned and errno is not set. On other failures\, the value of -1 is returned and errno is set indicating the cause of the failure. This call does not work for sockets.
if (pstat_getpathname(filename\,sizeof(filename)\,&s.pst_fid_text) == -1) { perror("pstat_getpathname"); return EXIT_FAILURE; }
printf("filename: %s\n"\,filename);
return EXIT_SUCCESS; }
Which the sample code would fall foul of. I'm wondering what other gotchas are involved. The code you quote allowed me to find a link to this: http://h21007.www2.hp.com/portal/site/dspp/menuitem.863c3e4cbcdc3f3515b49c108973a801?ciid=88086d6e1de021106d6e1de02110275d6e10RCRD
which has this:
Alternate program for 64-bit
#include \<dlfcn.h> #include \<unistd.h> #include \<stdlib.h> #include \<stdio.h> int main(int argc\, char *argv[]) { struct load_module_desc desc; char *name; dlget(-2\, &desc\, sizeof(desc)); name = dlgetname(&desc\, sizeof(desc)\, NULL\, NULL\, NULL); printf("executable is '%s' (from dlgetname).\n"\, name); return 0; }
I have *no* idea of the relative merits of the two approaches when both are available. The latter looks less complex\, and less prone to failure\, but I've no idea what downsides it has.
Nicholas Clark
On Wed\, Sep 28\, 2011 at 1:21 PM\, Nicholas Clark \nick@​ccl4\.org wrote:
I have *no* idea of the relative merits of the two approaches when both are available. The latter looks less complex\, and less prone to failure\, but I've no idea what downsides it has.
Unfortunately\, the main downside is that it doesn't actually appear to provide a full path:
# On both 11.23 and 11.31 $ ./my_dlget executable is './my_dlget' (from dlgetname).
I'm wondering if some guarantee is afforded for a process's executable name to be in the directory name lookup cache (DNLC) if its process information is queried immediately prior via pstat_getproc()\, as in the first code snippet. If there were\, then there'd be more assurance that pstat_getpathname() would return reliable information. The pstat docs don't say so (at least it doesn't jump right out)\, but since the DNLC is dumpable (per filesystem) via pstat_getmpathname()\, maybe it's possible to make some judgments based on empirical observation.
--Phil
On Wed\, Sep 28\, 2011 at 2:07 PM\, Philip Monsen \philip\.monsen@​gmail\.comwrote:
I'm wondering if some guarantee is afforded for a process's executable name to be in the directory name lookup cache (DNLC) if its process information is queried immediately prior via pstat_getproc()\, as in the first code snippet. If there were\, then there'd be more assurance that pstat_getpathname() would return reliable information. The pstat docs don't say so (at least it doesn't jump right out)\, but since the DNLC is dumpable (per filesystem) via pstat_getmpathname()\, maybe it's possible to make some judgments based on empirical observation.
Doing this empirical test is pretty much a non-starter for me given the restriction to use of pstat_getmpathname() from the manpage\, and my local lack of the required credentials:
The use of this function is limited to UID 0.
--Phil
Hello\, OK\, you are looking for something like this on AIX\, but in C without the use of system tools:
#!/usr/bin/perl
@proc = split/ /\,`procfiles $$|head -n 1`; if (-l $proc[2]) { print `readlink $proc[2]`; } else { print "$proc[2]\n"; }
exit 0;
# ./test.pl /usr/opt/perl5/bin/perl5.8.2
Bye Rainer
This issue is there in perl 5.22.0 in AIX and HPIA. Please let me know if there is a work around
This issue is there in perl 5.22.0 in AIX and HPIA. Please let me know if there is a work around
For HP-UX below approach is working. Can some one please validate.
Added the following code in perl_source/caretx.c
# elif defined(__hpux) #include \<dlfcn.h> struct load_module_desc desc; char *name; dlget(-2\, &desc\, sizeof(desc)); name = dlgetname(&desc\, sizeof(desc)\, NULL\, NULL\, NULL); sv_setpv(caret_x\, name); return;
For HP-UX below approach is working. Can some one please validate.
Added the following code in perl_source/caretx.c
# elif defined(__hpux) #include \<dlfcn.h> struct load_module_desc desc; char *name; dlget(-2\, &desc\, sizeof(desc)); name = dlgetname(&desc\, sizeof(desc)\, NULL\, NULL\, NULL); sv_setpv(caret_x\, name); return;
Migrated from rt.perl.org#93134 (status was 'open')
Searchable as RT93134$