diff options
Diffstat (limited to 'src/corelib/io')
-rw-r--r-- | src/corelib/io/qdatastream.cpp | 7 | ||||
-rw-r--r-- | src/corelib/io/qdatastream.h | 2 | ||||
-rw-r--r-- | src/corelib/io/qdebug.h | 2 | ||||
-rw-r--r-- | src/corelib/io/qfile.cpp | 43 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemengine.cpp | 2 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemengine_p.h | 2 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemengine_unix.cpp | 16 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemmetadata_p.h | 4 | ||||
-rw-r--r-- | src/corelib/io/qprocess.cpp | 38 | ||||
-rw-r--r-- | src/corelib/io/qprocess.h | 2 | ||||
-rw-r--r-- | src/corelib/io/qprocess_p.h | 44 | ||||
-rw-r--r-- | src/corelib/io/qprocess_unix.cpp | 6 | ||||
-rw-r--r-- | src/corelib/io/qprocess_win.cpp | 22 | ||||
-rw-r--r-- | src/corelib/io/qprocess_wince.cpp | 5 | ||||
-rw-r--r-- | src/corelib/io/qresource.cpp | 2 | ||||
-rw-r--r-- | src/corelib/io/qurl.cpp | 2 |
16 files changed, 151 insertions, 48 deletions
diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp index da38f8ae21..52b80badb8 100644 --- a/src/corelib/io/qdatastream.cpp +++ b/src/corelib/io/qdatastream.cpp @@ -538,9 +538,9 @@ void QDataStream::setByteOrder(ByteOrder bo) \value Qt_4_7 Same as Qt_4_6. \value Qt_4_8 Same as Qt_4_6. \value Qt_4_9 Same as Qt_4_6. - \value Qt_5_0 Version 13 (Qt 5.0, Qt 5.1, Qt 5.2) - \value Qt_5_1 Same as Qt_5_0. - \value Qt_5_2 Same as Qt_5_0. + \value Qt_5_0 Version 13 (Qt 5.0) + \value Qt_5_1 Version 14 (Qt 5.1, Qt 5.2) + \value Qt_5_2 Same as Qt_5_1. \sa setVersion(), version() */ @@ -572,6 +572,7 @@ void QDataStream::setByteOrder(ByteOrder bo) \table \header \li Qt Version \li QDataStream Version + \row \li Qt 5.1 \li 14 \row \li Qt 5.0 \li 13 \row \li Qt 4.6 \li 12 \row \li Qt 4.5 \li 11 diff --git a/src/corelib/io/qdatastream.h b/src/corelib/io/qdatastream.h index f893e6a503..eb064b3fe2 100644 --- a/src/corelib/io/qdatastream.h +++ b/src/corelib/io/qdatastream.h @@ -86,7 +86,7 @@ public: Qt_4_8 = Qt_4_7, Qt_4_9 = Qt_4_8, Qt_5_0 = 13, - Qt_5_1 = Qt_5_0, + Qt_5_1 = 14, Qt_5_2 = Qt_5_1 #if QT_VERSION >= 0x050300 #error Add the datastream version for this Qt version diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h index ce72fcd26d..9ed5f6e951 100644 --- a/src/corelib/io/qdebug.h +++ b/src/corelib/io/qdebug.h @@ -280,7 +280,7 @@ inline QDebug operator<<(QDebug debug, const QFlags<T> &flags) debug.nospace() << '|'; else needSeparator = true; - debug.nospace() << "0x" << QByteArray::number(T(1 << i), 16).constData(); + debug.nospace() << "0x" << QByteArray::number(typename QFlags<T>::Int(1) << i, 16).constData(); } } debug << ')'; diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index afa62a075f..e46ba28f47 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -559,14 +559,43 @@ QFile::rename(const QString &newName) } // If the file exists and it is a case-changing rename ("foo" -> "Foo"), // compare Ids to make sure it really is a different file. - if (QFile::exists(newName) - && (d->fileName.compare(newName, Qt::CaseInsensitive) - || QFileSystemEngine::id(QFileSystemEntry(d->fileName)) != QFileSystemEngine::id(QFileSystemEntry(newName)))) { - // ### Race condition. If a file is moved in after this, it /will/ be - // overwritten. On Unix, the proper solution is to use hardlinks: - // return ::link(old, new) && ::remove(old); - d->setError(QFile::RenameError, tr("Destination file exists")); + if (QFile::exists(newName)) { + if (d->fileName.compare(newName, Qt::CaseInsensitive) + || QFileSystemEngine::id(QFileSystemEntry(d->fileName)) != QFileSystemEngine::id(QFileSystemEntry(newName))) { + // ### Race condition. If a file is moved in after this, it /will/ be + // overwritten. On Unix, the proper solution is to use hardlinks: + // return ::link(old, new) && ::remove(old); + d->setError(QFile::RenameError, tr("Destination file exists")); + return false; + } +#ifdef Q_OS_LINUX + // rename() on Linux simply does nothing when renaming "foo" to "Foo" on a case-insensitive + // FS, such as FAT32. Move the file away and rename in 2 steps to work around. + QTemporaryFile tempFile(d->fileName + QStringLiteral(".XXXXXX")); + tempFile.setAutoRemove(false); + if (!tempFile.open(QIODevice::ReadWrite)) { + d->setError(QFile::RenameError, tempFile.errorString()); + return false; + } + tempFile.close(); + if (!d->engine()->rename(tempFile.fileName())) { + d->setError(QFile::RenameError, tr("Error while renaming.")); + return false; + } + if (tempFile.rename(newName)) { + d->fileEngine->setFileName(newName); + d->fileName = newName; + return true; + } + d->setError(QFile::RenameError, tempFile.errorString()); + // We need to restore the original file. + if (!tempFile.rename(d->fileName)) { + d->setError(QFile::RenameError, errorString() + QLatin1Char('\n') + + tr("Unable to restore from %1: %2"). + arg(QDir::toNativeSeparators(tempFile.fileName()), tempFile.errorString())); + } return false; +#endif } unsetError(); close(); diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index 71ecc4a0a0..53cf6158ad 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -272,7 +272,7 @@ void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer) // Attributes entryFlags |= QFileSystemMetaData::ExistsAttribute; size_ = statBuffer.st_size; -#if defined (Q_OS_MAC) && !defined(Q_OS_IOS) +#if defined(Q_OS_MACX) if (statBuffer.st_flags & UF_HIDDEN) { entryFlags |= QFileSystemMetaData::HiddenAttribute; knownFlagsMask |= QFileSystemMetaData::HiddenAttribute; diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index f3d3018da6..5719629958 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -84,7 +84,7 @@ public: static QString resolveGroupName(uint groupId); #endif -#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) +#if defined(Q_OS_MACX) static QString bundleName(const QFileSystemEntry &entry); #else static QString bundleName(const QFileSystemEntry &entry) { Q_UNUSED(entry) return QString(); } diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 4bfb03a41e..b18e32b29a 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE -#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) +#if defined(Q_OS_MACX) static inline bool _q_isMacHidden(const char *nativePath) { OSErr err; @@ -143,7 +143,7 @@ QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, ret.chop(1); return QFileSystemEntry(ret); } -#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) +#if defined(Q_OS_MACX) { FSRef fref; if (FSPathMakeRef((const UInt8 *)QFile::encodeName(QDir::cleanPath(link.filePath())).data(), &fref, 0) == noErr) { @@ -175,7 +175,7 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry, return QFileSystemEntry(slowCanonicalized(absoluteName(entry).filePath())); #else char *ret = 0; -# if defined(Q_OS_MAC) && !defined(Q_OS_IOS) +# if defined(Q_OS_MACX) // When using -mmacosx-version-min=10.4, we get the legacy realpath implementation, // which does not work properly with the realpath(X,0) form. See QTBUG-28282. if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) { @@ -335,7 +335,7 @@ QString QFileSystemEngine::resolveGroupName(uint groupId) return QString(); } -#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) +#if defined(Q_OS_MACX) //static QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) { @@ -355,7 +355,7 @@ QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what) { -#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) +#if defined(Q_OS_MACX) if (what & QFileSystemMetaData::BundleType) { if (!data.hasFlags(QFileSystemMetaData::DirectoryType)) what |= QFileSystemMetaData::DirectoryType; @@ -364,7 +364,7 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM // Mac OS >= 10.5: st_flags & UF_HIDDEN what |= QFileSystemMetaData::PosixStatFlags; } -#endif // defined(Q_OS_MAC) && !defined(Q_OS_IOS) +#endif // defined(Q_OS_MACX) if (what & QFileSystemMetaData::PosixStatFlags) what |= QFileSystemMetaData::PosixStatFlags; @@ -425,7 +425,7 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM | QFileSystemMetaData::ExistsAttribute; } -#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) +#if defined(Q_OS_MACX) if (what & QFileSystemMetaData::AliasType) { if (entryExists) { @@ -471,7 +471,7 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM data.knownFlagsMask |= QFileSystemMetaData::HiddenAttribute; } -#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) +#if defined(Q_OS_MACX) if (what & QFileSystemMetaData::BundleType) { if (entryExists && data.isDirectory()) { QCFType<CFStringRef> path = CFStringCreateWithBytes(0, diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index 2444a5fd63..1abc9b7ec4 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -100,7 +100,7 @@ public: LinkType = 0x00010000, FileType = 0x00020000, DirectoryType = 0x00040000, -#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) +#if defined(Q_OS_MACX) BundleType = 0x00080000, AliasType = 0x08000000, #else @@ -248,7 +248,7 @@ private: Q_DECLARE_OPERATORS_FOR_FLAGS(QFileSystemMetaData::MetaDataFlags) -#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) +#if defined(Q_OS_MACX) inline bool QFileSystemMetaData::isBundle() const { return (entryFlags & BundleType); } inline bool QFileSystemMetaData::isAlias() const { return (entryFlags & AliasType); } #else diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 59b6db7c79..b1861d8038 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -265,7 +265,13 @@ QProcessEnvironment &QProcessEnvironment::operator=(const QProcessEnvironment &o */ bool QProcessEnvironment::operator==(const QProcessEnvironment &other) const { - return d == other.d || (d && other.d && d->hash == other.d->hash); + if (d == other.d) + return true; + if (d && other.d) { + QProcessEnvironmentPrivate::OrderedMutexLocker locker(d, other.d); + return d->hash == other.d->hash; + } + return false; } /*! @@ -276,6 +282,7 @@ bool QProcessEnvironment::operator==(const QProcessEnvironment &other) const */ bool QProcessEnvironment::isEmpty() const { + // Needs no locking, as no hash nodes are accessed return d ? d->hash.isEmpty() : true; } @@ -302,7 +309,10 @@ void QProcessEnvironment::clear() */ bool QProcessEnvironment::contains(const QString &name) const { - return d ? d->hash.contains(d->prepareName(name)) : false; + if (!d) + return false; + QProcessEnvironmentPrivate::MutexLocker locker(d); + return d->hash.contains(d->prepareName(name)); } /*! @@ -319,7 +329,8 @@ bool QProcessEnvironment::contains(const QString &name) const */ void QProcessEnvironment::insert(const QString &name, const QString &value) { - // d detaches from null + // our re-impl of detach() detaches from null + d.detach(); // detach before prepareName() d->hash.insert(d->prepareName(name), d->prepareValue(value)); } @@ -333,8 +344,10 @@ void QProcessEnvironment::insert(const QString &name, const QString &value) */ void QProcessEnvironment::remove(const QString &name) { - if (d) + if (d) { + d.detach(); // detach before prepareName() d->hash.remove(d->prepareName(name)); + } } /*! @@ -349,6 +362,7 @@ QString QProcessEnvironment::value(const QString &name, const QString &defaultVa if (!d) return defaultValue; + QProcessEnvironmentPrivate::MutexLocker locker(d); QProcessEnvironmentPrivate::Hash::ConstIterator it = d->hash.constFind(d->prepareName(name)); if (it == d->hash.constEnd()) return defaultValue; @@ -371,7 +385,10 @@ QString QProcessEnvironment::value(const QString &name, const QString &defaultVa */ QStringList QProcessEnvironment::toStringList() const { - return d ? d->toList() : QStringList(); + if (!d) + return QStringList(); + QProcessEnvironmentPrivate::MutexLocker locker(d); + return d->toList(); } /*! @@ -382,7 +399,10 @@ QStringList QProcessEnvironment::toStringList() const */ QStringList QProcessEnvironment::keys() const { - return d ? d->keys() : QStringList(); + if (!d) + return QStringList(); + QProcessEnvironmentPrivate::MutexLocker locker(d); + return d->keys(); } /*! @@ -397,7 +417,8 @@ void QProcessEnvironment::insert(const QProcessEnvironment &e) if (!e.d) return; - // d detaches from null + // our re-impl of detach() detaches from null + QProcessEnvironmentPrivate::MutexLocker locker(e.d); d->insert(*e.d); } @@ -1006,6 +1027,7 @@ bool QProcessPrivate::_q_processDied() return false; #endif #ifdef Q_OS_WIN + drainOutputPipes(); if (processFinishedNotifier) processFinishedNotifier->setEnabled(false); #endif @@ -2339,7 +2361,7 @@ bool QProcess::startDetached(const QString &program) } QT_BEGIN_INCLUDE_NAMESPACE -#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) +#if defined(Q_OS_MACX) # include <crt_externs.h> # define environ (*_NSGetEnviron()) #elif defined(Q_OS_WINCE) || defined(Q_OS_IOS) diff --git a/src/corelib/io/qprocess.h b/src/corelib/io/qprocess.h index 29adf37f74..9da3e63f38 100644 --- a/src/corelib/io/qprocess.h +++ b/src/corelib/io/qprocess.h @@ -219,7 +219,7 @@ Q_SIGNALS: QPrivateSignal #endif ); - void finished(int exitCode); + void finished(int exitCode); // ### Qt 6: merge the two signals with a default value void finished(int exitCode, QProcess::ExitStatus exitStatus); void error(QProcess::ProcessError error); void stateChanged(QProcess::ProcessState state diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h index f658e54d4b..2a2cc9fb84 100644 --- a/src/corelib/io/qprocess_p.h +++ b/src/corelib/io/qprocess_p.h @@ -59,6 +59,9 @@ #include "QtCore/qshareddata.h" #include "private/qringbuffer_p.h" #include "private/qiodevice_p.h" +#ifdef Q_OS_UNIX +#include <QtCore/private/qorderedmutexlocker_p.h> +#endif #ifdef Q_OS_WIN #include "QtCore/qt_windows.h" @@ -148,6 +151,13 @@ public: inline QString nameToString(const Key &name) const { return name; } inline Value prepareValue(const QString &value) const { return value; } inline QString valueToString(const Value &value) const { return value; } + struct MutexLocker { + MutexLocker(const QProcessEnvironmentPrivate *) {} + }; + struct OrderedMutexLocker { + OrderedMutexLocker(const QProcessEnvironmentPrivate *, + const QProcessEnvironmentPrivate *) {} + }; #else inline Key prepareName(const QString &name) const { @@ -164,6 +174,37 @@ public: } inline Value prepareValue(const QString &value) const { return Value(value); } inline QString valueToString(const Value &value) const { return value.string(); } + + struct MutexLocker : public QMutexLocker + { + MutexLocker(const QProcessEnvironmentPrivate *d) : QMutexLocker(&d->mutex) {} + }; + struct OrderedMutexLocker : public QOrderedMutexLocker + { + OrderedMutexLocker(const QProcessEnvironmentPrivate *d1, + const QProcessEnvironmentPrivate *d2) : + QOrderedMutexLocker(&d1->mutex, &d2->mutex) + {} + }; + + QProcessEnvironmentPrivate() : QSharedData() {} + QProcessEnvironmentPrivate(const QProcessEnvironmentPrivate &other) : + QSharedData() + { + // This being locked ensures that the functions that only assign + // d pointers don't need explicit locking. + // We don't need to lock our own mutex, as this object is new and + // consequently not shared. For the same reason, non-const methods + // do not need a lock, as they detach objects (however, we need to + // ensure that they really detach before using prepareName()). + MutexLocker locker(&other); + hash = other.hash; + nameMap = other.nameMap; + // We need to detach our members, so that our mutex can protect them. + // As we are being detached, they likely would be detached a moment later anyway. + hash.detach(); + nameMap.detach(); + } #endif typedef QHash<Key, Value> Hash; @@ -172,6 +213,8 @@ public: #ifdef Q_OS_UNIX typedef QHash<QString, Key> NameHash; mutable NameHash nameMap; + + mutable QMutex mutex; #endif static QProcessEnvironment fromList(const QStringList &list); @@ -317,6 +360,7 @@ public: bool waitForDeadChild(); #endif #ifdef Q_OS_WIN + bool drainOutputPipes(); void flushPipeWriter(); qint64 pipeWriterBytesToWrite() const; #endif diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 7f7066271b..e9957d2384 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -472,7 +472,7 @@ bool QProcessPrivate::createChannel(Channel &channel) } QT_BEGIN_INCLUDE_NAMESPACE -#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) +#if defined(Q_OS_MACX) # include <crt_externs.h> # define environ (*_NSGetEnviron()) #else @@ -617,8 +617,10 @@ void QProcessPrivate::startProcess() // Duplicate the environment. int envc = 0; char **envp = 0; - if (environment.d.constData()) + if (environment.d.constData()) { + QProcessEnvironmentPrivate::MutexLocker locker(environment.d); envp = _q_dupEnvironment(environment.d.constData()->hash, &envc); + } // Encode the working directory if it's non-empty, otherwise just pass 0. const char *workingDirPtr = 0; diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index 0f36c3adbf..7776852277 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -625,21 +625,21 @@ bool QProcessPrivate::waitForStarted(int) return false; } -static bool drainOutputPipes(QProcessPrivate *d) +bool QProcessPrivate::drainOutputPipes() { - if (!d->stdoutReader && !d->stderrReader) + if (!stdoutReader && !stderrReader) return false; bool readyReadEmitted = false; forever { bool readOperationActive = false; - if (d->stdoutReader) { - readyReadEmitted |= d->stdoutReader->waitForReadyRead(0); - readOperationActive = d->stdoutReader->isReadOperationActive(); + if (stdoutReader) { + readyReadEmitted |= stdoutReader->waitForReadyRead(0); + readOperationActive = stdoutReader->isReadOperationActive(); } - if (d->stderrReader) { - readyReadEmitted |= d->stderrReader->waitForReadyRead(0); - readOperationActive |= d->stderrReader->isReadOperationActive(); + if (stderrReader) { + readyReadEmitted |= stderrReader->waitForReadyRead(0); + readOperationActive |= stderrReader->isReadOperationActive(); } if (!readOperationActive) break; @@ -669,7 +669,7 @@ bool QProcessPrivate::waitForReadyRead(int msecs) if (!pid) return false; if (WaitForSingleObject(pid->hProcess, 0) == WAIT_OBJECT_0) { - bool readyReadEmitted = drainOutputPipes(this); + bool readyReadEmitted = drainOutputPipes(); _q_processDied(); return readyReadEmitted; } @@ -772,12 +772,12 @@ bool QProcessPrivate::waitForFinished(int msecs) timer.resetIncrements(); if (!pid) { - drainOutputPipes(this); + drainOutputPipes(); return true; } if (WaitForSingleObject(pid->hProcess, timer.nextSleepTime()) == WAIT_OBJECT_0) { - drainOutputPipes(this); + drainOutputPipes(); _q_processDied(); return true; } diff --git a/src/corelib/io/qprocess_wince.cpp b/src/corelib/io/qprocess_wince.cpp index 712748aa59..ad9a328133 100644 --- a/src/corelib/io/qprocess_wince.cpp +++ b/src/corelib/io/qprocess_wince.cpp @@ -233,6 +233,11 @@ bool QProcessPrivate::waitForStarted(int) return false; } +bool QProcessPrivate::drainOutputPipes() +{ + return true; +} + bool QProcessPrivate::waitForReadyRead(int msecs) { return false; diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 7dfc9b977c..04ec81e159 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -665,7 +665,7 @@ int QResourceRoot::findNode(const QString &_path, const QLocale &locale) const qDebug() << " " << child+j << " :: " << name(child+j); } #endif - const uint h = qt_hash(segment.toString()); + const uint h = qt_hash(segment); //do the binary search for the hash int l = 0, r = child_count-1; diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index c71bb3afac..02e7b967ea 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -3731,7 +3731,7 @@ QString QUrl::errorString() const return QString(); QString errorSource; - int errorPosition; + int errorPosition = 0; QUrlPrivate::ErrorCode errorCode = d->validityError(&errorSource, &errorPosition); if (errorCode == QUrlPrivate::NoError) return QString(); |