diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libs/installer/protocol.h | 3 | ||||
-rw-r--r-- | src/libs/installer/remoteobject.cpp | 8 | ||||
-rw-r--r-- | src/libs/installer/remoteobject.h | 73 | ||||
-rw-r--r-- | src/libs/installer/remoteserverconnection.cpp | 230 | ||||
-rw-r--r-- | src/libs/installer/remoteserverconnection.h | 26 |
5 files changed, 205 insertions, 135 deletions
diff --git a/src/libs/installer/protocol.h b/src/libs/installer/protocol.h index 841b1a2a3..c2d6ccaa6 100644 --- a/src/libs/installer/protocol.h +++ b/src/libs/installer/protocol.h @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2021 The Qt Company Ltd. +** Copyright (C) 2022 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -50,6 +50,7 @@ enum struct StartAs { const char DefaultSocket[] = "ifw_srv"; const char DefaultAuthorizationKey[] = "DefaultAuthorizationKey"; +const char DefaultReply[] = "DefaultReply"; const char Create[] = "Create"; const char Shutdown[] = "Shutdown"; diff --git a/src/libs/installer/remoteobject.cpp b/src/libs/installer/remoteobject.cpp index 54034eb65..70ab48af3 100644 --- a/src/libs/installer/remoteobject.cpp +++ b/src/libs/installer/remoteobject.cpp @@ -122,6 +122,11 @@ bool RemoteObject::connectToServer(const QVariantList &arguments) sendPacket(m_socket, Protocol::Create, data); m_socket->flush(); + while (m_socket->bytesToWrite()) + m_socket->waitForBytesWritten(); + + const QString reply = readData<QString>(QLatin1String(Protocol::Create)); + Q_ASSERT(reply == QLatin1String(Protocol::DefaultReply)); return true; } @@ -137,7 +142,8 @@ bool RemoteObject::isConnectedToServer() const void RemoteObject::callRemoteMethod(const QString &name) { - writeData(name, dummy, dummy, dummy); + const QString reply = sendReceivePacket<QString>(name, dummy, dummy, dummy); + Q_ASSERT(reply == QLatin1String(Protocol::DefaultReply)); } } // namespace QInstaller diff --git a/src/libs/installer/remoteobject.h b/src/libs/installer/remoteobject.h index ecd86c984..4dce2a218 100644 --- a/src/libs/installer/remoteobject.h +++ b/src/libs/installer/remoteobject.h @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2022 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -55,59 +55,39 @@ public: template<typename T1, typename T2> void callRemoteMethod(const QString &name, const T1 &arg, const T2 &arg2) { - writeData(name, arg, arg2, dummy); + const QString reply = sendReceivePacket<QString>(name, arg, arg2, dummy); + Q_ASSERT(reply == QLatin1String(Protocol::DefaultReply)); } template<typename T1, typename T2, typename T3> void callRemoteMethod(const QString &name, const T1 &arg, const T2 &arg2, const T3 & arg3) { - writeData(name, arg, arg2, arg3); + const QString reply = sendReceivePacket<QString>(name, arg, arg2, arg3); + Q_ASSERT(reply == QLatin1String(Protocol::DefaultReply)); } template<typename T> T callRemoteMethod(const QString &name) const { - return callRemoteMethod<T>(name, dummy, dummy, dummy); + return sendReceivePacket<T>(name, dummy, dummy, dummy); } template<typename T, typename T1> T callRemoteMethod(const QString &name, const T1 &arg) const { - return callRemoteMethod<T>(name, arg, dummy, dummy); + return sendReceivePacket<T>(name, arg, dummy, dummy); } template<typename T, typename T1, typename T2> T callRemoteMethod(const QString &name, const T1 & arg, const T2 &arg2) const { - return callRemoteMethod<T>(name, arg, arg2, dummy); + return sendReceivePacket<T>(name, arg, arg2, dummy); } template<typename T, typename T1, typename T2, typename T3> T callRemoteMethod(const QString &name, const T1 &arg, const T2 &arg2, const T3 &arg3) const { - writeData(name, arg, arg2, arg3); - while (m_socket->bytesToWrite()) - m_socket->waitForBytesWritten(); - - QByteArray command; - QByteArray data; - while (!receivePacket(m_socket, &command, &data)) { - if (!m_socket->waitForReadyRead(-1)) { - throw Error(tr("Cannot read all data after sending command: %1. " - "Bytes expected: %2, Bytes received: %3. Error: %4").arg(name).arg(0) - .arg(m_socket->bytesAvailable()).arg(m_socket->errorString())); - } - } - - Q_ASSERT(command == Protocol::Reply); - - QDataStream stream(&data, QIODevice::ReadOnly); - - T result; - stream >> result; - Q_ASSERT(stream.status() == QDataStream::Ok); - Q_ASSERT(stream.atEnd()); - return result; + return sendReceivePacket<T>(name, arg, arg2, arg3); } protected: @@ -133,6 +113,17 @@ private: return false; } + template<typename T, typename T1, typename T2, typename T3> + T sendReceivePacket(const QString &name, const T1 &arg, const T2 &arg2, const T3 &arg3) const + { + writeData(name, arg, arg2, arg3); + while (m_socket->bytesToWrite()) + m_socket->waitForBytesWritten(); + + return readData<T>(name); + } + + template<typename T1, typename T2, typename T3> void writeData(const QString &name, const T1 &arg, const T2 &arg2, const T3 &arg3) const { @@ -150,6 +141,30 @@ private: m_socket->flush(); } + template<typename T> + T readData(const QString &name) const + { + QByteArray command; + QByteArray data; + while (!receivePacket(m_socket, &command, &data)) { + if (!m_socket->waitForReadyRead(-1)) { + throw Error(tr("Cannot read all data after sending command: %1. " + "Bytes expected: %2, Bytes received: %3. Error: %4").arg(name).arg(0) + .arg(m_socket->bytesAvailable()).arg(m_socket->errorString())); + } + } + + Q_ASSERT(command == Protocol::Reply); + + QDataStream stream(&data, QIODevice::ReadOnly); + + T result; + stream >> result; + Q_ASSERT(stream.status() == QDataStream::Ok); + Q_ASSERT(stream.atEnd()); + return result; + } + private: QString m_type; QLocalSocket *m_socket; diff --git a/src/libs/installer/remoteserverconnection.cpp b/src/libs/installer/remoteserverconnection.cpp index 2464c8469..0868dbe0a 100644 --- a/src/libs/installer/remoteserverconnection.cpp +++ b/src/libs/installer/remoteserverconnection.cpp @@ -46,13 +46,60 @@ namespace QInstaller { /*! \inmodule QtInstallerFramework - \class QInstaller::RemoteServerConnection + \class QInstaller::QProcessSignalReceiver \internal */ /*! \inmodule QtInstallerFramework - \class QInstaller::QProcessSignalReceiver + \class QInstaller::RemoteServerReply + \internal + \brief The RemoteServerReply class is used for sending a reply to a local socket. + + The class ensures exactly one reply is sent in the lifetime of an object + instantiated from this class. If the calling client has not explicitly sent + a reply, a default reply is automatically sent on destruction. +*/ + +/*! + Constructs reply object for \a socket. +*/ +RemoteServerReply::RemoteServerReply(QLocalSocket *socket) + : m_socket(socket) + , m_sent(false) +{} + +/*! + Destroys the object and sends the default reply, if + no other replies have been sent. +*/ +RemoteServerReply::~RemoteServerReply() +{ + send(QString::fromLatin1(Protocol::DefaultReply)); +} + +/*! + Sends a reply packet with \a¸ data to the socket. If a reply + has been already sent, this function does not send another. +*/ +template <typename T> +void RemoteServerReply::send(const T &data) +{ + if (m_sent || m_socket->state() != QLocalSocket::ConnectedState) + return; + + QByteArray result; + QDataStream returnStream(&result, QIODevice::WriteOnly); + returnStream << data; + + sendPacket(m_socket, Protocol::Reply, result); + m_socket->flush(); + m_sent = true; +} + +/*! + \inmodule QtInstallerFramework + \class QInstaller::RemoteServerConnection \internal */ @@ -106,18 +153,18 @@ void RemoteServerConnection::run() stream.setDevice(&buf); StreamChecker streamChecker(&stream); + RemoteServerReply reply(&socket); + if (authorized && command == QLatin1String(Protocol::Shutdown)) { authorized = false; - sendData(&socket, true); - socket.flush(); + reply.send(true); socket.close(); emit shutdownRequested(); return; } else if (command == QLatin1String(Protocol::Authorize)) { QString key; stream >> key; - sendData(&socket, (authorized = (key == m_authorizationKey))); - socket.flush(); + reply.send(authorized = (key == m_authorizationKey)); if (!authorized) { socket.close(); return; @@ -157,6 +204,8 @@ void RemoteServerConnection::run() #else Q_ASSERT_X(false, Q_FUNC_INFO, "No compatible archive handler exists for protocol."); #endif + } else { + qCDebug(QInstaller::lcServer) << "Unknown type for Create command:" << type; } continue; } @@ -164,8 +213,7 @@ void RemoteServerConnection::run() if (command == QLatin1String(Protocol::GetQProcessSignals)) { if (m_processSignalReceiver) { QMutexLocker _(&m_processSignalReceiver->m_lock); - sendData(&socket, m_processSignalReceiver->m_receivedSignals); - socket.flush(); + reply.send(m_processSignalReceiver->m_receivedSignals); m_processSignalReceiver->m_receivedSignals.clear(); } continue; @@ -173,8 +221,7 @@ void RemoteServerConnection::run() #ifdef IFW_LIBARCHIVE if (m_archiveSignalReceiver) { QMutexLocker _(&m_archiveSignalReceiver->m_lock); - sendData(&socket, m_archiveSignalReceiver->m_receivedSignals); - socket.flush(); + reply.send(m_archiveSignalReceiver->m_receivedSignals); m_archiveSignalReceiver->m_receivedSignals.clear(); } continue; @@ -184,52 +231,41 @@ void RemoteServerConnection::run() } if (command.startsWith(QLatin1String(Protocol::QProcess))) { - handleQProcess(&socket, command, stream); + handleQProcess(&reply, command, stream); } else if (command.startsWith(QLatin1String(Protocol::QSettings))) { - handleQSettings(&socket, command, stream, settings.data()); + handleQSettings(&reply, command, stream, settings.data()); } else if (command.startsWith(QLatin1String(Protocol::QAbstractFileEngine))) { - handleQFSFileEngine(&socket, command, stream); + handleQFSFileEngine(&reply, command, stream); } else if (command.startsWith(QLatin1String(Protocol::AbstractArchive))) { - handleArchive(&socket, command, stream); + handleArchive(&reply, command, stream); } else { qCDebug(QInstaller::lcServer) << "Unknown command:" << command; } - socket.flush(); } else { // authorization failed, connection not wanted socket.close(); - qCDebug(QInstaller::lcServer) << "Unknown command:" << command; + qCDebug(QInstaller::lcServer) << "Authorization failed."; return; } } } -template <typename T> -void RemoteServerConnection::sendData(QIODevice *device, const T &data) -{ - QByteArray result; - QDataStream returnStream(&result, QIODevice::WriteOnly); - returnStream << data; - - sendPacket(device, Protocol::Reply, result); -} - -void RemoteServerConnection::handleQProcess(QIODevice *socket, const QString &command, QDataStream &data) +void RemoteServerConnection::handleQProcess(RemoteServerReply *reply, const QString &command, QDataStream &data) { if (command == QLatin1String(Protocol::QProcessCloseWriteChannel)) { m_process->closeWriteChannel(); } else if (command == QLatin1String(Protocol::QProcessExitCode)) { - sendData(socket, m_process->exitCode()); + reply->send(m_process->exitCode()); } else if (command == QLatin1String(Protocol::QProcessExitStatus)) { - sendData(socket, static_cast<qint32> (m_process->exitStatus())); + reply->send(static_cast<qint32> (m_process->exitStatus())); } else if (command == QLatin1String(Protocol::QProcessKill)) { m_process->kill(); } else if (command == QLatin1String(Protocol::QProcessReadAll)) { - sendData(socket, m_process->readAll()); + reply->send(m_process->readAll()); } else if (command == QLatin1String(Protocol::QProcessReadAllStandardOutput)) { - sendData(socket, m_process->readAllStandardOutput()); + reply->send(m_process->readAllStandardOutput()); } else if (command == QLatin1String(Protocol::QProcessReadAllStandardError)) { - sendData(socket, m_process->readAllStandardError()); + reply->send(m_process->readAllStandardError()); } else if (command == QLatin1String(Protocol::QProcessStartDetached)) { QString program; QStringList arguments; @@ -240,7 +276,7 @@ void RemoteServerConnection::handleQProcess(QIODevice *socket, const QString &co qint64 pid = -1; bool success = QInstaller::startDetached(program, arguments, workingDirectory, &pid); - sendData(socket, qMakePair< bool, qint64>(success, pid)); + reply->send(qMakePair< bool, qint64>(success, pid)); } else if (command == QLatin1String(Protocol::QProcessSetWorkingDirectory)) { QString dir; data >> dir; @@ -250,7 +286,7 @@ void RemoteServerConnection::handleQProcess(QIODevice *socket, const QString &co data >> env; m_process->setEnvironment(env); } else if (command == QLatin1String(Protocol::QProcessEnvironment)) { - sendData(socket, m_process->environment()); + reply->send(m_process->environment()); } else if (command == QLatin1String(Protocol::QProcessStart3Arg)) { QString program; QStringList arguments; @@ -266,23 +302,23 @@ void RemoteServerConnection::handleQProcess(QIODevice *socket, const QString &co data >> mode; m_process->start(program, static_cast<QIODevice::OpenMode> (mode)); } else if (command == QLatin1String(Protocol::QProcessState)) { - sendData(socket, static_cast<qint32> (m_process->state())); + reply->send(static_cast<qint32> (m_process->state())); } else if (command == QLatin1String(Protocol::QProcessTerminate)) { m_process->terminate(); } else if (command == QLatin1String(Protocol::QProcessWaitForFinished)) { qint32 msecs; data >> msecs; - sendData(socket, m_process->waitForFinished(msecs)); + reply->send(m_process->waitForFinished(msecs)); } else if (command == QLatin1String(Protocol::QProcessWaitForStarted)) { qint32 msecs; data >> msecs; - sendData(socket, m_process->waitForStarted(msecs)); + reply->send(m_process->waitForStarted(msecs)); } else if (command == QLatin1String(Protocol::QProcessWorkingDirectory)) { - sendData(socket, m_process->workingDirectory()); + reply->send(m_process->workingDirectory()); } else if (command == QLatin1String(Protocol::QProcessErrorString)) { - sendData(socket, m_process->errorString()); + reply->send(m_process->errorString()); } else if (command == QLatin1String(Protocol::QProcessReadChannel)) { - sendData(socket, static_cast<qint32> (m_process->readChannel())); + reply->send(static_cast<qint32> (m_process->readChannel())); } else if (command == QLatin1String(Protocol::QProcessSetReadChannel)) { qint32 processChannel; data >> processChannel; @@ -290,9 +326,9 @@ void RemoteServerConnection::handleQProcess(QIODevice *socket, const QString &co } else if (command == QLatin1String(Protocol::QProcessWrite)) { QByteArray byteArray; data >> byteArray; - sendData(socket, m_process->write(byteArray)); + reply->send(m_process->write(byteArray)); } else if (command == QLatin1String(Protocol::QProcessProcessChannelMode)) { - sendData(socket, static_cast<qint32> (m_process->processChannelMode())); + reply->send(static_cast<qint32> (m_process->processChannelMode())); } else if (command == QLatin1String(Protocol::QProcessSetProcessChannelMode)) { qint32 processChannel; data >> processChannel; @@ -310,14 +346,14 @@ void RemoteServerConnection::handleQProcess(QIODevice *socket, const QString &co } } -void RemoteServerConnection::handleQSettings(QIODevice *socket, const QString &command, +void RemoteServerConnection::handleQSettings(RemoteServerReply *reply, const QString &command, QDataStream &data, PermissionSettings *settings) { if (!settings) return; if (command == QLatin1String(Protocol::QSettingsAllKeys)) { - sendData(socket, settings->allKeys()); + reply->send(settings->allKeys()); } else if (command == QLatin1String(Protocol::QSettingsBeginGroup)) { QString prefix; data >> prefix; @@ -331,29 +367,29 @@ void RemoteServerConnection::handleQSettings(QIODevice *socket, const QString &c } else if (command == QLatin1String(Protocol::QSettingsBeginReadArray)) { QString prefix; data >> prefix; - sendData(socket, settings->beginReadArray(prefix)); + reply->send(settings->beginReadArray(prefix)); } else if (command == QLatin1String(Protocol::QSettingsChildGroups)) { - sendData(socket, settings->childGroups()); + reply->send(settings->childGroups()); } else if (command == QLatin1String(Protocol::QSettingsChildKeys)) { - sendData(socket, settings->childKeys()); + reply->send(settings->childKeys()); } else if (command == QLatin1String(Protocol::QSettingsClear)) { settings->clear(); } else if (command == QLatin1String(Protocol::QSettingsContains)) { QString key; data >> key; - sendData(socket, settings->contains(key)); + reply->send(settings->contains(key)); } else if (command == QLatin1String(Protocol::QSettingsEndArray)) { settings->endArray(); } else if (command == QLatin1String(Protocol::QSettingsEndGroup)) { settings->endGroup(); } else if (command == QLatin1String(Protocol::QSettingsFallbacksEnabled)) { - sendData(socket, settings->fallbacksEnabled()); + reply->send(settings->fallbacksEnabled()); } else if (command == QLatin1String(Protocol::QSettingsFileName)) { - sendData(socket, settings->fileName()); + reply->send(settings->fileName()); } else if (command == QLatin1String(Protocol::QSettingsGroup)) { - sendData(socket, settings->group()); + reply->send(settings->group()); } else if (command == QLatin1String(Protocol::QSettingsIsWritable)) { - sendData(socket, settings->isWritable()); + reply->send(settings->isWritable()); } else if (command == QLatin1String(Protocol::QSettingsRemove)) { QString key; data >> key; @@ -367,7 +403,7 @@ void RemoteServerConnection::handleQSettings(QIODevice *socket, const QString &c data >> b; settings->setFallbacksEnabled(b); } else if (command == QLatin1String(Protocol::QSettingsStatus)) { - sendData(socket, settings->status()); + reply->send(settings->status()); } else if (command == QLatin1String(Protocol::QSettingsSync)) { settings->sync(); } else if (command == QLatin1String(Protocol::QSettingsSetValue)) { @@ -381,25 +417,25 @@ void RemoteServerConnection::handleQSettings(QIODevice *socket, const QString &c QVariant defaultValue; data >> key; data >> defaultValue; - sendData(socket, settings->value(key, defaultValue)); + reply->send(settings->value(key, defaultValue)); } else if (command == QLatin1String(Protocol::QSettingsOrganizationName)) { - sendData(socket, settings->organizationName()); + reply->send(settings->organizationName()); } else if (command == QLatin1String(Protocol::QSettingsApplicationName)) { - sendData(socket, settings->applicationName()); + reply->send(settings->applicationName()); } else if (!command.isEmpty()) { qCDebug(QInstaller::lcServer) << "Unknown QSettings command:" << command; } } -void RemoteServerConnection::handleQFSFileEngine(QIODevice *socket, const QString &command, +void RemoteServerConnection::handleQFSFileEngine(RemoteServerReply *reply, const QString &command, QDataStream &data) { if (command == QLatin1String(Protocol::QAbstractFileEngineAtEnd)) { - sendData(socket, m_engine->atEnd()); + reply->send(m_engine->atEnd()); } else if (command == QLatin1String(Protocol::QAbstractFileEngineCaseSensitive)) { - sendData(socket, m_engine->caseSensitive()); + reply->send(m_engine->caseSensitive()); } else if (command == QLatin1String(Protocol::QAbstractFileEngineClose)) { - sendData(socket, m_engine->close()); + reply->send(m_engine->close()); } else if (command == QLatin1String(Protocol::QAbstractFileEngineCopy)) { QString newName; data >>newName; @@ -407,90 +443,90 @@ void RemoteServerConnection::handleQFSFileEngine(QIODevice *socket, const QStrin // QFileSystemEngine::copyFile() is currently unimplemented on Linux, // copy using QFile instead of directly with QFSFileEngine. QFile file(m_engine->fileName(QAbstractFileEngine::AbsoluteName)); - sendData(socket, file.copy(newName)); + reply->send(file.copy(newName)); #else - sendData(socket, m_engine->copy(newName)); + reply->send(m_engine->copy(newName)); #endif } else if (command == QLatin1String(Protocol::QAbstractFileEngineEntryList)) { qint32 filters; QStringList filterNames; data >>filters; data >>filterNames; - sendData(socket, m_engine->entryList(static_cast<QDir::Filters> (filters), filterNames)); + reply->send(m_engine->entryList(static_cast<QDir::Filters> (filters), filterNames)); } else if (command == QLatin1String(Protocol::QAbstractFileEngineError)) { - sendData(socket, static_cast<qint32> (m_engine->error())); + reply->send(static_cast<qint32> (m_engine->error())); } else if (command == QLatin1String(Protocol::QAbstractFileEngineErrorString)) { - sendData(socket, m_engine->errorString()); + reply->send(m_engine->errorString()); } else if (command == QLatin1String(Protocol::QAbstractFileEngineFileFlags)) { qint32 flags; data >>flags; flags = m_engine->fileFlags(static_cast<QAbstractFileEngine::FileFlags>(flags)); - sendData(socket, static_cast<qint32>(flags)); + reply->send(static_cast<qint32>(flags)); } else if (command == QLatin1String(Protocol::QAbstractFileEngineFileName)) { qint32 file; data >>file; - sendData(socket, m_engine->fileName(static_cast<QAbstractFileEngine::FileName> (file))); + reply->send(m_engine->fileName(static_cast<QAbstractFileEngine::FileName> (file))); } else if (command == QLatin1String(Protocol::QAbstractFileEngineFlush)) { - sendData(socket, m_engine->flush()); + reply->send(m_engine->flush()); } else if (command == QLatin1String(Protocol::QAbstractFileEngineHandle)) { - sendData(socket, m_engine->handle()); + reply->send(m_engine->handle()); } else if (command == QLatin1String(Protocol::QAbstractFileEngineIsRelativePath)) { - sendData(socket, m_engine->isRelativePath()); + reply->send(m_engine->isRelativePath()); } else if (command == QLatin1String(Protocol::QAbstractFileEngineIsSequential)) { - sendData(socket, m_engine->isSequential()); + reply->send(m_engine->isSequential()); } else if (command == QLatin1String(Protocol::QAbstractFileEngineLink)) { QString newName; data >>newName; - sendData(socket, m_engine->link(newName)); + reply->send(m_engine->link(newName)); } else if (command == QLatin1String(Protocol::QAbstractFileEngineMkdir)) { QString dirName; bool createParentDirectories; data >>dirName; data >>createParentDirectories; - sendData(socket, m_engine->mkdir(dirName, createParentDirectories)); + reply->send(m_engine->mkdir(dirName, createParentDirectories)); } else if (command == QLatin1String(Protocol::QAbstractFileEngineOpen)) { qint32 openMode; data >>openMode; - sendData(socket, m_engine->open(static_cast<QIODevice::OpenMode> (openMode))); + reply->send(m_engine->open(static_cast<QIODevice::OpenMode> (openMode))); } else if (command == QLatin1String(Protocol::QAbstractFileEngineOwner)) { qint32 owner; data >>owner; - sendData(socket, m_engine->owner(static_cast<QAbstractFileEngine::FileOwner> (owner))); + reply->send(m_engine->owner(static_cast<QAbstractFileEngine::FileOwner> (owner))); } else if (command == QLatin1String(Protocol::QAbstractFileEngineOwnerId)) { qint32 owner; data >>owner; - sendData(socket, m_engine->ownerId(static_cast<QAbstractFileEngine::FileOwner> (owner))); + reply->send(m_engine->ownerId(static_cast<QAbstractFileEngine::FileOwner> (owner))); } else if (command == QLatin1String(Protocol::QAbstractFileEnginePos)) { - sendData(socket, m_engine->pos()); + reply->send(m_engine->pos()); } else if (command == QLatin1String(Protocol::QAbstractFileEngineRead)) { qint64 maxlen; data >> maxlen; QByteArray byteArray(maxlen, '\0'); const qint64 r = m_engine->read(byteArray.data(), maxlen); - sendData(socket, qMakePair<qint64, QByteArray>(r, byteArray)); + reply->send(qMakePair<qint64, QByteArray>(r, byteArray)); } else if (command == QLatin1String(Protocol::QAbstractFileEngineReadLine)) { qint64 maxlen; data >> maxlen; QByteArray byteArray(maxlen, '\0'); const qint64 r = m_engine->readLine(byteArray.data(), maxlen); - sendData(socket, qMakePair<qint64, QByteArray>(r, byteArray)); + reply->send(qMakePair<qint64, QByteArray>(r, byteArray)); } else if (command == QLatin1String(Protocol::QAbstractFileEngineRemove)) { - sendData(socket, m_engine->remove()); + reply->send(m_engine->remove()); } else if (command == QLatin1String(Protocol::QAbstractFileEngineRename)) { QString newName; data >>newName; - sendData(socket, m_engine->rename(newName)); + reply->send(m_engine->rename(newName)); } else if (command == QLatin1String(Protocol::QAbstractFileEngineRmdir)) { QString dirName; bool recurseParentDirectories; data >>dirName; data >>recurseParentDirectories; - sendData(socket, m_engine->rmdir(dirName, recurseParentDirectories)); + reply->send(m_engine->rmdir(dirName, recurseParentDirectories)); } else if (command == QLatin1String(Protocol::QAbstractFileEngineSeek)) { quint64 offset; data >>offset; - sendData(socket, m_engine->seek(offset)); + reply->send(m_engine->seek(offset)); } else if (command == QLatin1String(Protocol::QAbstractFileEngineSetFileName)) { QString fileName; data >>fileName; @@ -498,43 +534,43 @@ void RemoteServerConnection::handleQFSFileEngine(QIODevice *socket, const QStrin } else if (command == QLatin1String(Protocol::QAbstractFileEngineSetPermissions)) { uint perms; data >>perms; - sendData(socket, m_engine->setPermissions(perms)); + reply->send(m_engine->setPermissions(perms)); } else if (command == QLatin1String(Protocol::QAbstractFileEngineSetSize)) { qint64 size; data >>size; - sendData(socket, m_engine->setSize(size)); + reply->send(m_engine->setSize(size)); } else if (command == QLatin1String(Protocol::QAbstractFileEngineSize)) { - sendData(socket, m_engine->size()); + reply->send(m_engine->size()); } else if ((command == QLatin1String(Protocol::QAbstractFileEngineSupportsExtension)) || (command == QLatin1String(Protocol::QAbstractFileEngineExtension))) { // Implemented client side. } else if (command == QLatin1String(Protocol::QAbstractFileEngineWrite)) { QByteArray content; data >> content; - sendData(socket, m_engine->write(content.data(), content.size())); + reply->send(m_engine->write(content.data(), content.size())); } else if (command == QLatin1String(Protocol::QAbstractFileEngineSyncToDisk)) { - sendData(socket, m_engine->syncToDisk()); + reply->send(m_engine->syncToDisk()); } else if (command == QLatin1String(Protocol::QAbstractFileEngineRenameOverwrite)) { QString newFilename; data >> newFilename; - sendData(socket, m_engine->renameOverwrite(newFilename)); + reply->send(m_engine->renameOverwrite(newFilename)); } else if (command == QLatin1String(Protocol::QAbstractFileEngineFileTime)) { qint32 filetime; data >> filetime; - sendData(socket, m_engine->fileTime(static_cast<QAbstractFileEngine::FileTime> (filetime))); + reply->send(m_engine->fileTime(static_cast<QAbstractFileEngine::FileTime> (filetime))); } else if (!command.isEmpty()) { qCDebug(QInstaller::lcServer) << "Unknown QAbstractFileEngine command:" << command; } } -void RemoteServerConnection::handleArchive(QIODevice *socket, const QString &command, QDataStream &data) +void RemoteServerConnection::handleArchive(RemoteServerReply *reply, const QString &command, QDataStream &data) { #ifdef IFW_LIBARCHIVE LibArchiveArchive *archive = static_cast<LibArchiveArchive *>(m_archive.get()); if (command == QLatin1String(Protocol::AbstractArchiveOpen)) { qint32 openMode; data >> openMode; - sendData(socket, archive->open(static_cast<QIODevice::OpenMode>(openMode))); + reply->send(archive->open(static_cast<QIODevice::OpenMode>(openMode))); } else if (command == QLatin1String(Protocol::AbstractArchiveClose)) { archive->close(); } else if (command == QLatin1String(Protocol::AbstractArchiveSetFilename)) { @@ -542,7 +578,7 @@ void RemoteServerConnection::handleArchive(QIODevice *socket, const QString &com data >> fileName; archive->setFilename(fileName); } else if (command == QLatin1String(Protocol::AbstractArchiveErrorString)) { - sendData(socket, archive->errorString()); + reply->send(archive->errorString()); } else if (command == QLatin1String(Protocol::AbstractArchiveExtract)) { QString dirPath; quint64 total; @@ -552,11 +588,11 @@ void RemoteServerConnection::handleArchive(QIODevice *socket, const QString &com } else if (command == QLatin1String(Protocol::AbstractArchiveCreate)) { QStringList entries; data >> entries; - sendData(socket, archive->create(entries)); + reply->send(archive->create(entries)); } else if (command == QLatin1String(Protocol::AbstractArchiveList)) { - sendData(socket, archive->list()); + reply->send(archive->list()); } else if (command == QLatin1String(Protocol::AbstractArchiveIsSupported)) { - sendData(socket, archive->isSupported()); + reply->send(archive->isSupported()); } else if (command == QLatin1String(Protocol::AbstractArchiveSetCompressionLevel)) { qint32 level; data >> level; @@ -572,7 +608,7 @@ void RemoteServerConnection::handleArchive(QIODevice *socket, const QString &com data >> pos; archive->workerSetFilePosition(pos); } else if (command == QLatin1String(Protocol::AbstractArchiveWorkerStatus)) { - sendData(socket, static_cast<qint32>(archive->workerStatus())); + reply->send(static_cast<qint32>(archive->workerStatus())); } else if (command == QLatin1String(Protocol::AbstractArchiveCancel)) { archive->workerCancel(); } else if (!command.isEmpty()) { diff --git a/src/libs/installer/remoteserverconnection.h b/src/libs/installer/remoteserverconnection.h index 1fd179430..53f6a412b 100644 --- a/src/libs/installer/remoteserverconnection.h +++ b/src/libs/installer/remoteserverconnection.h @@ -38,7 +38,7 @@ #include <QtCore/private/qfsfileengine_p.h> QT_BEGIN_NAMESPACE -class QIODevice; +class QLocalSocket; QT_END_NAMESPACE namespace QInstaller { @@ -48,6 +48,20 @@ class PermissionSettings; class QProcessSignalReceiver; class AbstractArchiveSignalReceiver; +class RemoteServerReply +{ +public: + explicit RemoteServerReply(QLocalSocket *socket); + ~RemoteServerReply(); + + template <typename T> + void send(const T &data); + +private: + QLocalSocket *m_socket; + bool m_sent; +}; + class RemoteServerConnection : public QThread { Q_OBJECT @@ -63,13 +77,11 @@ signals: void shutdownRequested(); private: - template <typename T> - void sendData(QIODevice *device, const T &arg); - void handleQProcess(QIODevice *device, const QString &command, QDataStream &data); - void handleQSettings(QIODevice *device, const QString &command, QDataStream &data, + void handleQProcess(RemoteServerReply *reply, const QString &command, QDataStream &data); + void handleQSettings(RemoteServerReply *reply, const QString &command, QDataStream &data, PermissionSettings *settings); - void handleQFSFileEngine(QIODevice *device, const QString &command, QDataStream &data); - void handleArchive(QIODevice *device, const QString &command, QDataStream &data); + void handleQFSFileEngine(RemoteServerReply *reply, const QString &command, QDataStream &data); + void handleArchive(RemoteServerReply *reply, const QString &command, QDataStream &data); private: qintptr m_socketDescriptor; |