comparison misc/executable.cpp @ 563:668975a91fb2

Misc: add executable.cpp, get the executable path
author David Demelier <markand@malikania.fr>
date Tue, 21 Jun 2016 15:55:57 +0200
parents
children f8616f9fc9d5
comparison
equal deleted inserted replaced
562:b6c6d98054d9 563:668975a91fb2
1 #include <string>
2 #include <stdexcept>
3
4 #if defined(__linux__)
5 # include <unistd.h>
6
7 # include <cerrno>
8 # include <cstring>
9 # include <stdexcept>
10 #elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) || defined(__OpenBSD__)
11 # if defined(__NetBSD__)
12 # include <sys/param.h>
13 # else
14 # include <sys/types.h>
15 # endif
16
17 # if defined(__OpenBSD__)
18 # include <unistd.h>
19 # endif
20
21 # include <sys/sysctl.h>
22
23 # include <array>
24 # include <cerrno>
25 # include <climits>
26 # include <cstddef>
27 # include <cstdlib>
28 # include <cstring>
29 # include <stdexcept>
30 #elif defined(__APPLE__)
31 # include <cerrno>
32 # include <cstring>
33 # include <libproc.h>
34 # include <unistd.h>
35 #elif defined(_WIN32)
36 # include <Windows.h>
37 #endif
38
39 #if defined(__linux__)
40
41 std::string executable()
42 {
43 std::string result;
44
45 result.resize(2048, '\0');
46
47 auto size = readlink("/proc/self/exe", &result[0], 2048);
48
49 if (size < 0)
50 throw std::runtime_error(std::strerror(errno));
51
52 result.resize(size, '\0');
53
54 return result;
55 }
56
57 #elif defined(__FreeBSD__) || defined(__DragonFly__)
58
59 std::string executable()
60 {
61 std::array<int, 4> mib{ CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
62 std::string result;
63 std::size_t size = PATH_MAX + 1;
64
65 result.resize(size, '\0');
66
67 if (sysctl(mib.data(), 4, &result[0], &size, nullptr, 0) < 0)
68 throw std::runtime_error(std::strerror(errno));
69
70 result.resize(size, '\0');
71
72 return result;
73 }
74
75 #elif defined(__APPLE__)
76
77 std::string executable()
78 {
79 std::string result;
80 std::size_t size = PROC_PIDPATHINFO_MAXSIZE;
81
82 result.resize(size, '\0');
83
84 if ((size = proc_pidpath(getpid(), &result[0], size)) == 0)
85 throw std::runtime_error(std::strerror(errno));
86
87 result.resize(size, '\0');
88
89 return result;
90 }
91
92 #elif defined(_WIN32)
93
94 std::string executable()
95 {
96 std::string result;
97 std::size_t size = PATH_MAX;
98
99 result.resize(size, '\0');
100
101 if (!(size = GetModuleFileNameA(nullptr, &result[0], size)))
102 throw std::runtime_error("GetModuleFileName error");
103
104 result.resize(size, '\0');
105
106 return result;
107 }
108
109 #elif defined(__NetBSD__)
110
111 std::string executable()
112 {
113 std::string result;
114
115 #if defined(KERN_PROC_PATHNAME)
116 std::array<int, 4> mib{ CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME };
117 std::size_t size = MAXPATHLEN;
118
119 result.resize(size, '\0');
120
121 if (sysctl(mib.data(), 4, &result[0], &size, nullptr, 0) < 0)
122 throw std::runtime_error(std::strerror(errno));
123
124 result.resize(size, '\0');
125 #else
126 result.resize(2048, '\0');
127
128 auto size = readlink("/proc/curproc/exe", &result[0], 2048);
129
130 if (size < 0)
131 throw std::runtime_error(std::strerror(errno));
132
133 result.resize(size, '\0');
134 #endif
135
136 return result;
137 }
138
139 #elif defined(__OpenBSD__)
140
141 std::string executable()
142 {
143 char **paths, *path;
144 std::string result;
145 std::size_t len;
146 std::array<int, 4> mib{ CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV };
147
148 if (sysctl(mib.data(), 4, nullptr, &len, nullptr, 0) == -1)
149 throw std::runtime_error(std::strerror(errno));
150 if ((paths = static_cast<char **>(malloc(len))) == nullptr)
151 throw std::runtime_error(std::strerror(errno));
152
153 sysctl(mib.data(), 4, paths, &len, nullptr, 0);
154
155 if ((path = static_cast<char *>(std::malloc(PATH_MAX + 1))) == nullptr) {
156 std::free(paths);
157 throw std::runtime_error(std::strerror(errno));
158 }
159
160 realpath(paths[0], path);
161 result = path;
162
163 std::free(paths);
164 std::free(path);
165
166 return result;
167 }
168
169 #else
170
171 std::string executable()
172 {
173 // Not supported.
174 return "";
175 }
176
177 #endif