This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
2b2988251dbad7ebe59bb45efe61fb6595e2fefa
[metaconfig.git] / U / perl / usekernprocpathname.U
1 ?MAKE:usekernprocpathname: cat rm_try Compile run Setvar
2 ?MAKE:  -pick add $@ %<
3 ?S:usekernprocpathname:
4 ?S:     This variable, indicates that we can use sysctl with
5 ?S:     KERN_PROC_PATHNAME to get a full path for the executable, and hence
6 ?S:     convert $^X to an absolute path.
7 ?S:.
8 ?C:USE_KERN_PROC_PATHNAME:
9 ?C:     This symbol, if defined, indicates that we can use sysctl with
10 ?C:     KERN_PROC_PATHNAME to get a full path for the executable, and hence
11 ?C:     convert $^X to an absolute path.
12 ?C:.
13 ?H:#$usekernprocpathname USE_KERN_PROC_PATHNAME /**/
14 ?H:.
15 ?LINT:set usekernprocpathname
16 ?F:!try
17 : Determine if we can use sysctl with KERN_PROC_PATHNAME to find executing program
18 echo " "
19 echo "Determining whether we can use sysctl with KERN_PROC_PATHNAME to find executing program..." >&4
20 $cat >try.c <<'EOM'
21 /* Intentionally a long probe as I'd like to sanity check that the exact
22    approach is going to work, as thinking it will work, but only having it
23    part working at runtime is worse than not having it.  */
24
25 #include <sys/types.h>
26 #include <sys/sysctl.h>
27 #include <sys/param.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32
33 int
34 main(int argc, char **argv) {
35     char *buffer;
36     char *argv_leaf = strrchr(argv[0], '/');
37     char *buffer_leaf;
38     size_t size = 0;
39     int mib[4];
40
41     mib[0] = CTL_KERN;
42     mib[1] = KERN_PROC;
43     mib[2] = KERN_PROC_PATHNAME;
44     mib[3] = -1;
45
46     if (!argv_leaf) {
47         fprintf(stderr, "Can't locate / in '%s'\n", argv[0]);
48         return 1;
49     }
50
51     if (sysctl(mib, 4, NULL, &size, NULL, 0)) {
52         perror("sysctl");
53         return 2;
54     }
55
56     if (size < strlen(argv_leaf) + 1) {
57         fprintf(stderr, "size %lu is too short for a path\n",
58                 (unsigned long) size);
59         return 3;
60     }
61
62     if (size > MAXPATHLEN * MAXPATHLEN) {
63         fprintf(stderr, "size %lu is too long for a path\n",
64                 (unsigned long) size);
65         return 4;
66     }
67
68     buffer = malloc(size);
69     if (!buffer) {
70         perror("malloc");
71         return 5;
72     }
73
74     if (sysctl(mib, 4, buffer, &size, NULL, 0)) {
75         perror("sysctl");
76         return 6;
77     }
78
79     if (strlen(buffer) + 1 != size) {
80         fprintf(stderr, "size != strlen(buffer) + 1 (%lu != %lu)\n",
81                 (unsigned long)size, (unsigned long)strlen(buffer) + 1);
82         return 7;
83     }
84
85
86     if (*buffer != '/') {
87         fprintf(stderr, "Not an absolute path: '%s'\n", buffer);
88         return 8;
89     }
90
91     if (strstr(buffer, "/./")) {
92         fprintf(stderr, "Contains /./: '%s'\n", buffer);
93         return 9;
94     }
95
96     if (strstr(buffer, "/../")) {
97         fprintf(stderr, "Contains /../: '%s'\n", buffer);
98         return 10;
99     }
100
101     buffer_leaf = strrchr(buffer, '/');
102     if (strcmp(buffer_leaf, argv_leaf) != 0) {
103         fprintf(stderr, "Leafnames differ: '%s' vs '%s'\n", argv[0], buffer);
104         return 11;
105     }
106
107     free(buffer);
108
109     return 0;
110 }
111 EOM
112
113 val=$undef
114 set try
115 if eval $compile_ok; then
116         if $run ./try; then
117                 echo "You can use sysctl with KERN_PROC_PATHNAME to find the executing program." >&4
118                 val="$define"
119         else
120                 echo "Nope, sysctl with KERN_PROC_PATHNAME doesn't work here." >&4
121                 val="$undef"
122         fi
123 else
124         echo "I'm unable to compile the test program." >&4
125         echo "I'll assume no sysctl with KERN_PROC_PATHNAME here." >&4
126         val="$undef"
127 fi
128 $rm_try
129 set usekernprocpathname
130 eval $setvar
131