summaryrefslogtreecommitdiffstats
path: root/src/libs/installer/remoteserverconnection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/installer/remoteserverconnection.cpp')
-rw-r--r--src/libs/installer/remoteserverconnection.cpp227
1 files changed, 102 insertions, 125 deletions
diff --git a/src/libs/installer/remoteserverconnection.cpp b/src/libs/installer/remoteserverconnection.cpp
index 0bd1f54a9..17a90995b 100644
--- a/src/libs/installer/remoteserverconnection.cpp
+++ b/src/libs/installer/remoteserverconnection.cpp
@@ -40,6 +40,7 @@
#include "utils.h"
#include "permissionsettings.h"
+#include <QCoreApplication>
#include <QLocalSocket>
namespace QInstaller {
@@ -56,29 +57,48 @@ RemoteServerConnection::RemoteServerConnection(qintptr socketDescriptor, const Q
setObjectName(QString::fromLatin1("RemoteServerConnection(%1)").arg(socketDescriptor));
}
+// Helper RAII to ensure stream data was correctly (and completely) read
+struct StreamChecker {
+ StreamChecker(QDataStream *stream) : stream(stream) {}
+ ~StreamChecker() {
+ Q_ASSERT(stream->status() == QDataStream::Ok);
+ Q_ASSERT(stream->atEnd());
+ }
+private:
+ QDataStream *stream;
+};
+
void RemoteServerConnection::run()
{
QLocalSocket socket;
socket.setSocketDescriptor(m_socketDescriptor);
QScopedPointer<PermissionSettings> settings;
- QDataStream stream;
- stream.setDevice(&socket);
-
bool authorized = false;
while (socket.state() == QLocalSocket::ConnectedState) {
- // Use a polling approach here to kill the thread as soon as the connections
- // closes. This seems to be related to the fact that the keep alive thread connects
- // every second and immediately throws away the socket and therefore the connection.
- if (!socket.bytesAvailable() && !socket.waitForReadyRead(250))
+ QByteArray cmd;
+ QByteArray data;
+
+ if (!receivePacket(&socket, &cmd, &data)) {
+ socket.waitForReadyRead(250);
+#if defined(Q_OS_WIN) && QT_VERSION < QT_VERSION_CHECK(5,5,0)
+ // work around QTBUG-16688
+ QCoreApplication::processEvents();
+#endif
continue;
+ }
- QString command;
- stream >> command;
+ const QString command = QString::fromLatin1(cmd);
+ QBuffer buf;
+ buf.setBuffer(&data);
+ buf.open(QIODevice::ReadOnly);
+ QDataStream stream;
+ stream.setDevice(&buf);
+ StreamChecker streamChecker(&stream);
if (authorized && command == QLatin1String(Protocol::Shutdown)) {
authorized = false;
- sendData(stream, true);
+ sendData(&socket, true);
socket.flush();
socket.close();
emit shutdownRequested();
@@ -86,7 +106,7 @@ void RemoteServerConnection::run()
} else if (command == QLatin1String(Protocol::Authorize)) {
QString key;
stream >> key;
- sendData(stream, (authorized = (key == m_authorizationKey)));
+ sendData(&socket, (authorized = (key == m_authorizationKey)));
socket.flush();
if (!authorized) {
socket.close();
@@ -146,18 +166,18 @@ void RemoteServerConnection::run()
if (command == QLatin1String(Protocol::GetQProcessSignals)) {
if (m_signalReceiver) {
QMutexLocker _(&m_signalReceiver->m_lock);
- sendData(stream, m_signalReceiver->m_receivedSignals);
+ sendData(&socket, m_signalReceiver->m_receivedSignals);
m_signalReceiver->m_receivedSignals.clear();
}
continue;
}
if (command.startsWith(QLatin1String(Protocol::QProcess))) {
- handleQProcess(command, stream);
+ handleQProcess(&socket, command, stream);
} else if (command.startsWith(QLatin1String(Protocol::QSettings))) {
- handleQSettings(command, stream, settings.data());
+ handleQSettings(&socket, command, stream, settings.data());
} else if (command.startsWith(QLatin1String(Protocol::QAbstractFileEngine))) {
- handleQFSFileEngine(command, stream);
+ handleQFSFileEngine(&socket, command, stream);
} else {
qDebug() << "Unknown command:" << command;
}
@@ -171,47 +191,31 @@ void RemoteServerConnection::run()
}
template <typename T>
-void RemoteServerConnection::sendData(QDataStream &stream, const T &data)
+void RemoteServerConnection::sendData(QIODevice *device, const T &data)
{
QByteArray result;
QDataStream returnStream(&result, QIODevice::WriteOnly);
returnStream << data;
- stream << static_cast<quint32> (result.size());
- if (!result.isEmpty())
- stream.writeRawData(result.data(), result.size());
+ sendPacket(device, Protocol::Reply, result);
}
-void RemoteServerConnection::handleQProcess(const QString &command, QDataStream &stream)
+void RemoteServerConnection::handleQProcess(QIODevice *socket, const QString &command, QDataStream &data)
{
- quint32 size;
- stream >> size;
- while (stream.device()->bytesAvailable() < size) {
- if (!stream.device()->waitForReadyRead(30000)) {
- throw Error(tr("Could not read all data after sending command: %1. "
- "Bytes expected: %2, Bytes received: %3. Error: %4").arg(command).arg(size)
- .arg(stream.device()->bytesAvailable()).arg(stream.device()->errorString()));
- }
- }
-
- QByteArray ba;
- stream >> ba;
- QDataStream data(ba);
-
if (command == QLatin1String(Protocol::QProcessCloseWriteChannel)) {
m_process->closeWriteChannel();
} else if (command == QLatin1String(Protocol::QProcessExitCode)) {
- sendData(stream, m_process->exitCode());
+ sendData(socket, m_process->exitCode());
} else if (command == QLatin1String(Protocol::QProcessExitStatus)) {
- sendData(stream, static_cast<qint32> (m_process->exitStatus()));
+ sendData(socket, static_cast<qint32> (m_process->exitStatus()));
} else if (command == QLatin1String(Protocol::QProcessKill)) {
m_process->kill();
} else if (command == QLatin1String(Protocol::QProcessReadAll)) {
- sendData(stream, m_process->readAll());
+ sendData(socket, m_process->readAll());
} else if (command == QLatin1String(Protocol::QProcessReadAllStandardOutput)) {
- sendData(stream, m_process->readAllStandardOutput());
+ sendData(socket, m_process->readAllStandardOutput());
} else if (command == QLatin1String(Protocol::QProcessReadAllStandardError)) {
- sendData(stream, m_process->readAllStandardError());
+ sendData(socket, m_process->readAllStandardError());
} else if (command == QLatin1String(Protocol::QProcessStartDetached)) {
QString program;
QStringList arguments;
@@ -222,7 +226,7 @@ void RemoteServerConnection::handleQProcess(const QString &command, QDataStream
qint64 pid = -1;
bool success = QInstaller::startDetached(program, arguments, workingDirectory, &pid);
- sendData(stream, qMakePair< bool, qint64>(success, pid));
+ sendData(socket, qMakePair< bool, qint64>(success, pid));
} else if (command == QLatin1String(Protocol::QProcessSetWorkingDirectory)) {
QString dir;
data >> dir;
@@ -232,7 +236,7 @@ void RemoteServerConnection::handleQProcess(const QString &command, QDataStream
data >> env;
m_process->setEnvironment(env);
} else if (command == QLatin1String(Protocol::QProcessEnvironment)) {
- sendData(stream, m_process->environment());
+ sendData(socket, m_process->environment());
} else if (command == QLatin1String(Protocol::QProcessStart3Arg)) {
QString program;
QStringList arguments;
@@ -248,23 +252,23 @@ void RemoteServerConnection::handleQProcess(const QString &command, QDataStream
data >> mode;
m_process->start(program, static_cast<QIODevice::OpenMode> (mode));
} else if (command == QLatin1String(Protocol::QProcessState)) {
- sendData(stream, static_cast<qint32> (m_process->state()));
+ sendData(socket, 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(stream, m_process->waitForFinished(msecs));
+ sendData(socket, m_process->waitForFinished(msecs));
} else if (command == QLatin1String(Protocol::QProcessWaitForStarted)) {
qint32 msecs;
data >> msecs;
- sendData(stream, m_process->waitForStarted(msecs));
+ sendData(socket, m_process->waitForStarted(msecs));
} else if (command == QLatin1String(Protocol::QProcessWorkingDirectory)) {
- sendData(stream, m_process->workingDirectory());
+ sendData(socket, m_process->workingDirectory());
} else if (command == QLatin1String(Protocol::QProcessErrorString)) {
- sendData(stream, m_process->errorString());
+ sendData(socket, m_process->errorString());
} else if (command == QLatin1String(Protocol::QProcessReadChannel)) {
- sendData(stream, static_cast<qint32> (m_process->readChannel()));
+ sendData(socket, static_cast<qint32> (m_process->readChannel()));
} else if (command == QLatin1String(Protocol::QProcessSetReadChannel)) {
qint32 processChannel;
data >> processChannel;
@@ -272,9 +276,9 @@ void RemoteServerConnection::handleQProcess(const QString &command, QDataStream
} else if (command == QLatin1String(Protocol::QProcessWrite)) {
QByteArray byteArray;
data >> byteArray;
- sendData(stream, m_process->write(byteArray));
+ sendData(socket, m_process->write(byteArray));
} else if (command == QLatin1String(Protocol::QProcessProcessChannelMode)) {
- sendData(stream, static_cast<qint32> (m_process->processChannelMode()));
+ sendData(socket, static_cast<qint32> (m_process->processChannelMode()));
} else if (command == QLatin1String(Protocol::QProcessSetProcessChannelMode)) {
qint32 processChannel;
data >> processChannel;
@@ -292,28 +296,14 @@ void RemoteServerConnection::handleQProcess(const QString &command, QDataStream
}
}
-void RemoteServerConnection::handleQSettings(const QString &command, QDataStream &stream,
- PermissionSettings *settings)
+void RemoteServerConnection::handleQSettings(QIODevice *socket, const QString &command,
+ QDataStream &data, PermissionSettings *settings)
{
if (!settings)
return;
- quint32 size;
- stream >> size;
- while (stream.device()->bytesAvailable() < size) {
- if (!stream.device()->waitForReadyRead(30000)) {
- throw Error(tr("Could not read all data after sending command: %1. "
- "Bytes expected: %2, Bytes received: %3. Error: %4").arg(command).arg(size)
- .arg(stream.device()->bytesAvailable()).arg(stream.device()->errorString()));
- }
- }
-
- QByteArray ba;
- stream >> ba;
- QDataStream data(ba);
-
if (command == QLatin1String(Protocol::QSettingsAllKeys)) {
- sendData(stream, settings->allKeys());
+ sendData(socket, settings->allKeys());
} else if (command == QLatin1String(Protocol::QSettingsBeginGroup)) {
QString prefix;
data >> prefix;
@@ -327,29 +317,29 @@ void RemoteServerConnection::handleQSettings(const QString &command, QDataStream
} else if (command == QLatin1String(Protocol::QSettingsBeginReadArray)) {
QString prefix;
data >> prefix;
- sendData(stream, settings->beginReadArray(prefix));
+ sendData(socket, settings->beginReadArray(prefix));
} else if (command == QLatin1String(Protocol::QSettingsChildGroups)) {
- sendData(stream, settings->childGroups());
+ sendData(socket, settings->childGroups());
} else if (command == QLatin1String(Protocol::QSettingsChildKeys)) {
- sendData(stream, settings->childKeys());
+ sendData(socket, settings->childKeys());
} else if (command == QLatin1String(Protocol::QSettingsClear)) {
settings->clear();
} else if (command == QLatin1String(Protocol::QSettingsContains)) {
QString key;
data >> key;
- sendData(stream, settings->contains(key));
+ sendData(socket, 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(stream, settings->fallbacksEnabled());
+ sendData(socket, settings->fallbacksEnabled());
} else if (command == QLatin1String(Protocol::QSettingsFileName)) {
- sendData(stream, settings->fileName());
+ sendData(socket, settings->fileName());
} else if (command == QLatin1String(Protocol::QSettingsGroup)) {
- sendData(stream, settings->group());
+ sendData(socket, settings->group());
} else if (command == QLatin1String(Protocol::QSettingsIsWritable)) {
- sendData(stream, settings->isWritable());
+ sendData(socket, settings->isWritable());
} else if (command == QLatin1String(Protocol::QSettingsRemove)) {
QString key;
data >> key;
@@ -363,7 +353,7 @@ void RemoteServerConnection::handleQSettings(const QString &command, QDataStream
data >> b;
settings->setFallbacksEnabled(b);
} else if (command == QLatin1String(Protocol::QSettingsStatus)) {
- sendData(stream, settings->status());
+ sendData(socket, settings->status());
} else if (command == QLatin1String(Protocol::QSettingsSync)) {
settings->sync();
} else if (command == QLatin1String(Protocol::QSettingsSetValue)) {
@@ -377,122 +367,109 @@ void RemoteServerConnection::handleQSettings(const QString &command, QDataStream
QVariant defaultValue;
data >> key;
data >> defaultValue;
- sendData(stream, settings->value(key, defaultValue));
+ sendData(socket, settings->value(key, defaultValue));
} else if (command == QLatin1String(Protocol::QSettingsOrganizationName)) {
- sendData(stream, settings->organizationName());
+ sendData(socket, settings->organizationName());
} else if (command == QLatin1String(Protocol::QSettingsApplicationName)) {
- sendData(stream, settings->applicationName());
+ sendData(socket, settings->applicationName());
} else if (!command.isEmpty()) {
qDebug() << "Unknown QSettings command:" << command;
}
}
-void RemoteServerConnection::handleQFSFileEngine(const QString &command, QDataStream &stream)
+void RemoteServerConnection::handleQFSFileEngine(QIODevice *socket, const QString &command,
+ QDataStream &data)
{
- quint32 size;
- stream >> size;
- while (stream.device()->bytesAvailable() < size) {
- if (!stream.device()->waitForReadyRead(30000)) {
- throw Error(tr("Could not read all data after sending command: %1. "
- "Bytes expected: %2, Bytes received: %3. Error: %4").arg(command).arg(size)
- .arg(stream.device()->bytesAvailable()).arg(stream.device()->errorString()));
- }
- }
-
- QByteArray ba;
- stream >> ba;
- QDataStream data(ba);
-
if (command == QLatin1String(Protocol::QAbstractFileEngineAtEnd)) {
- sendData(stream, m_engine->atEnd());
+ sendData(socket, m_engine->atEnd());
} else if (command == QLatin1String(Protocol::QAbstractFileEngineCaseSensitive)) {
- sendData(stream, m_engine->caseSensitive());
+ sendData(socket, m_engine->caseSensitive());
} else if (command == QLatin1String(Protocol::QAbstractFileEngineClose)) {
- sendData(stream, m_engine->close());
+ sendData(socket, m_engine->close());
} else if (command == QLatin1String(Protocol::QAbstractFileEngineCopy)) {
QString newName;
data >>newName;
- sendData(stream, m_engine->copy(newName));
+ sendData(socket, m_engine->copy(newName));
} else if (command == QLatin1String(Protocol::QAbstractFileEngineEntryList)) {
qint32 filters;
QStringList filterNames;
data >>filters;
data >>filterNames;
- sendData(stream, m_engine->entryList(static_cast<QDir::Filters> (filters), filterNames));
+ sendData(socket, m_engine->entryList(static_cast<QDir::Filters> (filters), filterNames));
} else if (command == QLatin1String(Protocol::QAbstractFileEngineError)) {
- sendData(stream, static_cast<qint32> (m_engine->error()));
+ sendData(socket, static_cast<qint32> (m_engine->error()));
} else if (command == QLatin1String(Protocol::QAbstractFileEngineErrorString)) {
- sendData(stream, m_engine->errorString());
+ sendData(socket, m_engine->errorString());
}
else if (command == QLatin1String(Protocol::QAbstractFileEngineFileFlags)) {
qint32 flags;
data >>flags;
flags = m_engine->fileFlags(static_cast<QAbstractFileEngine::FileFlags>(flags));
- sendData(stream, static_cast<qint32>(flags));
+ sendData(socket, static_cast<qint32>(flags));
} else if (command == QLatin1String(Protocol::QAbstractFileEngineFileName)) {
qint32 file;
data >>file;
- sendData(stream, m_engine->fileName(static_cast<QAbstractFileEngine::FileName> (file)));
+ sendData(socket, m_engine->fileName(static_cast<QAbstractFileEngine::FileName> (file)));
} else if (command == QLatin1String(Protocol::QAbstractFileEngineFlush)) {
- sendData(stream, m_engine->flush());
+ sendData(socket, m_engine->flush());
} else if (command == QLatin1String(Protocol::QAbstractFileEngineHandle)) {
- sendData(stream, m_engine->handle());
+ sendData(socket, m_engine->handle());
} else if (command == QLatin1String(Protocol::QAbstractFileEngineIsRelativePath)) {
- sendData(stream, m_engine->isRelativePath());
+ sendData(socket, m_engine->isRelativePath());
} else if (command == QLatin1String(Protocol::QAbstractFileEngineIsSequential)) {
- sendData(stream, m_engine->isSequential());
+ sendData(socket, m_engine->isSequential());
} else if (command == QLatin1String(Protocol::QAbstractFileEngineLink)) {
QString newName;
data >>newName;
- sendData(stream, m_engine->link(newName));
+ sendData(socket, m_engine->link(newName));
} else if (command == QLatin1String(Protocol::QAbstractFileEngineMkdir)) {
QString dirName;
bool createParentDirectories;
data >>dirName;
data >>createParentDirectories;
- sendData(stream, m_engine->mkdir(dirName, createParentDirectories));
+ sendData(socket, m_engine->mkdir(dirName, createParentDirectories));
} else if (command == QLatin1String(Protocol::QAbstractFileEngineOpen)) {
qint32 openMode;
data >>openMode;
- sendData(stream, m_engine->open(static_cast<QIODevice::OpenMode> (openMode)));
+ sendData(socket, m_engine->open(static_cast<QIODevice::OpenMode> (openMode)));
} else if (command == QLatin1String(Protocol::QAbstractFileEngineOwner)) {
qint32 owner;
data >>owner;
- sendData(stream, m_engine->owner(static_cast<QAbstractFileEngine::FileOwner> (owner)));
+ sendData(socket, m_engine->owner(static_cast<QAbstractFileEngine::FileOwner> (owner)));
} else if (command == QLatin1String(Protocol::QAbstractFileEngineOwnerId)) {
qint32 owner;
data >>owner;
- sendData(stream, m_engine->ownerId(static_cast<QAbstractFileEngine::FileOwner> (owner)));
+ sendData(socket, m_engine->ownerId(static_cast<QAbstractFileEngine::FileOwner> (owner)));
} else if (command == QLatin1String(Protocol::QAbstractFileEnginePos)) {
- sendData(stream, m_engine->pos());
+ sendData(socket, 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(stream, qMakePair<qint64, QByteArray>(r, byteArray));
+ sendData(socket, 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(stream, qMakePair<qint64, QByteArray>(r, byteArray));
+ sendData(socket, qMakePair<qint64, QByteArray>(r, byteArray));
} else if (command == QLatin1String(Protocol::QAbstractFileEngineRemove)) {
- sendData(stream, m_engine->remove());
+ sendData(socket, m_engine->remove());
} else if (command == QLatin1String(Protocol::QAbstractFileEngineRename)) {
QString newName;
data >>newName;
- sendData(stream, m_engine->rename(newName));
+ sendData(socket, m_engine->rename(newName));
} else if (command == QLatin1String(Protocol::QAbstractFileEngineRmdir)) {
QString dirName;
bool recurseParentDirectories;
data >>dirName;
data >>recurseParentDirectories;
- sendData(stream, m_engine->rmdir(dirName, recurseParentDirectories));
+ sendData(socket, m_engine->rmdir(dirName, recurseParentDirectories));
} else if (command == QLatin1String(Protocol::QAbstractFileEngineSeek)) {
quint64 offset;
data >>offset;
- sendData(stream, m_engine->seek(offset));
+ sendData(socket, m_engine->seek(offset));
} else if (command == QLatin1String(Protocol::QAbstractFileEngineSetFileName)) {
QString fileName;
data >>fileName;
@@ -500,30 +477,30 @@ void RemoteServerConnection::handleQFSFileEngine(const QString &command, QDataSt
} else if (command == QLatin1String(Protocol::QAbstractFileEngineSetPermissions)) {
uint perms;
data >>perms;
- sendData(stream, m_engine->setPermissions(perms));
+ sendData(socket, m_engine->setPermissions(perms));
} else if (command == QLatin1String(Protocol::QAbstractFileEngineSetSize)) {
qint64 size;
data >>size;
- sendData(stream, m_engine->setSize(size));
+ sendData(socket, m_engine->setSize(size));
} else if (command == QLatin1String(Protocol::QAbstractFileEngineSize)) {
- sendData(stream, m_engine->size());
+ sendData(socket, 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(stream, m_engine->write(content.data(), content.size()));
+ sendData(socket, m_engine->write(content.data(), content.size()));
} else if (command == QLatin1String(Protocol::QAbstractFileEngineSyncToDisk)) {
- sendData(stream, m_engine->syncToDisk());
+ sendData(socket, m_engine->syncToDisk());
} else if (command == QLatin1String(Protocol::QAbstractFileEngineRenameOverwrite)) {
QString newFilename;
data >> newFilename;
- sendData(stream, m_engine->renameOverwrite(newFilename));
+ sendData(socket, m_engine->renameOverwrite(newFilename));
} else if (command == QLatin1String(Protocol::QAbstractFileEngineFileTime)) {
qint32 filetime;
data >> filetime;
- sendData(stream, m_engine->fileTime(static_cast<QAbstractFileEngine::FileTime> (filetime)));
+ sendData(socket, m_engine->fileTime(static_cast<QAbstractFileEngine::FileTime> (filetime)));
} else if (!command.isEmpty()) {
qDebug() << "Unknown QAbstractFileEngine command:" << command;
}