diff --git a/src/libs/utils/filepath.cpp b/src/libs/utils/filepath.cpp index 02335910ec9..3aa7e4a11d6 100644 --- a/src/libs/utils/filepath.cpp +++ b/src/libs/utils/filepath.cpp @@ -586,28 +586,32 @@ void FilePath::asyncFileContents(const Continuation &cont, const QByteArray &data) const +void FilePath::asyncWriteFileContents(const Continuation &cont, + const QByteArray &data, + qint64 offset) const { if (needsDevice()) { QTC_ASSERT(s_deviceHooks.asyncWriteFileContents, return); - s_deviceHooks.asyncWriteFileContents(cont, *this, data); + s_deviceHooks.asyncWriteFileContents(cont, *this, data, offset); return; } - cont(writeFileContents(data)); + cont(writeFileContents(data, offset)); } bool FilePath::needsDevice() const diff --git a/src/libs/utils/filepath.h b/src/libs/utils/filepath.h index 325eaeabf2d..d4b1f714b24 100644 --- a/src/libs/utils/filepath.h +++ b/src/libs/utils/filepath.h @@ -118,7 +118,7 @@ public: FilePaths dirEntries(const FileFilter &filter, QDir::SortFlags sort = QDir::NoSort) const; FilePaths dirEntries(QDir::Filters filters) const; std::optional fileContents(qint64 maxSize = -1, qint64 offset = 0) const; - bool writeFileContents(const QByteArray &data) const; + bool writeFileContents(const QByteArray &data, qint64 offset = 0) const; bool operator==(const FilePath &other) const; bool operator!=(const FilePath &other) const; @@ -180,7 +180,9 @@ public: void asyncFileContents(const Continuation &> &cont, qint64 maxSize = -1, qint64 offset = 0) const; - void asyncWriteFileContents(const Continuation &cont, const QByteArray &data) const; + void asyncWriteFileContents(const Continuation &cont, + const QByteArray &data, + qint64 offset = 0) const; // Prefer not to use // Using needsDevice() in "user" code is likely to result in code that @@ -259,7 +261,7 @@ public: const std::function &, // Abort on 'false' return. const FileFilter &)> iterateDirectory; std::function(const FilePath &, qint64, qint64)> fileContents; - std::function writeFileContents; + std::function writeFileContents; std::function lastModified; std::function permissions; std::function setPermissions; @@ -276,7 +278,8 @@ public: std::function &> &, const FilePath &, qint64, qint64)> asyncFileContents; - std::function &, const FilePath &, const QByteArray &)> asyncWriteFileContents; + std::function &, const FilePath &, const QByteArray &, qint64)> + asyncWriteFileContents; std::function ensureReachable; }; diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp index 8ab4bb9f8e6..38a30aa76f3 100644 --- a/src/plugins/docker/dockerdevice.cpp +++ b/src/plugins/docker/dockerdevice.cpp @@ -910,10 +910,17 @@ std::optional DockerDevice::fileContents(const FilePath &filePath, return d->fileContents(filePath, limit, offset); } -bool DockerDevice::writeFileContents(const FilePath &filePath, const QByteArray &data) const +bool DockerDevice::writeFileContents(const FilePath &filePath, + const QByteArray &data, + qint64 offset) const { QTC_ASSERT(handlesFile(filePath), return {}); - return d->runInShellSuccess({"dd", {"of=" + filePath.path()}}, data); + CommandLine cmd({"dd", {"of=" + filePath.path()}}); + if (offset != 0) { + cmd.addArg("bs=1"); + cmd.addArg(QString("seek=%1").arg(offset)); + } + return d->runInShellSuccess(cmd, data); } Environment DockerDevice::systemEnvironment() const diff --git a/src/plugins/docker/dockerdevice.h b/src/plugins/docker/dockerdevice.h index 7de2a762829..4e7840b9282 100644 --- a/src/plugins/docker/dockerdevice.h +++ b/src/plugins/docker/dockerdevice.h @@ -105,7 +105,9 @@ public: std::optional fileContents(const Utils::FilePath &filePath, qint64 limit, qint64 offset) const override; - bool writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const override; + bool writeFileContents(const Utils::FilePath &filePath, + const QByteArray &data, + qint64 offset) const override; QDateTime lastModified(const Utils::FilePath &filePath) const override; qint64 fileSize(const Utils::FilePath &filePath) const override; QFileDevice::Permissions permissions(const Utils::FilePath &filePath) const override; diff --git a/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp b/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp index baee2cd84eb..105e80e34f1 100644 --- a/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp +++ b/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp @@ -278,10 +278,12 @@ std::optional DesktopDevice::fileContents(const FilePath &filePath, return filePath.fileContents(limit, offset); } -bool DesktopDevice::writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const +bool DesktopDevice::writeFileContents(const FilePath &filePath, + const QByteArray &data, + qint64 offset) const { QTC_ASSERT(handlesFile(filePath), return {}); - return filePath.writeFileContents(data); + return filePath.writeFileContents(data, offset); } } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/devicesupport/desktopdevice.h b/src/plugins/projectexplorer/devicesupport/desktopdevice.h index b310c73b7d3..a2a17237ac3 100644 --- a/src/plugins/projectexplorer/devicesupport/desktopdevice.h +++ b/src/plugins/projectexplorer/devicesupport/desktopdevice.h @@ -56,7 +56,9 @@ public: std::optional fileContents(const Utils::FilePath &filePath, qint64 limit, qint64 offset) const override; - bool writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const override; + bool writeFileContents(const Utils::FilePath &filePath, + const QByteArray &data, + qint64 offset) const override; qint64 fileSize(const Utils::FilePath &filePath) const override; QFile::Permissions permissions(const Utils::FilePath &filePath) const override; bool setPermissions(const Utils::FilePath &filePath, QFile::Permissions) const override; diff --git a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp index c0ae7a1726e..febcc6436eb 100644 --- a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp +++ b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp @@ -544,10 +544,12 @@ DeviceManager::DeviceManager(bool isInstance) : d(std::make_uniqueasyncFileContents(cont, filePath, maxSize, offset); }; - deviceHooks.writeFileContents = [](const FilePath &filePath, const QByteArray &data) { + deviceHooks.writeFileContents = [](const FilePath &filePath, + const QByteArray &data, + qint64 offset) { auto device = DeviceManager::deviceForPath(filePath); QTC_ASSERT(device, return false); - return device->writeFileContents(filePath, data); + return device->writeFileContents(filePath, data, offset); }; deviceHooks.lastModified = [](const FilePath &filePath) { diff --git a/src/plugins/projectexplorer/devicesupport/idevice.cpp b/src/plugins/projectexplorer/devicesupport/idevice.cpp index 7b723a2fcee..9c391de5aed 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.cpp +++ b/src/plugins/projectexplorer/devicesupport/idevice.cpp @@ -384,19 +384,21 @@ void IDevice::asyncFileContents(const Continuation> &c cont(fileContents(filePath, limit, offset)); } -bool IDevice::writeFileContents(const FilePath &filePath, const QByteArray &data) const +bool IDevice::writeFileContents(const FilePath &filePath, const QByteArray &data, qint64 offset) const { Q_UNUSED(filePath); Q_UNUSED(data); + Q_UNUSED(offset); QTC_CHECK(false); return {}; } void IDevice::asyncWriteFileContents(const Continuation &cont, const FilePath &filePath, - const QByteArray &data) const + const QByteArray &data, + qint64 offset) const { - cont(writeFileContents(filePath, data)); + cont(writeFileContents(filePath, data, offset)); } QDateTime IDevice::lastModified(const FilePath &filePath) const diff --git a/src/plugins/projectexplorer/devicesupport/idevice.h b/src/plugins/projectexplorer/devicesupport/idevice.h index 3e144a9e502..58d0892fc65 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.h +++ b/src/plugins/projectexplorer/devicesupport/idevice.h @@ -243,7 +243,9 @@ public: virtual std::optional fileContents(const Utils::FilePath &filePath, qint64 limit, qint64 offset) const; - virtual bool writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const; + virtual bool writeFileContents(const Utils::FilePath &filePath, + const QByteArray &data, + qint64 offset) const; virtual QDateTime lastModified(const Utils::FilePath &filePath) const; virtual QFile::Permissions permissions(const Utils::FilePath &filePath) const; virtual bool setPermissions(const Utils::FilePath &filePath, QFile::Permissions) const; @@ -262,7 +264,8 @@ public: qint64 offset) const; virtual void asyncWriteFileContents(const Continuation &cont, const Utils::FilePath &filePath, - const QByteArray &data) const; + const QByteArray &data, + qint64 offset) const; virtual bool ensureReachable(const Utils::FilePath &other) const; diff --git a/src/plugins/remotelinux/linuxdevice.cpp b/src/plugins/remotelinux/linuxdevice.cpp index cf7fe54810a..2d2d8684d69 100644 --- a/src/plugins/remotelinux/linuxdevice.cpp +++ b/src/plugins/remotelinux/linuxdevice.cpp @@ -1318,10 +1318,17 @@ std::optional LinuxDevice::fileContents(const FilePath &filePath, return result.stdOut; } -bool LinuxDevice::writeFileContents(const FilePath &filePath, const QByteArray &data) const +bool LinuxDevice::writeFileContents(const FilePath &filePath, + const QByteArray &data, + qint64 offset) const { QTC_ASSERT(handlesFile(filePath), return {}); - return d->runInShellSuccess({"dd", {"of=" + filePath.path()}}, data); + CommandLine cmd({"dd", {"of=" + filePath.path()}}); + if (offset != 0) { + cmd.addArg("bs=1"); + cmd.addArg(QString("seek=%1").arg(offset)); + } + return d->runInShellSuccess(cmd, data); } static FilePaths dirsToCreate(const FilesToTransfer &files) diff --git a/src/plugins/remotelinux/linuxdevice.h b/src/plugins/remotelinux/linuxdevice.h index 0d4748cb308..1cecc12f2e7 100644 --- a/src/plugins/remotelinux/linuxdevice.h +++ b/src/plugins/remotelinux/linuxdevice.h @@ -58,7 +58,9 @@ public: std::optional fileContents(const Utils::FilePath &filePath, qint64 limit, qint64 offset) const override; - bool writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const override; + bool writeFileContents(const Utils::FilePath &filePath, + const QByteArray &data, + qint64 offset) const override; QDateTime lastModified(const Utils::FilePath &filePath) const override; Utils::ProcessInterface *createProcessInterface() const override; ProjectExplorer::FileTransferInterface *createFileTransferInterface( diff --git a/tests/auto/utils/fsengine/tst_fsengine.cpp b/tests/auto/utils/fsengine/tst_fsengine.cpp index c487711561e..09cbe4ac0ec 100644 --- a/tests/auto/utils/fsengine/tst_fsengine.cpp +++ b/tests/auto/utils/fsengine/tst_fsengine.cpp @@ -134,8 +134,10 @@ void tst_fsengine::initTestCase() qint64 offset) { return FilePath::fromString(filePath.path()).asyncFileContents(cont, maxSize, offset); }; - deviceHooks.writeFileContents = [](const FilePath &filePath, const QByteArray &data) { - return FilePath::fromString(filePath.path()).writeFileContents(data); + deviceHooks.writeFileContents = [](const FilePath &filePath, + const QByteArray &data, + qint64 offset) { + return FilePath::fromString(filePath.path()).writeFileContents(data, offset); }; deviceHooks.lastModified = [](const FilePath &filePath) { return FilePath::fromString(filePath.path()).lastModified();