diff options
author | Nicholas Clark <nick@ccl4.org> | 2011-09-21 14:32:58 +0200 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2011-09-27 22:23:10 +0200 |
commit | 2982a345b7a1edb63720282eef0fba5c61d0e6b5 (patch) | |
tree | 8fffd4f1ff976c438b5e9028adba2364cca3b07d /Configure | |
parent | 2480ae1c1b2fa11085b45f96de55cb16c3bcc343 (diff) | |
download | perl-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 'Configure')
-rwxr-xr-x | Configure | 117 |
1 files changed, 117 insertions, 0 deletions
@@ -1234,6 +1234,7 @@ usesocks='' d_oldpthreads='' use5005threads='' useithreads='' +usekernprocpathname='' usereentrant='' usethreads='' incpath='' @@ -19346,6 +19347,121 @@ $rm_try set ebcdic eval $setvar +: Determine if we can use sysctl with KERN_PROC_PATHNAME to find executing program +echo " " +echo "Determining whether we can use sysctl with KERN_PROC_PATHNAME to find executing program..." >&4 +$cat >try.c <<'EOM' +/* Intentionally a long probe as I'd like to sanity check that the exact + approach is going to work, as thinking it will work, but only having it + part working at runtime is worse than not having it. */ + +#include <sys/types.h> +#include <sys/sysctl.h> +#include <sys/param.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> + +int +main(int argc, char **argv) { + char *buffer; + char *argv_leaf = strrchr(argv[0], '/'); + char *buffer_leaf; + size_t size = 0; + int mib[4]; + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PATHNAME; + mib[3] = -1; + + if (!argv_leaf) { + fprintf(stderr, "Can't locate / in '%s'\n", argv[0]); + return 1; + } + + if (sysctl(mib, 4, NULL, &size, NULL, 0)) { + perror("sysctl"); + return 2; + } + + if (size < strlen(argv_leaf) + 1) { + fprintf(stderr, "size %lu is too short for a path\n", + (unsigned long) size); + return 3; + } + + if (size > MAXPATHLEN * MAXPATHLEN) { + fprintf(stderr, "size %lu is too long for a path\n", + (unsigned long) size); + return 4; + } + + buffer = malloc(size); + if (!buffer) { + perror("malloc"); + return 5; + } + + if (sysctl(mib, 4, buffer, &size, NULL, 0)) { + perror("sysctl"); + return 6; + } + + if (strlen(buffer) + 1 != size) { + fprintf(stderr, "size != strlen(buffer) + 1 (%lu != %lu)\n", + (unsigned long)size, (unsigned long)strlen(buffer) + 1); + return 7; + } + + + if (*buffer != '/') { + fprintf(stderr, "Not an absolute path: '%s'\n", buffer); + return 8; + } + + if (strstr(buffer, "/./")) { + fprintf(stderr, "Contains /./: '%s'\n", buffer); + return 9; + } + + if (strstr(buffer, "/../")) { + fprintf(stderr, "Contains /../: '%s'\n", buffer); + return 10; + } + + buffer_leaf = strrchr(buffer, '/'); + if (strcmp(buffer_leaf, argv_leaf) != 0) { + fprintf(stderr, "Leafnames differ: '%s' vs '%s'\n", argv[0], buffer); + return 11; + } + + free(buffer); + + return 0; +} +EOM + +val=$undef +set try +if eval $compile_ok; then + if $run ./try; then + echo "You can use sysctl with KERN_PROC_PATHNAME to find the executing program." >&4 + val="$define" + else + echo "Nope, sysctl with KERN_PROC_PATHNAME doesn't work here." >&4 + val="$undef" + fi +else + echo "I'm unable to compile the test program." >&4 + echo "I'll assume no sysctl with KERN_PROC_PATHNAME here." >&4 + val="$undef" +fi +$rm_try +set usekernprocpathname +eval $setvar + : Check how to flush echo " " $cat >&4 <<EOM @@ -23434,6 +23550,7 @@ usedl='$usedl' usedtrace='$usedtrace' usefaststdio='$usefaststdio' useithreads='$useithreads' +usekernprocpathname='$usekernprocpathname' uselargefiles='$uselargefiles' uselongdouble='$uselongdouble' usemallocwrap='$usemallocwrap' |