#include <cerrno> #include <cstring> #include <j/lang/env.hpp> namespace j { namespace lang { namespace Env { /** * 指定された環境変数の値を取得します。 * name に = が含まれている場合、= の前までをキーとして * 環境変数を検索します。 * * @param name 環境変数名 * @return 値 */ String get(const String &name) { String keyName = name; int eqPos = keyName.indexOf('='); if (eqPos >= 0) { keyName = std::move(keyName.substring(0, eqPos)); } #if (IS_WINDOWS) constexpr DWORD J_ENV_BUFFER_MAX = 32767; // Windows の環境変数の最大長は 327676 unique_ptr<char[]> buff = make_unique<char[]>(J_ENV_BUFFER_MAX); DWORD ret = GetEnvironmentVariable(keyName, &buff[0], J_ENV_BUFFER_MAX); if (ret != 0) { return String(buff.get()); } return String(); #else return String(getenv(keyName)); #endif } /** * 指定された name の環境変数が存在しない場合、環境変数 name に指定された値 value を設定します。 * overwrite が true の場合、その値を value に変更します。 * false の場合、name の値を変更せず true を返します。 * name に '=' 文字が含まれている場合、設定に失敗し false を返します。 * * @param name 環境変数名 * @param value 値 * @param overwrite true/false (上書きする/しない) * @return true/false (設定成功/失敗) */ bool set(const String &name, const String &value, bool overwrite) { #if (IS_WINDOWS) int eqPos = name.indexOf('='); if (eqPos >= 0) { return false; } char buff[1]; DWORD ret = GetEnvironmentVariable(name, buff, 1); if ((!overwrite) && (ret != 0)) { // 既に環境変数が存在し、overwrite が false のため成功 return true; } ret = SetEnvironmentVariable(name, value); return (ret != 0); #else int overwriteFlag = overwrite ? 1 : 0; int ret = setenv(name, value, overwriteFlag); return (ret == 0); #endif } /** * 変数 name の環境変数を削除します。 * * @param name 環境変数名 * @return true/false (成功/失敗) */ bool unset(const String &name) { #if (IS_WINDOWS) BOOL ret = SetEnvironmentVariable(name, NULL); return (ret != 0); #else int ret = unsetenv(name); return (ret == 0); #endif } } // namespace Errno } // namespace lang } // namespace j