summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkh <karsten.heimrich@theqtcompany.com>2014-11-28 16:41:15 +0100
committerKai Koehne <kai.koehne@theqtcompany.com>2014-12-01 16:11:55 +0100
commit52e176b4a40d55b84aac762b77da5262687f6503 (patch)
tree221c07797e1edf60a40951e496beedb0d4cb15cd
parenta439e6fab484461744a657f5173a738622064edf (diff)
Fix online installation into directory with elevated permissions.
Inside the Resource class we can't use QFile, as that will access the elevated running server to read from a only client side mapped file. Adjust Resource::readData to behave properly with the file engine's nativeRead(...) implementation, e.g. on Unix it returns -1 if called to read with a size of 0 bytes. Do not write to the socket if we are running in a different thread than the one the socket was created in. Fix logically broken connect function. Task-number: QTIFW-572 Change-Id: I993b5d3a5c217b0aedbbc27837dce2619e51d224 Reviewed-by: Niels Weber <niels.weber@theqtcompany.com> Reviewed-by: Takayuki ORITO <iori.ayane@gmail.com> Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com>
-rw-r--r--src/libs/installer/binaryformat.cpp7
-rw-r--r--src/libs/installer/binaryformat.h4
-rw-r--r--src/libs/installer/remoteclient.cpp56
-rw-r--r--src/libs/installer/remoteclient_p.h2
-rw-r--r--src/libs/installer/remoteobject.cpp12
5 files changed, 41 insertions, 40 deletions
diff --git a/src/libs/installer/binaryformat.cpp b/src/libs/installer/binaryformat.cpp
index 9cf7ef28a..015e21b2f 100644
--- a/src/libs/installer/binaryformat.cpp
+++ b/src/libs/installer/binaryformat.cpp
@@ -197,9 +197,14 @@ qint64 Resource::size() const
*/
qint64 Resource::readData(char* data, qint64 maxSize)
{
+ // check if there is anything left to read
+ maxSize = qMin<quint64>(maxSize, m_segment.length() - pos());
+ if (maxSize <= 0)
+ return 0;
+
const qint64 p = m_file.pos();
m_file.seek(m_segment.start() + pos());
- const qint64 amountRead = m_file.read(data, qMin<quint64>(maxSize, m_segment.length() - pos()));
+ const qint64 amountRead = m_file.read(data, maxSize);
m_file.seek(p);
return amountRead;
}
diff --git a/src/libs/installer/binaryformat.h b/src/libs/installer/binaryformat.h
index 85bc96d8c..551c701ce 100644
--- a/src/libs/installer/binaryformat.h
+++ b/src/libs/installer/binaryformat.h
@@ -39,7 +39,7 @@
#include "range.h"
#include <QCoreApplication>
-#include <QFile>
+#include <QtCore/private/qfsfileengine_p.h>
#include <QList>
#include <QSharedPointer>
@@ -87,7 +87,7 @@ private:
void setOpenMode(OpenMode mode) { QIODevice::setOpenMode(mode); }
private:
- QFile m_file;
+ QFSFileEngine m_file;
QByteArray m_name;
Range<qint64> m_segment;
};
diff --git a/src/libs/installer/remoteclient.cpp b/src/libs/installer/remoteclient.cpp
index d8c8478b6..573bd22ed 100644
--- a/src/libs/installer/remoteclient.cpp
+++ b/src/libs/installer/remoteclient.cpp
@@ -46,8 +46,6 @@ RemoteClient::RemoteClient()
RemoteClient::~RemoteClient()
{
- Q_D(RemoteClient);
- d->m_quit = true;
}
RemoteClient &RemoteClient::instance()
@@ -94,39 +92,31 @@ void RemoteClient::shutdown()
bool RemoteClient::connect(QTcpSocket *socket) const
{
Q_D(const RemoteClient);
- if (d->m_quit)
+ socket->connectToHost(d->m_address, d->m_port);
+
+ QElapsedTimer stopWatch;
+ stopWatch.start();
+ while ((socket->state() == QAbstractSocket::ConnectingState)
+ && (stopWatch.elapsed() < 30000)) {
+ if ((stopWatch.elapsed() % 2500) == 0)
+ QCoreApplication::processEvents();
+ }
+
+ if (socket->state() != QAbstractSocket::ConnectedState)
return false;
- int tries = 3;
- while ((tries > 0) && (!d->m_quit)) {
- socket->connectToHost(d->m_address, d->m_port);
-
- QElapsedTimer stopWatch;
- stopWatch.start();
- while ((socket->state() == QAbstractSocket::ConnectingState)
- && (stopWatch.elapsed() < 10000) && (!d->m_quit)) {
- --tries;
- if (!QCoreApplication::closingDown())
- qApp->processEvents();
- continue;
- }
- if ((socket->state() != QAbstractSocket::ConnectedState) || d->m_quit)
- return false;
-
- QDataStream stream;
- stream.setDevice(socket);
- stream << QString::fromLatin1(Protocol::Authorize) << d->m_key;
-
- socket->waitForBytesWritten(-1);
- if (!socket->bytesAvailable())
- socket->waitForReadyRead(-1);
-
- quint32 size; stream >> size;
- bool authorized; stream >> authorized;
- if (authorized && (!d->m_quit))
- return true;
- }
- return false;
+ QDataStream stream;
+ stream.setDevice(socket);
+ stream << QString::fromLatin1(Protocol::Authorize) << authorizationKey();
+
+ socket->waitForBytesWritten(-1);
+ if (!socket->bytesAvailable())
+ socket->waitForReadyRead(-1);
+
+ quint32 size; stream >> size;
+ bool authorized = false;
+ stream >> authorized;
+ return authorized;
}
bool RemoteClient::isActive() const
diff --git a/src/libs/installer/remoteclient_p.h b/src/libs/installer/remoteclient_p.h
index fdcfabb64..6c1d41951 100644
--- a/src/libs/installer/remoteclient_p.h
+++ b/src/libs/installer/remoteclient_p.h
@@ -122,7 +122,6 @@ public:
, m_key(QLatin1String(Protocol::DefaultAuthorizationKey))
, m_mode(Protocol::Mode::Debug)
, m_object(0)
- , m_quit(false)
{
}
@@ -263,7 +262,6 @@ private:
QThread m_thread;
Protocol::Mode m_mode;
KeepAliveObject *m_object;
- volatile bool m_quit;
};
} // namespace QInstaller
diff --git a/src/libs/installer/remoteobject.cpp b/src/libs/installer/remoteobject.cpp
index d69c49735..970eab228 100644
--- a/src/libs/installer/remoteobject.cpp
+++ b/src/libs/installer/remoteobject.cpp
@@ -37,6 +37,8 @@
#include "protocol.h"
#include "remoteclient.h"
+#include <QThread>
+
namespace QInstaller {
RemoteObject::RemoteObject(const QString &wrappedType, QObject *parent)
@@ -52,8 +54,14 @@ RemoteObject::RemoteObject(const QString &wrappedType, QObject *parent)
RemoteObject::~RemoteObject()
{
if (m_socket) {
- m_stream << QString::fromLatin1(Protocol::Destroy) << m_type;
- m_socket->waitForBytesWritten(-1);
+ if (QThread::currentThread() == m_socket->thread()) {
+ m_stream << QString::fromLatin1(Protocol::Destroy) << m_type;
+ m_socket->waitForBytesWritten(-1);
+ } else {
+ Q_ASSERT_X(false, Q_FUNC_INFO, "Socket running in a different Thread than this object.");
+ }
+ m_socket->deleteLater();
+ m_socket = 0;
}
}