| chigraph master Systems programming language written for beginners in LLVM

ExecutablePath.cpp
Go to the documentation of this file.
1
5 #include "chi/Support/ExecutablePath.hpp"
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
chi::executablePath
boost::filesystem::path executablePath()
Get the path of the executable.
chi
The namespace where chigraph lives.
Definition: BitcodeParser.hpp:12
ExecutablePath.hpp