From 941868e8d7ee2b749ffd2652dc18ab91401a1752 Mon Sep 17 00:00:00 2001 From: Stephan Witt Date: Sun, 16 Nov 2014 17:21:46 +0100 Subject: [PATCH] #9317 add method cleanDuplicateEnvVars() to correct the broken environment with duplicate PATH values passed by Yosemite's launchd(8) --- src/LyX.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) 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(); -- 2.39.2