diff options
author | Christian Kandeler <christian.kandeler@nokia.com> | 2012-08-01 16:26:27 +0200 |
---|---|---|
committer | hjk <qthjk@ovi.com> | 2012-08-02 10:36:04 +0200 |
commit | 753c62d75e73b101e485decebcf2f33d28b8f87e (patch) | |
tree | abf34e205130db9fcd66d7fb2b66606dfd8bf6dd /src/plugins/remotelinux | |
parent | ac8150624a5dcd1e681e6373e812201cd0725d33 (diff) | |
download | qt-creator-753c62d75e73b101e485decebcf2f33d28b8f87e.tar.gz |
Device support: Introduce IDevice helper classes.
These are for configuration of process and ports gathering activities,
respectively.
This couples related functionality more tightly, while keeping
the number of IDevice methods at a reasonable level.
For ports gathering, the patch also adds the ability to configure
both the command and the parsing function; the latter used to be
hardcoded in the PortsGatherer class.
Change-Id: I1b8940397a51efa7ddc05dd15cf861777d118c1a
Reviewed-by: hjk <qthjk@ovi.com>
Diffstat (limited to 'src/plugins/remotelinux')
-rw-r--r-- | src/plugins/remotelinux/linuxdevice.cpp | 172 | ||||
-rw-r--r-- | src/plugins/remotelinux/linuxdevice.h | 14 | ||||
-rw-r--r-- | src/plugins/remotelinux/remotelinuxdebugsupport.cpp | 8 | ||||
-rw-r--r-- | src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp | 1 | ||||
-rw-r--r-- | src/plugins/remotelinux/remotelinuxrunconfigurationwidget.cpp | 1 | ||||
-rw-r--r-- | src/plugins/remotelinux/remotelinuxruncontrol.cpp | 12 | ||||
-rw-r--r-- | src/plugins/remotelinux/remotelinuxruncontrol.h | 1 | ||||
-rw-r--r-- | src/plugins/remotelinux/remotelinuxutils.cpp | 14 | ||||
-rw-r--r-- | src/plugins/remotelinux/remotelinuxutils.h | 4 |
9 files changed, 136 insertions, 91 deletions
diff --git a/src/plugins/remotelinux/linuxdevice.cpp b/src/plugins/remotelinux/linuxdevice.cpp index 4a3b1d968f..864e76d033 100644 --- a/src/plugins/remotelinux/linuxdevice.cpp +++ b/src/plugins/remotelinux/linuxdevice.cpp @@ -54,6 +54,119 @@ static QString visualizeNull(QString s) return s.replace(QLatin1Char('\0'), QLatin1String("<null>")); } +QString LinuxDeviceProcessSupport::listProcessesCommandLine() const +{ + return QString::fromLatin1( + "for dir in `ls -d /proc/[0123456789]*`; do " + "test -d $dir || continue;" // Decrease the likelihood of a race condition. + "echo $dir;" + "cat $dir/cmdline;echo;" // cmdline does not end in newline + "cat $dir/stat;" + "readlink $dir/exe;" + "printf '%1''%2';" + "done").arg(Delimiter0).arg(Delimiter1); +} + +QList<DeviceProcess> LinuxDeviceProcessSupport::buildProcessList(const QString &listProcessesReply) const +{ + QList<DeviceProcess> processes; + const QStringList lines = listProcessesReply.split(QString::fromLatin1(Delimiter0) + + QString::fromLatin1(Delimiter1), QString::SkipEmptyParts); + foreach (const QString &line, lines) { + const QStringList elements = line.split(QLatin1Char('\n')); + if (elements.count() < 4) { + qDebug("%s: Expected four list elements, got %d. Line was '%s'.", Q_FUNC_INFO, + elements.count(), qPrintable(visualizeNull(line))); + continue; + } + bool ok; + const int pid = elements.first().mid(6).toInt(&ok); + if (!ok) { + qDebug("%s: Expected number in %s. Line was '%s'.", Q_FUNC_INFO, + qPrintable(elements.first()), qPrintable(visualizeNull(line))); + continue; + } + QString command = elements.at(1); + command.replace(QLatin1Char('\0'), QLatin1Char(' ')); + if (command.isEmpty()) { + const QString &statString = elements.at(2); + const int openParenPos = statString.indexOf(QLatin1Char('(')); + const int closedParenPos = statString.indexOf(QLatin1Char(')'), openParenPos); + if (openParenPos == -1 || closedParenPos == -1) + continue; + command = QLatin1Char('[') + + statString.mid(openParenPos + 1, closedParenPos - openParenPos - 1) + + QLatin1Char(']'); + } + + DeviceProcess process; + process.pid = pid; + process.cmdLine = command; + process.exe = elements.at(3); + processes.append(process); + } + + qSort(processes); + return processes; +} + +QString LinuxDeviceProcessSupport::killProcessByPidCommandLine(int pid) const +{ + return QLatin1String("kill -9 ") + QString::number(pid); +} + +QString LinuxDeviceProcessSupport::killProcessByNameCommandLine(const QString &filePath) const +{ + return QString::fromLatin1("cd /proc; for pid in `ls -d [0123456789]*`; " + "do " + "if [ \"`readlink /proc/$pid/exe`\" = \"%1\" ]; then " + " kill $pid; sleep 1; kill -9 $pid; " + "fi; " + "done").arg(filePath); +} + + +class LinuxPortsGatheringMethod : public ProjectExplorer::PortsGatheringMethod +{ + QByteArray commandLine(QAbstractSocket::NetworkLayerProtocol protocol) const + { + QString procFilePath; + int addressLength; + if (protocol == QAbstractSocket::IPv4Protocol) { + procFilePath = QLatin1String("/proc/net/tcp"); + addressLength = 8; + } else { + procFilePath = QLatin1String("/proc/net/tcp6"); + addressLength = 32; + } + return QString::fromLatin1("sed " + "'s/.*: [[:xdigit:]]\\{%1\\}:\\([[:xdigit:]]\\{4\\}\\).*/\\1/g' %2") + .arg(addressLength).arg(procFilePath).toUtf8(); + } + + QList<int> usedPorts(const QByteArray &output) const + { + QList<int> ports; + QList<QByteArray> portStrings = output.split('\n'); + portStrings.removeFirst(); + foreach (const QByteArray &portString, portStrings) { + if (portString.isEmpty()) + continue; + bool ok; + const int port = portString.toInt(&ok, 16); + if (ok) { + if (!ports.contains(port)) + ports << port; + } else { + qWarning("%s: Unexpected string '%s' is not a port.", + Q_FUNC_INFO, portString.data()); + } + } + return ports; + } +}; + + LinuxDevice::Ptr LinuxDevice::create(const QString &name, Core::Id type, MachineType machineType, Origin origin, Core::Id id) { @@ -128,65 +241,14 @@ ProjectExplorer::IDevice::Ptr LinuxDevice::clone() const return Ptr(new LinuxDevice(*this)); } -QString LinuxDevice::listProcessesCommandLine() const -{ - return QString::fromLatin1( - "for dir in `ls -d /proc/[0123456789]*`; do " - "test -d $dir || continue;" // Decrease the likelihood of a race condition. - "echo $dir;" - "cat $dir/cmdline;echo;" // cmdline does not end in newline - "cat $dir/stat;" - "readlink $dir/exe;" - "printf '%1''%2';" - "done").arg(Delimiter0).arg(Delimiter1); -} - -QString LinuxDevice::killProcessCommandLine(const DeviceProcess &process) const +DeviceProcessSupport::Ptr LinuxDevice::processSupport() const { - return QLatin1String("kill -9 ") + QString::number(process.pid); + return DeviceProcessSupport::Ptr(new LinuxDeviceProcessSupport); } -QList<DeviceProcess> LinuxDevice::buildProcessList(const QString &listProcessesReply) const +PortsGatheringMethod::Ptr LinuxDevice::portsGatheringMethod() const { - QList<DeviceProcess> processes; - const QStringList lines = listProcessesReply.split(QString::fromLatin1(Delimiter0) - + QString::fromLatin1(Delimiter1), QString::SkipEmptyParts); - foreach (const QString &line, lines) { - const QStringList elements = line.split(QLatin1Char('\n')); - if (elements.count() < 4) { - qDebug("%s: Expected four list elements, got %d. Line was '%s'.", Q_FUNC_INFO, - elements.count(), qPrintable(visualizeNull(line))); - continue; - } - bool ok; - const int pid = elements.first().mid(6).toInt(&ok); - if (!ok) { - qDebug("%s: Expected number in %s. Line was '%s'.", Q_FUNC_INFO, - qPrintable(elements.first()), qPrintable(visualizeNull(line))); - continue; - } - QString command = elements.at(1); - command.replace(QLatin1Char('\0'), QLatin1Char(' ')); - if (command.isEmpty()) { - const QString &statString = elements.at(2); - const int openParenPos = statString.indexOf(QLatin1Char('(')); - const int closedParenPos = statString.indexOf(QLatin1Char(')'), openParenPos); - if (openParenPos == -1 || closedParenPos == -1) - continue; - command = QLatin1Char('[') - + statString.mid(openParenPos + 1, closedParenPos - openParenPos - 1) - + QLatin1Char(']'); - } - - DeviceProcess process; - process.pid = pid; - process.cmdLine = command; - process.exe = elements.at(3); - processes.append(process); - } - - qSort(processes); - return processes; + return LinuxPortsGatheringMethod::Ptr(new LinuxPortsGatheringMethod); } } // namespace RemoteLinux diff --git a/src/plugins/remotelinux/linuxdevice.h b/src/plugins/remotelinux/linuxdevice.h index 3d4a5f7329..60a05c85b8 100644 --- a/src/plugins/remotelinux/linuxdevice.h +++ b/src/plugins/remotelinux/linuxdevice.h @@ -43,6 +43,15 @@ namespace Utils { class PortList; } namespace RemoteLinux { namespace Internal { class LinuxDevicePrivate; } +class REMOTELINUX_EXPORT LinuxDeviceProcessSupport : public ProjectExplorer::DeviceProcessSupport +{ +public: + QString listProcessesCommandLine() const; + QList<ProjectExplorer::DeviceProcess> buildProcessList(const QString &listProcessesReply) const; + QString killProcessByPidCommandLine(int pid) const; + QString killProcessByNameCommandLine(const QString &filePath) const; +}; + class REMOTELINUX_EXPORT LinuxDevice : public ProjectExplorer::IDevice { Q_DECLARE_TR_FUNCTIONS(RemoteLinux::Internal::LinuxDevice) @@ -62,9 +71,8 @@ public: void executeAction(Core::Id actionId, QWidget *parent) const; ProjectExplorer::IDevice::Ptr clone() const; - QString listProcessesCommandLine() const; - QString killProcessCommandLine(const ProjectExplorer::DeviceProcess &process) const; - QList<ProjectExplorer::DeviceProcess> buildProcessList(const QString &listProcessesReply) const; + ProjectExplorer::DeviceProcessSupport::Ptr processSupport() const; + ProjectExplorer::PortsGatheringMethod::Ptr portsGatheringMethod() const; protected: LinuxDevice() {} diff --git a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp index a0f57b283d..baa5be50af 100644 --- a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp +++ b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp @@ -30,7 +30,6 @@ #include "remotelinuxdebugsupport.h" #include "remotelinuxrunconfiguration.h" -#include "remotelinuxutils.h" #include <debugger/debuggerengine.h> #include <debugger/debuggerstartparameters.h> @@ -306,8 +305,11 @@ void LinuxDeviceDebugSupport::setFinished() return; d->portsGatherer.disconnect(this); d->appRunner.disconnect(this); - if (d->state == StartingRunner) - d->appRunner.stop(RemoteLinuxUtils::killApplicationCommandLine(d->remoteFilePath).toUtf8()); + if (d->state == StartingRunner) { + const QString stopCommand + = d->device->processSupport()->killProcessByNameCommandLine(d->remoteFilePath); + d->appRunner.stop(stopCommand.toUtf8()); + } d->state = Inactive; } diff --git a/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp b/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp index 9cdaf53ab0..e4e938cf36 100644 --- a/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp +++ b/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp @@ -32,7 +32,6 @@ #include "remotelinux_constants.h" #include "remotelinuxdeployconfigurationfactory.h" #include "remotelinuxrunconfiguration.h" -#include "remotelinuxutils.h" #include <projectexplorer/profileinformation.h> #include <projectexplorer/target.h> diff --git a/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.cpp b/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.cpp index c31910d3ad..8cc6c45283 100644 --- a/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.cpp +++ b/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.cpp @@ -31,7 +31,6 @@ #include "remotelinuxrunconfiguration.h" #include "remotelinuxenvironmentreader.h" -#include "remotelinuxutils.h" #include <coreplugin/coreconstants.h> #include <coreplugin/icore.h> diff --git a/src/plugins/remotelinux/remotelinuxruncontrol.cpp b/src/plugins/remotelinux/remotelinuxruncontrol.cpp index 3492cf3a73..554816cf58 100644 --- a/src/plugins/remotelinux/remotelinuxruncontrol.cpp +++ b/src/plugins/remotelinux/remotelinuxruncontrol.cpp @@ -30,7 +30,6 @@ #include "remotelinuxruncontrol.h" #include "remotelinuxrunconfiguration.h" -#include "remotelinuxutils.h" #include <projectexplorer/devicesupport/deviceapplicationrunner.h> #include <projectexplorer/profileinformation.h> @@ -54,7 +53,6 @@ public: QString remoteExecutable; QString arguments; QString prefix; - QByteArray stopCommand; }; RemoteLinuxRunControl::RemoteLinuxRunControl(RunConfiguration *rc) @@ -66,7 +64,6 @@ RemoteLinuxRunControl::RemoteLinuxRunControl(RunConfiguration *rc) d->remoteExecutable = lrc->remoteExecutableFilePath(); d->arguments = lrc->arguments(); d->prefix = lrc->commandPrefix(); - d->stopCommand = RemoteLinuxUtils::killApplicationCommandLine(d->remoteExecutable).toUtf8(); } RemoteLinuxRunControl::~RemoteLinuxRunControl() @@ -92,7 +89,9 @@ void RemoteLinuxRunControl::start() RunControl::StopResult RemoteLinuxRunControl::stop() { - d->runner.stop(d->stopCommand); + const QString stopCommandLine + = d->device->processSupport()->killProcessByNameCommandLine(d->remoteExecutable); + d->runner.stop(stopCommandLine.toUtf8()); return AsynchronousStop; } @@ -141,11 +140,6 @@ void RemoteLinuxRunControl::setApplicationRunnerPostRunAction(DeviceApplicationH d->runner.setPostRunAction(action); } -void RemoteLinuxRunControl::overrideStopCommandLine(const QByteArray &commandLine) -{ - d->stopCommand = commandLine; -} - void RemoteLinuxRunControl::setFinished() { d->runner.disconnect(this); diff --git a/src/plugins/remotelinux/remotelinuxruncontrol.h b/src/plugins/remotelinux/remotelinuxruncontrol.h index 86f690d66a..207644ca5b 100644 --- a/src/plugins/remotelinux/remotelinuxruncontrol.h +++ b/src/plugins/remotelinux/remotelinuxruncontrol.h @@ -52,7 +52,6 @@ public: void setApplicationRunnerPreRunAction(ProjectExplorer::DeviceApplicationHelperAction *action); void setApplicationRunnerPostRunAction(ProjectExplorer::DeviceApplicationHelperAction *action); - void overrideStopCommandLine(const QByteArray &commandLine); private slots: void handleErrorMessage(const QString &error); diff --git a/src/plugins/remotelinux/remotelinuxutils.cpp b/src/plugins/remotelinux/remotelinuxutils.cpp index 907d04e570..2eb4518a6c 100644 --- a/src/plugins/remotelinux/remotelinuxutils.cpp +++ b/src/plugins/remotelinux/remotelinuxutils.cpp @@ -29,20 +29,6 @@ **************************************************************************/ #include "remotelinuxutils.h" -#include "linuxdevice.h" - -#include <QCoreApplication> - namespace RemoteLinux { -QString RemoteLinuxUtils::killApplicationCommandLine(const QString &applicationFilePath) -{ - return QString::fromLatin1("cd /proc; for pid in `ls -d [0123456789]*`; " - "do " - "if [ \"`readlink /proc/$pid/exe`\" = \"%1\" ]; then " - " kill $pid; sleep 1; kill -9 $pid; " - "fi; " - "done").arg(applicationFilePath); -} - } // namespace RemoteLinux diff --git a/src/plugins/remotelinux/remotelinuxutils.h b/src/plugins/remotelinux/remotelinuxutils.h index b8bbf3b758..24d9c37488 100644 --- a/src/plugins/remotelinux/remotelinuxutils.h +++ b/src/plugins/remotelinux/remotelinuxutils.h @@ -32,15 +32,11 @@ #include "remotelinux_export.h" -#include <QSharedPointer> - namespace RemoteLinux { -class LinuxDevice; class REMOTELINUX_EXPORT RemoteLinuxUtils { public: - static QString killApplicationCommandLine(const QString &applicationFilePath); }; } // namespace RemoteLinux |