?MAKE:usensgetexecutablepath: cat rm_try Compile run Setvar ?MAKE: -pick add $@ %< ?S:usensgetexecutablepath: ?S: This symbol, if defined, indicates that we can use _NSGetExecutablePath ?S: and realpath to get a full path for the executable, and hence convert ?S: $^X to an absolute path. ?S:. ?C:USE_NSGETEXECUTABLEPATH: ?C: This symbol, if defined, indicates that we can use _NSGetExecutablePath ?C: and realpath to get a full path for the executable, and hence convert ?C: $^X to an absolute path. ?C:. ?H:#$usensgetexecutablepath USE_NSGETEXECUTABLEPATH /**/ ?H:. ?LINT:set usensgetexecutablepath ?F:!try : 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 #include #include #include #include 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 = (char *)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; 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