From 9ff851a204ecfcb8a6aa380679ad8d142f8c334c Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 3 Feb 2022 18:09:06 +0100 Subject: [PATCH] Docker/RL: Be more lazy with output decoding Conversion to QString is often not needed. Change-Id: I22fe0ec89419f784d2fe02245094fbe6da719f75 Reviewed-by: Jarek Kobus Reviewed-by: --- src/plugins/docker/dockerdevice.cpp | 36 ++++++++++++----------- src/plugins/remotelinux/linuxdevice.cpp | 38 +++++++++++++------------ 2 files changed, 40 insertions(+), 34 deletions(-) diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp index cf355fed182..2f81b4d4f67 100644 --- a/src/plugins/docker/dockerdevice.cpp +++ b/src/plugins/docker/dockerdevice.cpp @@ -263,7 +263,7 @@ public: bool runInContainer(const CommandLine &cmd) const; bool runInShell(const CommandLine &cmd) const; - QString outputForRunInShell(const CommandLine &cmd) const; + QByteArray outputForRunInShell(const CommandLine &cmd) const; void updateContainerAccess(); void updateFileSystemAccess(); @@ -1318,7 +1318,7 @@ QDateTime DockerDevice::lastModified(const FilePath &filePath) const return res; } - const QString output = d->outputForRunInShell({"stat", {"-c", "%Y", filePath.path()}}); + const QByteArray output = d->outputForRunInShell({"stat", {"-c", "%Y", filePath.path()}}); qint64 secs = output.toLongLong(); const QDateTime dt = QDateTime::fromSecsSinceEpoch(secs, Qt::UTC); return dt; @@ -1337,8 +1337,9 @@ FilePath DockerDevice::symLinkTarget(const FilePath &filePath) const return mapToGlobalPath(target); } - const QString output = d->outputForRunInShell({"readlink", {"-n", "-e", filePath.path()}}); - return output.isEmpty() ? FilePath() : filePath.withNewPath(output); + const QByteArray output = d->outputForRunInShell({"readlink", {"-n", "-e", filePath.path()}}); + const QString out = QString::fromUtf8(output.data(), output.size()); + return out.isEmpty() ? FilePath() : filePath.withNewPath(out); } qint64 DockerDevice::fileSize(const FilePath &filePath) const @@ -1351,7 +1352,7 @@ qint64 DockerDevice::fileSize(const FilePath &filePath) const return localAccess.fileSize(); } - const QString output = d->outputForRunInShell({"stat", {"-c", "%s", filePath.path()}}); + const QByteArray output = d->outputForRunInShell({"stat", {"-c", "%s", filePath.path()}}); return output.toLongLong(); } @@ -1365,7 +1366,7 @@ QFileDevice::Permissions DockerDevice::permissions(const FilePath &filePath) con return localAccess.permissions(); } - const QString output = d->outputForRunInShell({"stat", {"-c", "%a", filePath.path()}}); + const QByteArray output = d->outputForRunInShell({"stat", {"-c", "%a", filePath.path()}}); const uint bits = output.toUInt(nullptr, 8); QFileDevice::Permissions perm = {}; #define BIT(n, p) if (bits & (1<outputForRunInShell({"find", arguments}); - if (!output.isEmpty() && !output.startsWith(filePath.path())) { // missing find, unknown option - LOG("Setting 'do not use find'" << output.left(output.indexOf('\n'))); + const QByteArray output = d->outputForRunInShell({"find", arguments}); + const QString out = QString::fromUtf8(output.data(), output.size()); + if (!output.isEmpty() && !out.startsWith(filePath.path())) { // missing find, unknown option + LOG("Setting 'do not use find'" << out.left(out.indexOf('\n'))); d->m_useFind = false; return; } - const QStringList entries = output.split("\n", Qt::SkipEmptyParts); + const QStringList entries = out.split("\n", Qt::SkipEmptyParts); for (const QString &entry : entries) { if (entry.startsWith("find: ")) continue; @@ -1531,8 +1533,9 @@ void DockerDevice::iterateDirectory(const FilePath &filePath, } // if we do not have find - use ls as fallback - const QString output = d->outputForRunInShell({"ls", {"-1", "-b", "--", filePath.path()}}); - const QStringList entries = output.split('\n', Qt::SkipEmptyParts); + const QByteArray output = d->outputForRunInShell({"ls", {"-1", "-b", "--", filePath.path()}}); + const QString out = QString::fromUtf8(output.data(), output.size()); + const QStringList entries = out.split('\n', Qt::SkipEmptyParts); filterEntriesHelper(filePath, callBack, entries, filter); } @@ -1652,8 +1655,9 @@ void DockerDevice::aboutToBeRemoved() const void DockerDevicePrivate::fetchSystemEnviroment() { if (m_shell) { - const QString remoteOutput = outputForRunInShell({"env", {}}); - m_cachedEnviroment = Environment(remoteOutput.split('\n', Qt::SkipEmptyParts), q->osType()); + const QByteArray output = outputForRunInShell({"env", {}}); + const QString out = QString::fromUtf8(output.data(), output.size()); + m_cachedEnviroment = Environment(out.split('\n', Qt::SkipEmptyParts), q->osType()); return; } @@ -1715,7 +1719,7 @@ static QByteArray randomHex() return QString::number(val, 16).toUtf8(); } -QString DockerDevicePrivate::outputForRunInShell(const CommandLine &cmd) const +QByteArray DockerDevicePrivate::outputForRunInShell(const CommandLine &cmd) const { if (!DockerPlugin::isDaemonRunning().value_or(false)) return {}; @@ -1733,7 +1737,7 @@ QString DockerDevicePrivate::outputForRunInShell(const CommandLine &cmd) const LOG("Run command in shell:" << cmd.toUserOutput() << "output size:" << output.size()); if (QTC_GUARD(output.endsWith(markerWithNewLine))) output.chop(markerWithNewLine.size()); - return QString::fromUtf8(output, output.size()); + return output; } // Factory diff --git a/src/plugins/remotelinux/linuxdevice.cpp b/src/plugins/remotelinux/linuxdevice.cpp index abf8667018f..79028450c7e 100644 --- a/src/plugins/remotelinux/linuxdevice.cpp +++ b/src/plugins/remotelinux/linuxdevice.cpp @@ -246,7 +246,7 @@ public: return ok && result == 0; } - QString outputForRunInShell(const QString &cmd) + QByteArray outputForRunInShell(const QString &cmd) { QTC_ASSERT(m_shell, return {}); @@ -270,7 +270,7 @@ public: if (pos >= 0) output = output.left(pos); DEBUG("CHOPPED2 " << output); - return QString::fromUtf8(output, output.size()); + return output; } bool isRunning() const { return m_shell; } @@ -291,8 +291,8 @@ public: bool hasDisplay) const; bool setupShell(); bool runInShell(const CommandLine &cmd, const QByteArray &data = {}); - QString outputForRunInShell(const QString &cmd); - QString outputForRunInShell(const CommandLine &cmd); + QByteArray outputForRunInShell(const QString &cmd); + QByteArray outputForRunInShell(const CommandLine &cmd); LinuxDevice *q = nullptr; QThread m_shellThread; @@ -528,7 +528,7 @@ bool LinuxDevicePrivate::runInShell(const CommandLine &cmd, const QByteArray &da return ret; } -QString LinuxDevicePrivate::outputForRunInShell(const QString &cmd) +QByteArray LinuxDevicePrivate::outputForRunInShell(const QString &cmd) { QMutexLocker locker(&m_shellMutex); DEBUG(cmd); @@ -537,14 +537,14 @@ QString LinuxDevicePrivate::outputForRunInShell(const QString &cmd) QTC_ASSERT(ok, return {}); } - QString ret; + QByteArray ret; QMetaObject::invokeMethod(m_handler, [this, &cmd] { return m_handler->outputForRunInShell(cmd); }, Qt::BlockingQueuedConnection, &ret); return ret; } -QString LinuxDevicePrivate::outputForRunInShell(const CommandLine &cmd) +QByteArray LinuxDevicePrivate::outputForRunInShell(const CommandLine &cmd) { return outputForRunInShell(cmd.toUserOutput()); } @@ -658,7 +658,7 @@ bool LinuxDevice::renameFile(const FilePath &filePath, const FilePath &target) c QDateTime LinuxDevice::lastModified(const FilePath &filePath) const { QTC_ASSERT(handlesFile(filePath), return {}); - const QString output = d->outputForRunInShell({"stat", {"-c", "%Y", filePath.path()}}); + const QByteArray output = d->outputForRunInShell({"stat", {"-c", "%Y", filePath.path()}}); const qint64 secs = output.toLongLong(); const QDateTime dt = QDateTime::fromSecsSinceEpoch(secs, Qt::UTC); return dt; @@ -667,14 +667,15 @@ QDateTime LinuxDevice::lastModified(const FilePath &filePath) const FilePath LinuxDevice::symLinkTarget(const FilePath &filePath) const { QTC_ASSERT(handlesFile(filePath), return {}); - const QString output = d->outputForRunInShell({"readlink", {"-n", "-e", filePath.path()}}); - return output.isEmpty() ? FilePath() : filePath.withNewPath(output); + const QByteArray output = d->outputForRunInShell({"readlink", {"-n", "-e", filePath.path()}}); + const QString out = QString::fromUtf8(output.data(), output.size()); + return output.isEmpty() ? FilePath() : filePath.withNewPath(out); } qint64 LinuxDevice::fileSize(const FilePath &filePath) const { QTC_ASSERT(handlesFile(filePath), return -1); - const QString output = d->outputForRunInShell({"stat", {"-c", "%s", filePath.path()}}); + const QByteArray output = d->outputForRunInShell({"stat", {"-c", "%s", filePath.path()}}); return output.toLongLong(); } @@ -684,7 +685,7 @@ qint64 LinuxDevice::bytesAvailable(const FilePath &filePath) const CommandLine cmd("df", {"-k"}); cmd.addArg(filePath.path()); cmd.addArgs("|tail -n 1 |sed 's/ */ /g'|cut -d ' ' -f 4", CommandLine::Raw); - const QString output = d->outputForRunInShell(cmd.toUserOutput()); + const QByteArray output = d->outputForRunInShell(cmd.toUserOutput()); bool ok = false; const qint64 size = output.toLongLong(&ok); if (ok) @@ -695,7 +696,7 @@ qint64 LinuxDevice::bytesAvailable(const FilePath &filePath) const QFileDevice::Permissions LinuxDevice::permissions(const FilePath &filePath) const { QTC_ASSERT(handlesFile(filePath), return {}); - const QString output = d->outputForRunInShell({"stat", {"-c", "%a", filePath.path()}}); + const QByteArray output = d->outputForRunInShell({"stat", {"-c", "%a", filePath.path()}}); const uint bits = output.toUInt(nullptr, 8); QFileDevice::Permissions perm = {}; #define BIT(n, p) if (bits & (1<outputForRunInShell({"ls", {"-1", "-b", "--", filePath.path()}}); - const QStringList entries = output.split('\n', Qt::SkipEmptyParts); + const QByteArray output = d->outputForRunInShell({"ls", {"-1", "-b", "--", filePath.path()}}); + const QString out = QString::fromUtf8(output.data(), output.size()); + const QStringList entries = out.split('\n', Qt::SkipEmptyParts); filterEntriesHelper(filePath, callBack, entries, filter); } @@ -774,9 +776,9 @@ QByteArray LinuxDevice::fileContents(const FilePath &filePath, qint64 limit, qin } CommandLine cmd(FilePath::fromString("dd"), args, CommandLine::Raw); - const QString output = d->outputForRunInShell(cmd); - DEBUG(output << output.toLatin1() << QByteArray::fromHex(output.toLatin1())); - return output.toLatin1(); + const QByteArray output = d->outputForRunInShell(cmd); + DEBUG(output << output << QByteArray::fromHex(output)); + return output; } bool LinuxDevice::writeFileContents(const FilePath &filePath, const QByteArray &data) const