Elements 6.0.1
A C++ base framework for the Euclid Software.
Loading...
Searching...
No Matches
ModuleInfo.cpp
Go to the documentation of this file.
1
23
24#include <dlfcn.h>
25#include <libgen.h>
26#include <sys/param.h>
27#include <sys/times.h>
28#include <unistd.h>
29
30#ifdef __APPLE__
31#include <mach-o/dyld.h> // for _NSGetExecutablePath
32#endif
33
34#include <array>
35#include <cerrno>
36#include <cstdio>
37#include <cstdlib>
38#include <cstring>
39#include <fstream> // for ifstream
40#include <iostream>
41#include <sstream> // for stringstream
42#include <string> // for string
43#include <vector>
44
45#ifdef __APPLE__
46#include <climits> // for PATH_MAX
47#endif
48
49#include <boost/filesystem/operations.hpp> // for filesystem::exists, canonical
50
52#include "ElementsKernel/Path.h" // for Path::Item
53
54using std::string;
55using std::vector;
56
57namespace {
58vector<string> s_linkedModules;
59}
60
61namespace Elements {
62namespace System {
63
64ModuleInfo::ModuleInfo() : m_dlinfo{nullptr} {}
65
67 m_dlinfo.reset(new Dl_info);
68 ::dladdr(FuncPtrCast<void*>(funct), m_dlinfo.get());
69}
70
71const string ModuleInfo::name() const {
72 return ::basename(const_cast<char*>(m_dlinfo->dli_fname));
73}
74
75const string ModuleInfo::libraryName() const {
76 return const_cast<char*>(m_dlinfo->dli_fname);
77}
78
79const void* ModuleInfo::addresse() const {
80 return m_dlinfo->dli_saddr;
81}
82
83bool ModuleInfo::isEmpty() const {
84 return (m_dlinfo == nullptr);
85}
86
87ModuleInfo::operator const Dl_info&() const {
88 return *m_dlinfo;
89}
90
91namespace {
92ImageHandle s_module_handle = nullptr;
93}
95const string& moduleName() {
96 static string module{};
97 if (module.empty()) {
98 if ((processHandle() != nullptr) and (moduleHandle() != nullptr)) {
99 string mod = ::basename(const_cast<char*>((reinterpret_cast<Dl_info*>(moduleHandle()))->dli_fname));
100 module = mod.substr(static_cast<string::size_type>(0), mod.find('.'));
101 }
102 }
103 return module;
104}
105
107const string& moduleNameFull() {
108 static string module{};
109 if (module.empty()) {
110 if (processHandle() and moduleHandle()) {
111 std::array<char, PATH_MAX> name{"Unknown.module"};
112 name[0] = 0;
113 const char* path = (reinterpret_cast<Dl_info*>(moduleHandle())->dli_fname);
114 if (::realpath(path, name.data())) {
115 module = name.data();
116 }
117 }
118 }
119 return module;
120}
121
124 static ModuleType type = ModuleType::UNKNOWN;
125 if (type == ModuleType::UNKNOWN) {
126 const string& module = moduleNameFull();
127 std::size_t loc = module.rfind('.') + 1;
128 if (loc == 0) {
130 } else if (module[loc] == 'e' or module[loc] == 'E') {
132 } else if (module[loc] == 's' and module[loc + 1] == 'o') {
134 } else {
135 type = ModuleType::UNKNOWN;
136 }
137 }
138 return type;
139}
140
143 static std::int64_t pid = ::getpid();
144 static void* hP = reinterpret_cast<void*>(pid);
145 return hP;
146}
147
149 s_module_handle = handle;
150}
151
153 if (nullptr == s_module_handle) {
154 if (processHandle() != nullptr) {
155 static Dl_info info;
156 if (0 != ::dladdr(FuncPtrCast<void*>(moduleHandle), &info)) {
157 return &info;
158 }
159 }
160 }
161 return s_module_handle;
162}
163
165 // This does NOT work!
166 static Dl_info infoBuf;
167 static Dl_info* info;
168
169 if (nullptr == info) {
170 void* handle = ::dlopen(nullptr, RTLD_LAZY);
171 if (nullptr != handle) {
172 void* func = ::dlsym(handle, "main");
173 if (nullptr != func) {
174 if (0 != ::dladdr(func, &infoBuf)) {
175 info = &infoBuf;
176 }
177 }
178 }
179 }
180 return info;
181}
182
183const string& exeName() {
184 static string module{""};
185 if (module.empty()) {
186 module = getExecutablePath().string();
187 }
188 return module;
189}
190
191Path::Item getSelfProc() {
192
193 Path::Item self_proc{"/proc/self"};
194
195 Path::Item exe = self_proc / "exe";
196
197 if (not boost::filesystem::exists(exe)) {
198 std::stringstream self_str{};
199 self_str << "/proc/" << ::getpid();
200 self_proc = Path::Item(self_str.str());
201 }
202
203 return self_proc;
204}
205
207
208 vector<Path::Item> linked_modules;
209
210 Path::Item self_maps = getSelfProc() / "maps";
211 std::ifstream maps_str(self_maps.string());
212
213 string line;
214 while (std::getline(maps_str, line)) {
215 string address, perms, offset, dev, pathname;
216 unsigned inode;
217 std::istringstream iss(line);
218 if (not(iss >> address >> perms >> offset >> dev >> inode >> pathname)) {
219 continue;
220 }
221 if (perms == "r-xp" and boost::filesystem::exists(pathname)) {
222 linked_modules.emplace_back(Path::Item(pathname));
223 }
224 }
225
226 maps_str.close();
227
228 return linked_modules;
229}
230
232
233 if (s_linkedModules.size() == 0) {
234
235 for (auto m : linkedModulePaths()) {
236 s_linkedModules.emplace_back(m.string());
237 }
238 }
239 return s_linkedModules;
240}
241
242Path::Item getExecutablePath() {
243
244#ifdef __APPLE__
245 path self_proc{};
246 char pathbuf[PATH_MAX + 1];
247 unsigned int bufsize = sizeof(pathbuf);
248 _NSGetExecutablePath(pathbuf, &bufsize);
249 path self_exe = path(string(pathbuf));
250#else
251
252 Path::Item self_exe = getSelfProc() / "exe";
253
254#endif
255
256 return boost::filesystem::canonical(self_exe);
257}
258
259} // namespace System
260} // namespace Elements
OS specific details to access at run-time the module configuration of the process.
defines a Small helper function that allows the cast from void * to function pointer
provide functions to retrieve resources pointed by environment variables
const void * addresse() const
Definition: ModuleInfo.cpp:79
std::unique_ptr< Dl_info > m_dlinfo
Definition: ModuleInfo.h:55
const std::string name() const
Definition: ModuleInfo.cpp:71
const std::string libraryName() const
Definition: ModuleInfo.cpp:75
T close(T... args)
T emplace_back(T... args)
T find(T... args)
T get(T... args)
T getline(T... args)
void * ImageHandle
Definition of an image handle.
Definition: System.h:109
ELEMENTS_API void setModuleHandle(ImageHandle handle)
Attach module handle.
Definition: ModuleInfo.cpp:148
ELEMENTS_API Path::Item getSelfProc()
Get the path to the /proc directory of the process.
Definition: ModuleInfo.cpp:191
ELEMENTS_API ProcessHandle processHandle()
Handle to running process.
Definition: ModuleInfo.cpp:142
ELEMENTS_API ImageHandle moduleHandle()
Handle to currently executed module.
Definition: ModuleInfo.cpp:152
ELEMENTS_API ImageHandle exeHandle()
Handle to the executable file running.
Definition: ModuleInfo.cpp:164
ELEMENTS_API const std::string & moduleNameFull()
Get the full name of the (executable/DLL) file.
Definition: ModuleInfo.cpp:107
ELEMENTS_API const std::string & moduleName()
Get the name of the (executable/DLL) file without file-type.
Definition: ModuleInfo.cpp:95
ELEMENTS_API Path::Item getExecutablePath()
Get the full executable path.
Definition: ModuleInfo.cpp:242
ELEMENTS_API ModuleType moduleType()
Get type of the module.
Definition: ModuleInfo.cpp:123
ELEMENTS_API const std::vector< std::string > linkedModules()
Vector of names of linked modules.
Definition: ModuleInfo.cpp:231
ELEMENTS_API std::vector< Path::Item > linkedModulePaths()
Definition: ModuleInfo.cpp:206
ELEMENTS_API const std::string & exeName()
Name of the executable file running.
Definition: ModuleInfo.cpp:183
T reset(T... args)
T rfind(T... args)
T substr(T... args)