X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fsupport%2FSystemcall.cpp;h=3cb420bb518ebd1ccd106206e81c2dae48ed815e;hb=68957712dd4228a76b14611108fb61d926071e1f;hp=054be5f949e529cec1c8c667eeb8e427e46f91be;hpb=314b79576ecd43699ee530a28bc731f47cf7c8b2;p=lyx.git diff --git a/src/support/Systemcall.cpp b/src/support/Systemcall.cpp index 054be5f949..3cb420bb51 100644 --- a/src/support/Systemcall.cpp +++ b/src/support/Systemcall.cpp @@ -28,7 +28,7 @@ #include #include #include - +#include #define USE_QPROCESS @@ -52,7 +52,8 @@ namespace support { // Reuse of instance #ifndef USE_QPROCESS -int Systemcall::startscript(Starttype how, string const & what) +int Systemcall::startscript(Starttype how, string const & what, + bool /*process_events*/) { string command = what; @@ -99,28 +100,28 @@ string const parsecmd(string const & cmd, string & outfile) -int Systemcall::startscript(Starttype how, string const & what) +int Systemcall::startscript(Starttype how, string const & what, bool process_events) { string outfile; QString cmd = toqstr(parsecmd(what, outfile)); SystemcallPrivate d(outfile); - bool processEvents = false; d.startProcess(cmd); - if (!d.waitWhile(SystemcallPrivate::Starting, processEvents, 3000)) { - LYXERR0("QProcess " << cmd << " did not start!"); + if (!d.waitWhile(SystemcallPrivate::Starting, process_events, -1)) { + LYXERR0("Systemcall: '" << cmd << " did not start!"); LYXERR0("error " << d.errorMessage()); return 10; } if (how == DontWait) { - // TODO delete process later + QProcess* released = d.releaseProcess(); + (void) released; // TODO who deletes it? return 0; } - if (!d.waitWhile(SystemcallPrivate::Running, processEvents, 180000)) { - LYXERR0("QProcess " << cmd << " did not finished!"); + if (!d.waitWhile(SystemcallPrivate::Running, process_events, 180000)) { + LYXERR0("Systemcall: '" << cmd << "' did not finished!"); LYXERR0("error " << d.errorMessage()); LYXERR0("status " << d.exitStatusMessage()); return 20; @@ -128,20 +129,16 @@ int Systemcall::startscript(Starttype how, string const & what) int const exit_code = d.exitCode(); if (exit_code) { - LYXERR0("QProcess " << cmd << " finished!"); - LYXERR0("error " << exit_code << ": " << d.errorMessage()); + LYXERR0("Systemcall: '" << cmd << "' finished with exit code " << exit_code); } - d.flush(); - d.killProcess(); - return exit_code; } SystemcallPrivate::SystemcallPrivate(const std::string& of) : - proc_(new QProcess), outindex_(0), - errindex_(0), showout_(false), showerr_(false), outfile(of) + proc_(new QProcess), outindex_(0), errindex_(0), + outfile(of), showout_(false), showerr_(false), process_events(false) { if (!outfile.empty()) { // Check whether we have to simply throw away the output. @@ -163,23 +160,39 @@ SystemcallPrivate::SystemcallPrivate(const std::string& of) : void SystemcallPrivate::startProcess(const QString& cmd) { - state = SystemcallPrivate::Starting; - proc_->start(cmd); + if (proc_) { + state = SystemcallPrivate::Starting; + proc_->start(cmd); + } +} + + +void SystemcallPrivate::processEvents() +{ + if(process_events) { + //static int count = 0; qDebug() << count++ << ": waitAndProcessEvents"; + QCoreApplication::processEvents(QEventLoop::AllEvents); + } } void SystemcallPrivate::waitAndProcessEvents() { Sleep::millisec(100); - QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); + processEvents(); } -bool SystemcallPrivate::waitWhile(State waitwhile, bool processEvents, int timeout) +bool SystemcallPrivate::waitWhile(State waitwhile, bool proc_events, int timeout) { + if (!proc_) + return false; + + process_events = proc_events; + // Block GUI while waiting, // relay on QProcess' wait functions - if (!processEvents) { + if (!process_events) { if (waitwhile == Starting) return proc_->waitForStarted(timeout); if (waitwhile == Running) @@ -205,9 +218,10 @@ bool SystemcallPrivate::waitWhile(State waitwhile, bool processEvents, int timeo } - SystemcallPrivate::~SystemcallPrivate() { + flush(); + if (outindex_) { outdata_[outindex_] = '\0'; outindex_ = 0; @@ -220,25 +234,30 @@ SystemcallPrivate::~SystemcallPrivate() cerr << errdata_; } cerr.flush(); + + killProcess(); } void SystemcallPrivate::flush() { - // If the output has been redirected, we write it all at once. - // Even if we are not running in a terminal, the output could go - // to some log file, for example ~/.xsession-errors on *nix. - if (!os::is_terminal(os::STDOUT) && outfile.empty()) - cout << fromqstr(QString::fromLocal8Bit( - proc_->readAllStandardOutput().data())); - if (!os::is_terminal(os::STDERR)) - cerr << fromqstr(QString::fromLocal8Bit( - proc_->readAllStandardError().data())); + if (proc_) { + // If the output has been redirected, we write it all at once. + // Even if we are not running in a terminal, the output could go + // to some log file, for example ~/.xsession-errors on *nix. + if (!os::is_terminal(os::STDOUT) && outfile.empty()) + cout << fromqstr(QString::fromLocal8Bit( + proc_->readAllStandardOutput().data())); + if (!os::is_terminal(os::STDERR)) + cerr << fromqstr(QString::fromLocal8Bit( + proc_->readAllStandardError().data())); + } } + void SystemcallPrivate::stdOut() { - if (showout_) { + if (proc_ && showout_) { char c; proc_->setReadChannel(QProcess::StandardOutput); while (proc_->getChar(&c)) { @@ -250,12 +269,13 @@ void SystemcallPrivate::stdOut() } } } + processEvents(); } void SystemcallPrivate::stdErr() { - if (showerr_) { + if (proc_ && showerr_) { char c; proc_->setReadChannel(QProcess::StandardError); while (proc_->getChar(&c)) { @@ -267,10 +287,25 @@ void SystemcallPrivate::stdErr() } } } + processEvents(); +} + + +void SystemcallPrivate::processStarted() +{ + state = Running; + // why do we get two started signals? + //disconnect(proc_, SIGNAL(started()), this, SLOT(processStarted())); +} + + +void SystemcallPrivate::processFinished(int, QProcess::ExitStatus) +{ + state = Finished; } -void SystemcallPrivate::processError(QProcess::ProcessError err) +void SystemcallPrivate::processError(QProcess::ProcessError) { state = Error; } @@ -278,6 +313,9 @@ void SystemcallPrivate::processError(QProcess::ProcessError err) QString SystemcallPrivate::errorMessage() const { + if (!proc_) + return "No QProcess available"; + QString message; switch (proc_->error()) { case QProcess::FailedToStart: @@ -307,22 +345,11 @@ QString SystemcallPrivate::errorMessage() const } -void SystemcallPrivate::processStarted() -{ - state = Running; - // why do we get two started signals? - //disconnect(proc_, SIGNAL(started()), this, SLOT(processStarted())); -} - - -void SystemcallPrivate::processFinished(int, QProcess::ExitStatus status) -{ - state = Finished; -} - - QString SystemcallPrivate::exitStatusMessage() const { + if (!proc_) + return "No QProcess available"; + QString message; switch (proc_->exitStatus()) { case QProcess::NormalExit: @@ -338,24 +365,39 @@ QString SystemcallPrivate::exitStatusMessage() const return message; } + int SystemcallPrivate::exitCode() { + if (!proc_) + return -1; + return proc_->exitCode(); } +QProcess* SystemcallPrivate::releaseProcess() +{ + QProcess* released = proc_; + proc_ = 0; + return released; +} + + void SystemcallPrivate::killProcess() { killProcess(proc_); } + void SystemcallPrivate::killProcess(QProcess * p) { - p->disconnect(); - p->closeReadChannel(QProcess::StandardOutput); - p->closeReadChannel(QProcess::StandardError); - p->close(); - delete p; + if (p) { + p->disconnect(); + p->closeReadChannel(QProcess::StandardOutput); + p->closeReadChannel(QProcess::StandardError); + p->close(); + delete p; + } }