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:
Jarek Kobus
2022-05-06 00:13:52 +02:00
parent 7ef5001076
commit f62a4d6315
4 changed files with 34 additions and 58 deletions

View File

@@ -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>

View File

@@ -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();
} }
} }

View File

@@ -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;
}; };

View File

@@ -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)));
} }