X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fsupport%2FSystemcall.cpp;h=a270b4118dbfc59584518317b37bc948b525e7c3;hb=17c827d1774cb8a73d2d1973261a83b695209386;hp=cc2c3814ab761c17ec360316f1b071e7ea5e21aa;hpb=2a371bb4b3235462ea6632d31d50ee447933bef8;p=features.git diff --git a/src/support/Systemcall.cpp b/src/support/Systemcall.cpp index cc2c3814ab..a270b4118d 100644 --- a/src/support/Systemcall.cpp +++ b/src/support/Systemcall.cpp @@ -24,7 +24,6 @@ #include "support/ProgressInterface.h" #include "LyX.h" -#include "LyXRC.h" #include #include @@ -40,7 +39,7 @@ struct Sleep : QThread { - static void millisec(unsigned long ms) + static void millisec(unsigned long ms) { QThread::usleep(ms * 1000); } @@ -55,7 +54,7 @@ namespace lyx { namespace support { -class ProgressDummy : public ProgressInterface +class ProgressDummy : public ProgressInterface { public: ProgressDummy() {} @@ -206,7 +205,7 @@ string const parsecmd(string const & incmd, string & infile, string & outfile, in_double_quote = !in_double_quote; } } else if (c == '\\' && !escaped) { - escaped = !escaped; + escaped = true; } else if (c == '>' && !(in_double_quote || escaped)) { if (suffixIs(outcmd[o], " 2")) { outcmd[o] = rtrim(outcmd[o], "2"); @@ -231,9 +230,14 @@ string const parsecmd(string const & incmd, string & infile, string & outfile, return trim(outcmd[0]); } -} // namespace anon +} // namespace +void Systemcall::killscript() +{ + SystemcallPrivate::kill_script = true; +} + int Systemcall::startscript(Starttype how, string const & what, string const & path, string const & lpath, @@ -252,42 +256,34 @@ int Systemcall::startscript(Starttype how, string const & what, parsecmd(what_ss, infile, outfile, errfile).c_str()); SystemcallPrivate d(infile, outfile, errfile); + bool do_events = process_events || how == WaitLoop; -#ifdef Q_OS_WIN32 - // QProcess::startDetached cannot provide environment variables. When the - // environment variables are set using the latexEnvCmdPrefix and the process - // is started with QProcess::startDetached, a console window is shown every - // time a viewer is started. To avoid this, we fall back on Windows to the - // original implementation that creates a QProcess object. - d.startProcess(cmd, path, lpath, false); - if (!d.waitWhile(SystemcallPrivate::Starting, process_events, -1)) { - LYXERR0("Systemcall: '" << cmd << "' did not start!"); - LYXERR0("error " << d.errorMessage()); - return 10; - } - if (how == DontWait) { - d.releaseProcess(); - return 0; - } -#else d.startProcess(cmd, path, lpath, how == DontWait); if (how == DontWait && d.state == SystemcallPrivate::Running) - return 0; + return OK; if (d.state == SystemcallPrivate::Error - || !d.waitWhile(SystemcallPrivate::Starting, process_events, -1)) { - LYXERR0("Systemcall: '" << cmd << "' did not start!"); - LYXERR0("error " << d.errorMessage()); - return 10; + || !d.waitWhile(SystemcallPrivate::Starting, do_events, -1)) { + if (d.state == SystemcallPrivate::Error) { + LYXERR0("Systemcall: '" << cmd << "' did not start!"); + LYXERR0("error " << d.errorMessage()); + return NOSTART; + } else if (d.state == SystemcallPrivate::Killed) { + LYXERR0("Killed: " << cmd); + return KILLED; + } } -#endif - if (!d.waitWhile(SystemcallPrivate::Running, process_events, + if (!d.waitWhile(SystemcallPrivate::Running, do_events, os::timeout_min() * 60 * 1000)) { + if (d.state == SystemcallPrivate::Killed) { + LYXERR0("Killed: " << cmd); + return KILLED; + } LYXERR0("Systemcall: '" << cmd << "' did not finish!"); LYXERR0("error " << d.errorMessage()); LYXERR0("status " << d.exitStatusMessage()); - return 20; + return TIMEOUT; } int const exit_code = d.exitCode(); @@ -299,6 +295,9 @@ int Systemcall::startscript(Starttype how, string const & what, } +bool SystemcallPrivate::kill_script = false; + + SystemcallPrivate::SystemcallPrivate(std::string const & sf, std::string const & of, std::string const & ef) : state(Error), process_(new QProcess), out_index_(0), err_index_(0), @@ -371,6 +370,15 @@ void SystemcallPrivate::startProcess(QString const & cmd, string const & path, cmd_ = cmd; if (detached) { state = SystemcallPrivate::Running; +#ifdef Q_OS_WIN32 + // Avoid opening a console window when a viewer is started + if (in_file_.empty()) + process_->setStandardInputFile(QProcess::nullDevice()); + if (out_file_.empty()) + process_->setStandardOutputFile(QProcess::nullDevice()); + if (err_file_.empty()) + process_->setStandardErrorFile(QProcess::nullDevice()); +#endif if (!QProcess::startDetached(toqstr(latexEnvCmdPrefix(path, lpath)) + cmd_)) { state = SystemcallPrivate::Error; return; @@ -384,18 +392,19 @@ void SystemcallPrivate::startProcess(QString const & cmd, string const & path, } -void SystemcallPrivate::processEvents() -{ - if (process_events_) { - QCoreApplication::processEvents(/*QEventLoop::ExcludeUserInputEvents*/); - } -} - - -void SystemcallPrivate::waitAndProcessEvents() +bool SystemcallPrivate::waitAndCheck() { Sleep::millisec(100); - processEvents(); + if (kill_script) { + // is there a better place to reset this? + process_->kill(); + state = Killed; + kill_script = false; + LYXERR0("Export Canceled!!"); + return false; + } + QCoreApplication::processEvents(/*QEventLoop::ExcludeUserInputEvents*/); + return true; } @@ -410,7 +419,7 @@ bool queryStopCommand(QString const & cmd) 1, 1, _("&Stop it"), _("Let it &run")) == 0; } -} +} // namespace bool SystemcallPrivate::waitWhile(State waitwhile, bool process_events, int timeout) @@ -450,16 +459,21 @@ bool SystemcallPrivate::waitWhile(State waitwhile, bool process_events, int time // process events while waiting, no timeout if (timeout == -1) { while (state == waitwhile && state != Error) { - waitAndProcessEvents(); + // check for cancellation of background process + if (!waitAndCheck()) + return false; } return state != Error; - } + } // process events while waiting with timeout QTime timer; timer.start(); while (state == waitwhile && state != Error && !timedout) { - waitAndProcessEvents(); + // check for cancellation of background process + if (!waitAndCheck()) + return false; + if (timer.elapsed() > timeout) { bool stop = queryStopCommand(cmd_); // The command may have finished in the meantime @@ -556,7 +570,7 @@ void SystemcallPrivate::processError(QProcess::ProcessError) } -QString SystemcallPrivate::errorMessage() const +QString SystemcallPrivate::errorMessage() const { if (!process_) return "No QProcess available";