Elements  6.2
A C++ base framework for the Euclid Software.
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 
54 using std::string;
55 using std::vector;
56 
57 namespace {
58 vector<string> s_linkedModules;
59 }
60 
61 namespace Elements {
62 namespace System {
63 
64 ModuleInfo::ModuleInfo() : m_dlinfo{nullptr} {}
65 
66 ModuleInfo::ModuleInfo(void* funct) {
67  m_dlinfo.reset(new Dl_info);
68  ::dladdr(FuncPtrCast<void*>(funct), m_dlinfo.get());
69 }
70 
71 const string ModuleInfo::name() const {
72  return ::basename(const_cast<char*>(m_dlinfo->dli_fname));
73 }
74 
75 const string ModuleInfo::libraryName() const {
76  return const_cast<char*>(m_dlinfo->dli_fname);
77 }
78 
79 const void* ModuleInfo::addresse() const {
80  return m_dlinfo->dli_saddr;
81 }
82 
83 bool ModuleInfo::isEmpty() const {
84  return (m_dlinfo == nullptr);
85 }
86 
87 ModuleInfo::operator const Dl_info&() const {
88  return *m_dlinfo;
89 }
90 
91 namespace {
92 ImageHandle s_module_handle = nullptr;
93 }
95 const 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 
107 const 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) {
129  type = ModuleType::EXECUTABLE;
130  } else if (module[loc] == 'e' or module[loc] == 'E') {
131  type = ModuleType::EXECUTABLE;
132  } else if (module[loc] == 's' and module[loc + 1] == 'o') {
133  type = ModuleType::SHAREDLIB;
134  } else {
135  type = ModuleType::UNKNOWN;
136  }
137  }
138  return type;
139 }
140 
142 void* processHandle() {
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 
183 const string& exeName() {
184  static string module{""};
185  if (module.empty()) {
186  module = getExecutablePath().string();
187  }
188  return module;
189 }
190 
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;
216  string perms;
217  string offset;
218  string dev;
219  string pathname;
220  unsigned inode;
221  std::istringstream iss(line);
222  if (not(iss >> address >> perms >> offset >> dev >> inode >> pathname)) {
223  continue;
224  }
225  if (perms == "r-xp" and boost::filesystem::exists(pathname)) {
226  linked_modules.emplace_back(Path::Item(pathname));
227  }
228  }
229 
230  maps_str.close();
231 
232  return linked_modules;
233 }
234 
236 
237  if (s_linkedModules.size() == 0) {
238 
239  for (auto m : linkedModulePaths()) {
240  s_linkedModules.emplace_back(m.string());
241  }
242  }
243  return s_linkedModules;
244 }
245 
247 
248 #ifdef __APPLE__
249  path self_proc{};
250  char pathbuf[PATH_MAX + 1];
251  unsigned int bufsize = sizeof(pathbuf);
252  _NSGetExecutablePath(pathbuf, &bufsize);
253  path self_exe = path(string(pathbuf));
254 #else
255 
256  Path::Item self_exe = getSelfProc() / "exe";
257 
258 #endif
259 
260  return boost::filesystem::canonical(self_exe);
261 }
262 
263 } // namespace System
264 } // namespace Elements
Elements::Kernel::Path::Item
boost::filesystem::path Item
Definition: Path.h:56
Elements::System::ModuleInfo::name
const std::string name() const
Definition: ModuleInfo.cpp:71
std::string
STL class.
Elements::System::setModuleHandle
ELEMENTS_API void setModuleHandle(ImageHandle handle)
Attach module handle.
Definition: ModuleInfo.cpp:148
Path.h
provide functions to retrieve resources pointed by environment variables
Elements::System::moduleName
const ELEMENTS_API std::string & moduleName()
Get the name of the (executable/DLL) file without file-type.
Definition: ModuleInfo.cpp:95
std::vector
STL class.
std::string::find
T find(T... args)
Elements::System::ModuleType
ModuleType
Definition: ModuleInfo.h:58
Elements::System::exeHandle
ELEMENTS_API ImageHandle exeHandle()
Handle to the executable file running.
Definition: ModuleInfo.cpp:164
FuncPtrCast.h
defines a Small helper function that allows the cast from void * to function pointer
Elements::System::ModuleInfo::ModuleInfo
ModuleInfo()
Definition: ModuleInfo.cpp:64
std::stringstream
STL class.
std::unique_ptr::get
T get(T... args)
std::istringstream
STL class.
Elements::System::moduleNameFull
const ELEMENTS_API std::string & moduleNameFull()
Get the full name of the (executable/DLL) file.
Definition: ModuleInfo.cpp:107
Elements::System::linkedModules
const ELEMENTS_API std::vector< std::string > linkedModules()
Vector of names of linked modules.
Definition: ModuleInfo.cpp:235
Elements::System::ModuleType::EXECUTABLE
@ EXECUTABLE
std::unique_ptr::reset
T reset(T... args)
Elements::Kernel::Units::m
constexpr double m
Definition: SystemOfUnits.h:79
Elements::System::moduleType
ELEMENTS_API ModuleType moduleType()
Get type of the module.
Definition: ModuleInfo.cpp:123
Elements::System::ModuleInfo::libraryName
const std::string libraryName() const
Definition: ModuleInfo.cpp:75
std::array
STL class.
std::ifstream::close
T close(T... args)
std::int64_t
Elements::System::processHandle
ELEMENTS_API ProcessHandle processHandle()
Handle to running process.
Definition: ModuleInfo.cpp:142
std::string::substr
T substr(T... args)
std::vector::emplace_back
T emplace_back(T... args)
Elements::System::ModuleInfo::isEmpty
bool isEmpty() const
Definition: ModuleInfo.cpp:83
Elements::System::exeName
const ELEMENTS_API std::string & exeName()
Name of the executable file running.
Definition: ModuleInfo.cpp:183
Elements::System::ModuleInfo::addresse
const void * addresse() const
Definition: ModuleInfo.cpp:79
Elements::System::ModuleInfo::m_dlinfo
std::unique_ptr< Dl_info > m_dlinfo
Definition: ModuleInfo.h:55
Elements::System::moduleHandle
ELEMENTS_API ImageHandle moduleHandle()
Handle to currently executed module.
Definition: ModuleInfo.cpp:152
std::getline
T getline(T... args)
Elements::System::ModuleType::SHAREDLIB
@ SHAREDLIB
Elements::System::ImageHandle
void * ImageHandle
Definition of an image handle.
Definition: System.h:109
std::size_t
Elements::System::getSelfProc
ELEMENTS_API Path::Item getSelfProc()
Get the path to the /proc directory of the process.
Definition: ModuleInfo.cpp:191
ModuleInfo.h
OS specific details to access at run-time the module configuration of the process.
std::string::rfind
T rfind(T... args)
Elements::System::getExecutablePath
ELEMENTS_API Path::Item getExecutablePath()
Get the full executable path.
Definition: ModuleInfo.cpp:246
Elements::System::ModuleType::UNKNOWN
@ UNKNOWN
Elements::System::linkedModulePaths
ELEMENTS_API std::vector< Path::Item > linkedModulePaths()
Definition: ModuleInfo.cpp:206
Elements
Definition: callBackExample.h:35
std::ifstream
STL class.
Elements::Services::DataSync::path
Path::Item path
importing the path item from ElementsKernel
Definition: DataSyncUtils.h:41
Elements::System::InfoType::System
@ System