From 50f39cd752f7469cdbc46849a0aaf8a4dd8abf6f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 3 Nov 2021 10:53:10 -0400 Subject: [PATCH] implement and use a platform neutral abstraction of unsetenv(3) --- doc/src/Developer_platform.rst | 3 +++ src/platform.cpp | 24 +++++++++++++++++++++--- src/platform.h | 7 +++++++ unittest/cplusplus/test_lammps_class.cpp | 6 +----- unittest/utils/test_platform.cpp | 10 +++++++++- 5 files changed, 41 insertions(+), 9 deletions(-) diff --git a/doc/src/Developer_platform.rst b/doc/src/Developer_platform.rst index c9ecd30cec..cdc4bb6770 100644 --- a/doc/src/Developer_platform.rst +++ b/doc/src/Developer_platform.rst @@ -118,6 +118,9 @@ Environment variable functions .. doxygenfunction:: putenv :project: progguide +.. doxygenfunction:: unsetenv + :project: progguide + .. doxygenfunction:: list_pathenv :project: progguide diff --git a/src/platform.cpp b/src/platform.cpp index c701c37a80..708a42be8a 100644 --- a/src/platform.cpp +++ b/src/platform.cpp @@ -446,11 +446,11 @@ int platform::putenv(const std::string &vardef) auto found = vardef.find_first_of('='); #ifdef _WIN32 - // must assign a value to variable with _putenv() + // must assign a value to variable with _putenv_s() if (found == std::string::npos) - return _putenv(utils::strdup(vardef + "=1")); + return _putenv_s(vardef.c_str(), "1"); else - return _putenv(utils::strdup(vardef)); + return _putenv_s(vardef.substr(0, found).c_str(), vardef.substr(found+1).c_str()); #else if (found == std::string::npos) return setenv(vardef.c_str(), "", 1); @@ -460,6 +460,24 @@ int platform::putenv(const std::string &vardef) return -1; } +/* ---------------------------------------------------------------------- + unset environment variable +------------------------------------------------------------------------- */ + +int platform::unsetenv(const std::string &variable) +{ + if (variable.size() == 0) return -1; +#ifdef _WIN32 + // emulate POSIX semantics by returning -1 on trying to unset non-existing variable + const char *ptr = getenv(variable.c_str()); + if (!ptr) return -1; + // empty _putenv_s() definition deletes variable + return _putenv_s(variable.c_str(),""); +#else + return ::unsetenv(variable.c_str()); +#endif +} + /* ---------------------------------------------------------------------- split a "path" environment variable into a list ------------------------------------------------------------------------- */ diff --git a/src/platform.h b/src/platform.h index 95a0c3cc35..c079fd2cd1 100644 --- a/src/platform.h +++ b/src/platform.h @@ -125,6 +125,13 @@ namespace platform { int putenv(const std::string &vardef); + /*! Delete variable from the environment + * + * \param variable variable name + * \return -1 if failure otherwise 0 */ + + int unsetenv(const std::string &variable); + /*! Get list of entries in a path environment variable * * This provides a list of strings of the entries in an environment diff --git a/unittest/cplusplus/test_lammps_class.cpp b/unittest/cplusplus/test_lammps_class.cpp index 663c7358d9..3a1bde51ff 100644 --- a/unittest/cplusplus/test_lammps_class.cpp +++ b/unittest/cplusplus/test_lammps_class.cpp @@ -363,11 +363,7 @@ TEST(LAMMPS_init, NoOpenMP) FILE *fp = fopen("in.lammps_class_noomp", "w"); fputs("\n", fp); fclose(fp); -#if defined(__WIN32) - _putenv("OMP_NUM_THREADS"); -#else - unsetenv("OMP_NUM_THREADS"); -#endif + platform::unsetenv("OMP_NUM_THREADS"); const char *args[] = {"LAMMPS_init", "-in", "in.lammps_class_noomp", "-log", "none", "-nocite"}; char **argv = (char **)args; diff --git a/unittest/utils/test_platform.cpp b/unittest/utils/test_platform.cpp index 0f39534c31..ace546ba90 100644 --- a/unittest/utils/test_platform.cpp +++ b/unittest/utils/test_platform.cpp @@ -37,7 +37,7 @@ TEST(Platform, clock) ASSERT_GT(ct_used, 1e-4); } -TEST(Platform, putenv) +TEST(Platform, putenv_unsetenv) { const char *var = getenv("UNITTEST_VAR1"); ASSERT_EQ(var, nullptr); @@ -65,6 +65,14 @@ TEST(Platform, putenv) ASSERT_THAT(var, StrEq("one=two")); ASSERT_EQ(platform::putenv(""), -1); + + ASSERT_EQ(platform::unsetenv(""), -1); + ASSERT_EQ(platform::unsetenv("UNITTEST_VAR3=two"), -1); + var = getenv("UNITTEST_VAR1"); + ASSERT_NE(var, nullptr); + ASSERT_EQ(platform::unsetenv("UNITTEST_VAR1"), 0); + var = getenv("UNITTEST_VAR1"); + ASSERT_EQ(var, nullptr); } TEST(Platform, list_pathenv)