1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
/* See LICENSE file for copyright and license details. */
#include "common.h"
#ifndef TEST
#include <sys/auxv.h>
extern char *argv0;
static char *
getexecpath_by_execfn(void)
{
unsigned long auxval;
char *execpath, *path, *target;
const char *name, *s, *fdlink;
size_t n;
auxval = getauxval(AT_EXECFN);
if (!auxval)
return NULL;
name = (void *)auxval;
if (strstarts(name, "/dev/fd/"))
s = &name[sizeof("/dev/fd/") - 1U];
else if (strstarts(name, "/proc/self/fd/"))
s = &name[sizeof("/proc/self/fd/") - 1U];
else
return libsimple_abspath(name, NULL);
while (isdigit(*s))
s++;
if (*s) {
n = (size_t)(s - name);
path = malloc(n + 1U);
if (!path)
return NULL;
memcpy(path, name, n);
path[n] = '\0';
fdlink = path;
} else {
path = NULL;
fdlink = name;
}
target = libsimple_readmagiclink(fdlink);
free(path);
if (!target)
return NULL;
execpath = malloc(strlen(target) + strlen(s) + 1U);
if (!execpath) {
free(target);
return NULL;
}
stpcpy(stpcpy(execpath, target), s);
free(target);
return execpath;
}
static char *
getexecpath_by_execfd(void)
{
unsigned long auxval;
int fd;
char path[sizeof("/dev/fd/") + 3U * sizeof(int)];
errno = 0;
auxval = getauxval(AT_EXECFN);
if (!auxval && errno)
return NULL;
fd = (int)auxval;
sprintf(path, "/dev/fd/%i", fd);
return libsimple_readmagiclink(path);
}
static char *
getexecpath_by_proc_exe(void)
{
return libsimple_readmagiclink("/proc/self/exe");
}
static char *
getexecpath_by_argv0(void)
{
char *s = argv0;
if (strchr(s, '/'))
return libsimple_abspath(s, NULL);
return NULL;
}
char *
libsimple_getexecpath(void)
{
char *r;
if ((r = getexecpath_by_execfn()))
return r;
if ((r = getexecpath_by_execfd()))
return r;
if ((r = getexecpath_by_proc_exe()))
return r;
if ((r = getexecpath_by_argv0()))
return r;
return NULL;
}
#else
#include "test.h"
int
main(void) /* TODO test */
{
return 0;
}
#endif
|