|
2 | 2 | #include <string> |
3 | 3 | #include <sstream> |
4 | 4 | #include <fstream> |
5 | | - |
6 | | -#include "NativeCore.hpp" |
7 | | - |
8 | | -// std::filesystem library doesn't work @Ubuntu 16.10, read_symlink() always fails. |
9 | | -//#define USE_STD_FILESYSTEM |
10 | | -#ifdef USE_STD_FILESYSTEM |
11 | 5 | #include <experimental/filesystem> |
12 | | -#else |
13 | | -#include <dirent.h> |
14 | | -#include <sys/stat.h> |
15 | | -#include <unistd.h> |
16 | | - |
17 | | -class path |
18 | | -{ |
19 | | -public: |
20 | | - path() = default; |
21 | | - |
22 | | - path(const char* _path) |
23 | | - : path(std::string(_path)) |
24 | | - { |
25 | | - } |
26 | | - |
27 | | - path(const std::string& _path) |
28 | | - : buf(_path) |
29 | | - { |
30 | | - } |
31 | | - |
32 | | - path(const path&) = default; |
33 | | - |
34 | | - path& append(const std::string& part) |
35 | | - { |
36 | | - if (buf.back() != separator) |
37 | | - { |
38 | | - buf += separator; |
39 | | - } |
40 | | - buf += part; |
41 | 6 |
|
42 | | - return *this; |
43 | | - } |
44 | | - |
45 | | - path& operator/=(const path& p) |
46 | | - { |
47 | | - append(p.buf); |
48 | | - |
49 | | - return *this; |
50 | | - } |
51 | | - |
52 | | - const std::string& string() const |
53 | | - { |
54 | | - return buf; |
55 | | - } |
56 | | - |
57 | | - const char* c_str() const |
58 | | - { |
59 | | - return buf.c_str(); |
60 | | - } |
61 | | - |
62 | | -private: |
63 | | - static const char separator = '/'; |
64 | | - |
65 | | - std::string buf; |
66 | | -}; |
67 | | - |
68 | | -inline path operator/(const path& lhs, const path& rhs) |
69 | | -{ |
70 | | - return path(lhs) /= rhs; |
71 | | -} |
72 | | - |
73 | | -enum class FileType |
74 | | -{ |
75 | | - Unknown, |
| 7 | +#include "NativeCore.hpp" |
76 | 8 |
|
77 | | - File, |
78 | | - Directory, |
79 | | - Symlink |
80 | | -}; |
| 9 | +namespace fs = std::experimental::filesystem; |
81 | 10 |
|
82 | | -FileType file_type(const path& p) |
83 | | -{ |
84 | | - struct stat path_stat = {}; |
85 | | - if (::lstat(p.c_str(), &path_stat) == 0) |
86 | | - { |
87 | | - if (S_ISREG(path_stat.st_mode)) |
88 | | - { |
89 | | - return FileType::File; |
90 | | - } |
91 | | - else if (S_ISDIR(path_stat.st_mode)) |
92 | | - { |
93 | | - return FileType::Directory; |
94 | | - } |
95 | | - else if (S_ISLNK(path_stat.st_mode)) |
96 | | - { |
97 | | - return FileType::Symlink; |
98 | | - } |
99 | | - } |
100 | | - |
101 | | - return FileType::Unknown; |
102 | | -} |
| 11 | +// std::filesystem library doesn't work @Ubuntu 16.10, read_symlink() always fails. |
| 12 | +#define USE_CUSTOM_READ_SYMLINK |
103 | 13 |
|
104 | | -inline bool is_directory(const path& p) |
105 | | -{ |
106 | | - return file_type(p) == FileType::Directory; |
107 | | -} |
| 14 | +#ifdef USE_CUSTOM_READ_SYMLINK |
| 15 | +#include <unistd.h> |
108 | 16 |
|
109 | | -inline bool is_symlink(const path& p) |
| 17 | +fs::path my_read_symlink(const fs::path& p, std::error_code& ec) |
110 | 18 | { |
111 | | - return file_type(p) == FileType::Symlink; |
112 | | -} |
| 19 | + fs::path symlink_path; |
113 | 20 |
|
114 | | -bool read_symlink(const path& p, path& out_p) |
115 | | -{ |
116 | 21 | std::string temp(64, '\0'); |
117 | | - |
118 | 22 | for (;; temp.resize(temp.size() * 2)) |
119 | 23 | { |
120 | 24 | ssize_t result; |
121 | 25 | if ((result = ::readlink(p.c_str(), /*temp.data()*/ &temp[0], temp.size())) == -1) |
122 | 26 | { |
123 | | - return false; |
| 27 | + ec.assign(errno, std::system_category()); |
| 28 | + break; |
124 | 29 | } |
125 | 30 | else |
126 | 31 | { |
127 | 32 | if (result != (ssize_t)temp.size()) |
128 | 33 | { |
129 | | - out_p = path(std::string(temp.begin(), temp.begin() + result)); |
| 34 | + symlink_path = fs::path(std::string(temp.begin(), temp.begin() + result)); |
| 35 | + |
| 36 | + ec.clear(); |
130 | 37 |
|
131 | | - return true; |
| 38 | + break; |
132 | 39 | } |
133 | 40 | } |
134 | 41 | } |
| 42 | + |
| 43 | + return symlink_path; |
135 | 44 | } |
136 | 45 |
|
137 | 46 | #endif |
@@ -194,57 +103,33 @@ extern "C" void EnumerateProcesses(EnumerateProcessCallback callbackProcess) |
194 | 103 | return; |
195 | 104 | } |
196 | 105 |
|
197 | | -#ifdef USE_STD_FILESYSTEM |
198 | | - using namespace std::experimental::filesystem; |
199 | | - using namespace std; |
200 | | - |
201 | | - path procPath("/proc"); |
202 | | - if (is_directory(procPath)) |
| 106 | + fs::path procPath("/proc"); |
| 107 | + if (fs::is_directory(procPath)) |
203 | 108 | { |
204 | | - for (auto& d : directory_iterator(procPath)) |
| 109 | + for (auto& d : fs::directory_iterator(procPath)) |
205 | 110 | { |
206 | | - if (is_directory(d)) |
| 111 | + if (fs::is_directory(d)) |
207 | 112 | { |
208 | | - auto pidPath = d.path(); |
| 113 | + auto processPath = d.path(); |
209 | 114 |
|
210 | 115 | auto name = processPath.filename().string(); |
211 | 116 | if (is_number(name)) |
212 | 117 | { |
213 | 118 | auto exeSymLink = processPath / "exe"; |
214 | | - if (is_symlink(symlink_status(exeSymLink))) |
| 119 | + if (fs::is_symlink(fs::symlink_status(exeSymLink))) |
215 | 120 | { |
216 | | - error_code ec; |
217 | | - auto linkPath = read_symlink(exeSymLink, ec).string(); |
| 121 | + std::error_code ec; |
| 122 | + auto linkPath = |
| 123 | +#ifdef USE_CUSTOM_READ_SYMLINK |
| 124 | + my_read_symlink |
| 125 | +#else |
| 126 | + read_symlink |
| 127 | +#endif |
| 128 | + (exeSymLink, ec).string(); |
218 | 129 | if (!ec) |
219 | 130 | { |
220 | | -#else |
221 | | - path procPath("/proc"); |
222 | | - if (is_directory(procPath)) |
223 | | - { |
224 | | - auto directory = opendir(procPath.c_str()); |
225 | | - if (directory == nullptr) |
226 | | - { |
227 | | - return; |
228 | | - } |
| 131 | + auto auxvPath = processPath / "auxv"; |
229 | 132 |
|
230 | | - struct dirent *entry; |
231 | | - while ((entry = readdir(directory)) != nullptr) |
232 | | - { |
233 | | - auto pidPath = procPath / entry->d_name; |
234 | | - if (is_directory(pidPath)) |
235 | | - { |
236 | | - std::string name(entry->d_name); |
237 | | - if (is_number(name)) |
238 | | - { |
239 | | - auto exePath = pidPath / "exe"; |
240 | | - if (is_symlink(exePath)) |
241 | | - { |
242 | | - path linkPath; |
243 | | - if (read_symlink(exePath, linkPath)) |
244 | | - { |
245 | | -#endif |
246 | | - auto auxvPath = pidPath / "auxv"; |
247 | | - |
248 | 133 | auto platform = GetProcessPlatform(auxvPath.string()); |
249 | 134 | #ifdef NATIVE_CORE_64 |
250 | 135 | if (platform == Platform::X64) |
|
0 commit comments