diff options
author | Nicholas Clark <nick@ccl4.org> | 2011-09-21 15:33:09 +0100 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2011-09-27 22:25:05 +0200 |
commit | ae60cb464cebf89579ec0ff91db8b792b2f1e7cd (patch) | |
tree | fc1ab2f4a1d4d5360ffaf2df304bfe7c03f8c76c /Configure | |
parent | 2982a345b7a1edb63720282eef0fba5c61d0e6b5 (diff) | |
download | perl-ae60cb464cebf89579ec0ff91db8b792b2f1e7cd.tar.gz |
Where available, use _NSGetExecutablePath() to make $^X absolute.
In Configure, check whether _NSGetExecutablePath() can be used to find the
absolute pathname of the executable. If so, set usensgetexecutablepath in
config.sh and USE_NSGETEXECUTABLEPATH 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 OS X, and possible on other platforms that
use dyld.
Diffstat (limited to 'Configure')
-rwxr-xr-x | Configure | 102 |
1 files changed, 102 insertions, 0 deletions
@@ -1229,6 +1229,7 @@ nm_opt='' nm_so_opt='' runnm='' usenm='' +usensgetexecutablepath='' useperlio='' usesocks='' d_oldpthreads='' @@ -19462,6 +19463,106 @@ $rm_try set usekernprocpathname eval $setvar +: Determine if we can use _NSGetExecutablePath to find executing program +echo " " +echo "Determining whether we can use _NSGetExecutablePath 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 <mach-o/dyld.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/param.h> +#include <string.h> + +int +main(int argc, char **argv) { + char buf[1]; + uint32_t size = sizeof(buf); + int result; + char *buffer; + char *tidied; + char *argv_leaf = strrchr(argv[0], '/'); + char *tidied_leaf; + + if (!argv_leaf) { + fprintf(stderr, "Can't locate / in '%s'\n", argv[0]); + return 1; + } + + _NSGetExecutablePath(buf, &size); + if (size > MAXPATHLEN * MAXPATHLEN) { + fprintf(stderr, "_NSGetExecutablePath size %u is too long for a path\n", + (unsigned int) size); + return 2; + } + + buffer = malloc(size); + if (!buffer) { + perror("malloc"); + return 3; + } + + result = _NSGetExecutablePath(buffer, &size); + if (result != 0) { + fprintf(stderr, "_NSGetExecutablePath returned %i for a size of %u\n", + result, (unsigned int) size); + return 4; + } + + tidied = realpath(buffer, NULL); + if (!tidied) { + perror("realpath"); + return 5; + } + + free(buffer); + + if (*tidied != '/') { + fprintf(stderr, "Not an absolute path: '%s'\n", tidied); + return 6; + } + + if (strstr(tidied, "/./")) { + fprintf(stderr, "Contains /./: '%s'\n", tidied); + return 7; + } + + if (strstr(tidied, "/../")) { + fprintf(stderr, "Contains /../: '%s'\n", tidied); + return 8; + } + + tidied_leaf = strrchr(tidied, '/'); + if (strcmp(tidied_leaf, argv_leaf) != 0) { + fprintf(stderr, "Leafnames differ: '%s' vs '%s'\n", argv[0], tidied); + return 9; + } + + free(tidied); + + return 0; +} +EOM + +val=$undef +set try +if eval $compile_ok; then + if $run ./try; then + echo "You can use _NSGetExecutablePath to find the executing program." >&4 + val="$define" + else + echo "Nope, _NSGetExecutablePath doesn't work here." >&4 + fi +else + echo "I'm unable to compile the test program." >&4 + echo "I'll assume no _NSGetExecutablePath here." >&4 +fi +$rm_try +set usensgetexecutablepath +eval $setvar + : Check how to flush echo " " $cat >&4 <<EOM @@ -23558,6 +23659,7 @@ usemorebits='$usemorebits' usemultiplicity='$usemultiplicity' usemymalloc='$usemymalloc' usenm='$usenm' +usensgetexecutablepath='$usensgetexecutablepath' useopcode='$useopcode' useperlio='$useperlio' useposix='$useposix' |