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 "idevice.h"
|
||||
|
||||
#include <projectexplorer/devicesupport/idevice.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/processinfo.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/treemodel.h>
|
||||
|
@@ -24,75 +24,63 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "sshdeviceprocesslist.h"
|
||||
|
||||
#include "idevice.h"
|
||||
|
||||
#include <projectexplorer/devicesupport/idevice.h>
|
||||
#include <ssh/sshremoteprocessrunner.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/processinfo.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
|
||||
using namespace QSsh;
|
||||
using namespace Utils;
|
||||
|
||||
namespace ProjectExplorer {
|
||||
|
||||
class SshDeviceProcessList::SshDeviceProcessListPrivate
|
||||
class SshDeviceProcessListPrivate
|
||||
{
|
||||
public:
|
||||
SshRemoteProcessRunner process;
|
||||
DeviceProcessSignalOperation::Ptr signalOperation;
|
||||
QtcProcess m_process;
|
||||
DeviceProcessSignalOperation::Ptr m_signalOperation;
|
||||
};
|
||||
|
||||
SshDeviceProcessList::SshDeviceProcessList(const IDevice::ConstPtr &device, QObject *parent) :
|
||||
DeviceProcessList(device, parent), d(std::make_unique<SshDeviceProcessListPrivate>())
|
||||
{
|
||||
connect(&d->m_process, &QtcProcess::done, this, &SshDeviceProcessList::handleProcessDone);
|
||||
}
|
||||
|
||||
SshDeviceProcessList::~SshDeviceProcessList() = default;
|
||||
|
||||
void SshDeviceProcessList::doUpdate()
|
||||
{
|
||||
connect(&d->process, &SshRemoteProcessRunner::connectionError,
|
||||
this, &SshDeviceProcessList::handleConnectionError);
|
||||
connect(&d->process, &SshRemoteProcessRunner::finished,
|
||||
this, &SshDeviceProcessList::handleListProcessFinished);
|
||||
d->process.run(listProcessesCommandLine(), device()->sshParameters());
|
||||
d->m_process.close();
|
||||
d->m_process.setCommand({device()->mapToGlobalPath("/bin/sh"),
|
||||
{"-c", listProcessesCommandLine()}});
|
||||
d->m_process.start();
|
||||
}
|
||||
|
||||
void SshDeviceProcessList::doKillProcess(const ProcessInfo &process)
|
||||
{
|
||||
d->signalOperation = device()->signalOperation();
|
||||
QTC_ASSERT(d->signalOperation, return);
|
||||
connect(d->signalOperation.data(), &DeviceProcessSignalOperation::finished,
|
||||
d->m_signalOperation = device()->signalOperation();
|
||||
QTC_ASSERT(d->m_signalOperation, return);
|
||||
connect(d->m_signalOperation.data(), &DeviceProcessSignalOperation::finished,
|
||||
this, &SshDeviceProcessList::handleKillProcessFinished);
|
||||
d->signalOperation->killProcess(process.processId);
|
||||
d->m_signalOperation->killProcess(process.processId);
|
||||
}
|
||||
|
||||
void SshDeviceProcessList::handleConnectionError()
|
||||
void SshDeviceProcessList::handleProcessDone()
|
||||
{
|
||||
setFinished();
|
||||
reportError(tr("Connection failure: %1").arg(d->process.lastConnectionErrorString()));
|
||||
}
|
||||
|
||||
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));
|
||||
if (d->m_process.result() == ProcessResult::FinishedWithSuccess) {
|
||||
reportProcessListUpdated(buildProcessList(d->m_process.stdOut()));
|
||||
} else {
|
||||
handleProcessError(tr("Process listing command failed with exit code %1.")
|
||||
.arg(d->process.exitCode()));
|
||||
const QString errorMessage = d->m_process.exitStatus() == QProcess::NormalExit
|
||||
? 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)
|
||||
@@ -104,21 +92,12 @@ void SshDeviceProcessList::handleKillProcessFinished(const QString &errorString)
|
||||
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()
|
||||
{
|
||||
d->process.disconnect(this);
|
||||
if (d->signalOperation) {
|
||||
d->signalOperation->disconnect(this);
|
||||
d->signalOperation.clear();
|
||||
d->m_process.close();
|
||||
if (d->m_signalOperation) {
|
||||
d->m_signalOperation->disconnect(this);
|
||||
d->m_signalOperation.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -31,6 +31,8 @@
|
||||
|
||||
namespace ProjectExplorer {
|
||||
|
||||
class SshDeviceProcessListPrivate;
|
||||
|
||||
class PROJECTEXPLORER_EXPORT SshDeviceProcessList : public DeviceProcessList
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -39,8 +41,7 @@ public:
|
||||
~SshDeviceProcessList() override;
|
||||
|
||||
private:
|
||||
void handleConnectionError();
|
||||
void handleListProcessFinished();
|
||||
void handleProcessDone();
|
||||
void handleKillProcessFinished(const QString &errorString);
|
||||
|
||||
virtual QString listProcessesCommandLine() const = 0;
|
||||
@@ -49,10 +50,8 @@ private:
|
||||
void doUpdate() override;
|
||||
void doKillProcess(const Utils::ProcessInfo &process) override;
|
||||
|
||||
void handleProcessError(const QString &errorMessage);
|
||||
void setFinished();
|
||||
|
||||
class SshDeviceProcessListPrivate;
|
||||
const std::unique_ptr<SshDeviceProcessListPrivate> d;
|
||||
};
|
||||
|
||||
|
@@ -43,7 +43,7 @@ RemoteLinuxSignalOperation::~RemoteLinuxSignalOperation() = default;
|
||||
|
||||
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)
|
||||
@@ -80,9 +80,8 @@ QString RemoteLinuxSignalOperation::interruptProcessByNameCommandLine(const QStr
|
||||
|
||||
void RemoteLinuxSignalOperation::killProcess(qint64 pid)
|
||||
{
|
||||
run(QString::fromLatin1("%1; sleep 1; %2 && %3")
|
||||
run(QString::fromLatin1("%1 && %2")
|
||||
.arg(signalProcessGroupByPidCommandLine(pid, 15),
|
||||
signalProcessGroupByPidCommandLine(pid, 0),
|
||||
signalProcessGroupByPidCommandLine(pid, 9)));
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user