forked from qt-creator/qt-creator
Utils::ShellCommand: Use SynchronousProcess where posssible
Use SynchronousProcess::run and SynchronousProcess::runBlocking. Using SynchronousProcess::run in ShellCommand::runSynchronous is generally safe, since this method is usually called in its own thread. This makes the processing of cancel requests work again and makes output available via signals. Task-number: QTCREATORBUG-16532 Change-Id: I6907194bd00cd5713673d9b1911978d69b996a80 Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
@@ -351,58 +351,37 @@ Utils::SynchronousProcessResponse ShellCommand::runFullySynchronous(const Utils:
|
|||||||
const QString &workingDirectory,
|
const QString &workingDirectory,
|
||||||
const ExitCodeInterpreter &interpreter)
|
const ExitCodeInterpreter &interpreter)
|
||||||
{
|
{
|
||||||
Utils::SynchronousProcessResponse response;
|
|
||||||
|
|
||||||
// Set up process
|
// Set up process
|
||||||
QSharedPointer<QProcess> process = Utils::SynchronousProcess::createProcess(processFlags());
|
Utils::SynchronousProcess process;
|
||||||
if (!d->m_defaultWorkingDirectory.isEmpty())
|
process.setFlags(processFlags());
|
||||||
process->setWorkingDirectory(workDirectory(workingDirectory));
|
const QString dir = workDirectory(workingDirectory);
|
||||||
process->setProcessEnvironment(processEnvironment());
|
if (!dir.isEmpty())
|
||||||
|
process.setWorkingDirectory(dir);
|
||||||
|
process.setProcessEnvironment(processEnvironment());
|
||||||
if (d->m_flags & MergeOutputChannels)
|
if (d->m_flags & MergeOutputChannels)
|
||||||
process->setProcessChannelMode(QProcess::MergedChannels);
|
process.setProcessChannelMode(QProcess::MergedChannels);
|
||||||
|
if (d->m_codec)
|
||||||
|
process.setCodec(d->m_codec);
|
||||||
|
process.setTimeoutS(timeoutS);
|
||||||
|
process.setExitCodeInterpreter(interpreter);
|
||||||
|
|
||||||
// Start
|
SynchronousProcessResponse resp = process.runBlocking(binary.toString(), arguments);
|
||||||
process->start(binary.toString(), arguments, QIODevice::ReadOnly);
|
|
||||||
process->closeWriteChannel();
|
|
||||||
if (!process->waitForStarted()) {
|
|
||||||
response.result = Utils::SynchronousProcessResponse::StartFailed;
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
// process output
|
|
||||||
QByteArray stdOut;
|
|
||||||
QByteArray stdErr;
|
|
||||||
const bool timedOut =
|
|
||||||
!Utils::SynchronousProcess::readDataFromProcess(*process.data(), timeoutS,
|
|
||||||
&stdOut, &stdErr, true);
|
|
||||||
|
|
||||||
if (!d->m_aborted) {
|
if (!d->m_aborted) {
|
||||||
response.codec = d->m_codec ? d->m_codec : QTextCodec::codecForLocale();
|
const QString stdErr = resp.stdErr();
|
||||||
if (!stdErr.isEmpty()) {
|
if (!stdErr.isEmpty() && !(d->m_flags & SuppressStdErr))
|
||||||
response.rawStdErr = stdErr;
|
proxy->append(stdErr);
|
||||||
if (!(d->m_flags & SuppressStdErr))
|
|
||||||
proxy->append(response.stdErr());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!stdOut.isEmpty()) {
|
const QString stdOut = resp.stdOut();
|
||||||
response.rawStdOut = stdOut;
|
if (!stdOut.isEmpty() && d->m_flags & ShowStdOut) {
|
||||||
if (d->m_flags & ShowStdOut) {
|
if (d->m_flags & SilentOutput)
|
||||||
if (d->m_flags & SilentOutput)
|
proxy->appendSilently(stdOut);
|
||||||
proxy->appendSilently(response.stdOut());
|
else
|
||||||
else
|
proxy->append(stdOut);
|
||||||
proxy->append(response.stdOut());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Result
|
return resp;
|
||||||
if (timedOut)
|
|
||||||
response.result = Utils::SynchronousProcessResponse::Hang;
|
|
||||||
else if (process->exitStatus() != QProcess::NormalExit)
|
|
||||||
response.result = Utils::SynchronousProcessResponse::TerminatedAbnormally;
|
|
||||||
else
|
|
||||||
response.result = interpreter(process->exitCode());
|
|
||||||
return response;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SynchronousProcessResponse ShellCommand::runSynchronous(const FileName &binary,
|
SynchronousProcessResponse ShellCommand::runSynchronous(const FileName &binary,
|
||||||
@@ -415,15 +394,15 @@ SynchronousProcessResponse ShellCommand::runSynchronous(const FileName &binary,
|
|||||||
Utils::SynchronousProcess process;
|
Utils::SynchronousProcess process;
|
||||||
process.setExitCodeInterpreter(interpreter);
|
process.setExitCodeInterpreter(interpreter);
|
||||||
connect(this, &ShellCommand::terminate, &process, &Utils::SynchronousProcess::terminate);
|
connect(this, &ShellCommand::terminate, &process, &Utils::SynchronousProcess::terminate);
|
||||||
process.setWorkingDirectory(workingDirectory);
|
|
||||||
|
|
||||||
process.setProcessEnvironment(processEnvironment());
|
process.setProcessEnvironment(processEnvironment());
|
||||||
process.setTimeoutS(timeoutS);
|
process.setTimeoutS(timeoutS);
|
||||||
if (d->m_codec)
|
if (d->m_codec)
|
||||||
process.setCodec(d->m_codec);
|
process.setCodec(d->m_codec);
|
||||||
|
|
||||||
process.setFlags(processFlags());
|
process.setFlags(processFlags());
|
||||||
|
const QString dir = workDirectory(workingDirectory);
|
||||||
|
if (!dir.isEmpty())
|
||||||
|
process.setWorkingDirectory(dir);
|
||||||
|
process.setProcessEnvironment(processEnvironment());
|
||||||
// connect stderr to the output window if desired
|
// connect stderr to the output window if desired
|
||||||
if (d->m_flags & MergeOutputChannels) {
|
if (d->m_flags & MergeOutputChannels) {
|
||||||
process.setProcessChannelMode(QProcess::MergedChannels);
|
process.setProcessChannelMode(QProcess::MergedChannels);
|
||||||
@@ -459,8 +438,12 @@ SynchronousProcessResponse ShellCommand::runSynchronous(const FileName &binary,
|
|||||||
|
|
||||||
process.setTimeOutMessageBoxEnabled(true);
|
process.setTimeOutMessageBoxEnabled(true);
|
||||||
|
|
||||||
// Run!
|
if (d->m_codec)
|
||||||
return process.runBlocking(binary.toString(), arguments);
|
process.setCodec(d->m_codec);
|
||||||
|
process.setTimeoutS(timeoutS);
|
||||||
|
process.setExitCodeInterpreter(interpreter);
|
||||||
|
|
||||||
|
return process.run(binary.toString(), arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
const QVariant &ShellCommand::cookie() const
|
const QVariant &ShellCommand::cookie() const
|
||||||
|
Reference in New Issue
Block a user