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