2017-04-05 18:53:14 +00:00
|
|
|
/** @defgroup Utilities
|
2016-03-13 01:28:39 +00:00
|
|
|
*
|
2017-04-05 18:53:14 +00:00
|
|
|
* @brief Miscellaneous utilities.
|
|
|
|
*
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** @file environ.hh
|
|
|
|
*
|
|
|
|
* @brief A portable environment variable interface.
|
|
|
|
*
|
|
|
|
* Provides utility functions to portably get, set and unset environment
|
|
|
|
* variables.
|
|
|
|
*
|
|
|
|
* @copyright See COPYING.md in the project tree for further information.
|
2016-03-13 01:28:39 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef OSTD_ENVIRON_HH
|
|
|
|
#define OSTD_ENVIRON_HH
|
|
|
|
|
2016-07-06 18:40:43 +00:00
|
|
|
#include "ostd/platform.hh"
|
|
|
|
#include "ostd/internal/win32.hh"
|
|
|
|
|
2017-04-09 14:44:45 +00:00
|
|
|
#include <cstdlib>
|
|
|
|
#include <cstring>
|
2017-01-29 23:54:06 +00:00
|
|
|
#include <vector>
|
2017-01-30 18:25:09 +00:00
|
|
|
#include <optional>
|
2017-01-29 23:54:06 +00:00
|
|
|
|
2016-03-13 01:28:39 +00:00
|
|
|
#include "ostd/string.hh"
|
|
|
|
|
|
|
|
namespace ostd {
|
|
|
|
|
2017-04-05 18:53:14 +00:00
|
|
|
/** @addtogroup Utilities
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** @brief Gets an environment variable.
|
|
|
|
*
|
|
|
|
* @returns std::nullopt when the variable doesn't exist, and an std::string
|
|
|
|
* containing the environment variable's value if it does.
|
|
|
|
*
|
|
|
|
* This function is thread-safe as long as the environment is not modified
|
|
|
|
* within the program. Calling to lower level functions to set environment
|
|
|
|
* vars as well as env_set() or env_unset() at the same time would introduce
|
|
|
|
* potential data races.
|
|
|
|
*
|
|
|
|
* @see env_set(), env_unset()
|
|
|
|
*/
|
2017-02-16 17:48:14 +00:00
|
|
|
inline std::optional<std::string> env_get(string_range name) {
|
2016-03-13 01:28:39 +00:00
|
|
|
char buf[256];
|
2016-07-06 18:40:43 +00:00
|
|
|
auto tbuf = to_temp_cstr(name, buf, sizeof(buf));
|
2017-04-09 14:44:45 +00:00
|
|
|
char const *ret = std::getenv(tbuf.get());
|
2016-07-31 19:40:25 +00:00
|
|
|
if (!ret) {
|
2017-01-30 18:25:09 +00:00
|
|
|
return std::nullopt;
|
2016-07-31 19:40:25 +00:00
|
|
|
}
|
2017-01-29 23:54:06 +00:00
|
|
|
return std::string{ret};
|
2016-03-13 01:28:39 +00:00
|
|
|
}
|
|
|
|
|
2017-04-05 18:53:14 +00:00
|
|
|
/** @brief Sets an environment variable.
|
|
|
|
*
|
|
|
|
* If `update` is false, the environment variable will not be overwritten
|
|
|
|
* if it already exists. Keep in mind that true is still returned if the
|
|
|
|
* variable already exists and it's not being updated.
|
|
|
|
*
|
|
|
|
* This function is not thread safe. Do not call it from multiple threads
|
|
|
|
* and do not call it if a call to env_get() might be done from another
|
|
|
|
* thread at the time.
|
|
|
|
*
|
|
|
|
* @returns true on success, false on failure.
|
|
|
|
*
|
|
|
|
* @see env_get(), env_unset()
|
|
|
|
*/
|
2016-07-31 19:40:25 +00:00
|
|
|
inline bool env_set(
|
2017-02-16 17:48:14 +00:00
|
|
|
string_range name, string_range value, bool update = true
|
2016-07-31 19:40:25 +00:00
|
|
|
) {
|
2016-03-13 01:28:39 +00:00
|
|
|
char sbuf[2048];
|
|
|
|
char *buf = sbuf;
|
|
|
|
bool alloc = (name.size() + value.size() + 2) > sizeof(sbuf);
|
2016-07-31 19:40:25 +00:00
|
|
|
if (alloc) {
|
2016-03-13 01:28:39 +00:00
|
|
|
buf = new char[name.size() + value.size() + 2];
|
2016-07-31 19:40:25 +00:00
|
|
|
}
|
2016-03-13 01:28:39 +00:00
|
|
|
memcpy(buf, name.data(), name.size());
|
|
|
|
buf[name.size()] = '\0';
|
|
|
|
memcpy(&buf[name.size() + 1], value.data(), value.size());
|
|
|
|
buf[name.size() + value.size() + 1] = '\0';
|
2016-07-06 18:40:43 +00:00
|
|
|
#ifndef OSTD_PLATFORM_WIN32
|
2016-03-13 01:28:39 +00:00
|
|
|
bool ret = !setenv(buf, &buf[name.size() + 1], update);
|
2016-07-06 18:40:43 +00:00
|
|
|
#else
|
2016-07-31 19:40:25 +00:00
|
|
|
if (!update && GetEnvironmentVariable(buf, nullptr, 0)) {
|
2016-07-06 18:40:43 +00:00
|
|
|
return true;
|
2016-07-31 19:40:25 +00:00
|
|
|
}
|
2016-07-06 18:40:43 +00:00
|
|
|
bool ret = !!SetEnvironmentVariable(buf, &buf[name.size() + 1]);
|
|
|
|
#endif
|
2016-07-31 19:40:25 +00:00
|
|
|
if (alloc) {
|
2016-03-13 01:28:39 +00:00
|
|
|
delete[] buf;
|
2016-07-31 19:40:25 +00:00
|
|
|
}
|
2016-03-13 01:28:39 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-04-05 18:53:14 +00:00
|
|
|
/** @brief Unsets an environment varible.
|
|
|
|
*
|
|
|
|
* This function is not thread safe. Do not call it from multiple threads
|
|
|
|
* and do not call it if a call to env_get() might be done from another
|
|
|
|
* thread at the time.
|
|
|
|
*
|
|
|
|
* @returns true on success, false on failure.
|
|
|
|
*
|
|
|
|
* @see env_get(), env_set()
|
|
|
|
*/
|
2017-02-16 17:48:14 +00:00
|
|
|
inline bool env_unset(string_range name) {
|
2016-03-13 01:28:39 +00:00
|
|
|
char buf[256];
|
|
|
|
if (name.size() < sizeof(buf)) {
|
|
|
|
memcpy(buf, name.data(), name.size());
|
|
|
|
buf[name.size()] = '\0';
|
2016-07-06 18:40:43 +00:00
|
|
|
#ifndef OSTD_PLATFORM_WIN32
|
2016-03-13 01:28:39 +00:00
|
|
|
return !unsetenv(buf);
|
2016-07-06 18:40:43 +00:00
|
|
|
#else
|
|
|
|
return !!SetEnvironmentVariable(buf, nullptr);
|
|
|
|
#endif
|
2016-03-13 01:28:39 +00:00
|
|
|
}
|
2016-07-06 18:40:43 +00:00
|
|
|
#ifndef OSTD_PLATFORM_WIN32
|
2017-01-29 23:54:06 +00:00
|
|
|
return !unsetenv(std::string{name}.data());
|
2016-07-06 18:40:43 +00:00
|
|
|
#else
|
2017-01-29 23:54:06 +00:00
|
|
|
return !!SetEnvironmentVariable(std::string{name}.data(), nullptr);
|
2016-07-06 18:40:43 +00:00
|
|
|
#endif
|
2016-03-13 01:28:39 +00:00
|
|
|
}
|
|
|
|
|
2017-04-05 18:53:14 +00:00
|
|
|
/** @} */
|
|
|
|
|
2016-03-13 01:28:39 +00:00
|
|
|
} /* namespace ostd */
|
|
|
|
|
|
|
|
#endif
|
2017-04-05 18:53:14 +00:00
|
|
|
|
|
|
|
/** @} */
|