forked from qt-creator/qt-creator
ProjectExplorer: Consolidate ApplicationLauncher
Both local and remote runs now use QtcProcess or a derived class. Change-Id: Idd0645a5645ab91a6d49b9839d021c6757296d00 Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
@@ -82,7 +82,7 @@ public:
|
|||||||
void checkLocalDebugOutput(qint64 pid, const QString &message);
|
void checkLocalDebugOutput(qint64 pid, const QString &message);
|
||||||
void localProcessDone(int, QProcess::ExitStatus);
|
void localProcessDone(int, QProcess::ExitStatus);
|
||||||
qint64 applicationPID() const;
|
qint64 applicationPID() const;
|
||||||
bool isLocalRunning() const;
|
bool isRunning() const;
|
||||||
|
|
||||||
// Remote
|
// Remote
|
||||||
void doReportError(const QString &message,
|
void doReportError(const QString &message,
|
||||||
@@ -99,8 +99,9 @@ public:
|
|||||||
bool m_isLocal = true;
|
bool m_isLocal = true;
|
||||||
bool m_runAsRoot = false;
|
bool m_runAsRoot = false;
|
||||||
|
|
||||||
|
std::unique_ptr<QtcProcess> m_process;
|
||||||
|
|
||||||
// Local
|
// Local
|
||||||
std::unique_ptr<QtcProcess> m_localProcess;
|
|
||||||
bool m_useTerminal = false;
|
bool m_useTerminal = false;
|
||||||
QProcess::ProcessChannelMode m_processChannelMode;
|
QProcess::ProcessChannelMode m_processChannelMode;
|
||||||
// Keep track whether we need to emit a finished signal
|
// Keep track whether we need to emit a finished signal
|
||||||
@@ -113,7 +114,6 @@ public:
|
|||||||
qint64 m_listeningPid = 0;
|
qint64 m_listeningPid = 0;
|
||||||
|
|
||||||
// Remote
|
// Remote
|
||||||
DeviceProcess *m_deviceProcess = nullptr;
|
|
||||||
QString m_remoteErrorString;
|
QString m_remoteErrorString;
|
||||||
QProcess::ProcessError m_remoteError = QProcess::UnknownError;
|
QProcess::ProcessError m_remoteError = QProcess::UnknownError;
|
||||||
QProcess::ExitStatus m_remoteExitStatus = QProcess::CrashExit;
|
QProcess::ExitStatus m_remoteExitStatus = QProcess::CrashExit;
|
||||||
@@ -179,10 +179,10 @@ void ApplicationLauncher::stop()
|
|||||||
void ApplicationLauncherPrivate::stop()
|
void ApplicationLauncherPrivate::stop()
|
||||||
{
|
{
|
||||||
if (m_isLocal) {
|
if (m_isLocal) {
|
||||||
if (!isLocalRunning())
|
if (!isRunning())
|
||||||
return;
|
return;
|
||||||
QTC_ASSERT(m_localProcess, return);
|
QTC_ASSERT(m_process, return);
|
||||||
m_localProcess->stopProcess();
|
m_process->stopProcess();
|
||||||
localProcessDone(0, QProcess::CrashExit);
|
localProcessDone(0, QProcess::CrashExit);
|
||||||
} else {
|
} else {
|
||||||
if (m_stopRequested)
|
if (m_stopRequested)
|
||||||
@@ -193,7 +193,7 @@ void ApplicationLauncherPrivate::stop()
|
|||||||
Utils::NormalMessageFormat);
|
Utils::NormalMessageFormat);
|
||||||
switch (m_state) {
|
switch (m_state) {
|
||||||
case Run:
|
case Run:
|
||||||
m_deviceProcess->terminate();
|
m_process->terminate();
|
||||||
break;
|
break;
|
||||||
case Inactive:
|
case Inactive:
|
||||||
break;
|
break;
|
||||||
@@ -203,7 +203,7 @@ void ApplicationLauncherPrivate::stop()
|
|||||||
|
|
||||||
bool ApplicationLauncher::isRunning() const
|
bool ApplicationLauncher::isRunning() const
|
||||||
{
|
{
|
||||||
return d->isLocalRunning();
|
return d->isRunning();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ApplicationLauncher::isLocal() const
|
bool ApplicationLauncher::isLocal() const
|
||||||
@@ -211,11 +211,11 @@ bool ApplicationLauncher::isLocal() const
|
|||||||
return d->m_isLocal;
|
return d->m_isLocal;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ApplicationLauncherPrivate::isLocalRunning() const
|
bool ApplicationLauncherPrivate::isRunning() const
|
||||||
{
|
{
|
||||||
if (!m_localProcess)
|
if (!m_process)
|
||||||
return false;
|
return false;
|
||||||
return m_localProcess->state() != QProcess::NotRunning;
|
return m_process->state() != QProcess::NotRunning;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessHandle ApplicationLauncher::applicationPID() const
|
ProcessHandle ApplicationLauncher::applicationPID() const
|
||||||
@@ -225,23 +225,23 @@ ProcessHandle ApplicationLauncher::applicationPID() const
|
|||||||
|
|
||||||
qint64 ApplicationLauncherPrivate::applicationPID() const
|
qint64 ApplicationLauncherPrivate::applicationPID() const
|
||||||
{
|
{
|
||||||
if (!isLocalRunning())
|
if (!isRunning())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return m_localProcess->processId();
|
return m_process->processId();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ApplicationLauncher::errorString() const
|
QString ApplicationLauncher::errorString() const
|
||||||
{
|
{
|
||||||
if (d->m_isLocal)
|
if (d->m_isLocal)
|
||||||
return d->m_localProcess ? d->m_localProcess->errorString() : QString();
|
return d->m_process ? d->m_process->errorString() : QString();
|
||||||
return d->m_remoteErrorString;
|
return d->m_remoteErrorString;
|
||||||
}
|
}
|
||||||
|
|
||||||
QProcess::ProcessError ApplicationLauncher::processError() const
|
QProcess::ProcessError ApplicationLauncher::processError() const
|
||||||
{
|
{
|
||||||
if (d->m_isLocal)
|
if (d->m_isLocal)
|
||||||
return d->m_localProcess ? d->m_localProcess->error() : QProcess::UnknownError;
|
return d->m_process ? d->m_process->error() : QProcess::UnknownError;
|
||||||
return d->m_remoteError;
|
return d->m_remoteError;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,15 +249,15 @@ void ApplicationLauncherPrivate::localProcessError(QProcess::ProcessError error)
|
|||||||
{
|
{
|
||||||
// TODO: why below handlings are different?
|
// TODO: why below handlings are different?
|
||||||
if (m_useTerminal) {
|
if (m_useTerminal) {
|
||||||
emit q->appendMessage(m_localProcess->errorString(), ErrorMessageFormat);
|
emit q->appendMessage(m_process->errorString(), ErrorMessageFormat);
|
||||||
if (m_processRunning && m_localProcess->processId() == 0) {
|
if (m_processRunning && m_process->processId() == 0) {
|
||||||
m_processRunning = false;
|
m_processRunning = false;
|
||||||
emit q->processExited(-1, QProcess::NormalExit);
|
emit q->processExited(-1, QProcess::NormalExit);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
QString error;
|
QString error;
|
||||||
QProcess::ExitStatus status = QProcess::NormalExit;
|
QProcess::ExitStatus status = QProcess::NormalExit;
|
||||||
switch (m_localProcess->error()) {
|
switch (m_process->error()) {
|
||||||
case QProcess::FailedToStart:
|
case QProcess::FailedToStart:
|
||||||
error = ApplicationLauncher::tr("Failed to start program. Path or permissions wrong?");
|
error = ApplicationLauncher::tr("Failed to start program. Path or permissions wrong?");
|
||||||
break;
|
break;
|
||||||
@@ -269,7 +269,7 @@ void ApplicationLauncherPrivate::localProcessError(QProcess::ProcessError error)
|
|||||||
}
|
}
|
||||||
if (!error.isEmpty())
|
if (!error.isEmpty())
|
||||||
emit q->appendMessage(error, ErrorMessageFormat);
|
emit q->appendMessage(error, ErrorMessageFormat);
|
||||||
if (m_processRunning && !isLocalRunning()) {
|
if (m_processRunning && !isRunning()) {
|
||||||
m_processRunning = false;
|
m_processRunning = false;
|
||||||
emit q->processExited(-1, status);
|
emit q->processExited(-1, status);
|
||||||
}
|
}
|
||||||
@@ -279,7 +279,7 @@ void ApplicationLauncherPrivate::localProcessError(QProcess::ProcessError error)
|
|||||||
|
|
||||||
void ApplicationLauncherPrivate::readLocalStandardOutput()
|
void ApplicationLauncherPrivate::readLocalStandardOutput()
|
||||||
{
|
{
|
||||||
const QByteArray data = m_localProcess->readAllStandardOutput();
|
const QByteArray data = m_process->readAllStandardOutput();
|
||||||
const QString msg = m_outputCodec->toUnicode(
|
const QString msg = m_outputCodec->toUnicode(
|
||||||
data.constData(), data.length(), &m_outputCodecState);
|
data.constData(), data.length(), &m_outputCodecState);
|
||||||
emit q->appendMessage(msg, StdOutFormat, false);
|
emit q->appendMessage(msg, StdOutFormat, false);
|
||||||
@@ -287,7 +287,7 @@ void ApplicationLauncherPrivate::readLocalStandardOutput()
|
|||||||
|
|
||||||
void ApplicationLauncherPrivate::readLocalStandardError()
|
void ApplicationLauncherPrivate::readLocalStandardError()
|
||||||
{
|
{
|
||||||
const QByteArray data = m_localProcess->readAllStandardError();
|
const QByteArray data = m_process->readAllStandardError();
|
||||||
const QString msg = m_outputCodec->toUnicode(
|
const QString msg = m_outputCodec->toUnicode(
|
||||||
data.constData(), data.length(), &m_errorCodecState);
|
data.constData(), data.length(), &m_errorCodecState);
|
||||||
emit q->appendMessage(msg, StdErrFormat, false);
|
emit q->appendMessage(msg, StdErrFormat, false);
|
||||||
@@ -341,38 +341,36 @@ void ApplicationLauncherPrivate::start(const IDevice::ConstPtr &device, bool loc
|
|||||||
m_isLocal = local;
|
m_isLocal = local;
|
||||||
|
|
||||||
if (m_isLocal) {
|
if (m_isLocal) {
|
||||||
m_localProcess.reset(new QtcProcess(this));
|
m_process.reset(new QtcProcess(this));
|
||||||
m_localProcess->setTerminalMode(
|
m_process->setProcessChannelMode(m_processChannelMode);
|
||||||
m_useTerminal ? QtcProcess::TerminalOn : QtcProcess::TerminalOff);
|
|
||||||
m_localProcess->setProcessChannelMode(m_processChannelMode);
|
|
||||||
|
|
||||||
if (m_processChannelMode == QProcess::SeparateChannels) {
|
if (m_processChannelMode == QProcess::SeparateChannels) {
|
||||||
connect(m_localProcess.get(), &QtcProcess::readyReadStandardError,
|
connect(m_process.get(), &QtcProcess::readyReadStandardError,
|
||||||
this, &ApplicationLauncherPrivate::readLocalStandardError);
|
this, &ApplicationLauncherPrivate::readLocalStandardError);
|
||||||
}
|
}
|
||||||
if (!m_useTerminal) {
|
if (!m_useTerminal) {
|
||||||
connect(m_localProcess.get(), &QtcProcess::readyReadStandardOutput,
|
connect(m_process.get(), &QtcProcess::readyReadStandardOutput,
|
||||||
this, &ApplicationLauncherPrivate::readLocalStandardOutput);
|
this, &ApplicationLauncherPrivate::readLocalStandardOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(m_localProcess.get(), &QtcProcess::started,
|
connect(m_process.get(), &QtcProcess::started,
|
||||||
this, &ApplicationLauncherPrivate::handleProcessStarted);
|
this, &ApplicationLauncherPrivate::handleProcessStarted);
|
||||||
connect(m_localProcess.get(), &QtcProcess::finished, this, [this] {
|
connect(m_process.get(), &QtcProcess::finished, this, [this] {
|
||||||
localProcessDone(m_localProcess->exitCode(), m_localProcess->exitStatus());
|
localProcessDone(m_process->exitCode(), m_process->exitStatus());
|
||||||
});
|
});
|
||||||
connect(m_localProcess.get(), &QtcProcess::errorOccurred,
|
connect(m_process.get(), &QtcProcess::errorOccurred,
|
||||||
this, &ApplicationLauncherPrivate::localProcessError);
|
this, &ApplicationLauncherPrivate::localProcessError);
|
||||||
|
|
||||||
|
|
||||||
// Work around QTBUG-17529 (QtDeclarative fails with 'File name case mismatch' ...)
|
// Work around QTBUG-17529 (QtDeclarative fails with 'File name case mismatch' ...)
|
||||||
const FilePath fixedPath = m_runnable.workingDirectory.normalizedPathName();
|
const FilePath fixedPath = m_runnable.workingDirectory.normalizedPathName();
|
||||||
m_localProcess->setWorkingDirectory(fixedPath);
|
m_process->setWorkingDirectory(fixedPath);
|
||||||
|
|
||||||
Environment env = m_runnable.environment;
|
Environment env = m_runnable.environment;
|
||||||
if (m_runAsRoot)
|
if (m_runAsRoot)
|
||||||
RunControl::provideAskPassEntry(env);
|
RunControl::provideAskPassEntry(env);
|
||||||
|
|
||||||
m_localProcess->setEnvironment(env);
|
m_process->setEnvironment(env);
|
||||||
|
|
||||||
m_processRunning = true;
|
m_processRunning = true;
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
@@ -388,9 +386,8 @@ void ApplicationLauncherPrivate::start(const IDevice::ConstPtr &device, bool loc
|
|||||||
cmdLine = disclaim;
|
cmdLine = disclaim;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_localProcess->setRunAsRoot(m_runAsRoot);
|
m_process->setRunAsRoot(m_runAsRoot);
|
||||||
m_localProcess->setCommand(cmdLine);
|
m_process->setCommand(cmdLine);
|
||||||
m_localProcess->start();
|
|
||||||
} else {
|
} else {
|
||||||
QTC_ASSERT(m_state == Inactive, return);
|
QTC_ASSERT(m_state == Inactive, return);
|
||||||
|
|
||||||
@@ -416,32 +413,32 @@ void ApplicationLauncherPrivate::start(const IDevice::ConstPtr &device, bool loc
|
|||||||
m_stopRequested = false;
|
m_stopRequested = false;
|
||||||
m_remoteExitStatus = QProcess::NormalExit;
|
m_remoteExitStatus = QProcess::NormalExit;
|
||||||
|
|
||||||
m_deviceProcess = device->createProcess(this);
|
m_process.reset(device->createProcess(this));
|
||||||
m_deviceProcess->setTerminalMode(m_useTerminal ? QtcProcess::TerminalOn
|
connect(m_process.get(), &QtcProcess::started,
|
||||||
: QtcProcess::TerminalOff);
|
|
||||||
connect(m_deviceProcess, &DeviceProcess::started,
|
|
||||||
q, &ApplicationLauncher::processStarted);
|
q, &ApplicationLauncher::processStarted);
|
||||||
connect(m_deviceProcess, &DeviceProcess::readyReadStandardOutput,
|
connect(m_process.get(), &QtcProcess::readyReadStandardOutput,
|
||||||
this, &ApplicationLauncherPrivate::handleRemoteStdout);
|
this, &ApplicationLauncherPrivate::handleRemoteStdout);
|
||||||
connect(m_deviceProcess, &DeviceProcess::readyReadStandardError,
|
connect(m_process.get(), &QtcProcess::readyReadStandardError,
|
||||||
this, &ApplicationLauncherPrivate::handleRemoteStderr);
|
this, &ApplicationLauncherPrivate::handleRemoteStderr);
|
||||||
connect(m_deviceProcess, &DeviceProcess::errorOccurred,
|
connect(m_process.get(), &QtcProcess::errorOccurred,
|
||||||
this, &ApplicationLauncherPrivate::handleApplicationError);
|
this, &ApplicationLauncherPrivate::handleApplicationError);
|
||||||
connect(m_deviceProcess, &DeviceProcess::finished,
|
connect(m_process.get(), &QtcProcess::finished,
|
||||||
this, &ApplicationLauncherPrivate::handleApplicationFinished);
|
this, &ApplicationLauncherPrivate::handleApplicationFinished);
|
||||||
m_deviceProcess->setCommand(m_runnable.command);
|
m_process->setCommand(m_runnable.command);
|
||||||
m_deviceProcess->setWorkingDirectory(m_runnable.workingDirectory);
|
m_process->setWorkingDirectory(m_runnable.workingDirectory);
|
||||||
m_deviceProcess->setEnvironment(m_runnable.environment);
|
m_process->setEnvironment(m_runnable.environment);
|
||||||
m_deviceProcess->setExtraData(m_runnable.extraData);
|
m_process->setExtraData(m_runnable.extraData);
|
||||||
m_deviceProcess->start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_process->setTerminalMode(m_useTerminal ? QtcProcess::TerminalOn : QtcProcess::TerminalOff);
|
||||||
|
m_process->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplicationLauncherPrivate::handleApplicationError(QProcess::ProcessError error)
|
void ApplicationLauncherPrivate::handleApplicationError(QProcess::ProcessError error)
|
||||||
{
|
{
|
||||||
if (error == QProcess::FailedToStart) {
|
if (error == QProcess::FailedToStart) {
|
||||||
doReportError(ApplicationLauncher::tr("Application failed to start: %1")
|
doReportError(ApplicationLauncher::tr("Application failed to start: %1")
|
||||||
.arg(m_deviceProcess->errorString()));
|
.arg(m_process->errorString()));
|
||||||
setFinished();
|
setFinished();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -452,8 +449,8 @@ void ApplicationLauncherPrivate::setFinished()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
int exitCode = 0;
|
int exitCode = 0;
|
||||||
if (m_deviceProcess)
|
if (m_process)
|
||||||
exitCode = m_deviceProcess->exitCode();
|
exitCode = m_process->exitCode();
|
||||||
|
|
||||||
m_state = Inactive;
|
m_state = Inactive;
|
||||||
emit q->processExited(exitCode, m_remoteExitStatus);
|
emit q->processExited(exitCode, m_remoteExitStatus);
|
||||||
@@ -463,22 +460,22 @@ void ApplicationLauncherPrivate::handleApplicationFinished()
|
|||||||
{
|
{
|
||||||
QTC_ASSERT(m_state == Run, return);
|
QTC_ASSERT(m_state == Run, return);
|
||||||
|
|
||||||
if (m_deviceProcess->exitStatus() == QProcess::CrashExit)
|
if (m_process->exitStatus() == QProcess::CrashExit)
|
||||||
doReportError(m_deviceProcess->errorString(), QProcess::Crashed);
|
doReportError(m_process->errorString(), QProcess::Crashed);
|
||||||
setFinished();
|
setFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplicationLauncherPrivate::handleRemoteStdout()
|
void ApplicationLauncherPrivate::handleRemoteStdout()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_state == Run, return);
|
QTC_ASSERT(m_state == Run, return);
|
||||||
const QByteArray output = m_deviceProcess->readAllStandardOutput();
|
const QByteArray output = m_process->readAllStandardOutput();
|
||||||
emit q->appendMessage(QString::fromUtf8(output), Utils::StdOutFormat, false);
|
emit q->appendMessage(QString::fromUtf8(output), Utils::StdOutFormat, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplicationLauncherPrivate::handleRemoteStderr()
|
void ApplicationLauncherPrivate::handleRemoteStderr()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_state == Run, return);
|
QTC_ASSERT(m_state == Run, return);
|
||||||
const QByteArray output = m_deviceProcess->readAllStandardError();
|
const QByteArray output = m_process->readAllStandardError();
|
||||||
emit q->appendMessage(QString::fromUtf8(output), Utils::StdErrFormat, false);
|
emit q->appendMessage(QString::fromUtf8(output), Utils::StdErrFormat, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user