ProjectExplorer: Avoid need to fix up portsgatherer command lines

... by creating them with the right device to start with.

Change-Id: Ib2f0f10b67322fe66a609287a629d3d720d83c93
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
hjk
2022-05-10 12:53:27 +02:00
parent da0f0ac523
commit 7f2288d9cc
11 changed files with 139 additions and 164 deletions

View File

@@ -105,46 +105,6 @@ const QString s_pidMarker = "__qtc$$qtc__";
static Q_LOGGING_CATEGORY(dockerDeviceLog, "qtc.docker.device", QtWarningMsg);
#define LOG(x) qCDebug(dockerDeviceLog) << this << x << '\n'
class DockerPortsGatheringMethod : public PortsGatheringMethod
{
CommandLine commandLine(QAbstractSocket::NetworkLayerProtocol protocol) const override
{
// We might encounter the situation that protocol is given IPv6
// but the consumer of the free port information decides to open
// an IPv4(only) port. As a result the next IPv6 scan will
// report the port again as open (in IPv6 namespace), while the
// same port in IPv4 namespace might still be blocked, and
// re-use of this port fails.
// GDBserver behaves exactly like this.
Q_UNUSED(protocol)
// /proc/net/tcp* covers /proc/net/tcp and /proc/net/tcp6
return {"sed", "-e 's/.*: [[:xdigit:]]*:\\([[:xdigit:]]\\{4\\}\\).*/\\1/g' /proc/net/tcp*",
CommandLine::Raw};
}
QList<Utils::Port> usedPorts(const QByteArray &output) const override
{
QList<Utils::Port> ports;
QList<QByteArray> portStrings = output.split('\n');
foreach (const QByteArray &portString, portStrings) {
if (portString.size() != 4)
continue;
bool ok;
const Utils::Port 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;
}
};
class ContainerShell : public Utils::DeviceShell
{
public:
@@ -607,10 +567,46 @@ bool DockerDevice::canAutoDetectPorts() const
return true;
}
PortsGatheringMethod::Ptr DockerDevice::portsGatheringMethod() const
PortsGatheringMethod DockerDevice::portsGatheringMethod() const
{
return DockerPortsGatheringMethod::Ptr(new DockerPortsGatheringMethod);
}
return {
[this](QAbstractSocket::NetworkLayerProtocol protocol) -> CommandLine {
// We might encounter the situation that protocol is given IPv6
// but the consumer of the free port information decides to open
// an IPv4(only) port. As a result the next IPv6 scan will
// report the port again as open (in IPv6 namespace), while the
// same port in IPv4 namespace might still be blocked, and
// re-use of this port fails.
// GDBserver behaves exactly like this.
Q_UNUSED(protocol)
// /proc/net/tcp* covers /proc/net/tcp and /proc/net/tcp6
return {filePath("sed"),
"-e 's/.*: [[:xdigit:]]*:\\([[:xdigit:]]\\{4\\}\\).*/\\1/g' /proc/net/tcp*",
CommandLine::Raw};
},
[](const QByteArray &output) {
QList<Utils::Port> ports;
const QList<QByteArray> portStrings = output.split('\n');
for (const QByteArray &portString : portStrings) {
if (portString.size() != 4)
continue;
bool ok;
const Utils::Port 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;
}
};
};
DeviceProcessList *DockerDevice::createProcessListModel(QObject *) const
{