all repos — fluxbox @ 6280b9de0545a8af80ea2f54f5ebe4492a690dbf

custom fork of the fluxbox windowmanager

replaced setenv() completly by putenv(). since putenv() really puts the
*string into the environment we need to track what we putenv.
mathias mathias
commit

6280b9de0545a8af80ea2f54f5ebe4492a690dbf

parent

c55dce44fafa732a9ff01c3b9ea28df00feff8c7

1 files changed, 30 insertions(+), 6 deletions(-)

jump to
M src/FbCommands.ccsrc/FbCommands.cc

@@ -37,6 +37,7 @@ #include <unistd.h>

#include <fstream> #include <iostream> +#include <set> #ifdef HAVE_CSTDLIB #include <cstdlib>

@@ -145,12 +146,35 @@ m_name(name), m_value(value) {

} void ExportCmd::execute() { -// TODO: we need to analyze this a bit more -#if defined sgi && ! defined GCC - putenv((m_name + "=" + m_value).c_str()); -#else - setenv(m_name.c_str(), m_value.c_str(), 1); -#endif + + // the setenv()-routine is not everywhere available and + // putenv() doesnt manage the strings in the environment + // and hence we have to do that on our own to avoid memleaking + static std::set<char*> stored; + char* newenv = new char[m_name.size() + m_value.size() + 2]; + if (newenv) { + + char* oldenv = getenv(m_name.c_str()); + + // oldenv points to the value .. we have to go back a bit + if (oldenv && stored.find(oldenv - (m_name.size() + 1)) != stored.end()) + oldenv -= (m_name.size() + 1); + else + oldenv = NULL; + + memset(newenv, 0, m_name.size() + m_value.size() + 2); + strcat(newenv, m_name.c_str()); + strcat(newenv, "="); + strcat(newenv, m_value.c_str()); + + if (putenv(newenv) == 0) { + if (oldenv) { + stored.erase(oldenv); + delete[] oldenv; + } + stored.insert(newenv); + } + } }