#9317 add method cleanDuplicateEnvVars() to correct the broken environment with duplicate PATH values passed by Yosemite's launchd(8)

This commit is contained in:
Stephan Witt 2014-11-16 17:21:46 +01:00
parent f110ef2f41
commit 941868e8d7

View File

@ -77,6 +77,10 @@
using namespace std;
using namespace lyx::support;
#if defined (USE_MACOSX_PACKAGING)
#include <crt_externs.h>
#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<std::string> seen;
std::set<std::string> 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<std::string>::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();