2022-08-19 15:59:36 +02:00
|
|
|
// Copyright (C) 2016 BlackBerry Limited. All rights reserved.
|
2022-12-21 10:12:09 +01:00
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
2012-06-29 07:23:13 +02:00
|
|
|
|
2016-05-19 08:56:05 +02:00
|
|
|
#include "qnxdevice.h"
|
2019-02-20 19:13:28 +01:00
|
|
|
|
|
|
|
|
#include "qnxconstants.h"
|
2022-07-21 09:19:41 +02:00
|
|
|
#include "qnxdeployqtlibrariesdialog.h"
|
2013-05-30 13:53:28 +02:00
|
|
|
#include "qnxdevicetester.h"
|
2019-02-20 19:13:28 +01:00
|
|
|
#include "qnxdevicewizard.h"
|
2022-07-11 14:22:42 +02:00
|
|
|
#include "qnxtr.h"
|
2012-06-29 07:23:13 +02:00
|
|
|
|
2023-03-13 15:03:33 +01:00
|
|
|
#include <remotelinux/remotelinuxsignaloperation.h>
|
|
|
|
|
|
2016-04-19 16:43:30 +02:00
|
|
|
#include <utils/port.h>
|
2013-10-21 14:54:49 +02:00
|
|
|
#include <utils/qtcassert.h>
|
2022-05-02 19:59:40 +02:00
|
|
|
#include <utils/qtcprocess.h>
|
2013-04-29 15:45:00 +02:00
|
|
|
|
2020-06-19 13:46:26 +02:00
|
|
|
#include <QRegularExpression>
|
2013-04-29 15:45:00 +02:00
|
|
|
|
2014-11-27 17:46:45 +01:00
|
|
|
using namespace ProjectExplorer;
|
2022-02-14 18:37:56 +01:00
|
|
|
using namespace RemoteLinux;
|
2014-11-27 17:46:45 +01:00
|
|
|
using namespace Utils;
|
|
|
|
|
|
2022-07-21 09:19:41 +02:00
|
|
|
namespace Qnx::Internal {
|
2012-06-29 07:23:13 +02:00
|
|
|
|
2013-10-21 14:54:49 +02:00
|
|
|
const char QnxVersionKey[] = "QnxVersion";
|
2014-11-27 17:46:45 +01:00
|
|
|
|
2023-03-13 15:03:33 +01:00
|
|
|
static QString signalProcessByNameQnxCommandLine(const QString &filePath, int sig)
|
|
|
|
|
{
|
|
|
|
|
QString executable = filePath;
|
|
|
|
|
return QString::fromLatin1("for PID in $(ps -f -o pid,comm | grep %1 | awk '/%1/ {print $1}'); "
|
|
|
|
|
"do "
|
|
|
|
|
"kill -%2 $PID; "
|
|
|
|
|
"done").arg(executable.replace(QLatin1String("/"), QLatin1String("\\/"))).arg(sig);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class QnxDeviceProcessSignalOperation : public RemoteLinuxSignalOperation
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
explicit QnxDeviceProcessSignalOperation(const IDeviceConstPtr &device)
|
|
|
|
|
: RemoteLinuxSignalOperation(device)
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QString killProcessByNameCommandLine(const QString &filePath) const override
|
|
|
|
|
{
|
|
|
|
|
return QString::fromLatin1("%1; %2").arg(signalProcessByNameQnxCommandLine(filePath, 15),
|
|
|
|
|
signalProcessByNameQnxCommandLine(filePath, 9));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString interruptProcessByNameCommandLine(const QString &filePath) const override
|
|
|
|
|
{
|
|
|
|
|
return signalProcessByNameQnxCommandLine(filePath, 2);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2016-05-19 08:56:05 +02:00
|
|
|
QnxDevice::QnxDevice()
|
2019-01-11 14:50:08 +01:00
|
|
|
{
|
2022-07-11 14:22:42 +02:00
|
|
|
setDisplayType(Tr::tr("QNX"));
|
|
|
|
|
setDefaultDisplayName(Tr::tr("QNX Device"));
|
2019-08-16 10:17:45 +02:00
|
|
|
setOsType(OsTypeOtherUnix);
|
|
|
|
|
|
2022-07-11 14:22:42 +02:00
|
|
|
addDeviceAction({Tr::tr("Deploy Qt libraries..."), [](const IDevice::Ptr &device, QWidget *parent) {
|
2019-01-11 14:50:08 +01:00
|
|
|
QnxDeployQtLibrariesDialog dialog(device, parent);
|
|
|
|
|
dialog.exec();
|
|
|
|
|
}});
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-19 08:56:05 +02:00
|
|
|
int QnxDevice::qnxVersion() const
|
2013-10-21 14:54:49 +02:00
|
|
|
{
|
|
|
|
|
if (m_versionNumber == 0)
|
|
|
|
|
updateVersionNumber();
|
|
|
|
|
|
|
|
|
|
return m_versionNumber;
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-19 08:56:05 +02:00
|
|
|
void QnxDevice::updateVersionNumber() const
|
2013-10-21 14:54:49 +02:00
|
|
|
{
|
2022-05-02 19:59:40 +02:00
|
|
|
QtcProcess versionNumberProcess;
|
2013-10-21 14:54:49 +02:00
|
|
|
|
2022-05-10 15:33:33 +02:00
|
|
|
versionNumberProcess.setCommand({filePath("uname"), {"-r"}});
|
2022-05-02 19:59:40 +02:00
|
|
|
versionNumberProcess.runBlocking(EventLoopMode::On);
|
2013-10-21 14:54:49 +02:00
|
|
|
|
2023-01-05 17:55:04 +01:00
|
|
|
QByteArray output = versionNumberProcess.readAllRawStandardOutput();
|
2013-10-21 14:54:49 +02:00
|
|
|
QString versionMessage = QString::fromLatin1(output);
|
2020-06-19 13:46:26 +02:00
|
|
|
const QRegularExpression versionNumberRegExp("(\\d+)\\.(\\d+)\\.(\\d+)");
|
|
|
|
|
const QRegularExpressionMatch match = versionNumberRegExp.match(versionMessage);
|
|
|
|
|
if (match.hasMatch()) {
|
|
|
|
|
int major = match.captured(1).toInt();
|
|
|
|
|
int minor = match.captured(2).toInt();
|
|
|
|
|
int patch = match.captured(3).toInt();
|
2013-10-21 14:54:49 +02:00
|
|
|
m_versionNumber = (major << 16)|(minor<<8)|(patch);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-19 08:56:05 +02:00
|
|
|
void QnxDevice::fromMap(const QVariantMap &map)
|
2013-10-21 14:54:49 +02:00
|
|
|
{
|
|
|
|
|
m_versionNumber = map.value(QLatin1String(QnxVersionKey), 0).toInt();
|
2022-02-14 18:37:56 +01:00
|
|
|
LinuxDevice::fromMap(map);
|
2013-10-21 14:54:49 +02:00
|
|
|
}
|
|
|
|
|
|
2016-05-19 08:56:05 +02:00
|
|
|
QVariantMap QnxDevice::toMap() const
|
2013-10-21 14:54:49 +02:00
|
|
|
{
|
2022-02-14 18:37:56 +01:00
|
|
|
QVariantMap map(LinuxDevice::toMap());
|
2013-10-21 14:54:49 +02:00
|
|
|
map.insert(QLatin1String(QnxVersionKey), m_versionNumber);
|
|
|
|
|
return map;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-10 12:53:27 +02:00
|
|
|
PortsGatheringMethod QnxDevice::portsGatheringMethod() const
|
2012-08-01 16:26:27 +02:00
|
|
|
{
|
2022-05-10 12:53:27 +02:00
|
|
|
return {
|
|
|
|
|
// TODO: The command is probably needlessly complicated because the parsing method
|
|
|
|
|
// used to be fixed. These two can now be matched to each other.
|
|
|
|
|
[this](QAbstractSocket::NetworkLayerProtocol protocol) -> CommandLine {
|
|
|
|
|
Q_UNUSED(protocol)
|
|
|
|
|
return {filePath("netstat"), {"-na"}};
|
|
|
|
|
},
|
|
|
|
|
|
2022-05-12 08:42:51 +02:00
|
|
|
&Port::parseFromNetstatOutput
|
2022-05-10 12:53:27 +02:00
|
|
|
};
|
2012-08-01 16:26:27 +02:00
|
|
|
}
|
2013-04-29 15:45:00 +02:00
|
|
|
|
2016-05-19 08:56:05 +02:00
|
|
|
DeviceTester *QnxDevice::createDeviceTester() const
|
2013-05-30 13:53:28 +02:00
|
|
|
{
|
|
|
|
|
return new QnxDeviceTester;
|
|
|
|
|
}
|
2013-09-16 15:30:30 +02:00
|
|
|
|
2016-05-19 08:56:05 +02:00
|
|
|
DeviceProcessSignalOperation::Ptr QnxDevice::signalOperation() const
|
2013-09-16 15:30:30 +02:00
|
|
|
{
|
2022-05-03 16:30:25 +02:00
|
|
|
return DeviceProcessSignalOperation::Ptr(new QnxDeviceProcessSignalOperation(sharedFromThis()));
|
2013-09-16 15:30:30 +02:00
|
|
|
}
|
2014-11-27 17:46:45 +01:00
|
|
|
|
2019-02-20 19:13:28 +01:00
|
|
|
// Factory
|
|
|
|
|
|
2022-01-26 09:05:35 +01:00
|
|
|
QnxDeviceFactory::QnxDeviceFactory() : IDeviceFactory(Constants::QNX_QNX_OS_TYPE)
|
2019-02-20 19:13:28 +01:00
|
|
|
{
|
2022-07-11 14:22:42 +02:00
|
|
|
setDisplayName(Tr::tr("QNX Device"));
|
2019-02-20 19:13:28 +01:00
|
|
|
setCombinedIcon(":/qnx/images/qnxdevicesmall.png",
|
|
|
|
|
":/qnx/images/qnxdevice.png");
|
|
|
|
|
setConstructionFunction(&QnxDevice::create);
|
2022-01-26 09:05:35 +01:00
|
|
|
setCreator([] {
|
|
|
|
|
QnxDeviceWizard wizard;
|
|
|
|
|
if (wizard.exec() != QDialog::Accepted)
|
|
|
|
|
return IDevice::Ptr();
|
|
|
|
|
return wizard.device();
|
|
|
|
|
});
|
2019-02-20 19:13:28 +01:00
|
|
|
}
|
|
|
|
|
|
2022-07-21 09:19:41 +02:00
|
|
|
} // Qnx::Internal
|