/* ============================================================================= * scpp_env.cpp * Copyright (c) 2003 - 2011 Nomura Kei * LICENSE : * LGPL (GNU Lesser General General Public License - Version 3,29 June 2007) * http://www.gnu.org/copyleft/lesser.html * ============================================================================= * * 環境変数操作 * * 環境変数の値を取得/設定/削除します * */ #include <iostream> #include <cstdlib> #include <scpp_os.hpp> #include <scpp_errno.hpp> #include <scpp_env.hpp> namespace scpp { namespace Env { /// 環境変数用一時バッファサイズ (現状, Windows でのみ使用される) const int SCPP_ENV_BUFFER_MAX = 4096; /** * 指定された name の環境変数を取得します. * name に = が含まれる場合, = の前までをキーとして環境変数を検索します. * * 使用例) * @code * // sample.cpp * #include <iostream> * #include <scpp_env.hpp> * * int main(int argc, char* argv[]) * { * std::string envVal; * bool ret = scpp::env::getEnv(&envVal, "LANG"); * if (ret) * { * std::cout << "LANG=" << envVal << std::endl; * } * return 0; * } * ----- * $ g++ `scpp-config --cflags` -o sample sample.cpp `scpp-config --libs` * $ LANG=C * $ ./sample * LANG=C * @endcode * * @param buf 環境変数の値格納用文字バッファ * @param name 環境変数 */ bool getEnv(std::string* buf, const std::string& name) { // = より前までを nameKey に設定 std::string::size_type index = name.find("="); std::string nameKey = (index == std::string::npos) ? name : name.substr(0, index); #if (SCPP_IS_WINDOWS) // for Windows char tmpBuf[SCPP_ENV_BUFFER_MAX]; DWORD ret = GetEnvironmentVariable(nameKey.c_str(), (LPSTR) tmpBuf, sizeof(tmpBuf)); if (ret != 0) { *buf = tmpBuf; return true; } *buf = ""; return false; #else // for not Windows char* tmpBuf = getenv(nameKey.c_str()); if (tmpBuf != 0) { *buf = tmpBuf; return true; } *buf = ""; return false; #endif } /** * 環境変数設定. * * name が存在しない場合, 環境変数 name に値 value を設定し, * 環境に追加します. name が環境変数に存在する場合, * overwrite が true ならば, その値を value に変更します. * false ならば name の値を変更せず true を返します. * * name に '=' 文字が含まれている場合, * エラー番号に SCPP_EINVAL を設定し, エラーを返します. * * 使用例) * @code * // sample.cpp * #include <iostream> * #include <scpp_env.hpp> * * int main(int argc, char* argv[]) * { * bool ret = scpp::env::setEnv("LANG", "C"); * if (ret) * { * std::string envVal; * scpp::env::getEnv(&envVal, "LANG", true); * std::cout << "LANG=" << envVal << std::endl; * } * return 0; * } * ----- * $ g++ `scpp-config --cflags` -o sample sample.cpp `scpp-config --libs` * $ ./sample * LANG=C * @endcode * * @param name 環境変数名 * @param value 値 * @param overwrite true/false (上書きする/しない) * @return true/false (設定成功/失敗) */ bool setEnv(const std::string& name, const std::string& value, bool overwrite) { #if (SCPP_IS_WINDOWS) // for Windows std::string::size_type index = name.find("="); if (index != std::string::npos) { // = が含まれる Errno::setError(SCPP_EINVAL); return false; } // name が既に存在するか確認 LPSTR buf[1]; DWORD ret = GetEnvironmentVariable(name.c_str(), (LPSTR) buf, 1); if ((!overwrite) && (ret != 0)) { // 上書きしない場合, 既に環境変数にある -> true return true; } // 環境変数を設定する ret = SetEnvironmentVariable(name.c_str(), value.c_str()); return (ret != 0); #else // for Windows 以外 // = が含まれている場合, setenv 内でエラーになる int ret = setenv(name.c_str(), value.c_str(), overwrite); return (ret == 0); #endif } /** * 環境変数 name を環境から削除します. * * @param name 環境変数名 * @return true/false (削除成功/失敗) */ bool unsetEnv(const std::string& name) { #if (SCPP_IS_WINDOWS) // for Windows BOOL ret = SetEnvironmentVariable(name.c_str(), 0); return (ret != 0); #else // for Windows 以外 int ret = unsetenv(name.c_str()); return (ret == 0); #endif } } // namespace Env } // namespace scpp