| 1760 | // |
| 1761 | |
| 1762 | Result<std::string> GetEnvVar(std::string_view name) { |
| 1763 | #ifdef _WIN32 |
| 1764 | // On Windows, getenv() reads an early copy of the process' environment |
| 1765 | // which doesn't get updated when SetEnvironmentVariable() is called. |
| 1766 | std::string value(100, '\0'); |
| 1767 | |
| 1768 | uint32_t res = GetEnvironmentVariableA(name.data(), value.data(), |
| 1769 | static_cast<uint32_t>(value.size())); |
| 1770 | if (res >= value.size()) { |
| 1771 | // Value buffer too small, need to upsize |
| 1772 | // (`res` includes the null-terminating character in this case) |
| 1773 | value.resize(res); |
| 1774 | res = GetEnvironmentVariableA(name.data(), value.data(), |
| 1775 | static_cast<uint32_t>(value.size())); |
| 1776 | } |
| 1777 | if (res == 0) { |
| 1778 | return Status::KeyError("environment variable '", name, "' undefined"); |
| 1779 | } |
| 1780 | // On success, `res` does not include the null-terminating character |
| 1781 | DCHECK_EQ(value.data()[res], 0); |
| 1782 | value.resize(res); |
| 1783 | return value; |
| 1784 | #else |
| 1785 | char* c_str = getenv(name.data()); |
| 1786 | if (c_str == nullptr) { |
| 1787 | return Status::KeyError("environment variable '", name, "' undefined"); |
| 1788 | } |
| 1789 | return std::string(c_str); |
| 1790 | #endif |
| 1791 | } |
| 1792 | |
| 1793 | #ifdef _WIN32 |
| 1794 | Result<NativePathString> GetEnvVarNative(std::string_view name) { |