diff --git a/src/libs/utils/processinfo.cpp b/src/libs/utils/processinfo.cpp index 366800d3161..d6ecd4d2344 100644 --- a/src/libs/utils/processinfo.cpp +++ b/src/libs/utils/processinfo.cpp @@ -3,14 +3,13 @@ #include "processinfo.h" +#include "algorithm.h" #include "qtcprocess.h" -#if defined(Q_OS_UNIX) #include -#include -#include -#include -#include +#include + +#if defined(Q_OS_UNIX) #elif defined(Q_OS_WIN) #include "winutils.h" #ifdef QTCREATOR_PCH_H @@ -32,82 +31,64 @@ bool ProcessInfo::operator<(const ProcessInfo &other) const return commandLine < other.commandLine; } -#if defined(Q_OS_UNIX) - -static bool isUnixProcessId(const QString &procname) -{ - for (int i = 0; i != procname.size(); ++i) - if (!procname.at(i).isDigit()) - return false; - return true; -} - // Determine UNIX processes by reading "/proc". Default to ps if // it does not exist -static const char procDirC[] = "/proc/"; - -static QList getLocalProcessesUsingProc() +static QList getLocalProcessesUsingProc(const FilePath &procDir) { + static const QString execs = "-exec test -f {}/exe \\; " + "-exec test -f {}/cmdline \\; " + "-exec echo -en 'p{}\\ne' \\; " + "-exec readlink {}/exe \\; " + "-exec echo -n c \\; " + "-exec head -n 1 {}/cmdline \\; " + "-exec echo \\; " + "-exec echo __SKIP_ME__ \\;"; + + CommandLine cmd{procDir.withNewPath("find"), + {procDir.nativePath(), "-maxdepth", "1", "-type", "d", "-name", "[0-9]*"}}; + + cmd.addArgs(execs, CommandLine::Raw); + + QtcProcess procProcess; + procProcess.setCommand(cmd); + procProcess.runBlocking(); + QList processes; - const QString procDirPath = QLatin1String(procDirC); - const QDir procDir = QDir(QLatin1String(procDirC)); - const QStringList procIds = procDir.entryList(); - for (const QString &procId : procIds) { - if (!isUnixProcessId(procId)) - continue; - ProcessInfo proc; - proc.processId = procId.toInt(); - const QString root = procDirPath + procId; - const QFile exeFile(root + QLatin1String("/exe")); - proc.executable = exeFile.symLinkTarget(); + const auto lines = procProcess.readAllStandardOutput().split('\n'); + for (auto it = lines.begin(); it != lines.end(); ++it) { + if (it->startsWith('p')) { + ProcessInfo proc; + bool ok; + proc.processId = FilePath::fromUserInput(it->mid(1).trimmed()).fileName().toInt(&ok); + QTC_ASSERT(ok, continue); + ++it; - QFile cmdLineFile(root + QLatin1String("/cmdline")); - if (cmdLineFile.open(QIODevice::ReadOnly)) { // process may have exited - const QList tokens = cmdLineFile.readAll().split('\0'); - if (!tokens.isEmpty()) { - if (proc.executable.isEmpty()) - proc.executable = QString::fromLocal8Bit(tokens.front()); - for (const QByteArray &t : tokens) { - if (!proc.commandLine.isEmpty()) - proc.commandLine.append(QLatin1Char(' ')); - proc.commandLine.append(QString::fromLocal8Bit(t)); - } - } + QTC_ASSERT(it->startsWith('e'), continue); + proc.executable = it->mid(1).trimmed(); + ++it; + + QTC_ASSERT(it->startsWith('c'), continue); + proc.commandLine = it->mid(1).trimmed().replace('\0', ' '); + if (!proc.commandLine.contains("__SKIP_ME__")) + processes.append(proc); } - - if (proc.executable.isEmpty()) { - QFile statFile(root + QLatin1String("/stat")); - if (statFile.open(QIODevice::ReadOnly)) { - const QStringList data = QString::fromLocal8Bit(statFile.readAll()).split(QLatin1Char(' ')); - if (data.size() < 2) - continue; - proc.executable = data.at(1); - proc.commandLine = data.at(1); // PPID is element 3 - if (proc.executable.startsWith(QLatin1Char('(')) && proc.executable.endsWith(QLatin1Char(')'))) { - proc.executable.truncate(proc.executable.size() - 1); - proc.executable.remove(0, 1); - } - } - } - if (!proc.executable.isEmpty()) - processes.push_back(proc); } + return processes; } // Determine UNIX processes by running ps -static QMap getLocalProcessDataUsingPs(const QString &column) +static QMap getLocalProcessDataUsingPs(const FilePath &deviceRoot, + const QString &column) { QtcProcess process; - process.setCommand({"ps", {"-e", "-o", "pid," + column}}); - process.start(); - if (!process.waitForFinished()) - return {}; + process.setCommand({deviceRoot.withNewPath("ps"), {"-e", "-o", "pid," + column}}); + process.runBlocking(); // Split "457 /Users/foo.app arg1 arg2" - const QStringList lines = process.stdOut().split(QLatin1Char('\n')); + const QStringList lines = process.readAllStandardOutput().split(QLatin1Char('\n')); QMap result; for (int i = 1; i < lines.size(); ++i) { // Skip header const QString line = lines.at(i).trimmed(); @@ -118,14 +99,14 @@ static QMap getLocalProcessDataUsingPs(const QString &column) return result; } -static QList getLocalProcessesUsingPs() +static QList getLocalProcessesUsingPs(const FilePath &deviceRoot) { QList processes; // cmdLines are full command lines, usually with absolute path, // exeNames only the file part of the executable's path. - const QMap exeNames = getLocalProcessDataUsingPs("comm"); - const QMap cmdLines = getLocalProcessDataUsingPs("args"); + const QMap exeNames = getLocalProcessDataUsingPs(deviceRoot, "comm"); + const QMap cmdLines = getLocalProcessDataUsingPs(deviceRoot, "args"); for (auto it = exeNames.begin(), end = exeNames.end(); it != end; ++it) { const qint64 pid = it.key(); @@ -146,16 +127,68 @@ static QList getLocalProcessesUsingPs() return processes; } -QList ProcessInfo::processInfoList() +static QList getProcessesUsingPidin(const FilePath &pidin) { - const QDir procDir = QDir(QLatin1String(procDirC)); - return procDir.exists() ? getLocalProcessesUsingProc() : getLocalProcessesUsingPs(); + QtcProcess process; + process.setCommand({pidin, {"-F", "%a %A {/%n}"}}); + process.runBlocking(); + + QList processes; + QStringList lines = process.readAllStandardOutput().split(QLatin1Char('\n')); + if (lines.isEmpty()) + return processes; + + lines.pop_front(); // drop headers + const QRegularExpression re("\\s*(\\d+)\\s+(.*){(.*)}"); + + for (const QString &line : std::as_const(lines)) { + const QRegularExpressionMatch match = re.match(line); + if (match.hasMatch()) { + const QStringList captures = match.capturedTexts(); + if (captures.size() == 4) { + const int pid = captures[1].toInt(); + const QString args = captures[2]; + const QString exe = captures[3]; + ProcessInfo deviceProcess; + deviceProcess.processId = pid; + deviceProcess.executable = exe.trimmed(); + deviceProcess.commandLine = args.trimmed(); + processes.append(deviceProcess); + } + } + } + + return Utils::sorted(std::move(processes)); +} + +static QList processInfoListUnix(const FilePath &deviceRoot) +{ + const FilePath procDir = deviceRoot.withNewPath("/proc"); + const FilePath pidin = deviceRoot.withNewPath("pidin").searchInPath(); + + if (pidin.isExecutableFile()) + return getProcessesUsingPidin(pidin); + + if (procDir.isReadableDir()) + return getLocalProcessesUsingProc(procDir); + + return getLocalProcessesUsingPs(deviceRoot); +} + +#if defined(Q_OS_UNIX) + +QList ProcessInfo::processInfoList(const FilePath &deviceRoot) +{ + return processInfoListUnix(deviceRoot); } #elif defined(Q_OS_WIN) -QList ProcessInfo::processInfoList() +QList ProcessInfo::processInfoList(const FilePath &deviceRoot) { + if (deviceRoot.needsDevice()) + return processInfoListUnix(deviceRoot); + QList processes; PROCESSENTRY32 pe; diff --git a/src/libs/utils/processinfo.h b/src/libs/utils/processinfo.h index 47fd2d6d0de..90c1a97374d 100644 --- a/src/libs/utils/processinfo.h +++ b/src/libs/utils/processinfo.h @@ -5,6 +5,8 @@ #include "utils_global.h" +#include "filepath.h" + #include #include @@ -19,7 +21,7 @@ public: bool operator<(const ProcessInfo &other) const; - static QList processInfoList(); + static QList processInfoList(const Utils::FilePath &deviceRoot = Utils::FilePath()); }; } // namespace Utils diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp index a9687352529..9ead5e8c783 100644 --- a/src/plugins/docker/dockerdevice.cpp +++ b/src/plugins/docker/dockerdevice.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -486,7 +487,7 @@ CommandLine DockerDevicePrivate::withDockerExecCmd(const CommandLine &cmd, dockerCmd.addArgs({"/bin/sh", "-c"}); CommandLine exec("exec"); - exec.addCommandLineAsArgs(cmd); + exec.addCommandLineAsArgs(cmd, CommandLine::Raw); CommandLine echo("echo"); echo.addArgs("__qtc$$qtc__", CommandLine::Raw); @@ -494,7 +495,7 @@ CommandLine DockerDevicePrivate::withDockerExecCmd(const CommandLine &cmd, dockerCmd.addCommandLineAsSingleArg(echo); } else { - dockerCmd.addCommandLineAsArgs(cmd); + dockerCmd.addCommandLineAsArgs(cmd, CommandLine::Raw); } return dockerCmd; @@ -792,9 +793,9 @@ PortsGatheringMethod DockerDevice::portsGatheringMethod() const &Port::parseFromSedOutput}; }; -DeviceProcessList *DockerDevice::createProcessListModel(QObject *) const +DeviceProcessList *DockerDevice::createProcessListModel(QObject *parent) const { - return nullptr; + return new ProcessList(sharedFromThis(), parent); } DeviceTester *DockerDevice::createDeviceTester() const diff --git a/src/plugins/docker/dockerdevice.h b/src/plugins/docker/dockerdevice.h index 3ecc0118d49..38e9956a230 100644 --- a/src/plugins/docker/dockerdevice.h +++ b/src/plugins/docker/dockerdevice.h @@ -75,7 +75,7 @@ public: bool canAutoDetectPorts() const override; ProjectExplorer::PortsGatheringMethod portsGatheringMethod() const override; - bool canCreateProcessModel() const override { return false; } + bool canCreateProcessModel() const override { return true; } ProjectExplorer::DeviceProcessList *createProcessListModel(QObject *parent) const override; bool hasDeviceTester() const override { return false; } ProjectExplorer::DeviceTester *createDeviceTester() const override; diff --git a/src/plugins/projectexplorer/CMakeLists.txt b/src/plugins/projectexplorer/CMakeLists.txt index b14cb87a5ff..491587d7766 100644 --- a/src/plugins/projectexplorer/CMakeLists.txt +++ b/src/plugins/projectexplorer/CMakeLists.txt @@ -66,8 +66,7 @@ add_qtc_plugin(ProjectExplorer devicesupport/idevicefactory.cpp devicesupport/idevicefactory.h devicesupport/idevicefwd.h devicesupport/idevicewidget.h - devicesupport/localprocesslist.cpp devicesupport/localprocesslist.h - devicesupport/sshdeviceprocesslist.cpp devicesupport/sshdeviceprocesslist.h + devicesupport/processlist.cpp devicesupport/processlist.h devicesupport/sshparameters.cpp devicesupport/sshparameters.h devicesupport/sshsettings.cpp devicesupport/sshsettings.h devicesupport/sshsettingspage.cpp devicesupport/sshsettingspage.h diff --git a/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp b/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp index 566b669c393..724b6608aad 100644 --- a/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp +++ b/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp @@ -3,11 +3,11 @@ #include "desktopdevice.h" -#include "desktopprocesssignaloperation.h" -#include "deviceprocesslist.h" -#include "localprocesslist.h" #include "../projectexplorerconstants.h" #include "../projectexplorertr.h" +#include "desktopprocesssignaloperation.h" +#include "deviceprocesslist.h" +#include "processlist.h" #include @@ -137,7 +137,7 @@ bool DesktopDevice::canCreateProcessModel() const DeviceProcessList *DesktopDevice::createProcessListModel(QObject *parent) const { - return new Internal::LocalProcessList(sharedFromThis(), parent); + return new ProcessList(sharedFromThis(), parent); } DeviceProcessSignalOperation::Ptr DesktopDevice::signalOperation() const diff --git a/src/plugins/projectexplorer/devicesupport/localprocesslist.cpp b/src/plugins/projectexplorer/devicesupport/localprocesslist.cpp deleted file mode 100644 index c6fd49012fb..00000000000 --- a/src/plugins/projectexplorer/devicesupport/localprocesslist.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#include "localprocesslist.h" - -#include -#include - -#include - -#if defined(Q_OS_UNIX) -#include -#elif defined(Q_OS_WIN) -#include -#endif - -using namespace Utils; - -namespace ProjectExplorer { -namespace Internal { - -LocalProcessList::LocalProcessList(const IDevice::ConstPtr &device, QObject *parent) - : DeviceProcessList(device, parent) -{ -#if defined(Q_OS_UNIX) - setOwnPid(getpid()); -#elif defined(Q_OS_WIN) - setOwnPid(GetCurrentProcessId()); -#endif -} - -void LocalProcessList::doKillProcess(const ProcessInfo &processInfo) -{ - DeviceProcessSignalOperation::Ptr signalOperation = device()->signalOperation(); - connect(signalOperation.data(), &DeviceProcessSignalOperation::finished, - this, &LocalProcessList::reportDelayedKillStatus); - signalOperation->killProcess(processInfo.processId); -} - -void LocalProcessList::handleUpdate() -{ - reportProcessListUpdated(ProcessInfo::processInfoList()); -} - -void LocalProcessList::doUpdate() -{ - QTimer::singleShot(0, this, &LocalProcessList::handleUpdate); -} - -void LocalProcessList::reportDelayedKillStatus(const QString &errorMessage) -{ - if (errorMessage.isEmpty()) - reportProcessKilled(); - else - reportError(errorMessage); -} - -} // namespace Internal -} // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/devicesupport/processlist.cpp b/src/plugins/projectexplorer/devicesupport/processlist.cpp new file mode 100644 index 00000000000..11e0932832d --- /dev/null +++ b/src/plugins/projectexplorer/devicesupport/processlist.cpp @@ -0,0 +1,61 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "processlist.h" + +#include +#include + +#include + +#if defined(Q_OS_UNIX) +#include +#elif defined(Q_OS_WIN) +#include +#endif + +using namespace Utils; + +namespace ProjectExplorer { + +ProcessList::ProcessList(const IDevice::ConstPtr &device, QObject *parent) + : DeviceProcessList(device, parent) +{ +#if defined(Q_OS_UNIX) + setOwnPid(getpid()); +#elif defined(Q_OS_WIN) + setOwnPid(GetCurrentProcessId()); +#endif +} + +void ProcessList::doKillProcess(const ProcessInfo &processInfo) +{ + m_signalOperation = device()->signalOperation(); + connect(m_signalOperation.data(), + &DeviceProcessSignalOperation::finished, + this, + &ProcessList::reportDelayedKillStatus); + m_signalOperation->killProcess(processInfo.processId); +} + +void ProcessList::handleUpdate() +{ + reportProcessListUpdated(ProcessInfo::processInfoList(DeviceProcessList::device()->rootPath())); +} + +void ProcessList::doUpdate() +{ + QTimer::singleShot(0, this, &ProcessList::handleUpdate); +} + +void ProcessList::reportDelayedKillStatus(const QString &errorMessage) +{ + if (errorMessage.isEmpty()) + reportProcessKilled(); + else + reportError(errorMessage); + + m_signalOperation.reset(); +} + +} // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/devicesupport/localprocesslist.h b/src/plugins/projectexplorer/devicesupport/processlist.h similarity index 66% rename from src/plugins/projectexplorer/devicesupport/localprocesslist.h rename to src/plugins/projectexplorer/devicesupport/processlist.h index e3445f47b20..caebaf22f97 100644 --- a/src/plugins/projectexplorer/devicesupport/localprocesslist.h +++ b/src/plugins/projectexplorer/devicesupport/processlist.h @@ -4,16 +4,16 @@ #pragma once #include "deviceprocesslist.h" +#include "idevice.h" namespace ProjectExplorer { -namespace Internal { -class LocalProcessList : public DeviceProcessList +class PROJECTEXPLORER_EXPORT ProcessList : public DeviceProcessList { Q_OBJECT public: - explicit LocalProcessList(const IDeviceConstPtr &device, QObject *parent = nullptr); + explicit ProcessList(const IDeviceConstPtr &device, QObject *parent = nullptr); private: void doUpdate() override; @@ -22,7 +22,9 @@ private: private: void handleUpdate(); void reportDelayedKillStatus(const QString &errorMessage); + +private: + DeviceProcessSignalOperation::Ptr m_signalOperation; }; -} // namespace Internal } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/devicesupport/sshdeviceprocesslist.cpp b/src/plugins/projectexplorer/devicesupport/sshdeviceprocesslist.cpp deleted file mode 100644 index d64cde6e3ed..00000000000 --- a/src/plugins/projectexplorer/devicesupport/sshdeviceprocesslist.cpp +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#include "sshdeviceprocesslist.h" - -#include "idevice.h" -#include "../projectexplorertr.h" - -#include -#include -#include -#include - -using namespace Utils; - -namespace ProjectExplorer { - -class SshDeviceProcessListPrivate -{ -public: - QtcProcess m_process; - DeviceProcessSignalOperation::Ptr m_signalOperation; -}; - -SshDeviceProcessList::SshDeviceProcessList(const IDevice::ConstPtr &device, QObject *parent) : - DeviceProcessList(device, parent), d(std::make_unique()) -{ - connect(&d->m_process, &QtcProcess::done, this, &SshDeviceProcessList::handleProcessDone); -} - -SshDeviceProcessList::~SshDeviceProcessList() = default; - -void SshDeviceProcessList::doUpdate() -{ - d->m_process.close(); - d->m_process.setCommand({device()->filePath("/bin/sh"), {"-c", listProcessesCommandLine()}}); - d->m_process.start(); -} - -void SshDeviceProcessList::doKillProcess(const ProcessInfo &process) -{ - d->m_signalOperation = device()->signalOperation(); - QTC_ASSERT(d->m_signalOperation, return); - connect(d->m_signalOperation.data(), &DeviceProcessSignalOperation::finished, - this, &SshDeviceProcessList::handleKillProcessFinished); - d->m_signalOperation->killProcess(process.processId); -} - -void SshDeviceProcessList::handleProcessDone() -{ - if (d->m_process.result() == ProcessResult::FinishedWithSuccess) { - reportProcessListUpdated(buildProcessList(d->m_process.cleanedStdOut())); - } else { - const QString errorString = d->m_process.exitStatus() == QProcess::NormalExit - ? Tr::tr("Process listing command failed with exit code %1.").arg(d->m_process.exitCode()) - : d->m_process.errorString(); - const QString stdErr = d->m_process.cleanedStdErr(); - const QString outputString - = stdErr.isEmpty() ? stdErr : Tr::tr("Remote stderr was: %1").arg(stdErr); - reportError(Utils::joinStrings({errorString, outputString}, '\n')); - } - setFinished(); -} - -void SshDeviceProcessList::handleKillProcessFinished(const QString &errorString) -{ - if (errorString.isEmpty()) - reportProcessKilled(); - else - reportError(Tr::tr("Error: Kill process failed: %1").arg(errorString)); - setFinished(); -} - -void SshDeviceProcessList::setFinished() -{ - d->m_process.close(); - if (d->m_signalOperation) { - d->m_signalOperation->disconnect(this); - d->m_signalOperation.clear(); - } -} - -} // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/devicesupport/sshdeviceprocesslist.h b/src/plugins/projectexplorer/devicesupport/sshdeviceprocesslist.h deleted file mode 100644 index fd560f53755..00000000000 --- a/src/plugins/projectexplorer/devicesupport/sshdeviceprocesslist.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include "deviceprocesslist.h" - -#include - -namespace ProjectExplorer { - -class SshDeviceProcessListPrivate; - -class PROJECTEXPLORER_EXPORT SshDeviceProcessList : public DeviceProcessList -{ - Q_OBJECT -public: - explicit SshDeviceProcessList(const IDeviceConstPtr &device, QObject *parent = nullptr); - ~SshDeviceProcessList() override; - -private: - void handleProcessDone(); - void handleKillProcessFinished(const QString &errorString); - - virtual QString listProcessesCommandLine() const = 0; - virtual QList buildProcessList(const QString &listProcessesReply) const = 0; - - void doUpdate() override; - void doKillProcess(const Utils::ProcessInfo &process) override; - - void setFinished(); - - const std::unique_ptr d; -}; - -} // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/projectexplorer.qbs b/src/plugins/projectexplorer/projectexplorer.qbs index e7d3d76b794..315a8d361e0 100644 --- a/src/plugins/projectexplorer/projectexplorer.qbs +++ b/src/plugins/projectexplorer/projectexplorer.qbs @@ -227,8 +227,7 @@ Project { "idevicefactory.cpp", "idevicefactory.h", "idevicefwd.h", "idevicewidget.h", - "localprocesslist.cpp", "localprocesslist.h", - "sshdeviceprocesslist.cpp", "sshdeviceprocesslist.h", + "processlist.cpp", "processlist.h", "sshparameters.cpp", "sshparameters.h", "sshsettings.cpp", "sshsettings.h", "sshsettingspage.cpp", "sshsettingspage.h", diff --git a/src/plugins/qnx/CMakeLists.txt b/src/plugins/qnx/CMakeLists.txt index 2c0e77cee8c..2de34ae95f8 100644 --- a/src/plugins/qnx/CMakeLists.txt +++ b/src/plugins/qnx/CMakeLists.txt @@ -10,7 +10,6 @@ add_qtc_plugin(Qnx qnxdebugsupport.cpp qnxdebugsupport.h qnxdeployqtlibrariesdialog.cpp qnxdeployqtlibrariesdialog.h qnxdevice.cpp qnxdevice.h - qnxdeviceprocesslist.cpp qnxdeviceprocesslist.h qnxdevicetester.cpp qnxdevicetester.h qnxdevicewizard.cpp qnxdevicewizard.h qnxplugin.cpp diff --git a/src/plugins/qnx/qnx.qbs b/src/plugins/qnx/qnx.qbs index b9e19ead0b1..e62cc8975ce 100644 --- a/src/plugins/qnx/qnx.qbs +++ b/src/plugins/qnx/qnx.qbs @@ -30,8 +30,6 @@ QtcPlugin { "qnxdevice.h", "qnxdevicewizard.cpp", "qnxdevicewizard.h", - "qnxdeviceprocesslist.cpp", - "qnxdeviceprocesslist.h", "qnxdevicetester.cpp", "qnxdevicetester.h", "qnxconfigurationmanager.cpp", diff --git a/src/plugins/qnx/qnxdevice.cpp b/src/plugins/qnx/qnxdevice.cpp index 958f09a59e5..4460d5bf00d 100644 --- a/src/plugins/qnx/qnxdevice.cpp +++ b/src/plugins/qnx/qnxdevice.cpp @@ -6,7 +6,6 @@ #include "qnxconstants.h" #include "qnxdeployqtlibrariesdialog.h" #include "qnxdevicetester.h" -#include "qnxdeviceprocesslist.h" #include "qnxdevicewizard.h" #include "qnxtr.h" @@ -121,11 +120,6 @@ PortsGatheringMethod QnxDevice::portsGatheringMethod() const }; } -DeviceProcessList *QnxDevice::createProcessListModel(QObject *parent) const -{ - return new QnxDeviceProcessList(sharedFromThis(), parent); -} - DeviceTester *QnxDevice::createDeviceTester() const { return new QnxDeviceTester; diff --git a/src/plugins/qnx/qnxdevice.h b/src/plugins/qnx/qnxdevice.h index 0ee38912f37..f1deaf6a377 100644 --- a/src/plugins/qnx/qnxdevice.h +++ b/src/plugins/qnx/qnxdevice.h @@ -16,7 +16,6 @@ public: static Ptr create() { return Ptr(new QnxDevice); } ProjectExplorer::PortsGatheringMethod portsGatheringMethod() const override; - ProjectExplorer::DeviceProcessList *createProcessListModel(QObject *parent) const override; ProjectExplorer::DeviceProcessSignalOperation::Ptr signalOperation() const override; ProjectExplorer::DeviceTester *createDeviceTester() const override; diff --git a/src/plugins/qnx/qnxdeviceprocesslist.cpp b/src/plugins/qnx/qnxdeviceprocesslist.cpp deleted file mode 100644 index 39735329934..00000000000 --- a/src/plugins/qnx/qnxdeviceprocesslist.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (C) 2016 BlackBerry Limited. All rights reserved. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#include "qnxdeviceprocesslist.h" - -#include -#include -#include -#include - -#include -#include - -using namespace Utils; - -namespace Qnx::Internal { - -QnxDeviceProcessList::QnxDeviceProcessList( - const ProjectExplorer::IDevice::ConstPtr &device, QObject *parent) - : ProjectExplorer::SshDeviceProcessList(device, parent) -{ -} - -QString QnxDeviceProcessList::listProcessesCommandLine() const -{ - return QLatin1String("pidin -F '%a %A {/%n}'"); -} - -QList QnxDeviceProcessList::buildProcessList(const QString &listProcessesReply) const -{ - QList processes; - QStringList lines = listProcessesReply.split(QLatin1Char('\n')); - if (lines.isEmpty()) - return processes; - - lines.pop_front(); // drop headers - const QRegularExpression re("\\s*(\\d+)\\s+(.*){(.*)}"); - - for (const QString &line : std::as_const(lines)) { - const QRegularExpressionMatch match = re.match(line); - if (match.hasMatch()) { - const QStringList captures = match.capturedTexts(); - if (captures.size() == 4) { - const int pid = captures[1].toInt(); - const QString args = captures[2]; - const QString exe = captures[3]; - ProcessInfo deviceProcess; - deviceProcess.processId = pid; - deviceProcess.executable = exe.trimmed(); - deviceProcess.commandLine = args.trimmed(); - processes.append(deviceProcess); - } - } - } - - return Utils::sorted(std::move(processes)); -} - -} // Qnx::Internal diff --git a/src/plugins/qnx/qnxdeviceprocesslist.h b/src/plugins/qnx/qnxdeviceprocesslist.h deleted file mode 100644 index 0e71ae7ab01..00000000000 --- a/src/plugins/qnx/qnxdeviceprocesslist.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (C) 2016 BlackBerry Limited. All rights reserved. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include - -namespace Qnx::Internal { - -class QnxDeviceProcessList : public ProjectExplorer::SshDeviceProcessList -{ -public: - explicit QnxDeviceProcessList( - const ProjectExplorer::IDeviceConstPtr &device, QObject *parent = nullptr); - -private: - QString listProcessesCommandLine() const override; - QList buildProcessList(const QString &listProcessesReply) const override; -}; - -} // Qnx::Internal diff --git a/src/plugins/remotelinux/linuxdevice.cpp b/src/plugins/remotelinux/linuxdevice.cpp index fc3268c892d..345f6e28497 100644 --- a/src/plugins/remotelinux/linuxdevice.cpp +++ b/src/plugins/remotelinux/linuxdevice.cpp @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include @@ -51,9 +51,6 @@ namespace RemoteLinux { const QByteArray s_pidMarker = "__qtc"; -const char Delimiter0[] = "x--"; -const char Delimiter1[] = "---"; - static Q_LOGGING_CATEGORY(linuxDeviceLog, "qtc.remotelinux.device", QtWarningMsg); #define DEBUG(x) qCDebug(linuxDeviceLog) << x << '\n' @@ -274,77 +271,6 @@ private: IDevice::ConstPtr m_device; }; -static QString visualizeNull(QString s) -{ - return s.replace(QLatin1Char('\0'), QLatin1String("")); -} - -class LinuxDeviceProcessList : public SshDeviceProcessList -{ -public: - LinuxDeviceProcessList(const IDevice::ConstPtr &device, QObject *parent) - : SshDeviceProcessList(device, parent) - { - } - -private: - QString listProcessesCommandLine() const override - { - 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(QLatin1String(Delimiter0)).arg(QLatin1String(Delimiter1)); - } - - QList buildProcessList(const QString &listProcessesReply) const override - { - QList processes; - const QStringList lines = listProcessesReply.split(QString::fromLatin1(Delimiter0) - + QString::fromLatin1(Delimiter1), Qt::SkipEmptyParts); - for (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, - int(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(']'); - } - - ProcessInfo process; - process.processId = pid; - process.commandLine = command; - process.executable = elements.at(3); - processes.append(process); - } - - return Utils::sorted(std::move(processes)); - } -}; - - // LinuxDevicePrivate class ShellThreadHandler; @@ -1094,7 +1020,7 @@ PortsGatheringMethod LinuxDevice::portsGatheringMethod() const DeviceProcessList *LinuxDevice::createProcessListModel(QObject *parent) const { - return new LinuxDeviceProcessList(sharedFromThis(), parent); + return new ProcessList(sharedFromThis(), parent); } DeviceTester *LinuxDevice::createDeviceTester() const