From 9574d680e2e15094ba8173c28f1fa4c46c473fe3 Mon Sep 17 00:00:00 2001 From: Richard Heck Date: Mon, 27 Oct 2014 11:15:14 -0400 Subject: [PATCH] Fixes for LyX on OSX 10.10 (Yosemite). From Stephan Witt. --- lib/scripts/lyxpreview_tools.py | 4 +- src/graphics/PreviewLoader.cpp | 3 ++ src/support/ForkedCalls.cpp | 86 ++++++++++++++++++++++++++++++++- src/support/Systemcall.cpp | 20 ++++++++ 4 files changed, 110 insertions(+), 3 deletions(-) diff --git a/lib/scripts/lyxpreview_tools.py b/lib/scripts/lyxpreview_tools.py index 0f595e2bf3..de104b5b91 100644 --- a/lib/scripts/lyxpreview_tools.py +++ b/lib/scripts/lyxpreview_tools.py @@ -122,11 +122,11 @@ def run_command_popen(cmd, stderr2stdout): unix = True if stderr2stdout: pipe = subprocess.Popen(cmd, shell=unix, close_fds=unix, stdin=subprocess.PIPE, \ - stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, env=os.environ) cmd_stdout = pipe.communicate()[0] else: pipe = subprocess.Popen(cmd, shell=unix, close_fds=unix, stdin=subprocess.PIPE, \ - stdout=subprocess.PIPE, universal_newlines=True) + stdout=subprocess.PIPE, universal_newlines=True, env=os.environ) (cmd_stdout, cmd_stderr) = pipe.communicate() if cmd_stderr: sys.stderr.write(cmd_stderr) diff --git a/src/graphics/PreviewLoader.cpp b/src/graphics/PreviewLoader.cpp index b5d464d344..8f1cb126ed 100644 --- a/src/graphics/PreviewLoader.cpp +++ b/src/graphics/PreviewLoader.cpp @@ -589,6 +589,9 @@ void PreviewLoader::Impl::startLoading(bool wait) cs << pconverter_->command << " " << quoteName(latexfile.toFilesystemEncoding()) << " --dpi " << int(font_scaling_factor); + if (lyxerr.debugging(Debug::GRAPHICS)) { + cs << " --verbose"; + } // FIXME XHTML // The colors should be customizable. diff --git a/src/support/ForkedCalls.cpp b/src/support/ForkedCalls.cpp index d77248eadc..b37405ceb5 100644 --- a/src/support/ForkedCalls.cpp +++ b/src/support/ForkedCalls.cpp @@ -12,6 +12,8 @@ #include +#include "LyXRC.h" + #include "support/ForkedCalls.h" #include "support/debug.h" @@ -20,6 +22,7 @@ #include "support/lyxlib.h" #include "support/os.h" #include "support/Timeout.h" +#include "support/environment.h" #include "support/bind.h" @@ -46,6 +49,9 @@ using namespace std; +#ifdef USE_MACOSX_PACKAGING +#include +#endif namespace lyx { @@ -304,7 +310,10 @@ int ForkedCall::generateChild() return 1; // Make sure that a V2 python is run, if available. - string const line = cmd_prefix_ + + string const line = +#ifndef USE_MACOSX_PACKAGING + cmd_prefix_ + +#endif (prefixIs(command_, "python -tt") ? os::python() + command_.substr(10) : command_); @@ -387,7 +396,66 @@ int ForkedCall::generateChild() lyxerr << '\t'<< *ait << '\n'; lyxerr << "" << endl; } +#ifdef USE_MACOSX_PACKAGING + string path = getEnv("PATH"); + + // Combine TEXINPUTS prefix and environment + string ptex = getEnv("TEXINPUTS"); + if (!lyxrc.texinputs_prefix.empty()) { + string const texinputs = lyxrc.texinputs_prefix + ":" + ptex; + setEnv("TEXINPUTS", texinputs); + } + + char ** var = *_NSGetEnviron(); + // See #9308 - "LyX cannot work properly in Yosemite" + // This is a workaround for the POSIX incompatibility of Yosemite + // Duplicate the environment. + // Otherwise it's not passed when code inside of bundles + // forks a child and executes a sub-program. + vector envp; + for (; *var != 0; ++var) { + if (lyxerr.debugging(Debug::DEBUG)) { + lyxerr << "env: " << *var << '\n'; + } + envp.push_back(strdup(*var)); + } + envp.push_back(0); + envp.push_back(0); + + vector cmds; + if (0 == strchr(argv[0], '/')) { + while (!path.empty()) { + string element; + path = split(path,element,':'); + if (!suffixIs(element,'/')) element += "/"; + element += argv[0]; + if (lyxerr.debugging(Debug::GRAPHICS)) { + lyxerr << "try: " << element.data() << '\n'; + } + cmds.push_back(strdup(element.data())); + } + } + cmds.push_back(0); + pid_t const cpid = ::fork(); + if (cpid == 0) { + // Child + if (0 == strchr(argv[0], '/')) { + vector::iterator cit = cmds.begin(); + vector::iterator const cend = cmds.end(); + for (; cit != cend; ++cit) { + if (*cit) + execve(*cit, &*argv.begin(), &*envp.begin()); + } + } else { + execve(argv[0], &*argv.begin(), &*envp.begin()); + } + // If something goes wrong, we end up here + lyxerr << "execvp of \"" << command_ << "\" failed: " + << strerror(errno) << endl; + _exit(1); + } +#else pid_t const cpid = ::fork(); if (cpid == 0) { // Child @@ -398,6 +466,7 @@ int ForkedCall::generateChild() << strerror(errno) << endl; _exit(1); } +#endif #else // Windows @@ -418,6 +487,21 @@ int ForkedCall::generateChild() } #endif +#ifdef USE_MACOSX_PACKAGING + // Free duplicated command candidates. + vector::iterator cit = cmds.begin(); + vector::iterator const cend = cmds.end(); + for (; cit != cend; ++cit) + if (*cit) free(*cit); + // Free duplicated environment. + vector::iterator eit = envp.begin(); + vector::iterator const eend = envp.end(); + for (; eit != eend; ++eit) + if (*eit) free(*eit); + // Restore TEXINPUTS. + setEnv("TEXINPUTS", ptex); +#endif + if (cpid < 0) { // Error. lyxerr << "Could not fork: " << strerror(errno) << endl; diff --git a/src/support/Systemcall.cpp b/src/support/Systemcall.cpp index 34d645e349..26bd92e7f5 100644 --- a/src/support/Systemcall.cpp +++ b/src/support/Systemcall.cpp @@ -376,8 +376,28 @@ void SystemcallPrivate::startProcess(QString const & cmd, string const & path, b QProcess* released = releaseProcess(); delete released; } else if (process_) { +#ifdef Q_OS_MAC + process_->setProcessEnvironment(QProcessEnvironment::systemEnvironment()); + if (!lyxrc.texinputs_prefix.empty()) { + QProcessEnvironment environ = process_->processEnvironment(); + string const texinputs = fromqstr(environ.value("TEXINPUTS")); + string const texinputs_prefix = os::latex_path_list( + path.empty() ? lyxrc.texinputs_prefix : replaceCurdirPath(path, lyxrc.texinputs_prefix)); + environ.insert("TEXINPUTS", toqstr(".:" + texinputs_prefix + ':' + texinputs)); + process_->setProcessEnvironment(environ); + } + if (!lyxrc.path_prefix.empty()) { + QProcessEnvironment environ = process_->processEnvironment(); + string const path = fromqstr(environ.value("PATH")); + environ.insert("PATH", toqstr(lyxrc.path_prefix + ':' + path)); + process_->setProcessEnvironment(environ); + } + state = SystemcallPrivate::Starting; + process_->start(cmd_); +#else state = SystemcallPrivate::Starting; process_->start(toqstr(latexEnvCmdPrefix(path)) + cmd_); +#endif } } -- 2.39.5