chigraph  master
Systems programming language written for beginners in LLVM
ExecutablePath.cpp
Go to the documentation of this file.
1 
6 
7 #include <boost/filesystem/operations.hpp>
8 
9 namespace fs = boost::filesystem;
10 
11 // linux implementation
12 #ifdef __linux__
13 #include <dirent.h>
14 #include <fcntl.h>
15 #include <limits.h>
16 #include <stdio.h>
17 #include <sys/mman.h>
18 #include <sys/param.h>
19 #include <sys/stat.h>
20 #include <unistd.h>
21 #define NAMLEN(dirent) strlen((dirent)->d_name)
22 
23 namespace chi {
24 fs::path executablePath() {
25  char exe_path[MAXPATHLEN];
26  fs::path aPath("/proc/self/exe");
27  if (fs::exists(aPath)) {
28  // /proc is not always mounted under Linux (chroot for example).
29  ssize_t len = readlink(aPath.string().c_str(), exe_path, sizeof(exe_path));
30  if (len >= 0) return std::string(exe_path, len);
31  }
32  assert(false); // aah noo
33  return {};
34 }
35 } // namespace chi
36 
37 // osx
38 #elif defined __APPLE__
39 #include <mach-o/dyld.h>
40 #include <stdlib.h>
41 #include <sys/attr.h>
42 
43 namespace chi {
44 fs::path executablePath() {
45  // On OS X the executable path is saved to the stack by dyld. Reading it
46  // from there is much faster than calling dladdr, especially for large
47  // binaries with symbols.
48  char exe_path[MAXPATHLEN];
49  uint32_t size = sizeof(exe_path);
50  if (_NSGetExecutablePath(exe_path, &size) == 0) {
51  char link_path[MAXPATHLEN];
52  if (realpath(exe_path, link_path)) return link_path;
53  }
54  assert(false);
55  return {};
56 }
57 } // namespace chi
58 
59 #elif defined WIN32
60 #define WIN32_MEAN_AND_LEAN
61 #include <Windows.h>
62 
63 namespace chi {
64 
65 boost::filesystem::path executablePath() {
66  std::vector<wchar_t> PathName(MAX_PATH);
67  DWORD Size = ::GetModuleFileNameW(NULL, PathName.data(), PathName.size());
68 
69  // A zero return value indicates a failure other than insufficient space.
70  if (Size == 0) return "";
71 
72  // Insufficient space is determined by a return value equal to the size of
73  // the buffer passed in.
74  if (Size == PathName.size()) return "";
75 
76  // On success, GetModuleFileNameW returns the number of characters written to
77  // the buffer not including the NULL terminator.
78  PathName.resize(Size);
79 
80  // Convert the result from UTF-16 to UTF-8.
81  std::string PathNameUTF8(MAX_PATH);
82  if (UTF16ToUTF8(PathName.data(), PathName.size(), PathNameUTF8)) return "";
83 
84  return std::string(PathNameUTF8.c_str()());
85 }
86 
87 #else
88 #error GetMainExecutable is not implemented on this host yet.
89 #endif
boost::filesystem::path executablePath()
Get the path of the executable.
The namespace where chigraph lives.