From: Stephan Witt Date: Sun, 16 Nov 2014 16:21:46 +0000 (+0100) Subject: #9317 add method cleanDuplicateEnvVars() to correct the broken environment with dupli... X-Git-Tag: 2.2.0alpha1~1537 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=941868e8d7ee2b749ffd2652dc18ab91401a1752;p=features.git #9317 add method cleanDuplicateEnvVars() to correct the broken environment with duplicate PATH values passed by Yosemite's launchd(8) --- diff --git a/src/LyX.cpp b/src/LyX.cpp index 023f80dfc1..f805456cc7 100644 --- a/src/LyX.cpp +++ b/src/LyX.cpp @@ -77,6 +77,10 @@ using namespace std; using namespace lyx::support; +#if defined (USE_MACOSX_PACKAGING) +#include +#endif + namespace lyx { namespace Alert = frontend::Alert; @@ -706,6 +710,55 @@ void LyX::printError(ErrorItem const & ei) cerr << to_utf8(tmp) << endl; } +#if defined (USE_MACOSX_PACKAGING) +namespace { + // Unexposed--extract an environment variable name from its NAME=VALUE + // representation + std::string varname(const char* line) + { + size_t nameLen = strcspn(line, "="); + if (nameLen == strlen(line)) { + return std::string(); + } else { + return std::string(line, nameLen); + } + } +} + +void cleanDuplicateEnvVars() +{ + std::set seen; + std::set dupes; + + // Create a list of the environment variables that appear more than once + for (char **read = *_NSGetEnviron(); *read; read++) { + std::string name = varname(*read); + if (name.size() == 0) { + continue; + } + if (seen.find(name) != seen.end()) { + dupes.insert(name); + } else { + seen.insert(name); + } + } + + // Loop over the list of duplicated variables + for (std::set::iterator dupe = dupes.begin(); dupe != dupes.end(); dupe++) { + const char *name = (*dupe).c_str(); + char *val = getenv(name); + if (val != NULL) { + LYXERR(Debug::INIT, "Duplicate environment variable: " << name); + // unsetenv removes *all* instances of the variable from the environment + unsetenv(name); + + // replace with the value from getenv (in practice appears to be the + // first value in the list) + setenv(name, val, 0); + } + } +} +#endif bool LyX::init() { @@ -718,6 +771,10 @@ bool LyX::init() signal(SIGTERM, error_handler); // SIGPIPE can be safely ignored. +#if defined (USE_MACOSX_PACKAGING) + cleanDuplicateEnvVars(); +#endif + lyxrc.tempdir_path = package().temp_dir().absFileName(); lyxrc.document_path = package().document_dir().absFileName();