summaryrefslogtreecommitdiffstats
path: root/src/corelib/io
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io')
-rw-r--r--src/corelib/io/io.pri1
-rw-r--r--src/corelib/io/qdatastream.cpp36
-rw-r--r--src/corelib/io/qdatastream.h8
-rw-r--r--src/corelib/io/qdebug.cpp96
-rw-r--r--src/corelib/io/qdebug.h99
-rw-r--r--src/corelib/io/qfiledevice.cpp11
-rw-r--r--src/corelib/io/qfiledevice.h4
-rw-r--r--src/corelib/io/qfileselector.cpp9
-rw-r--r--src/corelib/io/qfsfileengine.cpp16
-rw-r--r--src/corelib/io/qfsfileengine_p.h1
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp8
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp20
-rw-r--r--src/corelib/io/qlockfile_win.cpp25
-rw-r--r--src/corelib/io/qloggingcategory.cpp88
-rw-r--r--src/corelib/io/qloggingcategory.h32
-rw-r--r--src/corelib/io/qloggingcategory_p.h66
-rw-r--r--src/corelib/io/qloggingregistry.cpp52
-rw-r--r--src/corelib/io/qloggingregistry_p.h6
-rw-r--r--src/corelib/io/qnoncontiguousbytedevice.cpp39
-rw-r--r--src/corelib/io/qnoncontiguousbytedevice_p.h6
-rw-r--r--src/corelib/io/qsavefile.cpp24
-rw-r--r--src/corelib/io/qsavefile_p.h1
-rw-r--r--src/corelib/io/qsettings.cpp297
-rw-r--r--src/corelib/io/qstandardpaths.cpp35
-rw-r--r--src/corelib/io/qstandardpaths.h4
-rw-r--r--src/corelib/io/qstandardpaths_android.cpp5
-rw-r--r--src/corelib/io/qstandardpaths_blackberry.cpp5
-rw-r--r--src/corelib/io/qstandardpaths_ios.mm3
-rw-r--r--src/corelib/io/qstandardpaths_mac.cpp16
-rw-r--r--src/corelib/io/qstandardpaths_unix.cpp8
-rw-r--r--src/corelib/io/qstandardpaths_win.cpp34
-rw-r--r--src/corelib/io/qstandardpaths_winrt.cpp7
-rw-r--r--src/corelib/io/qtemporaryfile.cpp3
-rw-r--r--src/corelib/io/qtextstream.cpp4
-rw-r--r--src/corelib/io/qurl.cpp64
-rw-r--r--src/corelib/io/qurl.h9
-rw-r--r--src/corelib/io/qwinoverlappedionotifier.cpp60
-rw-r--r--src/corelib/io/qwinoverlappedionotifier_p.h1
38 files changed, 659 insertions, 544 deletions
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri
index f651860e08..7afff7ff81 100644
--- a/src/corelib/io/io.pri
+++ b/src/corelib/io/io.pri
@@ -51,7 +51,6 @@ HEADERS += \
io/qfileselector.h \
io/qfileselector_p.h \
io/qloggingcategory.h \
- io/qloggingcategory_p.h \
io/qloggingregistry_p.h
SOURCES += \
diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp
index a6fbffee7e..127244e994 100644
--- a/src/corelib/io/qdatastream.cpp
+++ b/src/corelib/io/qdatastream.cpp
@@ -250,10 +250,6 @@ QT_BEGIN_NAMESPACE
if (q_status != Ok) \
return retVal;
-enum {
- DefaultStreamVersion = QDataStream::Qt_5_3
-};
-
/*!
Constructs a data stream that has no I/O device.
@@ -265,7 +261,7 @@ QDataStream::QDataStream()
dev = 0;
owndev = false;
byteorder = BigEndian;
- ver = DefaultStreamVersion;
+ ver = Qt_DefaultCompiledVersion;
noswap = QSysInfo::ByteOrder == QSysInfo::BigEndian;
q_status = Ok;
}
@@ -287,7 +283,7 @@ QDataStream::QDataStream(QIODevice *d)
dev = d; // set device
owndev = false;
byteorder = BigEndian; // default byte order
- ver = DefaultStreamVersion;
+ ver = Qt_DefaultCompiledVersion;
noswap = QSysInfo::ByteOrder == QSysInfo::BigEndian;
q_status = Ok;
}
@@ -315,7 +311,7 @@ QDataStream::QDataStream(QByteArray *a, QIODevice::OpenMode flags)
dev = buf;
owndev = true;
byteorder = BigEndian;
- ver = DefaultStreamVersion;
+ ver = Qt_DefaultCompiledVersion;
noswap = QSysInfo::ByteOrder == QSysInfo::BigEndian;
q_status = Ok;
}
@@ -339,7 +335,7 @@ QDataStream::QDataStream(const QByteArray &a)
dev = buf;
owndev = true;
byteorder = BigEndian;
- ver = DefaultStreamVersion;
+ ver = Qt_DefaultCompiledVersion;
noswap = QSysInfo::ByteOrder == QSysInfo::BigEndian;
q_status = Ok;
}
@@ -542,6 +538,8 @@ void QDataStream::setByteOrder(ByteOrder bo)
\value Qt_5_1 Version 14 (Qt 5.1)
\value Qt_5_2 Version 15 (Qt 5.2)
\value Qt_5_3 Same as Qt_5_2
+ \value Qt_5_4 Version 16 (Qt 5.4)
+ \omitvalue Qt_DefaultCompiledVersion
\sa setVersion(), version()
*/
@@ -557,7 +555,8 @@ void QDataStream::setByteOrder(ByteOrder bo)
/*!
\fn void QDataStream::setVersion(int v)
- Sets the version number of the data serialization format to \a v.
+ Sets the version number of the data serialization format to \a v,
+ a value of the \l Version enum.
You don't \e have to set a version if you are using the current
version of Qt, but for your own custom binary formats we
@@ -571,25 +570,6 @@ void QDataStream::setByteOrder(ByteOrder bo)
with an earlier version of Qt, use this function to modify the
serialization format used by QDataStream.
- \table
- \header \li Qt Version \li QDataStream Version
- \row \li Qt 5.2 \li 15
- \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
- \row \li Qt 4.4 \li 10
- \row \li Qt 4.3 \li 9
- \row \li Qt 4.2 \li 8
- \row \li Qt 4.0, 4.1 \li 7
- \row \li Qt 3.3 \li 6
- \row \li Qt 3.1, 3.2 \li 5
- \row \li Qt 3.0 \li 4
- \row \li Qt 2.1, 2.2, 2.3 \li 3
- \row \li Qt 2.0 \li 2
- \row \li Qt 1.x \li 1
- \endtable
-
The \l Version enum provides symbolic constants for the different
versions of Qt. For example:
diff --git a/src/corelib/io/qdatastream.h b/src/corelib/io/qdatastream.h
index 28f1d51a12..808fbe73f6 100644
--- a/src/corelib/io/qdatastream.h
+++ b/src/corelib/io/qdatastream.h
@@ -88,10 +88,12 @@ public:
Qt_5_0 = 13,
Qt_5_1 = 14,
Qt_5_2 = 15,
- Qt_5_3 = Qt_5_2
-#if QT_VERSION >= 0x050400
-#error Add the datastream version for this Qt version
+ Qt_5_3 = Qt_5_2,
+ Qt_5_4 = 16,
+#if QT_VERSION >= 0x050500
+#error Add the datastream version for this Qt version and update Qt_DefaultCompiledVersion
#endif
+ Qt_DefaultCompiledVersion = Qt_5_4
};
enum ByteOrder {
diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp
index 3370cce6d5..b0411f9dd9 100644
--- a/src/corelib/io/qdebug.cpp
+++ b/src/corelib/io/qdebug.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -79,6 +79,18 @@ QT_BEGIN_NAMESPACE
used to write debugging information to files and other devices. The constructor
that accepts a QString is used to write to a string for display or serialization.
+ \section1 Formatting Options
+
+ QDebug formats output so that it's easily readable. It automatically adds spaces
+ between arguments, and adds quotes around QString, QByteArray, QChar arguments.
+
+ You can tweak these options through the space(), nospace() and quote(), noquote()
+ methods. Furthermore, \l{QTextStream manipulators} can be piped into a QDebug
+ stream.
+
+ QDebugStateSaver limits changes to the formatting to the current scope.
+ resetFormat() resets the options to the default ones.
+
\section1 Writing Custom Types to a Stream
Many standard types can be written to QDebug objects, and Qt provides support for
@@ -128,6 +140,20 @@ QT_BEGIN_NAMESPACE
Flushes any pending data to be written and destroys the debug stream.
*/
+// Has been defined in the header / inlined before Qt 5.4
+QDebug::~QDebug()
+{
+ if (!--stream->ref) {
+ if (stream->space && stream->buffer.endsWith(QLatin1Char(' ')))
+ stream->buffer.chop(1);
+ if (stream->message_output) {
+ qt_message_output(stream->type,
+ stream->context,
+ stream->buffer);
+ }
+ delete stream;
+ }
+}
/*!
\fn QDebug::swap(QDebug &other)
@@ -138,6 +164,21 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ Resets the stream formatting options, bringing it back to its original constructed state.
+
+ \sa space(), quote()
+ \since 5.4
+*/
+QDebug &QDebug::resetFormat()
+{
+ stream->ts.reset();
+ stream->space = true;
+ if (stream->context.version > 1)
+ stream->flags = 0;
+ return *this;
+}
+
+/*!
\fn QDebug &QDebug::space()
Writes a space character to the debug stream and returns a reference to
@@ -188,6 +229,41 @@ QT_BEGIN_NAMESPACE
\sa QDebugStateSaver
*/
+
+/*!
+ \fn QDebug &QDebug::quote()
+ \since 5.4
+
+ Enables automatic insertion of quotation characters around QChar, QString and QByteArray
+ contents and returns a reference to the stream.
+
+ Quoting is enabled by default.
+
+ \sa noquote(), maybeQuote()
+*/
+
+/*!
+ \fn QDebug &QDebug::noquote()
+ \since 5.4
+
+ Disables automatic insertion of quotation characters around QChar, QString and QByteArray
+ contents and returns a reference to the stream.
+
+ \sa quote(), maybeQuote()
+*/
+
+/*!
+ \fn QDebug &QDebug::maybeQuote(char c)
+ \since 5.4
+
+ Writes a character \a c to the debug stream, depending on the
+ current setting for automatic insertion of quotes, and returns a reference to the stream.
+
+ The default character is a double quote \c{"}.
+
+ \sa quote(), noquote()
+*/
+
/*!
\fn QDebug &QDebug::operator<<(QChar t)
@@ -334,7 +410,9 @@ QT_BEGIN_NAMESPACE
\brief Convenience class for custom QDebug operators
- Saves the settings used by QDebug, and restores them upon destruction.
+ Saves the settings used by QDebug, and restores them upon destruction,
+ then calls maybeSpace(), to separate arguments with a space if
+ autoInsertSpaces() was true at the time of constructing the QDebugStateSaver.
The automatic insertion of spaces between writes is one of the settings
that QDebugStateSaver stores for the duration of the current block.
@@ -352,19 +430,33 @@ public:
QDebugStateSaverPrivate(QDebug &dbg)
: m_dbg(dbg),
m_spaces(dbg.autoInsertSpaces()),
+ m_flags(0),
m_streamParams(dbg.stream->ts.d_ptr->params)
{
+ if (m_dbg.stream->context.version > 1)
+ m_flags = m_dbg.stream->flags;
}
void restoreState()
{
+ const bool currentSpaces = m_dbg.autoInsertSpaces();
+ if (currentSpaces && !m_spaces)
+ if (m_dbg.stream->buffer.endsWith(QLatin1Char(' ')))
+ m_dbg.stream->buffer.chop(1);
+
m_dbg.setAutoInsertSpaces(m_spaces);
m_dbg.stream->ts.d_ptr->params = m_streamParams;
+ if (m_dbg.stream->context.version > 1)
+ m_dbg.stream->flags = m_flags;
+
+ if (!currentSpaces && m_spaces)
+ m_dbg.stream->ts << ' ';
}
QDebug &m_dbg;
// QDebug state
const bool m_spaces;
+ int m_flags;
// QTextStream state
const QTextStreamPrivate::Params m_streamParams;
diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h
index bdaaa05768..6b81d9431f 100644
--- a/src/corelib/io/qdebug.h
+++ b/src/corelib/io/qdebug.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -61,9 +61,9 @@ class Q_CORE_EXPORT QDebug
friend class QMessageLogger;
friend class QDebugStateSaverPrivate;
struct Stream {
- Stream(QIODevice *device) : ts(device), ref(1), type(QtDebugMsg), space(true), message_output(false) {}
- Stream(QString *string) : ts(string, QIODevice::WriteOnly), ref(1), type(QtDebugMsg), space(true), message_output(false) {}
- Stream(QtMsgType t) : ts(&buffer, QIODevice::WriteOnly), ref(1), type(t), space(true), message_output(true) {}
+ Stream(QIODevice *device) : ts(device), ref(1), type(QtDebugMsg), space(true), message_output(false), flags(0) {}
+ Stream(QString *string) : ts(string, QIODevice::WriteOnly), ref(1), type(QtDebugMsg), space(true), message_output(false), flags(0) {}
+ Stream(QtMsgType t) : ts(&buffer, QIODevice::WriteOnly), ref(1), type(t), space(true), message_output(true), flags(0) {}
QTextStream ts;
QString buffer;
int ref;
@@ -71,6 +71,18 @@ class Q_CORE_EXPORT QDebug
bool space;
bool message_output;
QMessageLogContext context;
+
+ enum FormatFlag {
+ NoQuotes = 0x1
+ };
+
+ // ### Qt 6: unify with space, introduce own version member
+ bool testFlag(FormatFlag flag) const { return (context.version > 1) ? (flags & flag) : false; }
+ void setFlag(FormatFlag flag) { if (context.version > 1) { flags |= flag; } }
+ void unsetFlag(FormatFlag flag) { if (context.version > 1) { flags &= ~flag; } }
+
+ // added in 5.4
+ int flags;
} *stream;
public:
inline QDebug(QIODevice *device) : stream(new Stream(device)) {}
@@ -78,22 +90,11 @@ public:
inline QDebug(QtMsgType t) : stream(new Stream(t)) {}
inline QDebug(const QDebug &o):stream(o.stream) { ++stream->ref; }
inline QDebug &operator=(const QDebug &other);
- inline ~QDebug() {
- if (!--stream->ref) {
- if (stream->space && stream->buffer.endsWith(QLatin1Char(' ')))
- stream->buffer.chop(1);
- if (stream->message_output) {
- QT_TRY {
- qt_message_output(stream->type,
- stream->context,
- stream->buffer);
- } QT_CATCH(std::bad_alloc&) { /* We're out of memory - give up. */ }
- }
- delete stream;
- }
- }
+ ~QDebug();
inline void swap(QDebug &other) { qSwap(stream, other.stream); }
+ QDebug &resetFormat();
+
inline QDebug &space() { stream->space = true; stream->ts << ' '; return *this; }
inline QDebug &nospace() { stream->space = false; return *this; }
inline QDebug &maybeSpace() { if (stream->space) stream->ts << ' '; return *this; }
@@ -101,7 +102,11 @@ public:
bool autoInsertSpaces() const { return stream->space; }
void setAutoInsertSpaces(bool b) { stream->space = b; }
- inline QDebug &operator<<(QChar t) { stream->ts << '\'' << t << '\''; return maybeSpace(); }
+ inline QDebug &quote() { stream->unsetFlag(Stream::NoQuotes); return *this; }
+ inline QDebug &noquote() { stream->setFlag(Stream::NoQuotes); return *this; }
+ inline QDebug &maybeQuote(char c = '"') { if (!(stream->testFlag(Stream::NoQuotes))) stream->ts << c; return *this; }
+
+ inline QDebug &operator<<(QChar t) { maybeQuote('\''); stream->ts << t; maybeQuote('\''); return maybeSpace(); }
inline QDebug &operator<<(bool t) { stream->ts << (t ? "true" : "false"); return maybeSpace(); }
inline QDebug &operator<<(char t) { stream->ts << t; return maybeSpace(); }
inline QDebug &operator<<(signed short t) { stream->ts << t; return maybeSpace(); }
@@ -115,10 +120,10 @@ public:
inline QDebug &operator<<(float t) { stream->ts << t; return maybeSpace(); }
inline QDebug &operator<<(double t) { stream->ts << t; return maybeSpace(); }
inline QDebug &operator<<(const char* t) { stream->ts << QString::fromUtf8(t); return maybeSpace(); }
- inline QDebug &operator<<(const QString & t) { stream->ts << '\"' << t << '\"'; return maybeSpace(); }
+ inline QDebug &operator<<(const QString & t) { maybeQuote(); stream->ts << t; maybeQuote(); return maybeSpace(); }
inline QDebug &operator<<(const QStringRef & t) { return operator<<(t.toString()); }
- inline QDebug &operator<<(QLatin1String t) { stream->ts << '\"' << t << '\"'; return maybeSpace(); }
- inline QDebug &operator<<(const QByteArray & t) { stream->ts << '\"' << t << '\"'; return maybeSpace(); }
+ inline QDebug &operator<<(QLatin1String t) { maybeQuote(); stream->ts << t; maybeQuote(); return maybeSpace(); }
+ inline QDebug &operator<<(const QByteArray & t) { maybeQuote(); stream->ts << t; maybeQuote(); return maybeSpace(); }
inline QDebug &operator<<(const void * t) { stream->ts << t; return maybeSpace(); }
inline QDebug &operator<<(QTextStreamFunction f) {
stream->ts << f;
@@ -150,6 +155,9 @@ public:
inline QNoDebug &space() { return *this; }
inline QNoDebug &nospace() { return *this; }
inline QNoDebug &maybeSpace() { return *this; }
+ inline QNoDebug &quote() { return *this; }
+ inline QNoDebug &noquote() { return *this; }
+ inline QNoDebug &maybeQuote(const char = '"') { return *this; }
template<typename T>
inline QNoDebug &operator<<(const T &) { return *this; }
@@ -164,13 +172,8 @@ inline QDebug &QDebug::operator=(const QDebug &other)
return *this;
}
-#if defined(FORCE_UREF)
-template <class T>
-inline QDebug &operator<<(QDebug debug, const QList<T> &list)
-#else
template <class T>
inline QDebug operator<<(QDebug debug, const QList<T> &list)
-#endif
{
const bool oldSetting = debug.autoInsertSpaces();
debug.nospace() << '(';
@@ -184,13 +187,8 @@ inline QDebug operator<<(QDebug debug, const QList<T> &list)
return debug.maybeSpace();
}
-#if defined(FORCE_UREF)
-template <typename T>
-inline QDebug &operator<<(QDebug debug, const QVector<T> &vec)
-#else
template <typename T>
inline QDebug operator<<(QDebug debug, const QVector<T> &vec)
-#endif
{
const bool oldSetting = debug.autoInsertSpaces();
debug.nospace() << "QVector";
@@ -198,13 +196,8 @@ inline QDebug operator<<(QDebug debug, const QVector<T> &vec)
return operator<<(debug, vec.toList());
}
-#if defined(FORCE_UREF)
-template <class aKey, class aT>
-inline QDebug &operator<<(QDebug debug, const QMap<aKey, aT> &map)
-#else
template <class aKey, class aT>
inline QDebug operator<<(QDebug debug, const QMap<aKey, aT> &map)
-#endif
{
const bool oldSetting = debug.autoInsertSpaces();
debug.nospace() << "QMap(";
@@ -217,13 +210,8 @@ inline QDebug operator<<(QDebug debug, const QMap<aKey, aT> &map)
return debug.maybeSpace();
}
-#if defined(FORCE_UREF)
-template <class aKey, class aT>
-inline QDebug &operator<<(QDebug debug, const QHash<aKey, aT> &hash)
-#else
template <class aKey, class aT>
inline QDebug operator<<(QDebug debug, const QHash<aKey, aT> &hash)
-#endif
{
const bool oldSetting = debug.autoInsertSpaces();
debug.nospace() << "QHash(";
@@ -235,13 +223,8 @@ inline QDebug operator<<(QDebug debug, const QHash<aKey, aT> &hash)
return debug.maybeSpace();
}
-#if defined(FORCE_UREF)
-template <class T1, class T2>
-inline QDebug &operator<<(QDebug debug, const QPair<T1, T2> &pair)
-#else
template <class T1, class T2>
inline QDebug operator<<(QDebug debug, const QPair<T1, T2> &pair)
-#endif
{
const bool oldSetting = debug.autoInsertSpaces();
debug.nospace() << "QPair(" << pair.first << ',' << pair.second << ')';
@@ -258,13 +241,8 @@ inline QDebug operator<<(QDebug debug, const QSet<T> &set)
return operator<<(debug, set.toList());
}
-#if defined(FORCE_UREF)
-template <class T>
-inline QDebug &operator<<(QDebug debug, const QContiguousCache<T> &cache)
-#else
template <class T>
inline QDebug operator<<(QDebug debug, const QContiguousCache<T> &cache)
-#endif
{
const bool oldSetting = debug.autoInsertSpaces();
debug.nospace() << "QContiguousCache(";
@@ -278,29 +256,24 @@ inline QDebug operator<<(QDebug debug, const QContiguousCache<T> &cache)
return debug.maybeSpace();
}
-#if defined(FORCE_UREF)
-template <class T>
-inline QDebug &operator<<(QDebug debug, const QFlags<T> &flags)
-#else
template <class T>
inline QDebug operator<<(QDebug debug, const QFlags<T> &flags)
-#endif
{
- const bool oldSetting = debug.autoInsertSpaces();
- debug.nospace() << "QFlags(";
+ QDebugStateSaver saver(debug);
+ debug.resetFormat();
+ debug.nospace() << "QFlags(" << hex << showbase;
bool needSeparator = false;
for (uint i = 0; i < sizeof(T) * 8; ++i) {
if (flags.testFlag(T(1 << i))) {
if (needSeparator)
- debug.nospace() << '|';
+ debug << '|';
else
needSeparator = true;
- debug.nospace() << "0x" << QByteArray::number(typename QFlags<T>::Int(1) << i, 16).constData();
+ debug << (typename QFlags<T>::Int(1) << i);
}
}
debug << ')';
- debug.setAutoInsertSpaces(oldSetting);
- return debug.maybeSpace();
+ return debug;
}
QT_END_NAMESPACE
diff --git a/src/corelib/io/qfiledevice.cpp b/src/corelib/io/qfiledevice.cpp
index f7e58a7bed..33cb6037f5 100644
--- a/src/corelib/io/qfiledevice.cpp
+++ b/src/corelib/io/qfiledevice.cpp
@@ -680,6 +680,13 @@ bool QFileDevice::setPermissions(Permissions permissions)
function.
\value NoOptions No options.
+ \value MapPrivateOption The mapped memory will be private, so any
+ modifications will not be visible to other processes and will not
+ be written to disk. Any such modifications will be lost when the
+ memory is unmapped. It is unspecified whether modifications made
+ to the file made after the mapping is created will be visible through
+ the mapped memory. This flag is not supported on Windows CE.
+ This enum value was introduced in Qt 5.4.
*/
/*!
@@ -689,6 +696,10 @@ bool QFileDevice::setPermissions(Permissions permissions)
or a new file is opened with this object, any maps that have not been
unmapped will automatically be unmapped.
+ The mapping will have the same open mode as the file (read and/or write),
+ except when using MapPrivateOption, in which case it is always possible
+ to write to the mapped memory.
+
Any mapping options can be passed through \a flags.
Returns a pointer to the memory or 0 if there is an error.
diff --git a/src/corelib/io/qfiledevice.h b/src/corelib/io/qfiledevice.h
index fc2779086a..4b13ffe589 100644
--- a/src/corelib/io/qfiledevice.h
+++ b/src/corelib/io/qfiledevice.h
@@ -112,8 +112,10 @@ public:
virtual Permissions permissions() const;
virtual bool setPermissions(Permissions permissionSpec);
+ // ### Qt 6: rename to MemoryMapFlag & make it a QFlags
enum MemoryMapFlags {
- NoOptions = 0
+ NoOptions = 0,
+ MapPrivateOption = 0x0001
};
uchar *map(qint64 offset, qint64 size, MemoryMapFlags flags = NoOptions);
diff --git a/src/corelib/io/qfileselector.cpp b/src/corelib/io/qfileselector.cpp
index 0fa1f02f5c..639310876a 100644
--- a/src/corelib/io/qfileselector.cpp
+++ b/src/corelib/io/qfileselector.cpp
@@ -51,10 +51,6 @@
#include <QtCore/QLocale>
#include <QtCore/QDebug>
-#ifdef Q_OS_UNIX
-#include <sys/utsname.h>
-#endif
-
QT_BEGIN_NAMESPACE
//Environment variable to allow tooling full control of file selectors
@@ -360,6 +356,7 @@ void QFileSelectorPrivate::updateSelectors()
QStringList QFileSelectorPrivate::platformSelectors()
{
+ // similar, but not identical to QSysInfo::osType
QStringList ret;
#if defined(Q_OS_WIN)
ret << QStringLiteral("windows");
@@ -390,9 +387,7 @@ QStringList QFileSelectorPrivate::platformSelectors()
ret << QStringLiteral("osx");
# endif
# else
- struct utsname u;
- if (uname(&u) != -1)
- ret << QString::fromLatin1(u.sysname).toLower();
+ ret << QSysInfo::kernelType();
# endif
#endif
return ret;
diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp
index 998a3334c9..3c4a2fac0b 100644
--- a/src/corelib/io/qfsfileengine.cpp
+++ b/src/corelib/io/qfsfileengine.cpp
@@ -179,9 +179,7 @@ QFSFileEngine::~QFSFileEngine()
} while (ret == -1 && errno == EINTR);
}
}
- QList<uchar*> keys = d->maps.keys();
- for (int i = 0; i < keys.count(); ++i)
- unmap(keys.at(i));
+ d->unmapAll();
}
/*!
@@ -463,6 +461,18 @@ qint64 QFSFileEngine::size() const
return d->nativeSize();
}
+/*!
+ \internal
+*/
+void QFSFileEnginePrivate::unmapAll()
+{
+ if (!maps.isEmpty()) {
+ const QList<uchar*> keys = maps.keys(); // Make a copy since unmap() modifies the map.
+ for (int i = 0; i < keys.count(); ++i)
+ unmap(keys.at(i));
+ }
+}
+
#ifndef Q_OS_WIN
/*!
\internal
diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h
index 21f38fea1d..b0610b1459 100644
--- a/src/corelib/io/qfsfileengine_p.h
+++ b/src/corelib/io/qfsfileengine_p.h
@@ -175,6 +175,7 @@ public:
uchar *map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags);
bool unmap(uchar *ptr);
+ void unmapAll();
mutable QFileSystemMetaData metaData;
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index 064a1a511f..f9c6c8ab98 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -713,6 +713,12 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla
if (openMode & QIODevice::ReadOnly) access |= PROT_READ;
if (openMode & QIODevice::WriteOnly) access |= PROT_WRITE;
+ int sharemode = MAP_SHARED;
+ if (flags & QFileDevice::MapPrivateOption) {
+ sharemode = MAP_PRIVATE;
+ access |= PROT_WRITE;
+ }
+
#if defined(Q_OS_INTEGRITY)
int pageSize = sysconf(_SC_PAGESIZE);
#else
@@ -730,7 +736,7 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla
realOffset &= ~(QT_OFF_T(pageSize - 1));
void *mapAddress = QT_MMAP((void*)0, realSize,
- access, MAP_SHARED, nativeHandle(), realOffset);
+ access, sharemode, nativeHandle(), realOffset);
if (MAP_FAILED != mapAddress) {
uchar *address = extra + static_cast<uchar*>(mapAddress);
maps[address] = QPair<int,size_t>(extra, realSize);
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp
index fb4107b95d..81aed5f7b4 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -965,6 +965,21 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
return 0;
}
+ // check/setup args to map
+ DWORD access = 0;
+ if (flags & QFileDevice::MapPrivateOption) {
+#ifdef FILE_MAP_COPY
+ access = FILE_MAP_COPY;
+#else
+ q->setError(QFile::UnspecifiedError, "MapPrivateOption unsupported");
+ return 0;
+#endif
+ } else if (openMode & QIODevice::WriteOnly) {
+ access = FILE_MAP_WRITE;
+ } else if (openMode & QIODevice::ReadOnly) {
+ access = FILE_MAP_READ;
+ }
+
if (mapHandle == NULL) {
// get handle to the file
HANDLE handle = fileHandle;
@@ -1011,11 +1026,6 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
}
}
- // setup args to map
- DWORD access = 0;
- if (openMode & QIODevice::ReadOnly) access = FILE_MAP_READ;
- if (openMode & QIODevice::WriteOnly) access = FILE_MAP_WRITE;
-
DWORD offsetHi = offset >> 32;
DWORD offsetLo = offset & Q_UINT64_C(0xffffffff);
SYSTEM_INFO sysinfo;
diff --git a/src/corelib/io/qlockfile_win.cpp b/src/corelib/io/qlockfile_win.cpp
index 28f6b02a64..00c8a85bcc 100644
--- a/src/corelib/io/qlockfile_win.cpp
+++ b/src/corelib/io/qlockfile_win.cpp
@@ -50,6 +50,11 @@
QT_BEGIN_NAMESPACE
+static inline QByteArray localHostName()
+{
+ return qgetenv("COMPUTERNAME");
+}
+
QLockFile::LockError QLockFilePrivate::tryLock_sys()
{
const QFileSystemEntry fileEntry(fileName);
@@ -98,7 +103,7 @@ QLockFile::LockError QLockFilePrivate::tryLock_sys()
fileData += '\n';
fileData += qAppName().toUtf8();
fileData += '\n';
- //fileData += localHostname(); // gethostname requires winsock init, see QHostInfo...
+ fileData += localHostName();
fileData += '\n';
DWORD bytesWritten = 0;
QLockFile::LockError error = QLockFile::NoError;
@@ -123,14 +128,16 @@ bool QLockFilePrivate::isApparentlyStale() const
// On WinRT there seems to be no way of obtaining information about other
// processes due to sandboxing
#ifndef Q_OS_WINRT
- HANDLE procHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
- if (!procHandle)
- return true;
- // We got a handle but check if process is still alive
- DWORD dwR = ::WaitForSingleObject(procHandle, 0);
- ::CloseHandle(procHandle);
- if (dwR == WAIT_TIMEOUT)
- return true;
+ if (hostname == QString::fromLocal8Bit(localHostName())) {
+ HANDLE procHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
+ if (!procHandle)
+ return true;
+ // We got a handle but check if process is still alive
+ DWORD dwR = ::WaitForSingleObject(procHandle, 0);
+ ::CloseHandle(procHandle);
+ if (dwR == WAIT_TIMEOUT)
+ return true;
+ }
#endif // !Q_OS_WINRT
const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime());
return staleLockTime > 0 && age > staleLockTime;
diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp
index 07245ddea2..a368e92932 100644
--- a/src/corelib/io/qloggingcategory.cpp
+++ b/src/corelib/io/qloggingcategory.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -40,7 +40,6 @@
****************************************************************************/
#include "qloggingcategory.h"
-#include "qloggingcategory_p.h"
#include "qloggingregistry_p.h"
QT_BEGIN_NAMESPACE
@@ -82,7 +81,7 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
\section1 Creating category objects
- The Q_LOGGING_CATEGORY() and the Q_DECLARE_LOGGING_CATEGORY() macros
+ The Q_DECLARE_LOGGING_CATEGORY() and Q_LOGGING_CATEGORY() macros
conveniently declare and create QLoggingCategory objects:
\snippet qloggingcategory/main.cpp 1
@@ -101,13 +100,21 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
\section1 Default category configuration
- In the default configuration \l isWarningEnabled() , \l isDebugEnabled() and
- \l isCriticalEnabled() will return \c true.
+ Both the QLoggingCategory constructor and the Q_LOGGING_CATEGORY() macro
+ accept an optional QtMsgType argument, which disables all message types with
+ a lower severity. That is, a category declared with
+
+ \snippet qloggingcategory/main.cpp 5
+
+ will log messages of type \c QtWarningMsg, \c QtCriticalMsg, \c QtFatalMsg, but will
+ ignore messages of type \c QtDebugMsg.
+
+ If no argument is passed, all messages will be logged.
\section1 Configuring Categories
- Categories can be centrally configured by either setting logging rules,
- or by installing a custom filter.
+ The default configuration of categories can be overridden either by setting logging
+ rules, or by installing a custom filter.
\section2 Logging Rules
@@ -131,7 +138,13 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
are automatically loaded from the \c [Rules] section of a logging
configuration file. Such configuration files are looked up in the QtProject
configuration directory, or explicitly set in a \c QT_LOGGING_CONF
- environment variable.
+ environment variable:
+
+ \code
+ [Rules]
+ *.debug=false
+ driver.usb.debug=true
+ \endcode
Rules set by \l setFilterRules() take precedence over rules specified
in the QtProject configuration directory, and can, in turn, be
@@ -177,7 +190,7 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
/*!
Constructs a QLoggingCategory object with the provided \a category name.
- The object becomes the local identifier for the category.
+ All message types for this category are enabled by default.
If \a category is \c{0}, the category name is changed to \c "default".
*/
@@ -185,23 +198,35 @@ QLoggingCategory::QLoggingCategory(const char *category)
: d(0),
name(0)
{
- Q_UNUSED(d);
- Q_UNUSED(placeholder);
- enabled.store(0x01010101); // enabledDebug = enabledWarning = enabledCritical = true;
+ init(category, QtDebugMsg);
+}
- const bool isDefaultCategory
- = (category == 0) || (strcmp(category, qtDefaultCategoryName) == 0);
+/*!
+ Constructs a QLoggingCategory object with the provided \a category name,
+ and enables all messages with types more severe or equal than \a enableForLevel.
- // normalize "default" category name, so that we can just do
- // pointer comparison in QLoggingRegistry::updateCategory
- if (isDefaultCategory) {
- name = qtDefaultCategoryName;
- } else {
+ If \a category is \c{0}, the category name is changed to \c "default".
+
+ \since 5.4
+*/
+QLoggingCategory::QLoggingCategory(const char *category, QtMsgType enableForLevel)
+ : d(0),
+ name(0)
+{
+ init(category, enableForLevel);
+}
+
+void QLoggingCategory::init(const char *category, QtMsgType severityLevel)
+{
+ enabled.store(0x01010101); // enabledDebug = enabledWarning = enabledCritical = true;
+
+ if (category)
name = category;
- }
+ else
+ name = qtDefaultCategoryName;
if (QLoggingRegistry *reg = QLoggingRegistry::instance())
- reg->registerCategory(this);
+ reg->registerCategory(this, severityLevel);
}
/*!
@@ -501,6 +526,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
*/
/*!
\macro Q_DECLARE_LOGGING_CATEGORY(name)
+ \sa Q_LOGGING_CATEGORY()
\relates QLoggingCategory
\since 5.2
@@ -512,11 +538,12 @@ void QLoggingCategory::setFilterRules(const QString &rules)
/*!
\macro Q_LOGGING_CATEGORY(name, string)
+ \sa Q_DECLARE_LOGGING_CATEGORY()
\relates QLoggingCategory
\since 5.2
Defines a logging category \a name, and makes it configurable under the
- \a string identifier.
+ \a string identifier. By default, all message types are enabled.
Only one translation unit in a library or executable can define a category
with a specific name.
@@ -524,4 +551,21 @@ void QLoggingCategory::setFilterRules(const QString &rules)
This macro must be used outside of a class or method.
*/
+/*!
+ \macro Q_LOGGING_CATEGORY(name, string, msgType)
+ \sa Q_DECLARE_LOGGING_CATEGORY()
+ \relates QLoggingCategory
+ \since 5.4
+
+ Defines a logging category \a name, and makes it configurable under the
+ \a string identifier. By default, messages of QtMsgType \a msgType
+ and more severe are enabled, types with a lower severity are disabled.
+
+ Only one translation unit in a library or executable can define a category
+ with a specific name.
+
+ This macro must be used outside of a class or method. It is only defined
+ if variadic macros are supported.
+*/
+
QT_END_NAMESPACE
diff --git a/src/corelib/io/qloggingcategory.h b/src/corelib/io/qloggingcategory.h
index 573af2105c..cca2031108 100644
--- a/src/corelib/io/qloggingcategory.h
+++ b/src/corelib/io/qloggingcategory.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -51,7 +51,9 @@ class Q_CORE_EXPORT QLoggingCategory
{
Q_DISABLE_COPY(QLoggingCategory)
public:
+ // ### Qt 6: Merge constructors
explicit QLoggingCategory(const char *category);
+ QLoggingCategory(const char *category, QtMsgType severityLevel);
~QLoggingCategory();
bool isEnabled(QtMsgType type) const;
@@ -80,7 +82,9 @@ public:
static void setFilterRules(const QString &rules);
private:
- void *d; // reserved for future use
+ void init(const char *category, QtMsgType severityLevel);
+
+ Q_DECL_UNUSED_MEMBER void *d; // reserved for future use
const char *name;
#ifdef Q_BIG_ENDIAN
@@ -100,22 +104,20 @@ private:
AtomicBools bools;
QBasicAtomicInt enabled;
};
- bool placeholder[4]; // reserve for future use
+ Q_DECL_UNUSED_MEMBER bool placeholder[4]; // reserved for future use
};
#define Q_DECLARE_LOGGING_CATEGORY(name) \
extern const QLoggingCategory &name();
-// relies on QLoggingCategory(QString) being thread safe!
-#define Q_LOGGING_CATEGORY(name, string) \
+#if defined(Q_COMPILER_VARIADIC_MACROS) || defined(Q_MOC_RUN)
+
+#define Q_LOGGING_CATEGORY(name, ...) \
const QLoggingCategory &name() \
{ \
- static const QLoggingCategory category(string); \
+ static const QLoggingCategory category(__VA_ARGS__); \
return category; \
}
-
-#ifdef Q_COMPILER_VARIADIC_MACROS
-
#define qCDebug(category, ...) \
for (bool qt_category_enabled = category().isDebugEnabled(); qt_category_enabled; qt_category_enabled = false) \
QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, category().categoryName()).debug(__VA_ARGS__)
@@ -126,14 +128,22 @@ private:
for (bool qt_category_enabled = category().isCriticalEnabled(); qt_category_enabled; qt_category_enabled = false) \
QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, category().categoryName()).critical(__VA_ARGS__)
-#else
+#else // defined(Q_COMPILER_VARIADIC_MACROS) || defined(Q_MOC_RUN)
+
+// Optional msgType argument not supported
+#define Q_LOGGING_CATEGORY(name, string) \
+ const QLoggingCategory &name() \
+ { \
+ static const QLoggingCategory category(string); \
+ return category; \
+ }
// check for enabled category inside QMessageLogger.
#define qCDebug qDebug
#define qCWarning qWarning
#define qCCritical qCritical
-#endif // Q_COMPILER_VARIADIC_MACROS
+#endif // Q_COMPILER_VARIADIC_MACROS || defined(Q_MOC_RUN)
#if defined(QT_NO_DEBUG_OUTPUT)
# undef qCDebug
diff --git a/src/corelib/io/qloggingcategory_p.h b/src/corelib/io/qloggingcategory_p.h
deleted file mode 100644
index 7802f017fd..0000000000
--- a/src/corelib/io/qloggingcategory_p.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QLOGGINGCATEGORY_P_H
-#define QLOGGINGCATEGORY_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of a number of Qt sources files. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qglobal.h>
-
-QT_BEGIN_NAMESPACE
-
-// unique pointer to default category
-// (allows to compare for pointers instead of strings)
-extern const char qtDefaultCategoryName[];
-
-QT_END_NAMESPACE
-
-#endif // QLOGGINGCATEGORY_P_H
diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp
index 575150f148..3ce0a571b4 100644
--- a/src/corelib/io/qloggingregistry.cpp
+++ b/src/corelib/io/qloggingregistry.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -40,7 +40,6 @@
****************************************************************************/
#include "qloggingregistry_p.h"
-#include "qloggingcategory_p.h"
#include <QtCore/qfile.h>
#include <QtCore/qstandardpaths.h>
@@ -131,15 +130,15 @@ void QLoggingRule::parse(const QStringRef &pattern)
// strip trailing ".messagetype"
if (pattern.endsWith(QLatin1String(".debug"))) {
p = QStringRef(pattern.string(), pattern.position(),
- pattern.length() - strlen(".debug"));
+ pattern.length() - 6); // strlen(".debug")
messageType = QtDebugMsg;
} else if (pattern.endsWith(QLatin1String(".warning"))) {
p = QStringRef(pattern.string(), pattern.position(),
- pattern.length() - strlen(".warning"));
+ pattern.length() - 8); // strlen(".warning")
messageType = QtWarningMsg;
} else if (pattern.endsWith(QLatin1String(".critical"))) {
p = QStringRef(pattern.string(), pattern.position(),
- pattern.length() - strlen(".critical"));
+ pattern.length() - 9); // strlen(".critical")
messageType = QtCriticalMsg;
} else {
p = pattern;
@@ -261,12 +260,12 @@ void QLoggingRegistry::init()
if (!rulesFilePath.isEmpty()) {
QFile file(QFile::decodeName(rulesFilePath));
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- QTextStream stream(&file);
- QLoggingSettingsParser parser;
- parser.setContent(stream);
if (qtLoggingDebug())
debugMsg("Loading \"%s\" ...",
QDir::toNativeSeparators(file.fileName()).toUtf8().constData());
+ QTextStream stream(&file);
+ QLoggingSettingsParser parser;
+ parser.setContent(stream);
envRules = parser.rules();
}
}
@@ -285,12 +284,12 @@ void QLoggingRegistry::init()
if (!envPath.isEmpty()) {
QFile file(envPath);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- QTextStream stream(&file);
- QLoggingSettingsParser parser;
- parser.setContent(stream);
if (qtLoggingDebug())
debugMsg("Loading \"%s\" ...",
QDir::toNativeSeparators(envPath).toUtf8().constData());
+ QTextStream stream(&file);
+ QLoggingSettingsParser parser;
+ parser.setContent(stream);
configRules = parser.rules();
}
}
@@ -307,12 +306,12 @@ void QLoggingRegistry::init()
This method might be called concurrently for the same category object.
*/
-void QLoggingRegistry::registerCategory(QLoggingCategory *cat)
+void QLoggingRegistry::registerCategory(QLoggingCategory *cat, QtMsgType enableForLevel)
{
QMutexLocker locker(&registryMutex);
if (!categories.contains(cat)) {
- categories.append(cat);
+ categories.insert(cat, enableForLevel);
(*categoryFilter)(cat);
}
}
@@ -324,8 +323,7 @@ void QLoggingRegistry::registerCategory(QLoggingCategory *cat)
void QLoggingRegistry::unregisterCategory(QLoggingCategory *cat)
{
QMutexLocker locker(&registryMutex);
-
- categories.removeOne(cat);
+ categories.remove(cat);
}
/*!
@@ -341,7 +339,7 @@ void QLoggingRegistry::setApiRules(const QString &content)
QMutexLocker locker(&registryMutex);
if (qtLoggingDebug())
- debugMsg("Loading logging rules set by Qt API ...");
+ debugMsg("Loading logging rules set by QLoggingCategory::setFilterRules ...");
apiRules = parser.rules();
@@ -361,7 +359,7 @@ void QLoggingRegistry::updateRules()
rules = configRules + apiRules + envRules;
- foreach (QLoggingCategory *cat, categories)
+ foreach (QLoggingCategory *cat, categories.keys())
(*categoryFilter)(cat);
}
@@ -380,7 +378,7 @@ QLoggingRegistry::installFilter(QLoggingCategory::CategoryFilter filter)
QLoggingCategory::CategoryFilter old = categoryFilter;
categoryFilter = filter;
- foreach (QLoggingCategory *cat, categories)
+ foreach (QLoggingCategory *cat, categories.keys())
(*categoryFilter)(cat);
return old;
@@ -397,18 +395,22 @@ QLoggingRegistry *QLoggingRegistry::instance()
*/
void QLoggingRegistry::defaultCategoryFilter(QLoggingCategory *cat)
{
- // QLoggingCategory() normalizes "default" strings
- // to qtDefaultCategoryName
- bool debug = true;
+ QLoggingRegistry *reg = QLoggingRegistry::instance();
+ Q_ASSERT(reg->categories.contains(cat));
+ QtMsgType enableForLevel = reg->categories.value(cat);
+
+ bool debug = (enableForLevel == QtDebugMsg) ? true : false;
+ bool warning = (enableForLevel <= QtWarningMsg) ? true : false;
+ bool critical = (enableForLevel <= QtCriticalMsg) ? true : false;
+
+ // hard-wired implementation of
+ // qt.*.debug=false
+ // qt.debug=false
char c;
if (!memcmp(cat->categoryName(), "qt", 2) && (!(c = cat->categoryName()[2]) || c == '.'))
debug = false;
- bool warning = true;
- bool critical = true;
-
QString categoryName = QLatin1String(cat->categoryName());
- QLoggingRegistry *reg = QLoggingRegistry::instance();
foreach (const QLoggingRule &item, reg->rules) {
int filterpass = item.pass(categoryName, QtDebugMsg);
if (filterpass != 0)
diff --git a/src/corelib/io/qloggingregistry_p.h b/src/corelib/io/qloggingregistry_p.h
index 48804cfc2b..ce2503b32c 100644
--- a/src/corelib/io/qloggingregistry_p.h
+++ b/src/corelib/io/qloggingregistry_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -113,7 +113,7 @@ public:
void init();
- void registerCategory(QLoggingCategory *category);
+ void registerCategory(QLoggingCategory *category, QtMsgType enableForLevel);
void unregisterCategory(QLoggingCategory *category);
void setApiRules(const QString &content);
@@ -134,7 +134,7 @@ private:
QVector<QLoggingRule> envRules;
QVector<QLoggingRule> apiRules;
QVector<QLoggingRule> rules;
- QList<QLoggingCategory*> categories;
+ QHash<QLoggingCategory*,QtMsgType> categories;
QLoggingCategory::CategoryFilter categoryFilter;
friend class ::tst_QLoggingRegistry;
diff --git a/src/corelib/io/qnoncontiguousbytedevice.cpp b/src/corelib/io/qnoncontiguousbytedevice.cpp
index b1e4dd7584..4c5fb38c67 100644
--- a/src/corelib/io/qnoncontiguousbytedevice.cpp
+++ b/src/corelib/io/qnoncontiguousbytedevice.cpp
@@ -506,6 +506,25 @@ QNonContiguousByteDevice* QNonContiguousByteDeviceFactory::create(QIODevice *dev
}
/*!
+ Create a QNonContiguousByteDevice out of a QIODevice, return it in a QSharedPointer.
+ For QFile, QBuffer and all other QIODevice, sequential or not.
+
+ \internal
+*/
+QSharedPointer<QNonContiguousByteDevice> QNonContiguousByteDeviceFactory::createShared(QIODevice *device)
+{
+ // shortcut if it is a QBuffer
+ if (QBuffer *buffer = qobject_cast<QBuffer*>(device))
+ return QSharedPointer<QNonContiguousByteDeviceBufferImpl>::create(buffer);
+
+ // ### FIXME special case if device is a QFile that supports map()
+ // then we can actually deal with the file without using read/peek
+
+ // generic QIODevice
+ return QSharedPointer<QNonContiguousByteDeviceIoDeviceImpl>::create(device); // FIXME
+}
+
+/*!
\fn static QNonContiguousByteDevice* QNonContiguousByteDeviceFactory::create(QSharedPointer<QRingBuffer> ringBuffer)
Create a QNonContiguousByteDevice out of a QRingBuffer.
@@ -518,6 +537,16 @@ QNonContiguousByteDevice* QNonContiguousByteDeviceFactory::create(QSharedPointer
}
/*!
+ Create a QNonContiguousByteDevice out of a QRingBuffer, return it in a QSharedPointer.
+
+ \internal
+*/
+QSharedPointer<QNonContiguousByteDevice> QNonContiguousByteDeviceFactory::createShared(QSharedPointer<QRingBuffer> ringBuffer)
+{
+ return QSharedPointer<QNonContiguousByteDeviceRingBufferImpl>::create(qMove(ringBuffer));
+}
+
+/*!
\fn static QNonContiguousByteDevice* QNonContiguousByteDeviceFactory::create(QByteArray *byteArray)
Create a QNonContiguousByteDevice out of a QByteArray.
@@ -530,6 +559,16 @@ QNonContiguousByteDevice* QNonContiguousByteDeviceFactory::create(QByteArray *by
}
/*!
+ Create a QNonContiguousByteDevice out of a QByteArray.
+
+ \internal
+*/
+QSharedPointer<QNonContiguousByteDevice> QNonContiguousByteDeviceFactory::createShared(QByteArray *byteArray)
+{
+ return QSharedPointer<QNonContiguousByteDeviceByteArrayImpl>::create(byteArray);
+}
+
+/*!
\fn static QIODevice* QNonContiguousByteDeviceFactory::wrap(QNonContiguousByteDevice* byteDevice)
Wrap the \a byteDevice (possibly again) into a QIODevice.
diff --git a/src/corelib/io/qnoncontiguousbytedevice_p.h b/src/corelib/io/qnoncontiguousbytedevice_p.h
index 4606ac2686..1e746db80f 100644
--- a/src/corelib/io/qnoncontiguousbytedevice_p.h
+++ b/src/corelib/io/qnoncontiguousbytedevice_p.h
@@ -90,8 +90,14 @@ class Q_CORE_EXPORT QNonContiguousByteDeviceFactory
{
public:
static QNonContiguousByteDevice* create(QIODevice *device);
+ static QSharedPointer<QNonContiguousByteDevice> createShared(QIODevice *device);
+
static QNonContiguousByteDevice* create(QByteArray *byteArray);
+ static QSharedPointer<QNonContiguousByteDevice> createShared(QByteArray *byteArray);
+
static QNonContiguousByteDevice* create(QSharedPointer<QRingBuffer> ringBuffer);
+ static QSharedPointer<QNonContiguousByteDevice> createShared(QSharedPointer<QRingBuffer> ringBuffer);
+
static QIODevice* wrap(QNonContiguousByteDevice* byteDevice);
};
diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp
index 2b901c7ccd..8be4125ef5 100644
--- a/src/corelib/io/qsavefile.cpp
+++ b/src/corelib/io/qsavefile.cpp
@@ -205,14 +205,32 @@ bool QSaveFile::open(OpenMode mode)
d->writeError = QFileDevice::WriteError;
return false;
}
- d->fileEngine = new QTemporaryFileEngine(d->fileName);
+
+ if (existingFile.isDir()) {
+ d->setError(QFileDevice::WriteError, QSaveFile::tr("Filename refers to a directory"));
+ d->writeError = QFileDevice::WriteError;
+ return false;
+ }
+
+ // Resolve symlinks. Don't use QFileInfo::canonicalFilePath so it still give the expected
+ // target even if the file does not exist
+ d->finalFileName = d->fileName;
+ if (existingFile.isSymLink()) {
+ int maxDepth = 128;
+ while (--maxDepth && existingFile.isSymLink())
+ existingFile.setFile(existingFile.symLinkTarget());
+ if (maxDepth > 0)
+ d->finalFileName = existingFile.filePath();
+ }
+
+ d->fileEngine = new QTemporaryFileEngine(d->finalFileName);
// Same as in QFile: QIODevice provides the buffering, so there's no need to request it from the file engine.
if (!d->fileEngine->open(mode | QIODevice::Unbuffered)) {
QFileDevice::FileError err = d->fileEngine->error();
#ifdef Q_OS_UNIX
if (d->directWriteFallback && err == QFileDevice::OpenError && errno == EACCES) {
delete d->fileEngine;
- d->fileEngine = QAbstractFileEngine::create(d->fileName);
+ d->fileEngine = QAbstractFileEngine::create(d->finalFileName);
if (d->fileEngine->open(mode | QIODevice::Unbuffered)) {
d->useTemporaryFile = false;
QFileDevice::open(mode);
@@ -285,7 +303,7 @@ bool QSaveFile::commit()
// atomically replace old file with new file
// Can't use QFile::rename for that, must use the file engine directly
Q_ASSERT(d->fileEngine);
- if (!d->fileEngine->renameOverwrite(d->fileName)) {
+ if (!d->fileEngine->renameOverwrite(d->finalFileName)) {
d->setError(d->fileEngine->error(), d->fileEngine->errorString());
d->fileEngine->remove();
delete d->fileEngine;
diff --git a/src/corelib/io/qsavefile_p.h b/src/corelib/io/qsavefile_p.h
index b9efd1ee7c..2134c4c9bc 100644
--- a/src/corelib/io/qsavefile_p.h
+++ b/src/corelib/io/qsavefile_p.h
@@ -70,6 +70,7 @@ protected:
~QSaveFilePrivate();
QString fileName;
+ QString finalFileName; // fileName with symbolic links resolved
QFileDevice::FileError writeError;
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index 1748170324..663ad3cc1b 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -53,6 +53,7 @@
#include "qmutex.h"
#include "qlibraryinfo.h"
#include "qtemporaryfile.h"
+#include "qstandardpaths.h"
#ifndef QT_NO_TEXTCODEC
# include "qtextcodec.h"
@@ -68,6 +69,11 @@
#include "qcoreapplication.h"
#endif
+#ifndef QT_BOOTSTRAPPED
+#include "qsavefile.h"
+#include "qlockfile.h"
+#endif
+
#ifdef Q_OS_VXWORKS
# include <ioLib.h>
#endif
@@ -101,12 +107,6 @@ using namespace ABI::Windows::Storage;
#define CSIDL_APPDATA 0x001a // <username>\Application Data
#endif
-#ifdef Q_AUTOTEST_EXPORT
-# define Q_AUTOTEST_EXPORT_HELPER Q_AUTOTEST_EXPORT
-#else
-# define Q_AUTOTEST_EXPORT_HELPER static
-#endif
-
// ************************************************************************
// QConfFile
@@ -141,101 +141,6 @@ static QBasicMutex settingsGlobalMutex;
static QSettings::Format globalDefaultFormat = QSettings::NativeFormat;
-#ifndef Q_OS_WIN
-inline bool qt_isEvilFsTypeName(const char *name)
-{
- return (qstrncmp(name, "nfs", 3) == 0
- || qstrncmp(name, "autofs", 6) == 0
- || qstrncmp(name, "cachefs", 7) == 0);
-}
-
-#if defined(Q_OS_BSD4) && !defined(Q_OS_NETBSD)
-QT_BEGIN_INCLUDE_NAMESPACE
-# include <sys/param.h>
-# include <sys/mount.h>
-QT_END_INCLUDE_NAMESPACE
-
-Q_AUTOTEST_EXPORT_HELPER bool qIsLikelyToBeNfs(int handle)
-{
- struct statfs buf;
- if (fstatfs(handle, &buf) != 0)
- return false;
- return qt_isEvilFsTypeName(buf.f_fstypename);
-}
-
-#elif defined(Q_OS_LINUX) || defined(Q_OS_HURD)
-QT_BEGIN_INCLUDE_NAMESPACE
-# include <sys/vfs.h>
-# ifdef QT_LINUXBASE
- // LSB 3.2 has fstatfs in sys/statfs.h, sys/vfs.h is just an empty dummy header
-# include <sys/statfs.h>
-# endif
-QT_END_INCLUDE_NAMESPACE
-# ifndef NFS_SUPER_MAGIC
-# define NFS_SUPER_MAGIC 0x00006969
-# endif
-# ifndef AUTOFS_SUPER_MAGIC
-# define AUTOFS_SUPER_MAGIC 0x00000187
-# endif
-# ifndef AUTOFSNG_SUPER_MAGIC
-# define AUTOFSNG_SUPER_MAGIC 0x7d92b1a0
-# endif
-
-Q_AUTOTEST_EXPORT_HELPER bool qIsLikelyToBeNfs(int handle)
-{
- struct statfs buf;
- if (fstatfs(handle, &buf) != 0)
- return false;
- return buf.f_type == NFS_SUPER_MAGIC
- || buf.f_type == AUTOFS_SUPER_MAGIC
- || buf.f_type == AUTOFSNG_SUPER_MAGIC;
-}
-
-#elif defined(Q_OS_SOLARIS) || defined(Q_OS_IRIX) || defined(Q_OS_AIX) || defined(Q_OS_HPUX) \
- || defined(Q_OS_OSF) || defined(Q_OS_QNX) || defined(Q_OS_SCO) \
- || defined(Q_OS_UNIXWARE) || defined(Q_OS_RELIANT) || defined(Q_OS_NETBSD)
-QT_BEGIN_INCLUDE_NAMESPACE
-# include <sys/statvfs.h>
-QT_END_INCLUDE_NAMESPACE
-
-Q_AUTOTEST_EXPORT_HELPER bool qIsLikelyToBeNfs(int handle)
-{
- struct statvfs buf;
- if (fstatvfs(handle, &buf) != 0)
- return false;
-#if defined(Q_OS_NETBSD)
- return qt_isEvilFsTypeName(buf.f_fstypename);
-#else
- return qt_isEvilFsTypeName(buf.f_basetype);
-#endif
-}
-#else
-Q_AUTOTEST_EXPORT_HELPER inline bool qIsLikelyToBeNfs(int /* handle */)
-{
- return true;
-}
-#endif
-
-static bool unixLock(int handle, int lockType)
-{
- /*
- NFS hangs on the fcntl() call below when statd or lockd isn't
- running. There's no way to detect this. Our work-around for
- now is to disable locking when we detect NFS (or AutoFS or
- CacheFS, which are probably wrapping NFS).
- */
- if (qIsLikelyToBeNfs(handle))
- return false;
-
- struct flock fl;
- fl.l_whence = SEEK_SET;
- fl.l_start = 0;
- fl.l_len = 0;
- fl.l_type = lockType;
- return fcntl(handle, F_SETLKW, &fl) == 0;
-}
-#endif
-
QConfFile::QConfFile(const QString &fileName, bool _userPerms)
: name(fileName), size(0), ref(1), userPerms(_userPerms)
{
@@ -1140,6 +1045,8 @@ static void initDefaultPaths(QMutexLocker *locker)
pathHash->insert(pathHashKey(QSettings::IniFormat, QSettings::SystemScope),
windowsConfigPath(CSIDL_COMMON_APPDATA) + QDir::separator());
#else
+
+#ifdef QT_NO_STANDARDPATHS
QString userPath;
char *env = getenv("XDG_CONFIG_HOME");
if (env == 0) {
@@ -1153,6 +1060,9 @@ static void initDefaultPaths(QMutexLocker *locker)
userPath += QLatin1Char('/');
userPath += QFile::decodeName(env);
}
+#else
+ QString userPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
+#endif
userPath += QLatin1Char('/');
pathHash->insert(pathHashKey(QSettings::IniFormat, QSettings::UserScope), userPath);
@@ -1457,105 +1367,30 @@ void QConfFileSettingsPrivate::syncConfFile(int confFileNo)
return;
}
+#ifndef QT_BOOTSTRAPPED
/*
- Open the configuration file and try to use it using a named
- semaphore on Windows and an advisory lock on Unix-based
- systems. This protect us against other QSettings instances
- trying to access the same file from other threads or
- processes.
-
- As it stands now, the locking mechanism doesn't work for
- .plist files.
- */
- QFile file(confFile->name);
- bool createFile = !file.exists();
- if (!readOnly && confFile->isWritable())
- file.open(QFile::ReadWrite);
- if (!file.isOpen())
- file.open(QFile::ReadOnly);
-
- if (!createFile && !file.isOpen())
- setStatus(QSettings::AccessError);
-
-#ifdef Q_OS_WIN
- HANDLE readSemaphore = 0;
- HANDLE writeSemaphore = 0;
- static const int FileLockSemMax = 50;
- int numReadLocks = readOnly ? 1 : FileLockSemMax;
-
- if (file.isOpen()) {
- // Acquire the write lock if we will be writing
- if (!readOnly) {
- QString writeSemName = QLatin1String("QSettingsWriteSem ");
- writeSemName.append(file.fileName());
-
-#ifndef Q_OS_WINRT
- writeSemaphore = CreateSemaphore(0, 1, 1, reinterpret_cast<const wchar_t *>(writeSemName.utf16()));
-#else
- writeSemaphore = CreateSemaphoreEx(0, 1, 1, reinterpret_cast<const wchar_t *>(writeSemName.utf16()), 0, SEMAPHORE_ALL_ACCESS);
-#endif
+ Use a lockfile in order to protect us against other QSettings instances
+ trying to write the same settings at the same time.
- if (writeSemaphore) {
-#ifndef Q_OS_WINRT
- WaitForSingleObject(writeSemaphore, INFINITE);
-#else
- WaitForSingleObjectEx(writeSemaphore, INFINITE, FALSE);
-#endif
- } else {
- setStatus(QSettings::AccessError);
- return;
- }
- }
-
- // Acquire all the read locks if we will be writing, to make sure nobody
- // reads while we're writing. If we are only reading, acquire a single
- // read lock.
- QString readSemName(QLatin1String("QSettingsReadSem "));
- readSemName.append(file.fileName());
-
-#ifndef Q_OS_WINRT
- readSemaphore = CreateSemaphore(0, FileLockSemMax, FileLockSemMax, reinterpret_cast<const wchar_t *>(readSemName.utf16()));
-#else
- readSemaphore = CreateSemaphoreEx(0, FileLockSemMax, FileLockSemMax, reinterpret_cast<const wchar_t *>(readSemName.utf16()), 0, SEMAPHORE_ALL_ACCESS);
-#endif
-
- if (readSemaphore) {
- for (int i = 0; i < numReadLocks; ++i)
-#ifndef Q_OS_WINRT
- WaitForSingleObject(readSemaphore, INFINITE);
-#else
- WaitForSingleObjectEx(readSemaphore, INFINITE, FALSE);
-#endif
- } else {
+ We only need to lock if we are actually writing as only concurrent writes are a problem.
+ Concurrent read and write are not a problem because the writing operation is atomic.
+ */
+ QLockFile lockFile(confFile->name + QLatin1String(".lock"));
+ if (!readOnly) {
+ if (!confFile->isWritable() || !lockFile.lock() ) {
setStatus(QSettings::AccessError);
- if (writeSemaphore != 0) {
- ReleaseSemaphore(writeSemaphore, 1, 0);
- CloseHandle(writeSemaphore);
- }
return;
}
}
-#else
- if (file.isOpen())
- unixLock(file.handle(), readOnly ? F_RDLCK : F_WRLCK);
#endif
- // If we have created the file, apply the file perms
- if (file.isOpen()) {
- if (createFile) {
- QFile::Permissions perms = file.permissions() | QFile::ReadOwner | QFile::WriteOwner;
- if (!confFile->userPerms)
- perms |= QFile::ReadGroup | QFile::ReadOther;
- file.setPermissions(perms);
- }
- }
-
/*
We hold the lock. Let's reread the file if it has changed
since last time we read it.
*/
QFileInfo fileInfo(confFile->name);
bool mustReadFile = true;
+ bool createFile = !fileInfo.exists();
if (!readOnly)
mustReadFile = (confFile->size != fileInfo.size()
@@ -1565,6 +1400,12 @@ void QConfFileSettingsPrivate::syncConfFile(int confFileNo)
confFile->unparsedIniSections.clear();
confFile->originalKeys.clear();
+ QFile file(confFile->name);
+ if (!createFile && !file.open(QFile::ReadOnly)) {
+ setStatus(QSettings::AccessError);
+ return;
+ }
+
/*
Files that we can't read (because of permissions or
because they don't exist) are treated as empty files.
@@ -1615,42 +1456,40 @@ void QConfFileSettingsPrivate::syncConfFile(int confFileNo)
ensureAllSectionsParsed(confFile);
ParsedSettingsMap mergedKeys = confFile->mergedKeyMap();
- if (file.isWritable()) {
#ifdef Q_OS_MAC
- if (format == QSettings::NativeFormat) {
- ok = writePlistFile(confFile->name, mergedKeys);
- } else
+ if (format == QSettings::NativeFormat) {
+ ok = writePlistFile(confFile->name, mergedKeys);
+ } else
#endif
- {
- file.seek(0);
- file.resize(0);
+ {
+#ifndef QT_BOOTSTRAPPED
+ QSaveFile sf(confFile->name);
+#else
+ QFile sf(confFile->name);
+#endif
+ if (!sf.open(QIODevice::WriteOnly)) {
+ setStatus(QSettings::AccessError);
+ ok = false;
+ } else if (format <= QSettings::IniFormat) {
+ ok = writeIniFile(sf, mergedKeys);
+ } else {
+ if (writeFunc) {
+ QSettings::SettingsMap tempOriginalKeys;
- if (format <= QSettings::IniFormat) {
- ok = writeIniFile(file, mergedKeys);
- if (!ok) {
- // try to restore old data; might work if the disk was full and the new data
- // was larger than the old data
- file.seek(0);
- file.resize(0);
- writeIniFile(file, confFile->originalKeys);
+ ParsedSettingsMap::const_iterator i = mergedKeys.constBegin();
+ while (i != mergedKeys.constEnd()) {
+ tempOriginalKeys.insert(i.key(), i.value());
+ ++i;
}
+ ok = writeFunc(sf, tempOriginalKeys);
} else {
- if (writeFunc) {
- QSettings::SettingsMap tempOriginalKeys;
-
- ParsedSettingsMap::const_iterator i = mergedKeys.constBegin();
- while (i != mergedKeys.constEnd()) {
- tempOriginalKeys.insert(i.key(), i.value());
- ++i;
- }
- ok = writeFunc(file, tempOriginalKeys);
- } else {
- ok = false;
- }
+ ok = false;
}
}
- } else {
- ok = false;
+#ifndef QT_BOOTSTRAPPED
+ if (ok)
+ ok = sf.commit();
+#endif
}
if (ok) {
@@ -1662,24 +1501,18 @@ void QConfFileSettingsPrivate::syncConfFile(int confFileNo)
QFileInfo fileInfo(confFile->name);
confFile->size = fileInfo.size();
confFile->timeStamp = fileInfo.lastModified();
+
+ // If we have created the file, apply the file perms
+ if (createFile) {
+ QFile::Permissions perms = fileInfo.permissions() | QFile::ReadOwner | QFile::WriteOwner;
+ if (!confFile->userPerms)
+ perms |= QFile::ReadGroup | QFile::ReadOther;
+ QFile(confFile->name).setPermissions(perms);
+ }
} else {
setStatus(QSettings::AccessError);
}
}
-
- /*
- Release the file lock.
- */
-#ifdef Q_OS_WIN
- if (readSemaphore != 0) {
- ReleaseSemaphore(readSemaphore, numReadLocks, 0);
- CloseHandle(readSemaphore);
- }
- if (writeSemaphore != 0) {
- ReleaseSemaphore(writeSemaphore, 1, 0);
- CloseHandle(writeSemaphore);
- }
-#endif
}
enum { Space = 0x1, Special = 0x2 };
@@ -2505,12 +2338,6 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
10.8 (Mountain Lion), only root can. However, 10.9 (Mavericks) changes
that rule again but only for the native format (plist files).
- \li On Unix and Mac OS X systems, the advisory file locking is disabled
- if NFS (or AutoFS or CacheFS) is detected to work around a bug in the
- NFS fcntl() implementation, which hangs forever if statd or lockd aren't
- running. Also, the locking isn't performed when accessing \c .plist
- files.
-
\li On the BlackBerry platform, applications run in a sandbox. They are not
allowed to read or write outside of this sandbox. This involves the
following limitations:
diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp
index bd9fa68d93..8c47ad1391 100644
--- a/src/corelib/io/qstandardpaths.cpp
+++ b/src/corelib/io/qstandardpaths.cpp
@@ -117,10 +117,9 @@ QT_BEGIN_NAMESPACE
\value HomeLocation Returns the user's home directory (the same as QDir::homePath()). On Unix
systems, this is equal to the HOME environment variable. This value might be
generic or application-specific, but the returned path is never empty.
- \value DataLocation Returns a directory location where persistent
- application data can be stored. This is an application-specific directory. To obtain a
- path to store data to be shared with other applications, use
- QStandardPaths::GenericDataLocation. The returned path is never empty.
+ \value DataLocation Returns the same value as AppLocalDataLocation. This enumeration value
+ is deprecated. Using AppDataLocation is preferable since on Windows, the roaming path is
+ recommended.
\value CacheLocation Returns a directory location where user-specific
non-essential (cached) data should be written. This is an application-specific directory.
The returned path is never empty.
@@ -142,6 +141,15 @@ QT_BEGIN_NAMESPACE
\value GenericConfigLocation Returns a directory location where user-specific
configuration files shared between multiple applications should be written.
This is a generic value and the returned path is never empty.
+ \value AppDataLocation Returns a directory location where persistent
+ application data can be stored. This is an application-specific directory.
+ To obtain a path to store data to be shared with other applications, use
+ QStandardPaths::GenericDataLocation. The returned path is never empty.
+ On the Windows operating system, this returns the roaming path.
+ This enum value was added in Qt 5.4.
+ \value AppLocalDataLocation Returns the local settings path on the Windows operating
+ system. On all other platforms, it returns the same value as AppDataLocation.
+ This enum value was added in Qt 5.4.
The following table gives examples of paths on different operating systems.
The first path is the writable path (unless noted). Other, additional
@@ -200,6 +208,12 @@ QT_BEGIN_NAMESPACE
\row \li GenericCacheLocation
\li "~/Library/Caches", "/Library/Caches"
\li "C:/Users/<USER>/AppData/Local/cache"
+ \row \li AppDataLocation
+ \li "~/Library/Application Support/<APPNAME>", "/Library/Application Support/<APPNAME>". "<APPDIR>/../Resources"
+ \li "C:/Users/<USER>/AppData/Roaming/<APPNAME>", "C:/ProgramData/<APPNAME>", "<APPDIR>", "<APPDIR>/data"
+ \row \li AppLocalDataLocation
+ \li "~/Library/Application Support/<APPNAME>", "/Library/Application Support/<APPNAME>". "<APPDIR>/../Resources"
+ \li "C:/Users/<USER>/AppData/Local/<APPNAME>", "C:/ProgramData/<APPNAME>", "<APPDIR>", "<APPDIR>/data"
\endtable
\table
@@ -255,6 +269,12 @@ QT_BEGIN_NAMESPACE
\row \li GenericCacheLocation
\li "<APPROOT>/data/Cache" (there is no shared cache)
\li "~/.cache"
+ \row \li AppDataLocation
+ \li "<APPROOT>/data", "<APPROOT>/app/native/assets"
+ \li "~/.local/share/<APPNAME>", "/usr/local/share/<APPNAME>", "/usr/share/<APPNAME>"
+ \row \li AppLocalDataLocation
+ \li "<APPROOT>/data", "<APPROOT>/app/native/assets"
+ \li "~/.local/share/<APPNAME>", "/usr/local/share/<APPNAME>", "/usr/share/<APPNAME>"
\endtable
\table
@@ -293,6 +313,8 @@ QT_BEGIN_NAMESPACE
\li "<USER>/Downloads", "<USER>/<APPNAME>/Downloads"
\row \li GenericCacheLocation
\li "<APPROOT>/cache" (there is no shared cache)
+ \row \li AppDataLocation
+ \li "<APPROOT>/files", "<USER>/<APPNAME>/files"
\endtable
In the table above, \c <APPNAME> is usually the organization name, the
@@ -534,8 +556,6 @@ QString QStandardPaths::displayName(StandardLocation type)
return QCoreApplication::translate("QStandardPaths", "Temporary Directory");
case HomeLocation:
return QCoreApplication::translate("QStandardPaths", "Home");
- case DataLocation:
- return QCoreApplication::translate("QStandardPaths", "Application Data");
case CacheLocation:
return QCoreApplication::translate("QStandardPaths", "Cache");
case GenericDataLocation:
@@ -550,6 +570,9 @@ QString QStandardPaths::displayName(StandardLocation type)
return QCoreApplication::translate("QStandardPaths", "Shared Cache");
case DownloadLocation:
return QCoreApplication::translate("QStandardPaths", "Download");
+ case AppDataLocation:
+ case AppLocalDataLocation:
+ return QCoreApplication::translate("QStandardPaths", "Application Data");
}
// not reached
return QString();
diff --git a/src/corelib/io/qstandardpaths.h b/src/corelib/io/qstandardpaths.h
index 08d6d7b50c..b93adbf156 100644
--- a/src/corelib/io/qstandardpaths.h
+++ b/src/corelib/io/qstandardpaths.h
@@ -70,7 +70,9 @@ public:
ConfigLocation,
DownloadLocation,
GenericCacheLocation,
- GenericConfigLocation
+ GenericConfigLocation,
+ AppDataLocation,
+ AppLocalDataLocation = DataLocation
};
static QString writableLocation(StandardLocation type);
diff --git a/src/corelib/io/qstandardpaths_android.cpp b/src/corelib/io/qstandardpaths_android.cpp
index 60b285a3d6..9bd4b4b428 100644
--- a/src/corelib/io/qstandardpaths_android.cpp
+++ b/src/corelib/io/qstandardpaths_android.cpp
@@ -244,7 +244,8 @@ QString QStandardPaths::writableLocation(StandardLocation type)
return getFilesDir() + testDir() + QLatin1String("/settings");
case QStandardPaths::GenericDataLocation:
return getExternalStorageDirectory() + testDir();
- case QStandardPaths::DataLocation:
+ case QStandardPaths::AppDataLocation:
+ case QStandardPaths::AppLocalDataLocation:
return getFilesDir() + testDir();
case QStandardPaths::GenericCacheLocation:
case QStandardPaths::RuntimeLocation:
@@ -301,7 +302,7 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
<< getExternalFilesDir("DIRECTORY_DOWNLOADS");
}
- if (type == DataLocation) {
+ if (type == AppDataLocation || type == AppLocalDataLocation) {
return QStringList() << writableLocation(type)
<< getExternalFilesDir();
}
diff --git a/src/corelib/io/qstandardpaths_blackberry.cpp b/src/corelib/io/qstandardpaths_blackberry.cpp
index ec2e61bd15..2e9d62cd05 100644
--- a/src/corelib/io/qstandardpaths_blackberry.cpp
+++ b/src/corelib/io/qstandardpaths_blackberry.cpp
@@ -63,7 +63,8 @@ QString QStandardPaths::writableLocation(StandardLocation type)
const QString sharedRoot = sharedDir.absolutePath();
switch (type) {
- case DataLocation:
+ case AppDataLocation:
+ case AppLocalDataLocation:
return QDir::homePath() + testModeInsert();
case DesktopLocation:
case HomeLocation:
@@ -108,7 +109,7 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
if (type == FontsLocation)
return QStringList(QLatin1String("/base/usr/fonts"));
- if (type == DataLocation)
+ if (type == AppDataLocation || type == AppLocalDataLocation)
dirs.append(QDir::homePath() + testModeInsert() + QLatin1String("native/assets"));
const QString localDir = writableLocation(type);
diff --git a/src/corelib/io/qstandardpaths_ios.mm b/src/corelib/io/qstandardpaths_ios.mm
index e2100045a6..cdca28b8b5 100644
--- a/src/corelib/io/qstandardpaths_ios.mm
+++ b/src/corelib/io/qstandardpaths_ios.mm
@@ -90,7 +90,8 @@ QString QStandardPaths::writableLocation(StandardLocation type)
case HomeLocation:
location = bundlePath();
break;
- case DataLocation:
+ case AppDataLocation:
+ case AppLocalDataLocation:
case GenericDataLocation:
location = pathForDirectory(NSDocumentDirectory);
break;
diff --git a/src/corelib/io/qstandardpaths_mac.cpp b/src/corelib/io/qstandardpaths_mac.cpp
index aff9112fb7..a27920899c 100644
--- a/src/corelib/io/qstandardpaths_mac.cpp
+++ b/src/corelib/io/qstandardpaths_mac.cpp
@@ -83,7 +83,8 @@ OSType translateLocation(QStandardPaths::StandardLocation type)
return kTemporaryFolderType;
case QStandardPaths::GenericDataLocation:
case QStandardPaths::RuntimeLocation:
- case QStandardPaths::DataLocation:
+ case QStandardPaths::AppDataLocation:
+ case QStandardPaths::AppLocalDataLocation:
return kApplicationSupportFolderType;
case QStandardPaths::GenericCacheLocation:
case QStandardPaths::CacheLocation:
@@ -128,7 +129,7 @@ static QString macLocation(QStandardPaths::StandardLocation type, short domain)
QString path = getFullPath(ref);
- if (type == QStandardPaths::DataLocation || type == QStandardPaths::CacheLocation)
+ if (type == QStandardPaths::AppDataLocation || type == QStandardPaths::AppLocalDataLocation || type == QStandardPaths::CacheLocation)
appendOrganizationAndApp(path);
return path;
}
@@ -140,9 +141,10 @@ QString QStandardPaths::writableLocation(StandardLocation type)
QString path;
switch (type) {
case GenericDataLocation:
- case DataLocation:
+ case AppDataLocation:
+ case AppLocalDataLocation:
path = qttestDir + QLatin1String("/Application Support");
- if (type == DataLocation)
+ if (type != GenericDataLocation)
appendOrganizationAndApp(path);
return path;
case GenericCacheLocation:
@@ -165,7 +167,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
case TempLocation:
return QDir::tempPath();
case GenericDataLocation:
- case DataLocation:
+ case AppLocalDataLocation:
case GenericCacheLocation:
case CacheLocation:
case RuntimeLocation:
@@ -179,13 +181,13 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
{
QStringList dirs;
- if (type == GenericDataLocation || type == DataLocation || type == GenericCacheLocation || type == CacheLocation) {
+ if (type == GenericDataLocation || type == AppDataLocation || type == AppLocalDataLocation || type == GenericCacheLocation || type == CacheLocation) {
const QString path = macLocation(type, kOnAppropriateDisk);
if (!path.isEmpty())
dirs.append(path);
}
- if (type == DataLocation) {
+ if (type == AppDataLocation || type == AppLocalDataLocation) {
CFBundleRef mainBundle = CFBundleGetMainBundle();
if (mainBundle) {
CFURLRef bundleUrl = CFBundleCopyBundleURL(mainBundle);
diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp
index e2ed7c3766..cde1e4bc72 100644
--- a/src/corelib/io/qstandardpaths_unix.cpp
+++ b/src/corelib/io/qstandardpaths_unix.cpp
@@ -90,7 +90,8 @@ QString QStandardPaths::writableLocation(StandardLocation type)
appendOrganizationAndApp(xdgCacheHome);
return xdgCacheHome;
}
- case DataLocation:
+ case AppDataLocation:
+ case AppLocalDataLocation:
case GenericDataLocation:
{
QString xdgDataHome = QFile::decodeName(qgetenv("XDG_DATA_HOME"));
@@ -98,7 +99,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
xdgDataHome = QDir::homePath() + QLatin1String("/.qttest/share");
if (xdgDataHome.isEmpty())
xdgDataHome = QDir::homePath() + QLatin1String("/.local/share");
- if (type == QStandardPaths::DataLocation)
+ if (type == AppDataLocation || type == AppLocalDataLocation)
appendOrganizationAndApp(xdgDataHome);
return xdgDataHome;
}
@@ -305,7 +306,8 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
for (int i = 0; i < dirs.count(); ++i)
dirs[i].append(QLatin1String("/applications"));
break;
- case DataLocation:
+ case AppDataLocation:
+ case AppLocalDataLocation:
dirs = xdgDataDirs();
for (int i = 0; i < dirs.count(); ++i)
appendOrganizationAndApp(dirs[i]);
diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp
index 062ab49207..aaa390ac34 100644
--- a/src/corelib/io/qstandardpaths_win.cpp
+++ b/src/corelib/io/qstandardpaths_win.cpp
@@ -81,6 +81,18 @@ static QString convertCharArray(const wchar_t *path)
return QDir::fromNativeSeparators(QString::fromWCharArray(path));
}
+static inline int clsidForAppDataLocation(QStandardPaths::StandardLocation type)
+{
+#ifndef Q_OS_WINCE
+ return type == QStandardPaths::AppDataLocation ?
+ CSIDL_APPDATA : // "Roaming" path
+ CSIDL_LOCAL_APPDATA; // Local path
+#else
+ Q_UNUSED(type)
+ return CSIDL_APPDATA;
+#endif
+}
+
QString QStandardPaths::writableLocation(StandardLocation type)
{
QString result;
@@ -92,15 +104,12 @@ QString QStandardPaths::writableLocation(StandardLocation type)
wchar_t path[MAX_PATH];
switch (type) {
- case ConfigLocation: // same as DataLocation, on Windows (oversight, but too late to fix it)
- case GenericConfigLocation: // same as GenericDataLocation, on Windows
- case DataLocation:
+ case ConfigLocation: // same as AppLocalDataLocation, on Windows
+ case GenericConfigLocation: // same as GenericDataLocation on Windows
+ case AppDataLocation:
+ case AppLocalDataLocation:
case GenericDataLocation:
-#if defined Q_OS_WINCE
- if (SHGetSpecialFolderPath(0, path, CSIDL_APPDATA, FALSE))
-#else
- if (SHGetSpecialFolderPath(0, path, CSIDL_LOCAL_APPDATA, FALSE))
-#endif
+ if (SHGetSpecialFolderPath(0, path, clsidForAppDataLocation(type), FALSE))
result = convertCharArray(path);
if (isTestModeEnabled())
result += QLatin1String("/qttest");
@@ -165,7 +174,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
// Although Microsoft has a Cache key it is a pointer to IE's cache, not a cache
// location for everyone. Most applications seem to be using a
// cache directory located in their AppData directory
- return writableLocation(DataLocation) + QLatin1String("/cache");
+ return writableLocation(AppLocalDataLocation) + QLatin1String("/cache");
case GenericCacheLocation:
return writableLocation(GenericDataLocation) + QLatin1String("/cache");
@@ -192,11 +201,12 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
{
wchar_t path[MAX_PATH];
switch (type) {
- case ConfigLocation: // same as DataLocation, on Windows (oversight, but too late to fix it)
+ case ConfigLocation: // same as AppLocalDataLocation, on Windows (oversight, but too late to fix it)
case GenericConfigLocation: // same as GenericDataLocation, on Windows
- case DataLocation:
+ case AppDataLocation:
+ case AppLocalDataLocation:
case GenericDataLocation:
- if (SHGetSpecialFolderPath(0, path, CSIDL_COMMON_APPDATA, FALSE)) {
+ if (SHGetSpecialFolderPath(0, path, clsidForAppDataLocation(type), FALSE)) {
QString result = convertCharArray(path);
if (type != GenericDataLocation && type != GenericConfigLocation) {
#ifndef QT_BOOTSTRAPPED
diff --git a/src/corelib/io/qstandardpaths_winrt.cpp b/src/corelib/io/qstandardpaths_winrt.cpp
index feafdf2e7c..81b9d10baf 100644
--- a/src/corelib/io/qstandardpaths_winrt.cpp
+++ b/src/corelib/io/qstandardpaths_winrt.cpp
@@ -73,9 +73,10 @@ QString QStandardPaths::writableLocation(StandardLocation type)
QString result;
switch (type) {
- case ConfigLocation: // same as DataLocation, on Windows
+ case ConfigLocation: // same as AppLocalDataLocation, on Windows
case GenericConfigLocation: // same as GenericDataLocation, on Windows
- case DataLocation:
+ case AppDataLocation:
+ case AppLocalDataLocation:
case GenericDataLocation: {
ComPtr<IApplicationDataStatics> applicationDataStatics;
if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_ApplicationData).Get(), &applicationDataStatics)))
@@ -98,7 +99,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
break;
}
case CacheLocation:
- return writableLocation(DataLocation) + QLatin1String("/cache");
+ return writableLocation(AppLocalDataLocation) + QLatin1String("/cache");
case GenericCacheLocation:
return writableLocation(GenericDataLocation) + QLatin1String("/cache");
diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
index 3cade0ed25..bc6c2f1f06 100644
--- a/src/corelib/io/qtemporaryfile.cpp
+++ b/src/corelib/io/qtemporaryfile.cpp
@@ -235,6 +235,8 @@ static bool createFileFromTemplate(NativeFileHandle &file,
//************* QTemporaryFileEngine
QTemporaryFileEngine::~QTemporaryFileEngine()
{
+ Q_D(QFSFileEngine);
+ d->unmapAll();
QFSFileEngine::close();
}
@@ -363,6 +365,7 @@ bool QTemporaryFileEngine::remove()
Q_D(QFSFileEngine);
// Since the QTemporaryFileEngine::close() does not really close the file,
// we must explicitly call QFSFileEngine::close() before we remove it.
+ d->unmapAll();
QFSFileEngine::close();
if (QFSFileEngine::remove()) {
d->fileEntry.clear();
diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp
index 288a939ab2..4002ce8694 100644
--- a/src/corelib/io/qtextstream.cpp
+++ b/src/corelib/io/qtextstream.cpp
@@ -2203,7 +2203,7 @@ void QTextStreamPrivate::putNumber(qulonglong number, bool negative)
// add thousands group separators. For backward compatibility we
// don't add a group separator for C locale.
- if (locale != QLocale::c())
+ if (locale != QLocale::c() && !locale.numberOptions().testFlag(QLocale::OmitGroupSeparator))
flags |= QLocaleData::ThousandsGroup;
const QLocaleData *dd = locale.d->m_data;
@@ -2414,6 +2414,8 @@ QTextStream &QTextStream::operator<<(double f)
flags |= QLocaleData::CapitalEorX;
if (numberFlags() & ForcePoint)
flags |= QLocaleData::Alternate;
+ if (locale() != QLocale::c() && !(locale().numberOptions() & QLocale::OmitGroupSeparator))
+ flags |= QLocaleData::ThousandsGroup;
const QLocaleData *dd = d->locale.d->m_data;
QString num = dd->doubleToString(f, d->params.realNumberPrecision, form, -1, flags);
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index 7018b333f2..51c48b88d7 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -364,6 +364,29 @@
*/
/*!
+ \enum QUrl::UserInputResolutionOption
+ \since 5.4
+
+ The user input resolution options define how fromUserInput() should
+ interpret strings that could either be a relative path or the short
+ form of a HTTP URL. For instance \c{file.pl} can be either a local file
+ or the URL \c{http://file.pl}.
+
+ \value DefaultResolution The default resolution mechanism is to check
+ whether a local file exists, in the working
+ directory given to fromUserInput, and only
+ return a local path in that case. Otherwise a URL
+ is assumed.
+ \value AssumeLocalFile This option makes fromUserInput() always return
+ a local path unless the input contains a scheme, such as
+ \c{http://file.pl}. This is useful for applications
+ such as text editors, which are able to create
+ the file if it doesn't exist.
+
+ \sa fromUserInput()
+*/
+
+/*!
\fn QUrl::QUrl(QUrl &&other)
Move-constructs a QUrl instance, making it point at the same
@@ -3715,11 +3738,15 @@ bool QUrl::isDetached() const
"//servername/path/to/file.txt". Note that only certain platforms can
actually open this file using QFile::open().
+ An empty \a localFile leads to an empty URL (since Qt 5.4).
+
\sa toLocalFile(), isLocalFile(), QDir::toNativeSeparators()
*/
QUrl QUrl::fromLocalFile(const QString &localFile)
{
QUrl url;
+ if (localFile.isEmpty())
+ return url;
url.setScheme(fileScheme());
QString deslashified = QDir::fromNativeSeparators(localFile);
@@ -4095,6 +4122,43 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Returns a valid URL from a user supplied \a userInput string if one can be
deducted. In the case that is not possible, an invalid QUrl() is returned.
+ This overload takes a \a workingDirectory path, in order to be able to
+ handle relative paths. This is especially useful when handling command
+ line arguments.
+ If \a workingDirectory is empty, no handling of relative paths will be done,
+ so this method will behave like its one argument overload.
+
+ By default, an input string that looks like a relative path will only be treated
+ as such if the file actually exists in the given working directory.
+
+ If the application can handle files that don't exist yet, it should pass the
+ flag AssumeLocalFile in \a options.
+
+ \since 5.4
+*/
+QUrl QUrl::fromUserInput(const QString &userInput, const QString &workingDirectory,
+ UserInputResolutionOptions options)
+{
+ QString trimmedString = userInput.trimmed();
+
+ if (trimmedString.isEmpty())
+ return QUrl();
+
+ // Check both QUrl::isRelative (to detect full URLs) and QDir::isAbsolutePath (since on Windows drive letters can be interpreted as schemes)
+ QUrl url = QUrl(trimmedString, QUrl::TolerantMode);
+ if (url.isRelative() && !QDir::isAbsolutePath(trimmedString)) {
+ QFileInfo fileInfo(QDir(workingDirectory), trimmedString);
+ if ((options & AssumeLocalFile) || fileInfo.exists())
+ return QUrl::fromLocalFile(fileInfo.absoluteFilePath());
+ }
+
+ return fromUserInput(trimmedString);
+}
+
+/*!
+ Returns a valid URL from a user supplied \a userInput string if one can be
+ deducted. In the case that is not possible, an invalid QUrl() is returned.
+
\since 4.6
Most applications that can browse the web, allow the user to input a URL
diff --git a/src/corelib/io/qurl.h b/src/corelib/io/qurl.h
index 602e91ce30..d621d7ef03 100644
--- a/src/corelib/io/qurl.h
+++ b/src/corelib/io/qurl.h
@@ -199,7 +199,16 @@ public:
QByteArray toEncoded(FormattingOptions options = FullyEncoded) const;
static QUrl fromEncoded(const QByteArray &url, ParsingMode mode = TolerantMode);
+ enum UserInputResolutionOption {
+ DefaultResolution,
+ AssumeLocalFile
+ };
+ Q_DECLARE_FLAGS(UserInputResolutionOptions, UserInputResolutionOption)
+
static QUrl fromUserInput(const QString &userInput);
+ // ### Qt6 merge with fromUserInput(QString), by adding = QString()
+ static QUrl fromUserInput(const QString &userInput, const QString &workingDirectory,
+ UserInputResolutionOptions options = DefaultResolution);
bool isValid() const;
QString errorString() const;
diff --git a/src/corelib/io/qwinoverlappedionotifier.cpp b/src/corelib/io/qwinoverlappedionotifier.cpp
index 33583afb78..06746c0597 100644
--- a/src/corelib/io/qwinoverlappedionotifier.cpp
+++ b/src/corelib/io/qwinoverlappedionotifier.cpp
@@ -41,6 +41,7 @@
#include "qwinoverlappedionotifier_p.h"
#include <qdebug.h>
+#include <qelapsedtimer.h>
#include <qmutex.h>
#include <qpointer.h>
#include <qqueue.h>
@@ -293,35 +294,58 @@ void QWinOverlappedIoNotifier::setEnabled(bool enabled)
}
/*!
- * Wait synchronously for the notified signal.
+ * Wait synchronously for any notified signal.
*
- * The function returns true if the notified signal was emitted for
- * the I/O operation that corresponds to the OVERLAPPED object.
+ * The function returns a pointer to the OVERLAPPED object corresponding to the completed I/O
+ * operation. In case no I/O operation was completed during the \a msec timeout, this function
+ * returns a null pointer.
*/
-bool QWinOverlappedIoNotifier::waitForNotified(int msecs, OVERLAPPED *overlapped)
+OVERLAPPED *QWinOverlappedIoNotifier::waitForAnyNotified(int msecs)
{
Q_D(QWinOverlappedIoNotifier);
if (!d->iocp->isRunning()) {
- qWarning("Called QWinOverlappedIoNotifier::waitForNotified on inactive notifier.");
- return false;
+ qWarning("Called QWinOverlappedIoNotifier::waitForAnyNotified on inactive notifier.");
+ return 0;
}
+ if (msecs == 0)
+ d->iocp->drainQueue();
+
+ switch (WaitForSingleObject(d->hSemaphore, msecs == -1 ? INFINITE : DWORD(msecs))) {
+ case WAIT_OBJECT_0:
+ ReleaseSemaphore(d->hSemaphore, 1, NULL);
+ return d->_q_notified();
+ case WAIT_TIMEOUT:
+ return 0;
+ default:
+ qErrnoWarning("QWinOverlappedIoNotifier::waitForAnyNotified: WaitForSingleObject failed.");
+ return 0;
+ }
+}
+
+/*!
+ * Wait synchronously for the notified signal.
+ *
+ * The function returns true if the notified signal was emitted for
+ * the I/O operation that corresponds to the OVERLAPPED object.
+ */
+bool QWinOverlappedIoNotifier::waitForNotified(int msecs, OVERLAPPED *overlapped)
+{
+ int t = msecs;
+ QElapsedTimer stopWatch;
+ stopWatch.start();
forever {
- if (msecs == 0)
- d->iocp->drainQueue();
- DWORD result = WaitForSingleObject(d->hSemaphore, msecs == -1 ? INFINITE : DWORD(msecs));
- if (result == WAIT_OBJECT_0) {
- ReleaseSemaphore(d->hSemaphore, 1, NULL);
- if (d->_q_notified() == overlapped)
- return true;
- continue;
- } else if (result == WAIT_TIMEOUT) {
+ OVERLAPPED *triggeredOverlapped = waitForAnyNotified(t);
+ if (!triggeredOverlapped)
return false;
+ if (triggeredOverlapped == overlapped)
+ return true;
+ if (msecs != -1) {
+ t = msecs - stopWatch.elapsed();
+ if (t < 0)
+ return false;
}
}
-
- qErrnoWarning("QWinOverlappedIoNotifier::waitForNotified: WaitForSingleObject failed.");
- return false;
}
/*!
diff --git a/src/corelib/io/qwinoverlappedionotifier_p.h b/src/corelib/io/qwinoverlappedionotifier_p.h
index f90fd2e615..25c0f3a081 100644
--- a/src/corelib/io/qwinoverlappedionotifier_p.h
+++ b/src/corelib/io/qwinoverlappedionotifier_p.h
@@ -76,6 +76,7 @@ public:
Qt::HANDLE handle() const;
void setEnabled(bool enabled);
+ OVERLAPPED *waitForAnyNotified(int msecs);
bool waitForNotified(int msecs, OVERLAPPED *overlapped);
Q_SIGNALS: