forked from qt-creator/qt-creator
Utils: Add fully blocking way to run a binary to SynchronousProcess
This does not use a nested event loop. Change-Id: I581acdd07546dc633ff4ce371c69b72a6f6c7a8f Reviewed-by: Alessandro Portale <alessandro.portale@theqtcompany.com> Reviewed-by: Vikas Pachdha <vikas.pachdha@theqtcompany.com>
This commit is contained in:
@@ -449,6 +449,48 @@ SynchronousProcessResponse SynchronousProcess::run(const QString &binary,
|
||||
return d->m_result;
|
||||
}
|
||||
|
||||
SynchronousProcessResponse SynchronousProcess::runBlocking(const QString &binary, const QStringList &args)
|
||||
{
|
||||
d->clearForRun();
|
||||
|
||||
// On Windows, start failure is triggered immediately if the
|
||||
// executable cannot be found in the path. Do not start the
|
||||
// event loop in that case.
|
||||
d->m_binary = binary;
|
||||
d->m_process.start(binary, args, QIODevice::ReadOnly);
|
||||
if (!d->m_process.waitForStarted(d->m_maxHangTimerCount * 1000)) {
|
||||
d->m_result.result = SynchronousProcessResponse::StartFailed;
|
||||
return d->m_result;
|
||||
}
|
||||
d->m_process.closeWriteChannel();
|
||||
if (d->m_process.waitForFinished(d->m_maxHangTimerCount * 1000)) {
|
||||
if (d->m_process.state() == QProcess::Running) {
|
||||
d->m_result.result = SynchronousProcessResponse::Hang;
|
||||
d->m_process.terminate();
|
||||
if (d->m_process.waitForFinished(1000) && d->m_process.state() == QProcess::Running) {
|
||||
d->m_process.kill();
|
||||
d->m_process.waitForFinished(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QTC_ASSERT(d->m_process.state() == QProcess::NotRunning, return d->m_result);
|
||||
d->m_result.exitCode = d->m_process.exitCode();
|
||||
if (d->m_result.result != SynchronousProcessResponse::StartFailed) {
|
||||
if (d->m_process.exitStatus() != QProcess::NormalExit)
|
||||
d->m_result.result = SynchronousProcessResponse::TerminatedAbnormally;
|
||||
else
|
||||
d->m_result.result = (exitCodeInterpreter())(d->m_result.exitCode);
|
||||
}
|
||||
processStdOut(false);
|
||||
processStdErr(false);
|
||||
|
||||
d->m_result.stdOut = d->m_stdOut.data;
|
||||
d->m_result.stdErr = d->m_stdErr.data;
|
||||
|
||||
return d->m_result;
|
||||
}
|
||||
|
||||
bool SynchronousProcess::terminate()
|
||||
{
|
||||
return stopProcess(d->m_process);
|
||||
|
||||
@@ -119,7 +119,10 @@ public:
|
||||
void setExitCodeInterpreter(const ExitCodeInterpreter &interpreter);
|
||||
ExitCodeInterpreter exitCodeInterpreter() const;
|
||||
|
||||
// Starts an nested event loop and runs the binary with the arguments
|
||||
SynchronousProcessResponse run(const QString &binary, const QStringList &args);
|
||||
// Starts the binary with the arguments blocking the UI fully
|
||||
SynchronousProcessResponse runBlocking(const QString &binary, const QStringList &args);
|
||||
|
||||
// Create a (derived) processes with flags applied.
|
||||
static QSharedPointer<QProcess> createProcess(unsigned flags);
|
||||
|
||||
Reference in New Issue
Block a user