?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 <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 = (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

