Skip to content

Commit dc6c820

Browse files
authored
fix: ensure macos path (#11)
1 parent f53406a commit dc6c820

1 file changed

Lines changed: 113 additions & 0 deletions

File tree

source/Runtime/Runtime_Posix.cpp

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,121 @@
33

44
#include <dlfcn.h>
55

6+
#ifdef __APPLE__
7+
#include <cstdlib>
8+
#include <filesystem>
9+
#include <fstream>
10+
#include <string>
11+
#include <system_error>
12+
#include <unordered_set>
13+
#endif
14+
615
#include "MaaUtils/Platform.h"
716

17+
#ifdef __APPLE__
18+
19+
__attribute__((constructor))
20+
static void ensure_macos_path()
21+
{
22+
std::string path_env;
23+
if (const char* existing = getenv("PATH")) {
24+
path_env = existing;
25+
}
26+
const auto original_path_env = path_env;
27+
28+
auto normalize = [](std::string s) -> std::string {
29+
while (s.size() > 1 && s.back() == '/') {
30+
s.pop_back();
31+
}
32+
return s;
33+
};
34+
35+
std::unordered_set<std::string> existing_dirs;
36+
{
37+
std::string::size_type start = 0;
38+
while (start < path_env.size()) {
39+
auto pos = path_env.find(':', start);
40+
std::string seg;
41+
if (pos == std::string::npos) {
42+
seg = normalize(path_env.substr(start));
43+
if (!seg.empty()) {
44+
existing_dirs.insert(std::move(seg));
45+
}
46+
break;
47+
}
48+
seg = normalize(path_env.substr(start, pos - start));
49+
if (!seg.empty()) {
50+
existing_dirs.insert(std::move(seg));
51+
}
52+
start = pos + 1;
53+
}
54+
}
55+
56+
auto append = [&](const std::string& raw) {
57+
auto dir = normalize(raw);
58+
if (dir.empty() || existing_dirs.count(dir)) {
59+
return;
60+
}
61+
std::error_code ec;
62+
if (!std::filesystem::is_directory(dir, ec) || ec) {
63+
return;
64+
}
65+
existing_dirs.insert(dir);
66+
if (path_env.empty()) {
67+
path_env = dir;
68+
}
69+
else {
70+
path_env += ':';
71+
path_env += dir;
72+
}
73+
};
74+
75+
auto read_paths_from = [&](const std::filesystem::path& file) {
76+
std::ifstream ifs(file);
77+
if (!ifs.is_open()) {
78+
return;
79+
}
80+
std::string line;
81+
while (std::getline(ifs, line)) {
82+
if (!line.empty() && line.back() == '\r') {
83+
line.pop_back();
84+
}
85+
append(line);
86+
}
87+
};
88+
89+
// read /etc/paths
90+
read_paths_from("/etc/paths");
91+
92+
// read /etc/paths.d/*
93+
{
94+
std::error_code ec;
95+
std::filesystem::directory_iterator it("/etc/paths.d", ec);
96+
std::filesystem::directory_iterator end;
97+
for (; it != end; it.increment(ec)) {
98+
if (ec) {
99+
ec.clear();
100+
continue;
101+
}
102+
if (it->is_regular_file(ec) && !ec) {
103+
read_paths_from(it->path());
104+
}
105+
}
106+
}
107+
108+
// common paths that may not be in /etc/paths
109+
append("/opt/homebrew/bin");
110+
append("/opt/homebrew/sbin");
111+
append("/usr/local/bin");
112+
append("/usr/local/sbin");
113+
114+
if (path_env != original_path_env) {
115+
setenv("PATH", path_env.c_str(), 1);
116+
}
117+
}
118+
119+
#endif // __APPLE__
120+
8121
MAA_NS_BEGIN
9122

10123
void init_library_dir();

0 commit comments

Comments
 (0)