forked from qt-creator/qt-creator
SshDeviceProcessList: Don't use SshRemoteProcessRunner
Use QtcProcess with a path on device instead.
Remove some unneeded includes.
Fix killing a process on remote linux. It amends the old commit
that added "kill -0 -pid pid" command in the middle.
There is no defined "0" signal for kill command, so removing it here.
Currently the issue was that after calling kill -15 the process
may have got terminated and the subsequent call to kill -9
(after one second of sleep) failed with an error.
Instead, we call in a row: kill -15 and kill -9, without the
sleep command inside. It looks like this works fine, and the
old app gets terminated, so the subsequent kill -9 doesn't
cause an error.
This commit makes "Show Running Processes..." work again for remotes.
Amends be4bd1dc06
Change-Id: Id70884bdd0302e6d59f2f58d61f3f3d89a067391
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -24,9 +24,8 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "deviceprocesslist.h"
|
#include "deviceprocesslist.h"
|
||||||
|
#include "idevice.h"
|
||||||
|
|
||||||
#include <projectexplorer/devicesupport/idevice.h>
|
|
||||||
#include <utils/fileutils.h>
|
|
||||||
#include <utils/processinfo.h>
|
#include <utils/processinfo.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/treemodel.h>
|
#include <utils/treemodel.h>
|
||||||
|
@@ -24,75 +24,63 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "sshdeviceprocesslist.h"
|
#include "sshdeviceprocesslist.h"
|
||||||
|
|
||||||
#include "idevice.h"
|
#include "idevice.h"
|
||||||
|
|
||||||
#include <projectexplorer/devicesupport/idevice.h>
|
|
||||||
#include <ssh/sshremoteprocessrunner.h>
|
|
||||||
#include <utils/fileutils.h>
|
|
||||||
#include <utils/processinfo.h>
|
#include <utils/processinfo.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
#include <utils/qtcprocess.h>
|
||||||
|
|
||||||
using namespace QSsh;
|
using namespace QSsh;
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
|
|
||||||
class SshDeviceProcessList::SshDeviceProcessListPrivate
|
class SshDeviceProcessListPrivate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SshRemoteProcessRunner process;
|
QtcProcess m_process;
|
||||||
DeviceProcessSignalOperation::Ptr signalOperation;
|
DeviceProcessSignalOperation::Ptr m_signalOperation;
|
||||||
};
|
};
|
||||||
|
|
||||||
SshDeviceProcessList::SshDeviceProcessList(const IDevice::ConstPtr &device, QObject *parent) :
|
SshDeviceProcessList::SshDeviceProcessList(const IDevice::ConstPtr &device, QObject *parent) :
|
||||||
DeviceProcessList(device, parent), d(std::make_unique<SshDeviceProcessListPrivate>())
|
DeviceProcessList(device, parent), d(std::make_unique<SshDeviceProcessListPrivate>())
|
||||||
{
|
{
|
||||||
|
connect(&d->m_process, &QtcProcess::done, this, &SshDeviceProcessList::handleProcessDone);
|
||||||
}
|
}
|
||||||
|
|
||||||
SshDeviceProcessList::~SshDeviceProcessList() = default;
|
SshDeviceProcessList::~SshDeviceProcessList() = default;
|
||||||
|
|
||||||
void SshDeviceProcessList::doUpdate()
|
void SshDeviceProcessList::doUpdate()
|
||||||
{
|
{
|
||||||
connect(&d->process, &SshRemoteProcessRunner::connectionError,
|
d->m_process.close();
|
||||||
this, &SshDeviceProcessList::handleConnectionError);
|
d->m_process.setCommand({device()->mapToGlobalPath("/bin/sh"),
|
||||||
connect(&d->process, &SshRemoteProcessRunner::finished,
|
{"-c", listProcessesCommandLine()}});
|
||||||
this, &SshDeviceProcessList::handleListProcessFinished);
|
d->m_process.start();
|
||||||
d->process.run(listProcessesCommandLine(), device()->sshParameters());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SshDeviceProcessList::doKillProcess(const ProcessInfo &process)
|
void SshDeviceProcessList::doKillProcess(const ProcessInfo &process)
|
||||||
{
|
{
|
||||||
d->signalOperation = device()->signalOperation();
|
d->m_signalOperation = device()->signalOperation();
|
||||||
QTC_ASSERT(d->signalOperation, return);
|
QTC_ASSERT(d->m_signalOperation, return);
|
||||||
connect(d->signalOperation.data(), &DeviceProcessSignalOperation::finished,
|
connect(d->m_signalOperation.data(), &DeviceProcessSignalOperation::finished,
|
||||||
this, &SshDeviceProcessList::handleKillProcessFinished);
|
this, &SshDeviceProcessList::handleKillProcessFinished);
|
||||||
d->signalOperation->killProcess(process.processId);
|
d->m_signalOperation->killProcess(process.processId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SshDeviceProcessList::handleConnectionError()
|
void SshDeviceProcessList::handleProcessDone()
|
||||||
{
|
{
|
||||||
setFinished();
|
if (d->m_process.result() == ProcessResult::FinishedWithSuccess) {
|
||||||
reportError(tr("Connection failure: %1").arg(d->process.lastConnectionErrorString()));
|
reportProcessListUpdated(buildProcessList(d->m_process.stdOut()));
|
||||||
}
|
|
||||||
|
|
||||||
void SshDeviceProcessList::handleListProcessFinished()
|
|
||||||
{
|
|
||||||
const QString error = d->process.errorString();
|
|
||||||
setFinished();
|
|
||||||
if (!error.isEmpty()) {
|
|
||||||
handleProcessError(error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (d->process.exitCode() == 0) {
|
|
||||||
const QByteArray remoteStdout = d->process.readAllStandardOutput();
|
|
||||||
const QString stdoutString
|
|
||||||
= QString::fromUtf8(remoteStdout.data(), remoteStdout.count());
|
|
||||||
reportProcessListUpdated(buildProcessList(stdoutString));
|
|
||||||
} else {
|
} else {
|
||||||
handleProcessError(tr("Process listing command failed with exit code %1.")
|
const QString errorMessage = d->m_process.exitStatus() == QProcess::NormalExit
|
||||||
.arg(d->process.exitCode()));
|
? tr("Process listing command failed with exit code %1.").arg(d->m_process.exitCode())
|
||||||
|
: d->m_process.errorString();
|
||||||
|
const QString stdErr = d->m_process.stdErr();
|
||||||
|
const QString fullMessage = stdErr.isEmpty()
|
||||||
|
? errorMessage : errorMessage + '\n' + tr("Remote stderr was: %1").arg(stdErr);
|
||||||
|
reportError(fullMessage);
|
||||||
}
|
}
|
||||||
|
setFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SshDeviceProcessList::handleKillProcessFinished(const QString &errorString)
|
void SshDeviceProcessList::handleKillProcessFinished(const QString &errorString)
|
||||||
@@ -104,21 +92,12 @@ void SshDeviceProcessList::handleKillProcessFinished(const QString &errorString)
|
|||||||
setFinished();
|
setFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SshDeviceProcessList::handleProcessError(const QString &errorMessage)
|
|
||||||
{
|
|
||||||
QString fullMessage = errorMessage;
|
|
||||||
const QByteArray remoteStderr = d->process.readAllStandardError();
|
|
||||||
if (!remoteStderr.isEmpty())
|
|
||||||
fullMessage += QLatin1Char('\n') + tr("Remote stderr was: %1").arg(QString::fromUtf8(remoteStderr));
|
|
||||||
reportError(fullMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SshDeviceProcessList::setFinished()
|
void SshDeviceProcessList::setFinished()
|
||||||
{
|
{
|
||||||
d->process.disconnect(this);
|
d->m_process.close();
|
||||||
if (d->signalOperation) {
|
if (d->m_signalOperation) {
|
||||||
d->signalOperation->disconnect(this);
|
d->m_signalOperation->disconnect(this);
|
||||||
d->signalOperation.clear();
|
d->m_signalOperation.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -31,6 +31,8 @@
|
|||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
|
|
||||||
|
class SshDeviceProcessListPrivate;
|
||||||
|
|
||||||
class PROJECTEXPLORER_EXPORT SshDeviceProcessList : public DeviceProcessList
|
class PROJECTEXPLORER_EXPORT SshDeviceProcessList : public DeviceProcessList
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -39,8 +41,7 @@ public:
|
|||||||
~SshDeviceProcessList() override;
|
~SshDeviceProcessList() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handleConnectionError();
|
void handleProcessDone();
|
||||||
void handleListProcessFinished();
|
|
||||||
void handleKillProcessFinished(const QString &errorString);
|
void handleKillProcessFinished(const QString &errorString);
|
||||||
|
|
||||||
virtual QString listProcessesCommandLine() const = 0;
|
virtual QString listProcessesCommandLine() const = 0;
|
||||||
@@ -49,10 +50,8 @@ private:
|
|||||||
void doUpdate() override;
|
void doUpdate() override;
|
||||||
void doKillProcess(const Utils::ProcessInfo &process) override;
|
void doKillProcess(const Utils::ProcessInfo &process) override;
|
||||||
|
|
||||||
void handleProcessError(const QString &errorMessage);
|
|
||||||
void setFinished();
|
void setFinished();
|
||||||
|
|
||||||
class SshDeviceProcessListPrivate;
|
|
||||||
const std::unique_ptr<SshDeviceProcessListPrivate> d;
|
const std::unique_ptr<SshDeviceProcessListPrivate> d;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -43,7 +43,7 @@ RemoteLinuxSignalOperation::~RemoteLinuxSignalOperation() = default;
|
|||||||
|
|
||||||
static QString signalProcessGroupByPidCommandLine(qint64 pid, int signal)
|
static QString signalProcessGroupByPidCommandLine(qint64 pid, int signal)
|
||||||
{
|
{
|
||||||
return QString::fromLatin1("kill -%1 -%2 %2").arg(signal).arg(pid);
|
return QString::fromLatin1("kill -%1 %2").arg(signal).arg(pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteLinuxSignalOperation::run(const QString &command)
|
void RemoteLinuxSignalOperation::run(const QString &command)
|
||||||
@@ -80,9 +80,8 @@ QString RemoteLinuxSignalOperation::interruptProcessByNameCommandLine(const QStr
|
|||||||
|
|
||||||
void RemoteLinuxSignalOperation::killProcess(qint64 pid)
|
void RemoteLinuxSignalOperation::killProcess(qint64 pid)
|
||||||
{
|
{
|
||||||
run(QString::fromLatin1("%1; sleep 1; %2 && %3")
|
run(QString::fromLatin1("%1 && %2")
|
||||||
.arg(signalProcessGroupByPidCommandLine(pid, 15),
|
.arg(signalProcessGroupByPidCommandLine(pid, 15),
|
||||||
signalProcessGroupByPidCommandLine(pid, 0),
|
|
||||||
signalProcessGroupByPidCommandLine(pid, 9)));
|
signalProcessGroupByPidCommandLine(pid, 9)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user