summaryrefslogtreecommitdiff
path: root/perl.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2011-09-21 14:32:58 +0200
committerNicholas Clark <nick@ccl4.org>2011-09-27 22:23:10 +0200
commit2982a345b7a1edb63720282eef0fba5c61d0e6b5 (patch)
tree8fffd4f1ff976c438b5e9028adba2364cca3b07d /perl.c
parent2480ae1c1b2fa11085b45f96de55cb16c3bcc343 (diff)
downloadperl-2982a345b7a1edb63720282eef0fba5c61d0e6b5.tar.gz
Where available, use sysctl() with KERN_PROC_PATHNAME to make $^X absolute.
In Configure, check whether sysctl() and KERN_PROC_PATHNAME can be used to find the absolute pathname of the executable. If so, set usekernprocpathname in config.sh and USE_KERN_PROC_PATHNAME in config.h. If this is set, then use this approach in S_set_caret_X() to canonicalise $^X as an absolute path. This approach works on (at least) FreeBSD, and doesn't rely on the /proc filesystem existing, or /proc/curproc/file being present.
Diffstat (limited to 'perl.c')
-rw-r--r--perl.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/perl.c b/perl.c
index 0b3d9c6723..5d2159d089 100644
--- a/perl.c
+++ b/perl.c
@@ -38,6 +38,10 @@
#include "nwutil.h"
#endif
+#ifdef USE_KERN_PROC_PATHNAME
+# include <sys/sysctl.h>
+#endif
+
#ifdef DEBUG_LEAKING_SCALARS_FORK_DUMP
# ifdef I_SYSUIO
# include <sys/uio.h>
@@ -1390,7 +1394,27 @@ S_set_caret_X(pTHX) {
#if defined(OS2)
sv_setpv(caret_x, os2_execname(aTHX));
#else
-# ifdef HAS_PROCSELFEXE
+# ifdef USE_KERN_PROC_PATHNAME
+ size_t size = 0;
+ int mib[4];
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_PATHNAME;
+ mib[3] = -1;
+
+ if (sysctl(mib, 4, NULL, &size, NULL, 0) == 0
+ && size > 0 && size < MAXPATHLEN * MAXPATHLEN) {
+ sv_grow(caret_x, size);
+
+ if (sysctl(mib, 4, SvPVX(caret_x), &size, NULL, 0) == 0
+ && size > 2) {
+ SvPOK_only(caret_x);
+ SvCUR_set(caret_x, size - 1);
+ SvTAINT(caret_x);
+ return;
+ }
+ }
+# elif defined(HAS_PROCSELFEXE)
char buf[MAXPATHLEN];
int len = readlink(PROCSELFEXE_PATH, buf, sizeof(buf) - 1);