| 54 | } |
| 55 | |
| 56 | std::pair<int, std::string> execute_process_capture( |
| 57 | const std::filesystem::path& program, |
| 58 | const std::vector<std::string>& args, |
| 59 | const std::optional<std::pair<std::string, std::string>>& env_override = std::nullopt) { |
| 60 | std::string output; |
| 61 | int exit_code = -1; |
| 62 | |
| 63 | #ifdef _WIN32 |
| 64 | auto build_environment_block = |
| 65 | [&](const std::optional<std::pair<std::string, std::string>>& override_pair) { |
| 66 | std::vector<wchar_t> block; |
| 67 | if (!override_pair) { |
| 68 | return block; |
| 69 | } |
| 70 | |
| 71 | std::vector<std::wstring> entries; |
| 72 | if (LPWCH env = GetEnvironmentStringsW()) { |
| 73 | for (const wchar_t* current = env; *current; current += wcslen(current) + 1) { |
| 74 | entries.emplace_back(current); |
| 75 | } |
| 76 | FreeEnvironmentStringsW(env); |
| 77 | } |
| 78 | |
| 79 | const std::wstring key = lfs::core::utf8_to_wstring(override_pair->first); |
| 80 | const std::wstring value = lfs::core::utf8_to_wstring(override_pair->second); |
| 81 | const std::wstring entry = key + L"=" + value; |
| 82 | |
| 83 | bool replaced = false; |
| 84 | for (auto& existing : entries) { |
| 85 | const size_t pos = existing.find(L'='); |
| 86 | if (pos == std::wstring::npos) { |
| 87 | continue; |
| 88 | } |
| 89 | const std::wstring name = existing.substr(0, pos); |
| 90 | if (_wcsicmp(name.c_str(), key.c_str()) == 0) { |
| 91 | existing = entry; |
| 92 | replaced = true; |
| 93 | break; |
| 94 | } |
| 95 | } |
| 96 | if (!replaced) { |
| 97 | entries.push_back(entry); |
| 98 | } |
| 99 | |
| 100 | std::sort(entries.begin(), entries.end(), [](const std::wstring& a, const std::wstring& b) { |
| 101 | return _wcsicmp(a.c_str(), b.c_str()) < 0; |
| 102 | }); |
| 103 | |
| 104 | for (const auto& existing : entries) { |
| 105 | block.insert(block.end(), existing.begin(), existing.end()); |
| 106 | block.push_back(L'\0'); |
| 107 | } |
| 108 | block.push_back(L'\0'); |
| 109 | return block; |
| 110 | }; |
| 111 | |
| 112 | SECURITY_ATTRIBUTES sa; |
| 113 | sa.nLength = sizeof(SECURITY_ATTRIBUTES); |
no test coverage detected