Mercurial > code
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 |