summaryrefslogtreecommitdiffstats
path: root/src/corelib/io
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io')
-rw-r--r--src/corelib/io/forkfd_qt.cpp82
-rw-r--r--src/corelib/io/io.pri9
-rw-r--r--src/corelib/io/qbuffer.cpp4
-rw-r--r--src/corelib/io/qbuffer.h22
-rw-r--r--src/corelib/io/qdatastream.cpp1
-rw-r--r--src/corelib/io/qdatastream.h5
-rw-r--r--src/corelib/io/qdebug.cpp168
-rw-r--r--src/corelib/io/qdebug.h101
-rw-r--r--src/corelib/io/qdir.cpp29
-rw-r--r--src/corelib/io/qfile.h12
-rw-r--r--src/corelib/io/qfiledevice.h18
-rw-r--r--src/corelib/io/qfiledevice_p.h2
-rw-r--r--src/corelib/io/qfileselector.cpp37
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp57
-rw-r--r--src/corelib/io/qfilesystementry.cpp8
-rw-r--r--src/corelib/io/qfilesystemwatcher.cpp20
-rw-r--r--src/corelib/io/qfilesystemwatcher_inotify_p.h4
-rw-r--r--src/corelib/io/qfilesystemwatcher_polling_p.h4
-rw-r--r--src/corelib/io/qfsfileengine_iterator_p.h8
-rw-r--r--src/corelib/io/qfsfileengine_p.h68
-rw-r--r--src/corelib/io/qiodevice.cpp210
-rw-r--r--src/corelib/io/qiodevice_p.h4
-rw-r--r--src/corelib/io/qipaddress.cpp3
-rw-r--r--src/corelib/io/qloggingcategory.cpp75
-rw-r--r--src/corelib/io/qloggingcategory.h19
-rw-r--r--src/corelib/io/qloggingregistry.cpp11
-rw-r--r--src/corelib/io/qnoncontiguousbytedevice.cpp29
-rw-r--r--src/corelib/io/qnoncontiguousbytedevice_p.h55
-rw-r--r--src/corelib/io/qprocess.cpp31
-rw-r--r--src/corelib/io/qprocess.h20
-rw-r--r--src/corelib/io/qprocess_p.h20
-rw-r--r--src/corelib/io/qprocess_unix.cpp533
-rw-r--r--src/corelib/io/qresource.cpp22
-rw-r--r--src/corelib/io/qresource_iterator_p.h6
-rw-r--r--src/corelib/io/qresource_p.h60
-rw-r--r--src/corelib/io/qsettings.cpp5
-rw-r--r--src/corelib/io/qsettings.h2
-rw-r--r--src/corelib/io/qsettings_p.h18
-rw-r--r--src/corelib/io/qstandardpaths.cpp16
-rw-r--r--src/corelib/io/qstandardpaths.h1
-rw-r--r--src/corelib/io/qstandardpaths_android.cpp1
-rw-r--r--src/corelib/io/qstandardpaths_blackberry.cpp1
-rw-r--r--src/corelib/io/qstandardpaths_haiku.cpp222
-rw-r--r--src/corelib/io/qstandardpaths_ios.mm1
-rw-r--r--src/corelib/io/qstandardpaths_mac.mm10
-rw-r--r--src/corelib/io/qstandardpaths_unix.cpp31
-rw-r--r--src/corelib/io/qstandardpaths_win.cpp2
-rw-r--r--src/corelib/io/qstandardpaths_winrt.cpp1
-rw-r--r--src/corelib/io/qstorageinfo_p.h6
-rw-r--r--src/corelib/io/qstorageinfo_unix.cpp7
-rw-r--r--src/corelib/io/qstorageinfo_win.cpp8
-rw-r--r--src/corelib/io/qtemporaryfile.cpp1
-rw-r--r--src/corelib/io/qtemporaryfile.h4
-rw-r--r--src/corelib/io/qtextstream.cpp155
-rw-r--r--src/corelib/io/qtextstream.h2
-rw-r--r--src/corelib/io/qtextstream_p.h8
-rw-r--r--src/corelib/io/qtldurl.cpp2
-rw-r--r--src/corelib/io/qurl.h8
-rw-r--r--src/corelib/io/qurlrecode.cpp4
59 files changed, 1389 insertions, 884 deletions
diff --git a/src/corelib/io/forkfd_qt.cpp b/src/corelib/io/forkfd_qt.cpp
new file mode 100644
index 0000000000..dbfeda7895
--- /dev/null
+++ b/src/corelib/io/forkfd_qt.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Intel Corporation
+** 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$
+**
+****************************************************************************/
+
+// these might be defined via precompiled headers
+#ifndef _POSIX_C_SOURCE
+# define _POSIX_C_SOURCE 200809L
+#endif
+#if !defined(_XOPEN_SOURCE) && !defined(__QNXNTO__)
+# define _XOPEN_SOURCE 500
+#endif
+
+#include <QtCore/qatomic.h>
+
+#if defined(QT_NO_DEBUG) && !defined(NDEBUG)
+# define NDEBUG
+#endif
+
+typedef QT_PREPEND_NAMESPACE(QBasicAtomicInt) ffd_atomic_int;
+#define ffd_atomic_pointer(type) QT_PREPEND_NAMESPACE(QBasicAtomicPointer<type>)
+
+QT_BEGIN_NAMESPACE
+
+#define FFD_ATOMIC_INIT(val) Q_BASIC_ATOMIC_INITIALIZER(val)
+
+#define FFD_ATOMIC_RELAXED Relaxed
+#define FFD_ATOMIC_ACQUIRE Acquire
+#define FFD_ATOMIC_RELEASE Release
+#define loadRelaxed load
+#define storeRelaxed store
+
+#define FFD_CONCAT(x, y) x ## y
+
+#define ffd_atomic_load(ptr,order) (ptr)->FFD_CONCAT(load, order)()
+#define ffd_atomic_store(ptr,val,order) (ptr)->FFD_CONCAT(store, order)(val)
+#define ffd_atomic_exchange(ptr,val,order) (ptr)->FFD_CONCAT(fetchAndStore, order)(val)
+#define ffd_atomic_compare_exchange(ptr,expected,desired,order1,order2) \
+ (ptr)->FFD_CONCAT(testAndSet, order1)(*expected, desired, *expected)
+#define ffd_atomic_add_fetch(ptr,val,order) ((ptr)->FFD_CONCAT(fetchAndAdd, order)(val) + val)
+
+QT_END_NAMESPACE
+
+extern "C" {
+#include "../../3rdparty/forkfd/forkfd.c"
+}
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri
index 77788e3cca..78349fbc49 100644
--- a/src/corelib/io/io.pri
+++ b/src/corelib/io/io.pri
@@ -137,6 +137,10 @@ win32 {
io/qlockfile_unix.cpp \
io/qprocess_unix.cpp \
io/qfilesystemiterator_unix.cpp \
+ io/forkfd_qt.cpp
+ HEADERS += \
+ ../3rdparty/forkfd/forkfd.h
+ INCLUDEPATH += ../3rdparty/forkfd
!nacl:mac: {
SOURCES += io/qsettings_mac.cpp
@@ -165,6 +169,11 @@ win32 {
SOURCES += \
io/qstandardpaths_android.cpp \
io/qstorageinfo_unix.cpp
+ } else:haiku {
+ SOURCES += \
+ io/qstandardpaths_haiku.cpp \
+ io/qstorageinfo_unix.cpp
+ LIBS += -lbe
} else {
SOURCES += \
io/qstandardpaths_unix.cpp \
diff --git a/src/corelib/io/qbuffer.cpp b/src/corelib/io/qbuffer.cpp
index 5377eb21e3..200d6a0c0c 100644
--- a/src/corelib/io/qbuffer.cpp
+++ b/src/corelib/io/qbuffer.cpp
@@ -54,8 +54,8 @@ public:
QByteArray *buf;
QByteArray defaultBuf;
- virtual qint64 peek(char *data, qint64 maxSize);
- virtual QByteArray peek(qint64 maxSize);
+ virtual qint64 peek(char *data, qint64 maxSize) Q_DECL_OVERRIDE;
+ virtual QByteArray peek(qint64 maxSize) Q_DECL_OVERRIDE;
#ifndef QT_NO_QOBJECT
// private slots
diff --git a/src/corelib/io/qbuffer.h b/src/corelib/io/qbuffer.h
index 24b05aad13..56c80f8a7d 100644
--- a/src/corelib/io/qbuffer.h
+++ b/src/corelib/io/qbuffer.h
@@ -67,22 +67,22 @@ public:
inline void setData(const char *data, int len);
const QByteArray &data() const;
- bool open(OpenMode openMode);
+ bool open(OpenMode openMode) Q_DECL_OVERRIDE;
- void close();
- qint64 size() const;
- qint64 pos() const;
- bool seek(qint64 off);
- bool atEnd() const;
- bool canReadLine() const;
+ void close() Q_DECL_OVERRIDE;
+ qint64 size() const Q_DECL_OVERRIDE;
+ qint64 pos() const Q_DECL_OVERRIDE;
+ bool seek(qint64 off) Q_DECL_OVERRIDE;
+ bool atEnd() const Q_DECL_OVERRIDE;
+ bool canReadLine() const Q_DECL_OVERRIDE;
protected:
#ifndef QT_NO_QOBJECT
- void connectNotify(const QMetaMethod &);
- void disconnectNotify(const QMetaMethod &);
+ void connectNotify(const QMetaMethod &) Q_DECL_OVERRIDE;
+ void disconnectNotify(const QMetaMethod &) Q_DECL_OVERRIDE;
#endif
- qint64 readData(char *data, qint64 maxlen);
- qint64 writeData(const char *data, qint64 len);
+ qint64 readData(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
+ qint64 writeData(const char *data, qint64 len) Q_DECL_OVERRIDE;
private:
Q_DECLARE_PRIVATE(QBuffer)
diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp
index beaafe4762..60f04ce4f1 100644
--- a/src/corelib/io/qdatastream.cpp
+++ b/src/corelib/io/qdatastream.cpp
@@ -525,6 +525,7 @@ void QDataStream::setByteOrder(ByteOrder bo)
\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)
+ \value Qt_5_5 Same as Qt_5_4
\omitvalue Qt_DefaultCompiledVersion
\sa setVersion(), version()
diff --git a/src/corelib/io/qdatastream.h b/src/corelib/io/qdatastream.h
index 75ffa11543..8e1d777011 100644
--- a/src/corelib/io/qdatastream.h
+++ b/src/corelib/io/qdatastream.h
@@ -82,10 +82,11 @@ public:
Qt_5_2 = 15,
Qt_5_3 = Qt_5_2,
Qt_5_4 = 16,
-#if QT_VERSION >= 0x050500
+ Qt_5_5 = Qt_5_4,
+#if QT_VERSION >= 0x050600
#error Add the datastream version for this Qt version and update Qt_DefaultCompiledVersion
#endif
- Qt_DefaultCompiledVersion = Qt_5_4
+ Qt_DefaultCompiledVersion = Qt_5_5
};
enum ByteOrder {
diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp
index 5c77ccdcbf..ad61621a93 100644
--- a/src/corelib/io/qdebug.cpp
+++ b/src/corelib/io/qdebug.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Intel Corporation.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -40,9 +41,13 @@
#include "qdebug.h"
#include <private/qtextstream_p.h>
+#include <private/qtools_p.h>
QT_BEGIN_NAMESPACE
+using QtMiscUtils::toHexUpper;
+using QtMiscUtils::fromHex;
+
// This file is needed to force compilation of QDebug into the kernel library.
/*!
@@ -148,6 +153,167 @@ QDebug::~QDebug()
}
/*!
+ \internal
+*/
+void QDebug::putUcs4(uint ucs4)
+{
+ maybeQuote('\'');
+ if (ucs4 < 0x20) {
+ stream->ts << hex << "\\x" << ucs4 << reset;
+ } else if (ucs4 < 0x80) {
+ stream->ts << char(ucs4);
+ } else {
+ stream->ts << hex << qSetPadChar(QLatin1Char('0'));
+ if (ucs4 < 0x10000)
+ stream->ts << qSetFieldWidth(4) << "\\u";
+ else
+ stream->ts << qSetFieldWidth(8) << "\\U";
+ stream->ts << ucs4 << reset;
+ }
+ maybeQuote('\'');
+}
+
+template <typename Char>
+static inline void putEscapedString(QTextStreamPrivate *d, const Char *begin, int length, bool isUnicode = true)
+{
+ QChar quote(QLatin1Char('"'));
+ d->write(&quote, 1);
+
+ bool lastWasHexEscape = false;
+ const Char *end = begin + length;
+ for (const Char *p = begin; p != end; ++p) {
+ // check if we need to insert "" to break an hex escape sequence
+ if (Q_UNLIKELY(lastWasHexEscape)) {
+ if (fromHex(*p) != -1) {
+ // yes, insert it
+ QChar quotes[] = { QLatin1Char('"'), QLatin1Char('"') };
+ d->write(quotes, 2);
+ }
+ lastWasHexEscape = false;
+ }
+
+ if (sizeof(Char) == sizeof(QChar)) {
+ int runLength = 0;
+ while (p + runLength != end &&
+ p[runLength] < 0x7f && p[runLength] >= 0x20 && p[runLength] != '\\' && p[runLength] != '"')
+ ++runLength;
+ if (runLength) {
+ d->write(reinterpret_cast<const QChar *>(p), runLength);
+ p += runLength - 1;
+ continue;
+ }
+ } else if (*p < 0x7f && *p >= 0x20 && *p != '\\' && *p != '"') {
+ QChar c = QLatin1Char(*p);
+ d->write(&c, 1);
+ continue;
+ }
+
+ // print as an escape sequence
+ int buflen = 2;
+ ushort buf[sizeof "\\U12345678" - 1];
+ buf[0] = '\\';
+
+ switch (*p) {
+ case '"':
+ case '\\':
+ buf[1] = *p;
+ break;
+ case '\b':
+ buf[1] = 'b';
+ break;
+ case '\f':
+ buf[1] = 'f';
+ break;
+ case '\n':
+ buf[1] = 'n';
+ break;
+ case '\r':
+ buf[1] = 'r';
+ break;
+ case '\t':
+ buf[1] = 't';
+ break;
+ default:
+ if (!isUnicode) {
+ // print as hex escape
+ buf[1] = 'x';
+ buf[2] = toHexUpper(uchar(*p) >> 4);
+ buf[3] = toHexUpper(uchar(*p));
+ buflen = 4;
+ lastWasHexEscape = true;
+ break;
+ }
+ if (QChar::isHighSurrogate(*p)) {
+ if ((p + 1) != end && QChar::isLowSurrogate(p[1])) {
+ // properly-paired surrogates
+ uint ucs4 = QChar::surrogateToUcs4(*p, p[1]);
+ ++p;
+ buf[1] = 'U';
+ buf[2] = '0'; // toHexUpper(ucs4 >> 32);
+ buf[3] = '0'; // toHexUpper(ucs4 >> 28);
+ buf[4] = toHexUpper(ucs4 >> 20);
+ buf[5] = toHexUpper(ucs4 >> 16);
+ buf[6] = toHexUpper(ucs4 >> 12);
+ buf[7] = toHexUpper(ucs4 >> 8);
+ buf[8] = toHexUpper(ucs4 >> 4);
+ buf[9] = toHexUpper(ucs4);
+ buflen = 10;
+ break;
+ }
+ // improperly-paired surrogates, fall through
+ }
+ buf[1] = 'u';
+ buf[2] = toHexUpper(ushort(*p) >> 12);
+ buf[3] = toHexUpper(ushort(*p) >> 8);
+ buf[4] = toHexUpper(*p >> 4);
+ buf[5] = toHexUpper(*p);
+ buflen = 6;
+ }
+ d->write(reinterpret_cast<QChar *>(buf), buflen);
+ }
+
+ d->write(&quote, 1);
+}
+
+/*!
+ \internal
+ Duplicated from QtTest::toPrettyUnicode().
+*/
+void QDebug::putString(const QChar *begin, size_t length)
+{
+ if (stream->testFlag(Stream::NoQuotes)) {
+ // no quotes, write the string directly too (no pretty-printing)
+ // this respects the QTextStream state, though
+ stream->ts.d_ptr->putString(begin, length);
+ } else {
+ // we'll reset the QTextStream formatting mechanisms, so save the state
+ QDebugStateSaver saver(*this);
+ stream->ts.d_ptr->params.reset();
+ putEscapedString(stream->ts.d_ptr.data(), reinterpret_cast<const ushort *>(begin), length);
+ }
+}
+
+/*!
+ \internal
+ Duplicated from QtTest::toPrettyCString().
+*/
+void QDebug::putByteArray(const char *begin, size_t length, Latin1Content content)
+{
+ if (stream->testFlag(Stream::NoQuotes)) {
+ // no quotes, write the string directly too (no pretty-printing)
+ // this respects the QTextStream state, though
+ QString string = content == ContainsLatin1 ? QString::fromLatin1(begin, length) : QString::fromUtf8(begin, length);
+ stream->ts.d_ptr->putString(string);
+ } else {
+ // we'll reset the QTextStream formatting mechanisms, so save the state
+ QDebugStateSaver saver(*this);
+ stream->ts.d_ptr->params.reset();
+ putEscapedString(stream->ts.d_ptr.data(), reinterpret_cast<const uchar *>(begin),
+ length, content == ContainsLatin1);
+ }
+}
+
+/*!
\fn QDebug::swap(QDebug &other)
\since 5.0
diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h
index 4edb3057fb..27abf2a740 100644
--- a/src/corelib/io/qdebug.h
+++ b/src/corelib/io/qdebug.h
@@ -76,6 +76,12 @@ class Q_CORE_EXPORT QDebug
// added in 5.4
int flags;
} *stream;
+
+ enum Latin1Content { ContainsBinary = 0, ContainsLatin1 };
+
+ void putUcs4(uint ucs4);
+ void putString(const QChar *begin, size_t length);
+ void putByteArray(const char *begin, size_t length, Latin1Content content);
public:
inline QDebug(QIODevice *device) : stream(new Stream(device)) {}
inline QDebug(QString *string) : stream(new Stream(string)) {}
@@ -83,7 +89,7 @@ public:
inline QDebug(const QDebug &o):stream(o.stream) { ++stream->ref; }
inline QDebug &operator=(const QDebug &other);
~QDebug();
- inline void swap(QDebug &other) { qSwap(stream, other.stream); }
+ inline void swap(QDebug &other) Q_DECL_NOTHROW { qSwap(stream, other.stream); }
QDebug &resetFormat();
@@ -98,11 +104,15 @@ public:
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<<(QChar t) { putUcs4(t.unicode()); 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(); }
inline QDebug &operator<<(unsigned short t) { stream->ts << t; return maybeSpace(); }
+#ifdef Q_COMPILER_UNICODE_STRINGS
+ inline QDebug &operator<<(char16_t t) { return *this << QChar(t); }
+ inline QDebug &operator<<(char32_t t) { putUcs4(t); return maybeSpace(); }
+#endif
inline QDebug &operator<<(signed int t) { stream->ts << t; return maybeSpace(); }
inline QDebug &operator<<(unsigned int t) { stream->ts << t; return maybeSpace(); }
inline QDebug &operator<<(signed long t) { stream->ts << t; return maybeSpace(); }
@@ -112,11 +122,14 @@ 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) { maybeQuote(); stream->ts << t; maybeQuote(); return maybeSpace(); }
- inline QDebug &operator<<(const QStringRef & t) { return operator<<(t.toString()); }
- 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 QString & t) { putString(t.constData(), uint(t.length())); return maybeSpace(); }
+ inline QDebug &operator<<(const QStringRef & t) { putString(t.constData(), uint(t.length())); return maybeSpace(); }
+ inline QDebug &operator<<(QLatin1String t) { putByteArray(t.latin1(), t.size(), ContainsLatin1); return maybeSpace(); }
+ inline QDebug &operator<<(const QByteArray & t) { putByteArray(t.constData(), t.size(), ContainsBinary); return maybeSpace(); }
inline QDebug &operator<<(const void * t) { stream->ts << t; return maybeSpace(); }
+#ifdef Q_COMPILER_NULLPTR
+ inline QDebug &operator<<(std::nullptr_t) { stream->ts << "(nullptr)"; return maybeSpace(); }
+#endif
inline QDebug &operator<<(QTextStreamFunction f) {
stream->ts << f;
return *this;
@@ -268,6 +281,82 @@ inline QDebug operator<<(QDebug debug, const QFlags<T> &flags)
return debug;
}
+#ifdef Q_OS_MAC
+
+// We provide QDebug stream operators for commonly used Core Foundation
+// and Core Graphics types, as well as NSObject. Additional CF/CG types
+// may be added by the user, using Q_DECLARE_QDEBUG_OPERATOR_FOR_CF_TYPE.
+
+#define QT_FOR_EACH_CORE_FOUNDATION_TYPE(F) \
+ F(CFArray) \
+ F(CFURL) \
+ F(CFData) \
+ F(CFNumber) \
+ F(CFDictionary) \
+ F(CFLocale) \
+ F(CFDate) \
+ F(CFBoolean) \
+ F(CFTimeZone) \
+
+#define QT_FOR_EACH_MUTABLE_CORE_FOUNDATION_TYPE(F) \
+ F(CFError) \
+ F(CFBundle) \
+
+#define QT_FOR_EACH_CORE_GRAPHICS_TYPE(F) \
+ F(CGPath) \
+
+#define QT_FOR_EACH_MUTABLE_CORE_GRAPHICS_TYPE(F) \
+ F(CGColorSpace) \
+ F(CGImage) \
+ F(CGFont) \
+ F(CGColor) \
+
+#define QT_FORWARD_DECLARE_CF_TYPE(type) Q_FORWARD_DECLARE_CF_TYPE(type);
+#define QT_FORWARD_DECLARE_MUTABLE_CF_TYPE(type) Q_FORWARD_DECLARE_MUTABLE_CF_TYPE(type);
+#define QT_FORWARD_DECLARE_CG_TYPE(type) typedef const struct type *type ## Ref;
+#define QT_FORWARD_DECLARE_MUTABLE_CG_TYPE(type) typedef struct type *type ## Ref;
+
+QT_END_NAMESPACE
+Q_FORWARD_DECLARE_CF_TYPE(CFString);
+Q_FORWARD_DECLARE_OBJC_CLASS(NSObject);
+QT_FOR_EACH_CORE_FOUNDATION_TYPE(QT_FORWARD_DECLARE_CF_TYPE);
+QT_FOR_EACH_MUTABLE_CORE_FOUNDATION_TYPE(QT_FORWARD_DECLARE_MUTABLE_CF_TYPE);
+QT_FOR_EACH_CORE_GRAPHICS_TYPE(QT_FORWARD_DECLARE_CG_TYPE);
+QT_FOR_EACH_MUTABLE_CORE_GRAPHICS_TYPE(QT_FORWARD_DECLARE_MUTABLE_CG_TYPE);
+QT_BEGIN_NAMESPACE
+
+#define QT_FORWARD_DECLARE_QDEBUG_OPERATOR_FOR_CF_TYPE(CFType) \
+ Q_CORE_EXPORT QDebug operator<<(QDebug, CFType##Ref);
+
+#define Q_DECLARE_QDEBUG_OPERATOR_FOR_CF_TYPE(CFType) \
+ QDebug operator<<(QDebug debug, CFType##Ref ref) \
+ { \
+ if (!ref) \
+ return debug << QT_STRINGIFY(CFType) "Ref(0x0)"; \
+ if (CFStringRef description = CFCopyDescription(ref)) { \
+ QDebugStateSaver saver(debug); \
+ debug.noquote() << description; \
+ CFRelease(description); \
+ } \
+ return debug; \
+ }
+
+// Defined in qcore_mac_objc.mm
+Q_CORE_EXPORT QDebug operator<<(QDebug, const NSObject *);
+Q_CORE_EXPORT QDebug operator<<(QDebug, CFStringRef);
+
+QT_FOR_EACH_CORE_FOUNDATION_TYPE(QT_FORWARD_DECLARE_QDEBUG_OPERATOR_FOR_CF_TYPE);
+QT_FOR_EACH_MUTABLE_CORE_FOUNDATION_TYPE(QT_FORWARD_DECLARE_QDEBUG_OPERATOR_FOR_CF_TYPE);
+QT_FOR_EACH_CORE_GRAPHICS_TYPE(QT_FORWARD_DECLARE_QDEBUG_OPERATOR_FOR_CF_TYPE);
+QT_FOR_EACH_MUTABLE_CORE_GRAPHICS_TYPE(QT_FORWARD_DECLARE_QDEBUG_OPERATOR_FOR_CF_TYPE);
+
+#undef QT_FORWARD_DECLARE_CF_TYPE
+#undef QT_FORWARD_DECLARE_MUTABLE_CF_TYPE
+#undef QT_FORWARD_DECLARE_CG_TYPE
+#undef QT_FORWARD_DECLARE_MUTABLE_CG_TYPE
+
+#endif // Q_OS_MAC
+
QT_END_NAMESPACE
#endif // QDEBUG_H
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index a5e189a825..92f2fc0815 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -2271,6 +2271,8 @@ QStringList QDir::nameFiltersFromString(const QString &nameFilter)
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, QDir::Filters filters)
{
+ QDebugStateSaver save(debug);
+ debug.resetFormat();
QStringList flags;
if (filters == QDir::NoFilter) {
flags << QLatin1String("NoFilter");
@@ -2291,12 +2293,14 @@ QDebug operator<<(QDebug debug, QDir::Filters filters)
if (filters & QDir::System) flags << QLatin1String("System");
if (filters & QDir::CaseSensitive) flags << QLatin1String("CaseSensitive");
}
- debug << "QDir::Filters(" << qPrintable(flags.join(QLatin1Char('|'))) << ')';
+ debug.noquote() << "QDir::Filters(" << flags.join(QLatin1Char('|')) << ')';
return debug;
}
static QDebug operator<<(QDebug debug, QDir::SortFlags sorting)
{
+ QDebugStateSaver save(debug);
+ debug.resetFormat();
if (sorting == QDir::NoSort) {
debug << "QDir::SortFlags(NoSort)";
} else {
@@ -2312,24 +2316,23 @@ static QDebug operator<<(QDebug debug, QDir::SortFlags sorting)
if (sorting & QDir::IgnoreCase) flags << QLatin1String("IgnoreCase");
if (sorting & QDir::LocaleAware) flags << QLatin1String("LocaleAware");
if (sorting & QDir::Type) flags << QLatin1String("Type");
- debug << "QDir::SortFlags(" << qPrintable(type)
- << '|'
- << qPrintable(flags.join(QLatin1Char('|'))) << ')';
+ debug.noquote() << "QDir::SortFlags(" << type << '|' << flags.join(QLatin1Char('|')) << ')';
}
return debug;
}
QDebug operator<<(QDebug debug, const QDir &dir)
{
- debug.maybeSpace() << "QDir(" << dir.path()
- << ", nameFilters = {"
- << qPrintable(dir.nameFilters().join(QLatin1Char(',')))
- << "}, "
- << dir.sorting()
- << ','
- << dir.filter()
- << ')';
- return debug.space();
+ QDebugStateSaver save(debug);
+ debug.resetFormat();
+ debug << "QDir(" << dir.path() << ", nameFilters = {"
+ << dir.nameFilters().join(QLatin1Char(','))
+ << "}, "
+ << dir.sorting()
+ << ','
+ << dir.filter()
+ << ')';
+ return debug;
}
#endif // QT_NO_DEBUG_STREAM
diff --git a/src/corelib/io/qfile.h b/src/corelib/io/qfile.h
index 75f246da96..3c44ee3397 100644
--- a/src/corelib/io/qfile.h
+++ b/src/corelib/io/qfile.h
@@ -63,7 +63,7 @@ public:
#endif
~QFile();
- QString fileName() const;
+ QString fileName() const Q_DECL_OVERRIDE;
void setFileName(const QString &name);
#if defined(Q_OS_DARWIN)
@@ -116,18 +116,18 @@ public:
bool copy(const QString &newName);
static bool copy(const QString &fileName, const QString &newName);
- bool open(OpenMode flags);
+ bool open(OpenMode flags) Q_DECL_OVERRIDE;
bool open(FILE *f, OpenMode ioFlags, FileHandleFlags handleFlags=DontCloseHandle);
bool open(int fd, OpenMode ioFlags, FileHandleFlags handleFlags=DontCloseHandle);
- qint64 size() const;
+ qint64 size() const Q_DECL_OVERRIDE;
- bool resize(qint64 sz);
+ bool resize(qint64 sz) Q_DECL_OVERRIDE;
static bool resize(const QString &filename, qint64 sz);
- Permissions permissions() const;
+ Permissions permissions() const Q_DECL_OVERRIDE;
static Permissions permissions(const QString &filename);
- bool setPermissions(Permissions permissionSpec);
+ bool setPermissions(Permissions permissionSpec) Q_DECL_OVERRIDE;
static bool setPermissions(const QString &filename, Permissions permissionSpec);
protected:
diff --git a/src/corelib/io/qfiledevice.h b/src/corelib/io/qfiledevice.h
index b79b0055fa..ca12bb0411 100644
--- a/src/corelib/io/qfiledevice.h
+++ b/src/corelib/io/qfiledevice.h
@@ -86,19 +86,19 @@ public:
FileError error() const;
void unsetError();
- virtual void close();
+ virtual void close() Q_DECL_OVERRIDE;
- bool isSequential() const;
+ bool isSequential() const Q_DECL_OVERRIDE;
int handle() const;
virtual QString fileName() const;
- qint64 pos() const;
- bool seek(qint64 offset);
- bool atEnd() const;
+ qint64 pos() const Q_DECL_OVERRIDE;
+ bool seek(qint64 offset) Q_DECL_OVERRIDE;
+ bool atEnd() const Q_DECL_OVERRIDE;
bool flush();
- qint64 size() const;
+ qint64 size() const Q_DECL_OVERRIDE;
virtual bool resize(qint64 sz);
virtual Permissions permissions() const;
@@ -122,9 +122,9 @@ protected:
QFileDevice(QFileDevicePrivate &dd, QObject *parent = 0);
#endif
- qint64 readData(char *data, qint64 maxlen);
- qint64 writeData(const char *data, qint64 len);
- qint64 readLineData(char *data, qint64 maxlen);
+ qint64 readData(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
+ qint64 writeData(const char *data, qint64 len) Q_DECL_OVERRIDE;
+ qint64 readLineData(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
private:
Q_DISABLE_COPY(QFileDevice)
diff --git a/src/corelib/io/qfiledevice_p.h b/src/corelib/io/qfiledevice_p.h
index 891a5e4be4..da29c51468 100644
--- a/src/corelib/io/qfiledevice_p.h
+++ b/src/corelib/io/qfiledevice_p.h
@@ -64,7 +64,7 @@ protected:
inline bool ensureFlushed() const;
- bool putCharHelper(char c);
+ bool putCharHelper(char c) Q_DECL_OVERRIDE;
void setError(QFileDevice::FileError err);
void setError(QFileDevice::FileError err, const QString &errorString);
diff --git a/src/corelib/io/qfileselector.cpp b/src/corelib/io/qfileselector.cpp
index 5d1d5dfe23..b95e628b0f 100644
--- a/src/corelib/io/qfileselector.cpp
+++ b/src/corelib/io/qfileselector.cpp
@@ -145,7 +145,9 @@ QFileSelectorPrivate::QFileSelectorPrivate()
Selectors normally available are
\list
\li platform, any of the following strings which match the platform the application is running
- on: android, blackberry, ios, osx, darwin, mac, linux, wince, unix, windows.
+ on (list not exhaustive): android, blackberry, ios, osx, darwin, mac, linux, wince, unix,
+ windows. On Linux, if it can be determined, the name of the distribution too, like debian,
+ fedora or opensuse.
\li locale, same as QLocale::system().name().
\endlist
@@ -335,7 +337,7 @@ void QFileSelectorPrivate::updateSelectors()
if (envSelectors.count())
sharedData->staticSelectors << envSelectors;
- if (!qgetenv(env_override).isEmpty())
+ if (!qEnvironmentVariableIsEmpty(env_override))
return;
sharedData->staticSelectors << sharedData->preloadedStatics; //Potential for static selectors from other modules
@@ -351,10 +353,10 @@ QStringList QFileSelectorPrivate::platformSelectors()
// similar, but not identical to QSysInfo::osType
QStringList ret;
#if defined(Q_OS_WIN)
+ // can't fall back to QSysInfo because we need both "winphone" and "winrt" for the Windows Phone case
ret << QStringLiteral("windows");
-# if defined(Q_OS_WINCE)
- ret << QStringLiteral("wince");
-# elif defined(Q_OS_WINRT)
+ ret << QSysInfo::kernelType(); // "wince" and "winnt"
+# if defined(Q_OS_WINRT)
ret << QStringLiteral("winrt");
# if defined(Q_OS_WINPHONE)
ret << QStringLiteral("winphone");
@@ -362,25 +364,16 @@ QStringList QFileSelectorPrivate::platformSelectors()
# endif
#elif defined(Q_OS_UNIX)
ret << QStringLiteral("unix");
-# if defined(Q_OS_ANDROID)
- ret << QStringLiteral("android");
-# elif defined(Q_OS_BLACKBERRY)
- ret << QStringLiteral("blackberry");
-# elif defined(Q_OS_QNX)
- ret << QStringLiteral("qnx");
-# elif defined(Q_OS_LINUX)
- ret << QStringLiteral("linux");
-# elif defined(Q_OS_DARWIN)
- ret << QStringLiteral("darwin");
- ret << QStringLiteral("mac"); // compatibility synonym
-# if defined(Q_OS_IOS)
- ret << QStringLiteral("ios");
-# elif defined(Q_OS_OSX)
- ret << QStringLiteral("osx");
-# endif
-# else
+# if !defined(Q_OS_ANDROID) && !defined(Q_OS_BLACKBERRY)
+ // we don't want "linux" for Android or "qnx" for Blackberry here
ret << QSysInfo::kernelType();
+# ifdef Q_OS_MAC
+ ret << QStringLiteral("mac"); // compatibility, since kernelType() is "darwin"
+# endif
# endif
+ QString productName = QSysInfo::productType();
+ if (productName != QLatin1String("unknown"))
+ ret << productName; // "opensuse", "fedora", "osx", "ios", "blackberry", "android"
#endif
return ret;
}
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index bfa4483ca7..10326dea06 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -250,6 +250,26 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry,
return QFileSystemEntry(ret);
}
}
+
+# elif defined(Q_OS_ANDROID)
+ // On some Android versions, realpath() will return a path even if it does not exist
+ // To work around this, we check existence in advance.
+ if (!data.hasFlags(QFileSystemMetaData::ExistsAttribute))
+ fillMetaData(entry, data, QFileSystemMetaData::ExistsAttribute);
+
+ if (!data.exists()) {
+ ret = 0;
+ errno = ENOENT;
+ } else {
+ ret = (char*)malloc(PATH_MAX + 1);
+ if (realpath(entry.nativeFilePath().constData(), (char*)ret) == 0) {
+ const int savedErrno = errno; // errno is checked below, and free() might change it
+ free(ret);
+ errno = savedErrno;
+ ret = 0;
+ }
+ }
+
# else
# if _POSIX_VERSION >= 200801L
ret = realpath(entry.nativeFilePath().constData(), (char*)0);
@@ -723,36 +743,29 @@ bool QFileSystemEngine::setCurrentPath(const QFileSystemEntry &path)
QFileSystemEntry QFileSystemEngine::currentPath()
{
QFileSystemEntry result;
- QT_STATBUF st;
- if (QT_STAT(".", &st) == 0) {
#if defined(__GLIBC__) && !defined(PATH_MAX)
- char *currentName = ::get_current_dir_name();
- if (currentName) {
- result = QFileSystemEntry(QByteArray(currentName), QFileSystemEntry::FromNativePath());
- ::free(currentName);
- }
+ char *currentName = ::get_current_dir_name();
+ if (currentName) {
+ result = QFileSystemEntry(QByteArray(currentName), QFileSystemEntry::FromNativePath());
+ ::free(currentName);
+ }
#else
- char currentName[PATH_MAX+1];
- if (::getcwd(currentName, PATH_MAX)) {
+ char currentName[PATH_MAX+1];
+ if (::getcwd(currentName, PATH_MAX)) {
#if defined(Q_OS_VXWORKS) && defined(VXWORKS_VXSIM)
- QByteArray dir(currentName);
- if (dir.indexOf(':') < dir.indexOf('/'))
- dir.remove(0, dir.indexOf(':')+1);
+ QByteArray dir(currentName);
+ if (dir.indexOf(':') < dir.indexOf('/'))
+ dir.remove(0, dir.indexOf(':')+1);
- qstrncpy(currentName, dir.constData(), PATH_MAX);
+ qstrncpy(currentName, dir.constData(), PATH_MAX);
#endif
- result = QFileSystemEntry(QByteArray(currentName), QFileSystemEntry::FromNativePath());
- }
+ result = QFileSystemEntry(QByteArray(currentName), QFileSystemEntry::FromNativePath());
+ }
# if defined(QT_DEBUG)
- if (result.isEmpty())
- qWarning("QFileSystemEngine::currentPath: getcwd() failed");
+ if (result.isEmpty())
+ qWarning("QFileSystemEngine::currentPath: getcwd() failed");
# endif
#endif
- } else {
-# if defined(QT_DEBUG)
- qWarning("QFileSystemEngine::currentPath: stat(\".\") failed");
-# endif
- }
return result;
}
QT_END_NAMESPACE
diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp
index 8e48dd1630..69c0e08763 100644
--- a/src/corelib/io/qfilesystementry.cpp
+++ b/src/corelib/io/qfilesystementry.cpp
@@ -315,13 +315,7 @@ void QFileSystemEntry::findLastSeparator() const
{
if (m_lastSeparator == -2) {
resolveFilePath();
- m_lastSeparator = -1;
- for (int i = m_filePath.size() - 1; i >= 0; --i) {
- if (m_filePath[i].unicode() == '/') {
- m_lastSeparator = i;
- break;
- }
- }
+ m_lastSeparator = m_filePath.lastIndexOf(QLatin1Char('/'));
}
}
diff --git a/src/corelib/io/qfilesystemwatcher.cpp b/src/corelib/io/qfilesystemwatcher.cpp
index 4bca8d90a0..416dd29d23 100644
--- a/src/corelib/io/qfilesystemwatcher.cpp
+++ b/src/corelib/io/qfilesystemwatcher.cpp
@@ -52,9 +52,9 @@
# include "qfilesystemwatcher_win_p.h"
#elif defined(USE_INOTIFY)
# include "qfilesystemwatcher_inotify_p.h"
-#elif defined(Q_OS_FREEBSD) || defined(Q_OS_IOS) || (defined(Q_OS_OSX) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7)
+#elif defined(Q_OS_FREEBSD) || defined(Q_OS_IOS)
# include "qfilesystemwatcher_kqueue_p.h"
-#elif defined(Q_OS_OSX) && MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_6
+#elif defined(Q_OS_OSX)
# include "qfilesystemwatcher_fsevents_p.h"
#endif
@@ -68,9 +68,9 @@ QFileSystemWatcherEngine *QFileSystemWatcherPrivate::createNativeEngine(QObject
// there is a chance that inotify may fail on Linux pre-2.6.13 (August
// 2005), so we can't just new inotify directly.
return QInotifyFileSystemWatcherEngine::create(parent);
-#elif defined(Q_OS_FREEBSD) || defined(Q_OS_IOS) || (defined(Q_OS_OSX) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7)
+#elif defined(Q_OS_FREEBSD) || defined(Q_OS_IOS)
return QKqueueFileSystemWatcherEngine::create(parent);
-#elif defined(Q_OS_OSX) && MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_6
+#elif defined(Q_OS_OSX)
return QFseventsFileSystemWatcherEngine::create(parent);
#else
Q_UNUSED(parent);
@@ -394,12 +394,12 @@ QStringList QFileSystemWatcher::removePaths(const QStringList &paths)
/*!
\fn void QFileSystemWatcher::directoryChanged(const QString &path)
- This signal is emitted when the directory at a specified \a path,
- is modified (e.g., when a file is added, modified or deleted) or
- removed from disk. Note that if there are several changes during a
- short period of time, some of the changes might not emit this
- signal. However, the last change in the sequence of changes will
- always generate this signal.
+ This signal is emitted when the directory at a specified \a path
+ is modified (e.g., when a file is added or deleted) or removed
+ from disk. Note that if there are several changes during a short
+ period of time, some of the changes might not emit this signal.
+ However, the last change in the sequence of changes will always
+ generate this signal.
\sa fileChanged()
*/
diff --git a/src/corelib/io/qfilesystemwatcher_inotify_p.h b/src/corelib/io/qfilesystemwatcher_inotify_p.h
index a9bc8486dc..506f571e2b 100644
--- a/src/corelib/io/qfilesystemwatcher_inotify_p.h
+++ b/src/corelib/io/qfilesystemwatcher_inotify_p.h
@@ -64,8 +64,8 @@ public:
static QInotifyFileSystemWatcherEngine *create(QObject *parent);
- QStringList addPaths(const QStringList &paths, QStringList *files, QStringList *directories);
- QStringList removePaths(const QStringList &paths, QStringList *files, QStringList *directories);
+ QStringList addPaths(const QStringList &paths, QStringList *files, QStringList *directories) Q_DECL_OVERRIDE;
+ QStringList removePaths(const QStringList &paths, QStringList *files, QStringList *directories) Q_DECL_OVERRIDE;
private Q_SLOTS:
void readFromInotify();
diff --git a/src/corelib/io/qfilesystemwatcher_polling_p.h b/src/corelib/io/qfilesystemwatcher_polling_p.h
index f39d72d5d8..3833869806 100644
--- a/src/corelib/io/qfilesystemwatcher_polling_p.h
+++ b/src/corelib/io/qfilesystemwatcher_polling_p.h
@@ -104,8 +104,8 @@ class QPollingFileSystemWatcherEngine : public QFileSystemWatcherEngine
public:
QPollingFileSystemWatcherEngine(QObject *parent);
- QStringList addPaths(const QStringList &paths, QStringList *files, QStringList *directories);
- QStringList removePaths(const QStringList &paths, QStringList *files, QStringList *directories);
+ QStringList addPaths(const QStringList &paths, QStringList *files, QStringList *directories) Q_DECL_OVERRIDE;
+ QStringList removePaths(const QStringList &paths, QStringList *files, QStringList *directories) Q_DECL_OVERRIDE;
private Q_SLOTS:
void timeout();
diff --git a/src/corelib/io/qfsfileengine_iterator_p.h b/src/corelib/io/qfsfileengine_iterator_p.h
index cc5b36fc57..35cb89673c 100644
--- a/src/corelib/io/qfsfileengine_iterator_p.h
+++ b/src/corelib/io/qfsfileengine_iterator_p.h
@@ -62,11 +62,11 @@ public:
QFSFileEngineIterator(QDir::Filters filters, const QStringList &filterNames);
~QFSFileEngineIterator();
- QString next();
- bool hasNext() const;
+ QString next() Q_DECL_OVERRIDE;
+ bool hasNext() const Q_DECL_OVERRIDE;
- QString currentFileName() const;
- QFileInfo currentFileInfo() const;
+ QString currentFileName() const Q_DECL_OVERRIDE;
+ QFileInfo currentFileInfo() const Q_DECL_OVERRIDE;
private:
void advance() const;
diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h
index 3963a9cb11..f843a870b8 100644
--- a/src/corelib/io/qfsfileengine_p.h
+++ b/src/corelib/io/qfsfileengine_p.h
@@ -69,46 +69,46 @@ public:
explicit QFSFileEngine(const QString &file);
~QFSFileEngine();
- bool open(QIODevice::OpenMode openMode);
+ bool open(QIODevice::OpenMode openMode) Q_DECL_OVERRIDE;
bool open(QIODevice::OpenMode flags, FILE *fh);
- bool close();
- bool flush();
- bool syncToDisk();
- qint64 size() const;
- qint64 pos() const;
- bool seek(qint64);
- bool isSequential() const;
- bool remove();
- bool copy(const QString &newName);
- bool rename(const QString &newName);
- bool renameOverwrite(const QString &newName);
- bool link(const QString &newName);
- bool mkdir(const QString &dirName, bool createParentDirectories) const;
- bool rmdir(const QString &dirName, bool recurseParentDirectories) const;
- bool setSize(qint64 size);
- bool caseSensitive() const;
- bool isRelativePath() const;
- QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const;
- FileFlags fileFlags(FileFlags type) const;
- bool setPermissions(uint perms);
- QString fileName(FileName file) const;
- uint ownerId(FileOwner) const;
- QString owner(FileOwner) const;
- QDateTime fileTime(FileTime time) const;
- void setFileName(const QString &file);
- int handle() const;
+ bool close() Q_DECL_OVERRIDE;
+ bool flush() Q_DECL_OVERRIDE;
+ bool syncToDisk() Q_DECL_OVERRIDE;
+ qint64 size() const Q_DECL_OVERRIDE;
+ qint64 pos() const Q_DECL_OVERRIDE;
+ bool seek(qint64) Q_DECL_OVERRIDE;
+ bool isSequential() const Q_DECL_OVERRIDE;
+ bool remove() Q_DECL_OVERRIDE;
+ bool copy(const QString &newName) Q_DECL_OVERRIDE;
+ bool rename(const QString &newName) Q_DECL_OVERRIDE;
+ bool renameOverwrite(const QString &newName) Q_DECL_OVERRIDE;
+ bool link(const QString &newName) Q_DECL_OVERRIDE;
+ bool mkdir(const QString &dirName, bool createParentDirectories) const Q_DECL_OVERRIDE;
+ bool rmdir(const QString &dirName, bool recurseParentDirectories) const Q_DECL_OVERRIDE;
+ bool setSize(qint64 size) Q_DECL_OVERRIDE;
+ bool caseSensitive() const Q_DECL_OVERRIDE;
+ bool isRelativePath() const Q_DECL_OVERRIDE;
+ QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const Q_DECL_OVERRIDE;
+ FileFlags fileFlags(FileFlags type) const Q_DECL_OVERRIDE;
+ bool setPermissions(uint perms) Q_DECL_OVERRIDE;
+ QString fileName(FileName file) const Q_DECL_OVERRIDE;
+ uint ownerId(FileOwner) const Q_DECL_OVERRIDE;
+ QString owner(FileOwner) const Q_DECL_OVERRIDE;
+ QDateTime fileTime(FileTime time) const Q_DECL_OVERRIDE;
+ void setFileName(const QString &file) Q_DECL_OVERRIDE;
+ int handle() const Q_DECL_OVERRIDE;
#ifndef QT_NO_FILESYSTEMITERATOR
- Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames);
- Iterator *endEntryList();
+ Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames) Q_DECL_OVERRIDE;
+ Iterator *endEntryList() Q_DECL_OVERRIDE;
#endif
- qint64 read(char *data, qint64 maxlen);
- qint64 readLine(char *data, qint64 maxlen);
- qint64 write(const char *data, qint64 len);
+ qint64 read(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
+ qint64 readLine(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
+ qint64 write(const char *data, qint64 len) Q_DECL_OVERRIDE;
- bool extension(Extension extension, const ExtensionOption *option = 0, ExtensionReturn *output = 0);
- bool supportsExtension(Extension extension) const;
+ bool extension(Extension extension, const ExtensionOption *option = 0, ExtensionReturn *output = 0) Q_DECL_OVERRIDE;
+ bool supportsExtension(Extension extension) const Q_DECL_OVERRIDE;
//FS only!!
bool open(QIODevice::OpenMode flags, int fd);
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index 72ec6ff403..388c623bcb 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -117,8 +117,7 @@ void debugBinaryString(const char *data, qint64 maxlen)
*/
QIODevicePrivate::QIODevicePrivate()
: openMode(QIODevice::NotOpen), buffer(QIODEVICE_BUFFERSIZE),
- pos(0), devicePos(0), seqDumpPos(0)
- , pPos(&pos), pDevicePos(&devicePos)
+ pos(0), devicePos(0)
, baseReadLineDataCalled(false)
, firstRead(true)
, accessMode(Unset)
@@ -566,7 +565,6 @@ void QIODevice::close()
d->openMode = NotOpen;
d->errorString.clear();
d->pos = 0;
- d->seqDumpPos = 0;
d->buffer.clear();
d->firstRead = true;
}
@@ -733,12 +731,6 @@ qint64 QIODevice::bytesToWrite() const
return qint64(0);
}
-#ifdef Q_CC_RVCT
-// arm mode makes the 64-bit integer operations much faster in RVCT 2.2
-#pragma push
-#pragma arm
-#endif
-
/*!
Reads at most \a maxSize bytes from the device into \a data, and
returns the number of bytes read. If an error occurs, such as when
@@ -761,11 +753,14 @@ qint64 QIODevice::read(char *data, qint64 maxSize)
this, data, int(maxSize), int(d->pos), int(d->buffer.size()));
#endif
+ const bool sequential = d->isSequential();
+
// Short circuit for getChar()
if (maxSize == 1) {
int chint;
while ((chint = d->buffer.getChar()) != -1) {
- ++(*d->pPos);
+ if (!sequential)
+ ++d->pos;
char c = char(uchar(chint));
if (c == '\r' && (d->openMode & Text))
@@ -783,27 +778,21 @@ qint64 QIODevice::read(char *data, qint64 maxSize)
CHECK_MAXLEN(read, qint64(-1));
qint64 readSoFar = 0;
- bool moreToRead = true;
- do {
+ bool madeBufferReadsOnly = true;
+ bool deviceAtEof = false;
+ char *readPtr = data;
+ forever {
// Try reading from the buffer.
- qint64 lastReadChunkSize = d->buffer.read(data, maxSize);
- if (lastReadChunkSize > 0) {
- *d->pPos += lastReadChunkSize;
- readSoFar += lastReadChunkSize;
- // fast exit when satisfied by buffer
- if (lastReadChunkSize == maxSize && !(d->openMode & Text)) {
- if (d->buffer.isEmpty()) {
- d->buffer.clear();
- readData(data, 0);
- }
- return readSoFar;
- }
-
- data += lastReadChunkSize;
- maxSize -= lastReadChunkSize;
+ qint64 bufferReadChunkSize = d->buffer.read(data, maxSize);
+ if (bufferReadChunkSize > 0) {
+ if (!sequential)
+ d->pos += bufferReadChunkSize;
+ readSoFar += bufferReadChunkSize;
+ data += bufferReadChunkSize;
+ maxSize -= bufferReadChunkSize;
#if defined QIODEVICE_DEBUG
- printf("%p \treading %d bytes from buffer into position %d\n", this, lastReadChunkSize,
- int(readSoFar) - lastReadChunkSize);
+ printf("%p \treading %d bytes from buffer into position %d\n", this,
+ bufferReadChunkSize, int(readSoFar) - bufferReadChunkSize);
#endif
} else {
if (d->firstRead) {
@@ -811,105 +800,88 @@ qint64 QIODevice::read(char *data, qint64 maxSize)
// for fast pos updates.
CHECK_READABLE(read, qint64(-1));
d->firstRead = false;
- if (d->isSequential()) {
- d->pPos = &d->seqDumpPos;
- d->pDevicePos = &d->seqDumpPos;
- }
}
+ }
- if (!maxSize)
- return readSoFar;
-
- if ((d->openMode & Unbuffered) == 0 && maxSize < QIODEVICE_BUFFERSIZE) {
- // In buffered mode, we try to fill up the QIODevice buffer before
- // we do anything else.
- // buffer is empty at this point, try to fill it
- const int bytesToBuffer = QIODEVICE_BUFFERSIZE;
- char *writePointer = d->buffer.reserve(bytesToBuffer);
-
- // Make sure the device is positioned correctly.
- if (d->pos != d->devicePos && !d->isSequential() && !seek(d->pos))
- return readSoFar ? readSoFar : qint64(-1);
- qint64 readFromDevice = readData(writePointer, bytesToBuffer);
- d->buffer.chop(bytesToBuffer - (readFromDevice < 0 ? 0 : int(readFromDevice)));
-
- if (readFromDevice > 0) {
- *d->pDevicePos += readFromDevice;
+ if (maxSize > 0 && !deviceAtEof) {
+ qint64 readFromDevice = 0;
+ // Make sure the device is positioned correctly.
+ if (sequential || d->pos == d->devicePos || seek(d->pos)) {
+ madeBufferReadsOnly = false; // fix readData attempt
+ if (maxSize >= QIODEVICE_BUFFERSIZE || (d->openMode & Unbuffered)) {
+ // Read big chunk directly to output buffer
+ readFromDevice = readData(data, maxSize);
+ deviceAtEof = (readFromDevice != maxSize);
#if defined QIODEVICE_DEBUG
- printf("%p \treading %d from device into buffer\n", this, int(readFromDevice));
+ printf("%p \treading %d bytes from device (total %d)\n", this,
+ int(readFromDevice), int(readSoFar));
#endif
-
- if (!d->buffer.isEmpty()) {
- lastReadChunkSize = d->buffer.read(data, maxSize);
- readSoFar += lastReadChunkSize;
- data += lastReadChunkSize;
- maxSize -= lastReadChunkSize;
- *d->pPos += lastReadChunkSize;
+ if (readFromDevice > 0) {
+ readSoFar += readFromDevice;
+ data += readFromDevice;
+ maxSize -= readFromDevice;
+ if (!sequential) {
+ d->pos += readFromDevice;
+ d->devicePos += readFromDevice;
+ }
+ }
+ } else {
+ const int bytesToBuffer = QIODEVICE_BUFFERSIZE;
+ // Try to fill QIODevice buffer by single read
+ readFromDevice = readData(d->buffer.reserve(bytesToBuffer), bytesToBuffer);
+ deviceAtEof = (readFromDevice != bytesToBuffer);
+ d->buffer.chop(bytesToBuffer - qMax(0, int(readFromDevice)));
+ if (readFromDevice > 0) {
+ if (!sequential)
+ d->devicePos += readFromDevice;
#if defined QIODEVICE_DEBUG
- printf("%p \treading %d bytes from buffer at position %d\n", this,
- lastReadChunkSize, int(readSoFar));
+ printf("%p \treading %d from device into buffer\n", this,
+ int(readFromDevice));
#endif
+ continue;
}
}
+ } else {
+ readFromDevice = -1;
}
- }
- // If we need more, try reading from the device.
- if (maxSize > 0) {
- // Make sure the device is positioned correctly.
- if (d->pos != d->devicePos && !d->isSequential() && !seek(d->pos))
- return readSoFar ? readSoFar : qint64(-1);
- qint64 readFromDevice = readData(data, maxSize);
-#if defined QIODEVICE_DEBUG
- printf("%p \treading %d bytes from device (total %d)\n", this, int(readFromDevice), int(readSoFar));
-#endif
- if (readFromDevice == -1 && readSoFar == 0) {
+ if (readFromDevice < 0 && readSoFar == 0) {
// error and we haven't read anything: return immediately
- return -1;
- }
- if (readFromDevice > 0) {
- lastReadChunkSize += int(readFromDevice);
- readSoFar += readFromDevice;
- data += readFromDevice;
- maxSize -= readFromDevice;
- *d->pPos += readFromDevice;
- *d->pDevicePos += readFromDevice;
+ return qint64(-1);
}
}
- // Best attempt has been made to read data, don't try again except for text mode adjustment below
- moreToRead = false;
- if (readSoFar && d->openMode & Text) {
- char *readPtr = data - lastReadChunkSize;
+ if ((d->openMode & Text) && readPtr < data) {
const char *endPtr = data;
- if (readPtr < endPtr) {
- // optimization to avoid initial self-assignment
- while (*readPtr != '\r') {
- if (++readPtr == endPtr)
- return readSoFar;
- }
+ // optimization to avoid initial self-assignment
+ while (*readPtr != '\r') {
+ if (++readPtr == endPtr)
+ break;
+ }
- char *writePtr = readPtr;
+ char *writePtr = readPtr;
- while (readPtr < endPtr) {
- char ch = *readPtr++;
- if (ch != '\r')
- *writePtr++ = ch;
- else {
- --readSoFar;
- --data;
- ++maxSize;
- }
+ while (readPtr < endPtr) {
+ char ch = *readPtr++;
+ if (ch != '\r')
+ *writePtr++ = ch;
+ else {
+ --readSoFar;
+ --data;
+ ++maxSize;
}
-
- // Make sure we get more data if there is room for more. This
- // is very important for when someone seeks to the start of a
- // '\r\n' and reads one character - they should get the '\n'.
- moreToRead = (readPtr != writePtr);
}
+
+ // Make sure we get more data if there is room for more. This
+ // is very important for when someone seeks to the start of a
+ // '\r\n' and reads one character - they should get the '\n'.
+ readPtr = data;
+ continue;
}
- } while (moreToRead);
+
+ break;
+ }
#if defined QIODEVICE_DEBUG
printf("%p \treturning %d, d->pos == %d, d->buffer.size() == %d\n", this,
@@ -917,16 +889,14 @@ qint64 QIODevice::read(char *data, qint64 maxSize)
debugBinaryString(data - readSoFar, readSoFar);
#endif
- if (d->buffer.isEmpty())
+ if (madeBufferReadsOnly && d->buffer.isEmpty()) {
+ d->buffer.clear();
readData(data, 0);
+ }
return readSoFar;
}
-#ifdef Q_CC_RVCT
-#pragma pop
-#endif
-
/*!
\overload
@@ -1039,12 +1009,6 @@ QByteArray QIODevice::readAll()
return result;
}
-#ifdef Q_CC_RVCT
-// arm mode makes the 64-bit integer operations much faster in RVCT 2.2
-#pragma push
-#pragma arm
-#endif
-
/*!
This function reads a line of ASCII characters from the device, up
to a maximum of \a maxSize - 1 bytes, stores the characters in \a
@@ -1264,10 +1228,6 @@ qint64 QIODevice::readLineData(char *data, qint64 maxSize)
return readSoFar;
}
-#ifdef Q_CC_RVCT
-#pragma pop
-#endif
-
/*!
Returns \c true if a complete line of data can be read from the device;
otherwise returns \c false.
@@ -1455,7 +1415,8 @@ qint64 QIODevicePrivate::peek(char *data, qint64 maxSize)
return readBytes;
buffer.ungetBlock(data, readBytes);
- *pPos -= readBytes;
+ if (!isSequential())
+ pos -= readBytes;
return readBytes;
}
@@ -1470,7 +1431,8 @@ QByteArray QIODevicePrivate::peek(qint64 maxSize)
return result;
buffer.ungetBlock(result.constData(), result.size());
- *pPos -= result.size();
+ if (!isSequential())
+ pos -= result.size();
return result;
}
diff --git a/src/corelib/io/qiodevice_p.h b/src/corelib/io/qiodevice_p.h
index d764cb0fbb..ac76f8ded8 100644
--- a/src/corelib/io/qiodevice_p.h
+++ b/src/corelib/io/qiodevice_p.h
@@ -209,10 +209,6 @@ public:
QIODevicePrivateLinearBuffer buffer;
qint64 pos;
qint64 devicePos;
- // these three are for fast position updates during read, avoiding isSequential test
- qint64 seqDumpPos;
- qint64 *pPos;
- qint64 *pDevicePos;
bool baseReadLineDataCalled;
bool firstRead;
diff --git a/src/corelib/io/qipaddress.cpp b/src/corelib/io/qipaddress.cpp
index 44da22489d..d436cd2dd6 100644
--- a/src/corelib/io/qipaddress.cpp
+++ b/src/corelib/io/qipaddress.cpp
@@ -33,6 +33,7 @@
#include "qipaddress_p.h"
#include "private/qlocale_tools_p.h"
+#include "private/qtools_p.h"
#include "qvarlengtharray.h"
QT_BEGIN_NAMESPACE
@@ -240,7 +241,7 @@ const QChar *parseIp6(IPv6Address &address, const QChar *begin, const QChar *end
static inline QChar toHex(uchar c)
{
- return ushort(c > 9 ? c + 'a' - 0xA : c + '0');
+ return QtMiscUtils::toHexLower(c);
}
void toString(QString &appendTo, IPv6Address address)
diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp
index 79d20601a6..a032fe3d1b 100644
--- a/src/corelib/io/qloggingcategory.cpp
+++ b/src/corelib/io/qloggingcategory.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2015 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.
@@ -64,8 +64,8 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
QLoggingCategory represents a certain logging category - identified by a
string - at runtime. A category can be configured to enable or disable
logging of messages per message type. Whether a message type is enabled or
- not can be checked with the \l isDebugEnabled(), \l isWarningEnabled(), and
- \l isCriticalEnabled() methods.
+ not can be checked with the \l isDebugEnabled(), \l isInfoEnabled(),
+ \l isWarningEnabled(), and \l isCriticalEnabled() methods.
All objects are meant to be configured by a common registry (see also
\l{Configuring Categories}). Different objects can also represent the same
@@ -82,8 +82,8 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
\section1 Checking Category Configuration
- QLoggingCategory provides \l isDebugEnabled(), \l isWarningEnabled(),
- \l isCriticalEnabled(), as well as \l isEnabled()
+ QLoggingCategory provides \l isDebugEnabled(), \l isInfoEnabled(),
+ \l isWarningEnabled(), \l isCriticalEnabled(), as well as \l isEnabled()
to check whether messages for the given message type should be logged.
\note The qCDebug(), qCWarning(), qCCritical() macros prevent arguments
@@ -101,7 +101,7 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
\snippet qloggingcategory/main.cpp 5
will log messages of type \c QtWarningMsg, \c QtCriticalMsg, \c QtFatalMsg, but will
- ignore messages of type \c QtDebugMsg.
+ ignore messages of type \c QtDebugMsg and \c QtInfoMsg.
If no argument is passed, all messages will be logged.
@@ -122,7 +122,7 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
\c <category> is the name of the category, potentially with \c{*} as a
wildcard symbol as the first or last character (or at both positions).
- The optional \c <type> must be either \c debug, \c warning, or \c critical.
+ The optional \c <type> must be either \c debug, \c info, \c warning, or \c critical.
Lines that do not fit this scheme are ignored.
Rules are evaluated in text order, from first to last. That is, if two rules
@@ -250,6 +250,21 @@ QLoggingCategory::~QLoggingCategory()
expensive generation of data that is only used for debug output.
*/
+
+/*!
+ \fn bool QLoggingCategory::isInfoEnabled() const
+
+ Returns \c true if informational messages should be shown for this category.
+ Returns \c false otherwise.
+
+ \note The \l qCInfo() macro already does this check before executing any
+ code. However, calling this method may be useful to avoid
+ expensive generation of data that is only used for debug output.
+
+ \since 5.5
+*/
+
+
/*!
\fn bool QLoggingCategory::isWarningEnabled() const
@@ -280,6 +295,7 @@ bool QLoggingCategory::isEnabled(QtMsgType msgtype) const
{
switch (msgtype) {
case QtDebugMsg: return isDebugEnabled();
+ case QtInfoMsg: return isInfoEnabled();
case QtWarningMsg: return isWarningEnabled();
case QtCriticalMsg: return isCriticalEnabled();
case QtFatalMsg: return true;
@@ -302,10 +318,12 @@ void QLoggingCategory::setEnabled(QtMsgType type, bool enable)
switch (type) {
#ifdef Q_ATOMIC_INT8_IS_SUPPORTED
case QtDebugMsg: bools.enabledDebug.store(enable); break;
+ case QtInfoMsg: bools.enabledInfo.store(enable); break;
case QtWarningMsg: bools.enabledWarning.store(enable); break;
case QtCriticalMsg: bools.enabledCritical.store(enable); break;
#else
case QtDebugMsg: setBoolLane(&enabled, enable, DebugShift); break;
+ case QtInfoMsg: setBoolLane(&enabled, enable, InfoShift); break;
case QtWarningMsg: setBoolLane(&enabled, enable, WarningShift); break;
case QtCriticalMsg: setBoolLane(&enabled, enable, CriticalShift); break;
#endif
@@ -331,7 +349,7 @@ void QLoggingCategory::setEnabled(QtMsgType type, bool enable)
/*!
Returns a pointer to the global category \c "default" that
- is used e.g. by qDebug(), qWarning(), qCritical(), qFatal().
+ is used e.g. by qDebug(), qInfo(), qWarning(), qCritical(), qFatal().
\note The returned pointer may be null during destruction of
static objects.
@@ -439,6 +457,47 @@ void QLoggingCategory::setFilterRules(const QString &rules)
*/
/*!
+ \macro qCInfo(category)
+ \relates QLoggingCategory
+ \since 5.5
+
+ Returns an output stream for informational messages in the logging category
+ \a category.
+
+ The macro expands to code that checks whether
+ \l QLoggingCategory::isInfoEnabled() evaluates to \c true.
+ If so, the stream arguments are processed and sent to the message handler.
+
+ Example:
+
+ \snippet qloggingcategory/main.cpp qcinfo_stream
+
+ \note Arguments are not processed if debug output for the category is not
+ enabled, so do not rely on any side effects.
+
+ \sa qInfo()
+*/
+
+/*!
+ \macro qCInfo(category, const char *message, ...)
+ \relates QLoggingCategory
+ \since 5.5
+
+ Logs an informational message \a message in the logging category \a category.
+ \a message might contain place holders that are replaced by additional
+ arguments, similar to the C printf() function.
+
+ Example:
+
+ \snippet qloggingcategory/main.cpp qcinfo_printf
+
+ \note Arguments might not be processed if debug output for the category is
+ not enabled, so do not rely on any side effects.
+
+ \sa qInfo()
+*/
+
+/*!
\macro qCWarning(category)
\relates QLoggingCategory
\since 5.2
diff --git a/src/corelib/io/qloggingcategory.h b/src/corelib/io/qloggingcategory.h
index c7e242af08..5504ebab3b 100644
--- a/src/corelib/io/qloggingcategory.h
+++ b/src/corelib/io/qloggingcategory.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2015 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.
@@ -53,10 +53,12 @@ public:
#ifdef Q_ATOMIC_INT8_IS_SUPPORTED
bool isDebugEnabled() const { return bools.enabledDebug.load(); }
+ bool isInfoEnabled() const { return bools.enabledInfo.load(); }
bool isWarningEnabled() const { return bools.enabledWarning.load(); }
bool isCriticalEnabled() const { return bools.enabledCritical.load(); }
#else
bool isDebugEnabled() const { return enabled.load() >> DebugShift & 1; }
+ bool isInfoEnabled() const { return enabled.load() >> InfoShift & 1; }
bool isWarningEnabled() const { return enabled.load() >> WarningShift & 1; }
bool isCriticalEnabled() const { return enabled.load() >> CriticalShift & 1; }
#endif
@@ -80,9 +82,9 @@ private:
const char *name;
#ifdef Q_BIG_ENDIAN
- enum { DebugShift = 0, WarningShift = 8, CriticalShift = 16 };
+ enum { DebugShift = 0, WarningShift = 8, CriticalShift = 16, InfoShift = 24 };
#else
- enum { DebugShift = 24, WarningShift = 16, CriticalShift = 8 };
+ enum { DebugShift = 24, WarningShift = 16, CriticalShift = 8, InfoShift = 0};
#endif
struct AtomicBools {
@@ -90,6 +92,7 @@ private:
QBasicAtomicInteger<bool> enabledDebug;
QBasicAtomicInteger<bool> enabledWarning;
QBasicAtomicInteger<bool> enabledCritical;
+ QBasicAtomicInteger<bool> enabledInfo;
#endif
};
union {
@@ -114,6 +117,9 @@ private:
#define qCDebug(category, ...) \
for (bool qt_category_enabled = category().isDebugEnabled(); qt_category_enabled; qt_category_enabled = false) \
QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC, category().categoryName()).debug(__VA_ARGS__)
+#define qCInfo(category, ...) \
+ for (bool qt_category_enabled = category().isInfoEnabled(); qt_category_enabled; qt_category_enabled = false) \
+ QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC, category().categoryName()).info(__VA_ARGS__)
#define qCWarning(category, ...) \
for (bool qt_category_enabled = category().isWarningEnabled(); qt_category_enabled; qt_category_enabled = false) \
QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC, category().categoryName()).warning(__VA_ARGS__)
@@ -133,6 +139,7 @@ private:
// check for enabled category inside QMessageLogger.
#define qCDebug qDebug
+#define qCInfo qInfo
#define qCWarning qWarning
#define qCCritical qCritical
@@ -142,9 +149,13 @@ private:
# undef qCDebug
# define qCDebug(category) QT_NO_QDEBUG_MACRO()
#endif
+#if defined(QT_NO_INFO_OUTPUT)
+# undef qCInfo
+# define qCInfo(category) QT_NO_QDEBUG_MACRO()
+#endif
#if defined(QT_NO_WARNING_OUTPUT)
# undef qCWarning
-# define qCWarning(category) QT_NO_QWARNING_MACRO()
+# define qCWarning(category) QT_NO_QDEBUG_MACRO()
#endif
QT_END_NAMESPACE
diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp
index 8af1487834..0c916df910 100644
--- a/src/corelib/io/qloggingregistry.cpp
+++ b/src/corelib/io/qloggingregistry.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2015 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.
@@ -124,6 +124,10 @@ void QLoggingRule::parse(const QStringRef &pattern)
p = QStringRef(pattern.string(), pattern.position(),
pattern.length() - 6); // strlen(".debug")
messageType = QtDebugMsg;
+ } else if (pattern.endsWith(QLatin1String(".info"))) {
+ p = QStringRef(pattern.string(), pattern.position(),
+ pattern.length() - 5); // strlen(".info")
+ messageType = QtInfoMsg;
} else if (pattern.endsWith(QLatin1String(".warning"))) {
p = QStringRef(pattern.string(), pattern.position(),
pattern.length() - 8); // strlen(".warning")
@@ -392,6 +396,7 @@ void QLoggingRegistry::defaultCategoryFilter(QLoggingCategory *cat)
QtMsgType enableForLevel = reg->categories.value(cat);
bool debug = (enableForLevel == QtDebugMsg);
+ bool info = (enableForLevel <= QtInfoMsg);
bool warning = (enableForLevel <= QtWarningMsg);
bool critical = (enableForLevel <= QtCriticalMsg);
@@ -409,6 +414,9 @@ void QLoggingRegistry::defaultCategoryFilter(QLoggingCategory *cat)
int filterpass = item.pass(categoryName, QtDebugMsg);
if (filterpass != 0)
debug = (filterpass > 0);
+ filterpass = item.pass(categoryName, QtInfoMsg);
+ if (filterpass != 0)
+ info = (filterpass > 0);
filterpass = item.pass(categoryName, QtWarningMsg);
if (filterpass != 0)
warning = (filterpass > 0);
@@ -418,6 +426,7 @@ void QLoggingRegistry::defaultCategoryFilter(QLoggingCategory *cat)
}
cat->setEnabled(QtDebugMsg, debug);
+ cat->setEnabled(QtInfoMsg, info);
cat->setEnabled(QtWarningMsg, warning);
cat->setEnabled(QtCriticalMsg, critical);
}
diff --git a/src/corelib/io/qnoncontiguousbytedevice.cpp b/src/corelib/io/qnoncontiguousbytedevice.cpp
index 11510a8397..1c10ef9f83 100644
--- a/src/corelib/io/qnoncontiguousbytedevice.cpp
+++ b/src/corelib/io/qnoncontiguousbytedevice.cpp
@@ -94,17 +94,7 @@ QT_BEGIN_NAMESPACE
Moves the internal read pointer back to the beginning.
Returns \c false if this was not possible.
- \sa atEnd(), disableReset()
-
- \internal
-*/
-/*!
- \fn void QNonContiguousByteDevice::disableReset()
-
- Disable the reset() call, e.g. it will always
- do nothing and return false.
-
- \sa reset()
+ \sa atEnd()
\internal
*/
@@ -131,7 +121,7 @@ QT_BEGIN_NAMESPACE
\internal
*/
-QNonContiguousByteDevice::QNonContiguousByteDevice() : QObject((QObject*)0), resetDisabled(false)
+QNonContiguousByteDevice::QNonContiguousByteDevice() : QObject((QObject*)0)
{
}
@@ -139,11 +129,6 @@ QNonContiguousByteDevice::~QNonContiguousByteDevice()
{
}
-void QNonContiguousByteDevice::disableReset()
-{
- resetDisabled = true;
-}
-
// FIXME we should scrap this whole implementation and instead change the ByteArrayImpl to be able to cope with sub-arrays?
QNonContiguousByteDeviceBufferImpl::QNonContiguousByteDeviceBufferImpl(QBuffer *b) : QNonContiguousByteDevice()
{
@@ -176,8 +161,6 @@ bool QNonContiguousByteDeviceBufferImpl::atEnd()
bool QNonContiguousByteDeviceBufferImpl::reset()
{
- if (resetDisabled)
- return false;
return arrayImpl->reset();
}
@@ -224,9 +207,6 @@ bool QNonContiguousByteDeviceByteArrayImpl::atEnd()
bool QNonContiguousByteDeviceByteArrayImpl::reset()
{
- if (resetDisabled)
- return false;
-
currentPosition = 0;
return true;
}
@@ -275,9 +255,6 @@ bool QNonContiguousByteDeviceRingBufferImpl::atEnd()
bool QNonContiguousByteDeviceRingBufferImpl::reset()
{
- if (resetDisabled)
- return false;
-
currentPosition = 0;
return true;
}
@@ -378,8 +355,6 @@ bool QNonContiguousByteDeviceIoDeviceImpl::atEnd()
bool QNonContiguousByteDeviceIoDeviceImpl::reset()
{
- if (resetDisabled)
- return false;
bool reset = (initialPosition == 0) ? device->reset() : device->seek(initialPosition);
if (reset) {
eof = false; // assume eof is false, it will be true after a read has been attempted
diff --git a/src/corelib/io/qnoncontiguousbytedevice_p.h b/src/corelib/io/qnoncontiguousbytedevice_p.h
index c05ae11b0f..d36422e82c 100644
--- a/src/corelib/io/qnoncontiguousbytedevice_p.h
+++ b/src/corelib/io/qnoncontiguousbytedevice_p.h
@@ -62,8 +62,6 @@ public:
virtual bool advanceReadPointer(qint64 amount) = 0;
virtual bool atEnd() = 0;
virtual bool reset() = 0;
- void disableReset();
- bool isResetDisabled() { return resetDisabled; }
virtual qint64 size() = 0;
virtual ~QNonContiguousByteDevice();
@@ -72,7 +70,6 @@ protected:
QNonContiguousByteDevice();
- bool resetDisabled;
Q_SIGNALS:
void readyRead();
void readProgress(qint64 current, qint64 total);
@@ -101,11 +98,11 @@ class QNonContiguousByteDeviceByteArrayImpl : public QNonContiguousByteDevice
public:
QNonContiguousByteDeviceByteArrayImpl(QByteArray *ba);
~QNonContiguousByteDeviceByteArrayImpl();
- const char* readPointer(qint64 maximumLength, qint64 &len);
- bool advanceReadPointer(qint64 amount);
- bool atEnd();
- bool reset();
- qint64 size();
+ const char* readPointer(qint64 maximumLength, qint64 &len) Q_DECL_OVERRIDE;
+ bool advanceReadPointer(qint64 amount) Q_DECL_OVERRIDE;
+ bool atEnd() Q_DECL_OVERRIDE;
+ bool reset() Q_DECL_OVERRIDE;
+ qint64 size() Q_DECL_OVERRIDE;
protected:
QByteArray* byteArray;
qint64 currentPosition;
@@ -116,11 +113,11 @@ class QNonContiguousByteDeviceRingBufferImpl : public QNonContiguousByteDevice
public:
QNonContiguousByteDeviceRingBufferImpl(QSharedPointer<QRingBuffer> rb);
~QNonContiguousByteDeviceRingBufferImpl();
- const char* readPointer(qint64 maximumLength, qint64 &len);
- bool advanceReadPointer(qint64 amount);
- bool atEnd();
- bool reset();
- qint64 size();
+ const char* readPointer(qint64 maximumLength, qint64 &len) Q_DECL_OVERRIDE;
+ bool advanceReadPointer(qint64 amount) Q_DECL_OVERRIDE;
+ bool atEnd() Q_DECL_OVERRIDE;
+ bool reset() Q_DECL_OVERRIDE;
+ qint64 size() Q_DECL_OVERRIDE;
protected:
QSharedPointer<QRingBuffer> ringBuffer;
qint64 currentPosition;
@@ -133,11 +130,11 @@ class QNonContiguousByteDeviceIoDeviceImpl : public QNonContiguousByteDevice
public:
QNonContiguousByteDeviceIoDeviceImpl(QIODevice *d);
~QNonContiguousByteDeviceIoDeviceImpl();
- const char* readPointer(qint64 maximumLength, qint64 &len);
- bool advanceReadPointer(qint64 amount);
- bool atEnd();
- bool reset();
- qint64 size();
+ const char* readPointer(qint64 maximumLength, qint64 &len) Q_DECL_OVERRIDE;
+ bool advanceReadPointer(qint64 amount) Q_DECL_OVERRIDE;
+ bool atEnd() Q_DECL_OVERRIDE;
+ bool reset() Q_DECL_OVERRIDE;
+ qint64 size() Q_DECL_OVERRIDE;
protected:
QIODevice* device;
QByteArray* currentReadBuffer;
@@ -155,11 +152,11 @@ class QNonContiguousByteDeviceBufferImpl : public QNonContiguousByteDevice
public:
QNonContiguousByteDeviceBufferImpl(QBuffer *b);
~QNonContiguousByteDeviceBufferImpl();
- const char* readPointer(qint64 maximumLength, qint64 &len);
- bool advanceReadPointer(qint64 amount);
- bool atEnd();
- bool reset();
- qint64 size();
+ const char* readPointer(qint64 maximumLength, qint64 &len) Q_DECL_OVERRIDE;
+ bool advanceReadPointer(qint64 amount) Q_DECL_OVERRIDE;
+ bool atEnd() Q_DECL_OVERRIDE;
+ bool reset() Q_DECL_OVERRIDE;
+ qint64 size() Q_DECL_OVERRIDE;
protected:
QBuffer* buffer;
QByteArray byteArray;
@@ -172,13 +169,13 @@ class QByteDeviceWrappingIoDevice : public QIODevice
public:
QByteDeviceWrappingIoDevice (QNonContiguousByteDevice *bd);
~QByteDeviceWrappingIoDevice ();
- virtual bool isSequential () const;
- virtual bool atEnd () const;
- virtual bool reset ();
- virtual qint64 size () const;
+ virtual bool isSequential () const Q_DECL_OVERRIDE;
+ virtual bool atEnd () const Q_DECL_OVERRIDE;
+ virtual bool reset () Q_DECL_OVERRIDE;
+ virtual qint64 size () const Q_DECL_OVERRIDE;
protected:
- virtual qint64 readData ( char * data, qint64 maxSize );
- virtual qint64 writeData ( const char * data, qint64 maxSize );
+ virtual qint64 readData ( char * data, qint64 maxSize ) Q_DECL_OVERRIDE;
+ virtual qint64 writeData ( const char * data, qint64 maxSize ) Q_DECL_OVERRIDE;
QNonContiguousByteDevice *byteDevice;
};
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index 939cecfb44..408f07f00e 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -89,6 +89,8 @@ QT_END_NAMESPACE
#ifdef Q_OS_WIN
#include <qwineventnotifier.h>
+#else
+#include <private/qcore_unix_p.h>
#endif
#ifndef QT_NO_PROCESS
@@ -810,8 +812,7 @@ QProcessPrivate::QProcessPrivate()
deathNotifier = 0;
childStartedPipe[0] = INVALID_Q_PIPE;
childStartedPipe[1] = INVALID_Q_PIPE;
- deathPipe[0] = INVALID_Q_PIPE;
- deathPipe[1] = INVALID_Q_PIPE;
+ forkfd = -1;
exitCode = 0;
crashed = false;
dying = false;
@@ -821,9 +822,6 @@ QProcessPrivate::QProcessPrivate()
notifier = 0;
processFinishedNotifier = 0;
#endif // Q_OS_WIN
-#ifdef Q_OS_UNIX
- serial = 0;
-#endif
}
/*!
@@ -890,9 +888,10 @@ void QProcessPrivate::cleanup()
closeChannel(&stderrChannel);
closeChannel(&stdinChannel);
destroyPipe(childStartedPipe);
- destroyPipe(deathPipe);
#ifdef Q_OS_UNIX
- serial = 0;
+ if (forkfd != -1)
+ qt_safe_close(forkfd);
+ forkfd = -1;
#endif
}
@@ -1079,6 +1078,17 @@ bool QProcessPrivate::_q_processDied()
processError = QProcess::Crashed;
q->setErrorString(QProcess::tr("Process crashed"));
emit q->error(processError);
+ } else {
+#ifdef QPROCESS_USE_SPAWN
+ // if we're using posix_spawn, waitForStarted always succeeds.
+ // POSIX documents that the sub-process launched by posix_spawn will exit with code
+ // 127 if anything prevents the target program from starting.
+ // http://pubs.opengroup.org/onlinepubs/009695399/functions/posix_spawn.html
+ if (exitStatus == QProcess::NormalExit && exitCode == 127) {
+ processError = QProcess::FailedToStart;
+ q->setErrorString(QProcess::tr("Process failed to start (spawned process exited with code 127)"));
+ }
+#endif
}
bool wasRunning = (processState == QProcess::Running);
@@ -1754,6 +1764,9 @@ QProcessEnvironment QProcess::processEnvironment() const
If msecs is -1, this function will not time out.
+ \note On some UNIX operating systems, this function may return true but
+ the process may later report a QProcess::FailedToStart error.
+
\sa started(), waitForReadyRead(), waitForBytesWritten(), waitForFinished()
*/
bool QProcess::waitForStarted(int msecs)
@@ -2348,7 +2361,7 @@ int QProcess::execute(const QString &program, const QStringList &arguments)
QProcess process;
process.setReadChannelMode(ForwardedChannels);
process.start(program, arguments);
- if (!process.waitForFinished(-1))
+ if (!process.waitForFinished(-1) || process.error() == FailedToStart)
return -2;
return process.exitStatus() == QProcess::NormalExit ? process.exitCode() : -1;
}
@@ -2371,7 +2384,7 @@ int QProcess::execute(const QString &command)
QProcess process;
process.setReadChannelMode(ForwardedChannels);
process.start(command);
- if (!process.waitForFinished(-1))
+ if (!process.waitForFinished(-1) || process.error() == FailedToStart)
return -2;
return process.exitStatus() == QProcess::NormalExit ? process.exitCode() : -1;
}
diff --git a/src/corelib/io/qprocess.h b/src/corelib/io/qprocess.h
index 8d90177c8b..af3db4ecf6 100644
--- a/src/corelib/io/qprocess.h
+++ b/src/corelib/io/qprocess.h
@@ -182,8 +182,8 @@ public:
qint64 processId() const;
bool waitForStarted(int msecs = 30000);
- bool waitForReadyRead(int msecs = 30000);
- bool waitForBytesWritten(int msecs = 30000);
+ bool waitForReadyRead(int msecs = 30000) Q_DECL_OVERRIDE;
+ bool waitForBytesWritten(int msecs = 30000) Q_DECL_OVERRIDE;
bool waitForFinished(int msecs = 30000);
QByteArray readAllStandardOutput();
@@ -193,12 +193,12 @@ public:
QProcess::ExitStatus exitStatus() const;
// QIODevice
- qint64 bytesAvailable() const;
- qint64 bytesToWrite() const;
- bool isSequential() const;
- bool canReadLine() const;
- void close();
- bool atEnd() const;
+ qint64 bytesAvailable() const Q_DECL_OVERRIDE;
+ qint64 bytesToWrite() const Q_DECL_OVERRIDE;
+ bool isSequential() const Q_DECL_OVERRIDE;
+ bool canReadLine() const Q_DECL_OVERRIDE;
+ void close() Q_DECL_OVERRIDE;
+ bool atEnd() const Q_DECL_OVERRIDE;
static int execute(const QString &program, const QStringList &arguments);
static int execute(const QString &command);
@@ -254,8 +254,8 @@ protected:
virtual void setupChildProcess();
// QIODevice
- qint64 readData(char *data, qint64 maxlen);
- qint64 writeData(const char *data, qint64 len);
+ qint64 readData(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
+ qint64 writeData(const char *data, qint64 len) Q_DECL_OVERRIDE;
private:
Q_DECLARE_PRIVATE(QProcess)
diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h
index 35626ddc38..3f86960c74 100644
--- a/src/corelib/io/qprocess_p.h
+++ b/src/corelib/io/qprocess_p.h
@@ -62,6 +62,9 @@ typedef HANDLE Q_PIPE;
#else
typedef int Q_PIPE;
#define INVALID_Q_PIPE -1
+# ifdef Q_OS_QNX
+# define QPROCESS_USE_SPAWN
+# endif
#endif
#ifndef QT_NO_PROCESS
@@ -98,7 +101,7 @@ public:
QByteArray key;
uint hash;
};
-inline uint qHash(const QProcEnvKey &key) { return key.hash; }
+inline uint qHash(const QProcEnvKey &key) Q_DECL_NOTHROW { return key.hash; }
class QProcEnvValue
{
@@ -331,12 +334,13 @@ public:
QProcessEnvironment environment;
Q_PIPE childStartedPipe[2];
- Q_PIPE deathPipe[2];
void destroyPipe(Q_PIPE pipe[2]);
QSocketNotifier *startupSocketNotifier;
QSocketNotifier *deathNotifier;
+ int forkfd;
+
#ifdef Q_OS_WIN
// the wonderful windows notifier
QTimer *notifier;
@@ -345,10 +349,10 @@ public:
void start(QIODevice::OpenMode mode);
void startProcess();
-#if defined(Q_OS_UNIX) && !defined(Q_OS_QNX)
+#if defined(Q_OS_UNIX) && !defined(QPROCESS_USE_SPAWN)
void execChild(const char *workingDirectory, char **path, char **argv, char **envp);
-#elif defined(Q_OS_QNX)
- pid_t spawnChild(const char *workingDirectory, char **argv, char **envp);
+#elif defined(QPROCESS_USE_SPAWN)
+ pid_t spawnChild(pid_t *ppid, const char *workingDirectory, char **argv, char **envp);
#endif
bool processStarted();
void terminateProcess();
@@ -369,9 +373,6 @@ public:
int exitCode;
QProcess::ExitStatus exitStatus;
bool crashed;
-#ifdef Q_OS_UNIX
- int serial;
-#endif
bool waitForStarted(int msecs = 30000);
bool waitForReadyRead(int msecs = 30000);
@@ -389,9 +390,6 @@ public:
QList<QSocketNotifier *> defaultNotifiers() const;
#endif // Q_OS_BLACKBERRY
-#ifdef Q_OS_UNIX
- static void initializeProcessManager();
-#endif
};
QT_END_NAMESPACE
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index cc154cfbc5..014ff12313 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -95,15 +95,14 @@ QT_END_NAMESPACE
#include <qthread.h>
#include <qelapsedtimer.h>
+#ifdef Q_OS_QNX
+# include <sys/neutrino.h>
+#endif
+
#include <errno.h>
#include <stdlib.h>
#include <string.h>
-#ifdef Q_OS_QNX
-#include "qvarlengtharray.h"
-
-#include <spawn.h>
-#include <sys/neutrino.h>
-#endif
+#include <forkfd.h>
QT_BEGIN_NAMESPACE
@@ -111,38 +110,6 @@ QT_BEGIN_NAMESPACE
// so we will use 512
static const int errorBufferMax = 512;
-static int qt_qprocess_deadChild_pipe[2];
-static struct sigaction qt_sa_old_sigchld_handler;
-static void qt_sa_sigchld_sigaction(int signum, siginfo_t *info, void *context)
-{
- // *Never* use the info or contect variables in this function
- // (except for passing them to the next signal in the chain).
- // We cannot be sure if another library or if the application
- // installed a signal handler for SIGCHLD without SA_SIGINFO
- // and fails to pass the arguments to us. If they do that,
- // these arguments contain garbage and we'd most likely crash.
-
- qt_safe_write(qt_qprocess_deadChild_pipe[1], "", 1);
-#if defined (QPROCESS_DEBUG)
- fprintf(stderr, "*** SIGCHLD\n");
-#endif
-
- // load as volatile
- volatile struct sigaction *vsa = &qt_sa_old_sigchld_handler;
-
- if (qt_sa_old_sigchld_handler.sa_flags & SA_SIGINFO) {
- void (*oldAction)(int, siginfo_t *, void *) = vsa->sa_sigaction;
-
- if (oldAction)
- oldAction(signum, info, context);
- } else {
- void (*oldAction)(int) = vsa->sa_handler;
-
- if (oldAction && oldAction != SIG_IGN)
- oldAction(signum);
- }
-}
-
static inline void add_fd(int &nfds, int fd, fd_set *fdset)
{
FD_SET(fd, fdset);
@@ -150,199 +117,6 @@ static inline void add_fd(int &nfds, int fd, fd_set *fdset)
nfds = fd;
}
-struct QProcessInfo {
- QProcess *process;
- int deathPipe;
- int exitResult;
- pid_t pid;
- int serialNumber;
-};
-
-class QProcessManager : public QThread
-{
- Q_OBJECT
-public:
- QProcessManager();
- ~QProcessManager();
-
- void run();
- void catchDeadChildren();
- void add(pid_t pid, QProcess *process);
- void remove(QProcess *process);
- void lock();
- void unlock();
-
-private:
- QMutex mutex;
- QHash<int, QProcessInfo *> children;
-};
-
-
-static QProcessManager *processManagerInstance = 0;
-
-static QProcessManager *processManager()
-{
- // The constructor of QProcessManager should be called only once
- // so we cannot use Q_GLOBAL_STATIC directly for QProcessManager
- static QBasicMutex processManagerGlobalMutex;
- QMutexLocker locker(&processManagerGlobalMutex);
-
- if (!processManagerInstance)
- new QProcessManager;
-
- Q_ASSERT(processManagerInstance);
- return processManagerInstance;
-}
-
-QProcessManager::QProcessManager()
-{
-#if defined (QPROCESS_DEBUG)
- qDebug() << "QProcessManager::QProcessManager()";
-#endif
- // initialize the dead child pipe and make it non-blocking. in the
- // extremely unlikely event that the pipe fills up, we do not under any
- // circumstances want to block.
- qt_safe_pipe(qt_qprocess_deadChild_pipe, O_NONBLOCK);
-
- // set up the SIGCHLD handler, which writes a single byte to the dead
- // child pipe every time a child dies.
-
- struct sigaction action;
- // use the old handler as template, i.e., preserve the signal mask
- // otherwise the original signal handler might be interrupted although it
- // was marked to never be interrupted
- ::sigaction(SIGCHLD, NULL, &action);
- action.sa_sigaction = qt_sa_sigchld_sigaction;
- // set the SA_SIGINFO flag such that we can use the three argument handler
- // function
- action.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
- ::sigaction(SIGCHLD, &action, &qt_sa_old_sigchld_handler);
-
- processManagerInstance = this;
-}
-
-QProcessManager::~QProcessManager()
-{
- // notify the thread that we're shutting down.
- qt_safe_write(qt_qprocess_deadChild_pipe[1], "@", 1);
- qt_safe_close(qt_qprocess_deadChild_pipe[1]);
- wait();
-
- // on certain unixes, closing the reading end of the pipe will cause
- // select in run() to block forever, rather than return with EBADF.
- qt_safe_close(qt_qprocess_deadChild_pipe[0]);
-
- qt_qprocess_deadChild_pipe[0] = -1;
- qt_qprocess_deadChild_pipe[1] = -1;
-
- qDeleteAll(children.values());
- children.clear();
-
- struct sigaction currentAction;
- ::sigaction(SIGCHLD, 0, &currentAction);
- if (currentAction.sa_sigaction == qt_sa_sigchld_sigaction) {
- ::sigaction(SIGCHLD, &qt_sa_old_sigchld_handler, 0);
- }
-
- processManagerInstance = 0;
-}
-
-void QProcessManager::run()
-{
- forever {
- fd_set readset;
- FD_ZERO(&readset);
- FD_SET(qt_qprocess_deadChild_pipe[0], &readset);
-
-#if defined (QPROCESS_DEBUG)
- qDebug() << "QProcessManager::run() waiting for children to die";
-#endif
-
- // block forever, or until activity is detected on the dead child
- // pipe. the only other peers are the SIGCHLD signal handler, and the
- // QProcessManager destructor.
- int nselect = select(qt_qprocess_deadChild_pipe[0] + 1, &readset, 0, 0, 0);
- if (nselect < 0) {
- if (errno == EINTR)
- continue;
- break;
- }
-
- // empty only one byte from the pipe, even though several SIGCHLD
- // signals may have been delivered in the meantime, to avoid race
- // conditions.
- char c;
- if (qt_safe_read(qt_qprocess_deadChild_pipe[0], &c, 1) < 0 || c == '@')
- break;
-
- // catch any and all children that we can.
- catchDeadChildren();
- }
-}
-
-void QProcessManager::catchDeadChildren()
-{
- QMutexLocker locker(&mutex);
-
- // try to catch all children whose pid we have registered, and whose
- // deathPipe is still valid (i.e, we have not already notified it).
- QHash<int, QProcessInfo *>::Iterator it = children.begin();
- while (it != children.end()) {
- // notify all children that they may have died. they need to run
- // waitpid() in their own thread.
- QProcessInfo *info = it.value();
- qt_safe_write(info->deathPipe, "", 1);
-
-#if defined (QPROCESS_DEBUG)
- qDebug() << "QProcessManager::run() sending death notice to" << info->process;
-#endif
- ++it;
- }
-}
-
-static QBasicAtomicInt idCounter = Q_BASIC_ATOMIC_INITIALIZER(1);
-
-void QProcessManager::add(pid_t pid, QProcess *process)
-{
-#if defined (QPROCESS_DEBUG)
- qDebug() << "QProcessManager::add() adding pid" << pid << "process" << process;
-#endif
-
- // insert a new info structure for this process
- QProcessInfo *info = new QProcessInfo;
- info->process = process;
- info->deathPipe = process->d_func()->deathPipe[1];
- info->exitResult = 0;
- info->pid = pid;
-
- int serial = idCounter.fetchAndAddRelaxed(1);
- process->d_func()->serial = serial;
- children.insert(serial, info);
-}
-
-void QProcessManager::remove(QProcess *process)
-{
- QMutexLocker locker(&mutex);
-
- int serial = process->d_func()->serial;
- QProcessInfo *info = children.take(serial);
-#if defined (QPROCESS_DEBUG)
- if (info)
- qDebug() << "QProcessManager::remove() removing pid" << info->pid << "process" << info->process;
-#endif
- delete info;
-}
-
-void QProcessManager::lock()
-{
- mutex.lock();
-}
-
-void QProcessManager::unlock()
-{
- mutex.unlock();
-}
-
static int qt_create_pipe(int *pipe)
{
if (pipe[0] != -1)
@@ -562,14 +336,11 @@ void QProcessPrivate::startProcess()
qDebug("QProcessPrivate::startProcess()");
#endif
- processManager()->start();
-
// Initialize pipes
if (!openChannel(stdinChannel) ||
!openChannel(stdoutChannel) ||
!openChannel(stderrChannel) ||
- qt_create_pipe(childStartedPipe) != 0 ||
- qt_create_pipe(deathPipe) != 0) {
+ qt_create_pipe(childStartedPipe) != 0) {
processError = QProcess::FailedToStart;
q->setErrorString(qt_error_string(errno));
emit q->error(processError);
@@ -582,11 +353,6 @@ void QProcessPrivate::startProcess()
QSocketNotifier::Read, q);
QObject::connect(startupSocketNotifier, SIGNAL(activated(int)),
q, SLOT(_q_startupNotification()));
-
- deathNotifier = new QSocketNotifier(deathPipe[0],
- QSocketNotifier::Read, q);
- QObject::connect(deathNotifier, SIGNAL(activated(int)),
- q, SLOT(_q_processDied()));
}
// Start the process (platform dependent)
@@ -669,14 +435,17 @@ void QProcessPrivate::startProcess()
}
// Start the process manager, and fork off the child process.
- processManager()->lock();
-#if defined(Q_OS_QNX)
- pid_t childPid = spawnChild(workingDirPtr, argv, envp);
+#if defined(QPROCESS_USE_SPAWN)
+ pid_t childPid;
+ forkfd = spawnChild(&childPid, workingDirPtr, argv, envp);
+ Q_ASSUME(forkfd != FFD_CHILD_PROCESS);
#else
- pid_t childPid = fork();
- int lastForkErrno = errno;
+ pid_t childPid;
+ forkfd = ::forkfd(FFD_CLOEXEC, &childPid);
#endif
- if (childPid != 0) {
+ int lastForkErrno = errno;
+ if (forkfd != FFD_CHILD_PROCESS) {
+ // Parent process.
// Clean up duplicated memory.
free(dupProgramName);
for (int i = 1; i <= arguments.count(); ++i)
@@ -690,23 +459,15 @@ void QProcessPrivate::startProcess()
delete [] path;
}
- // This is not a valid check under QNX, because the semantics are
- // different. While under other platforms where fork() may succeed and exec() can still fail,
- // causing the childPid to hold a valid value (and thus evaluating the
- // following if to false), and then signaling the error via
- // childStartedPipe, under QNX on the other hand, spawn() return value will be assigned
- // to childPid (which will be -1 in case of failure). This will force
- // QProcess to cleanup, instead of signaling the error via
- // childStartedPipe. Since it will invalidade the pipes, functions like
- // QProcess::waitForStarted() will fail, for childStartedPipe will be
- // '-1' and mess with the select() calls.
-#if !defined(Q_OS_QNX)
- if (childPid < 0) {
+ // On QNX, if spawnChild failed, childPid will be -1 but forkfd is still 0.
+ // This is intentional because we only want to handle failure to fork()
+ // here, which is a rare occurrence. Handling of the failure to start is
+ // done elsewhere.
+ if (forkfd == -1) {
// Cleanup, report error and return
#if defined (QPROCESS_DEBUG)
qDebug("fork failed: %s", qPrintable(qt_error_string(lastForkErrno)));
#endif
- processManager()->unlock();
q->setProcessState(QProcess::NotRunning);
processError = QProcess::FailedToStart;
q->setErrorString(QProcess::tr("Resource error (fork failure): %1").arg(qt_error_string(lastForkErrno)));
@@ -716,21 +477,17 @@ void QProcessPrivate::startProcess()
}
// Start the child.
- if (childPid == 0) {
+#if !defined(QPROCESS_USE_SPAWN)
+ if (forkfd == FFD_CHILD_PROCESS) {
execChild(workingDirPtr, path, argv, envp);
::_exit(-1);
}
#endif
- // Register the child. In the mean time, we can get a SIGCHLD, so we need
- // to keep the lock held to avoid a race to catch the child.
- processManager()->add(childPid, q);
pid = Q_PID(childPid);
- processManager()->unlock();
// parent
// close the ends we don't use and make all pipes non-blocking
- ::fcntl(deathPipe[0], F_SETFL, ::fcntl(deathPipe[0], F_GETFL) | O_NONBLOCK);
qt_safe_close(childStartedPipe[1]);
childStartedPipe[1] = -1;
@@ -756,110 +513,151 @@ void QProcessPrivate::startProcess()
}
if (stderrChannel.pipe[0] != -1)
::fcntl(stderrChannel.pipe[0], F_SETFL, ::fcntl(stderrChannel.pipe[0], F_GETFL) | O_NONBLOCK);
+
+ if (threadData->eventDispatcher) {
+ deathNotifier = new QSocketNotifier(forkfd, QSocketNotifier::Read, q);
+ QObject::connect(deathNotifier, SIGNAL(activated(int)),
+ q, SLOT(_q_processDied()));
+ }
}
-#if defined(Q_OS_QNX)
-static pid_t doSpawn(int fd_count, int fd_map[], char **argv, char **envp,
- const char *workingDir, bool spawn_detached)
+#if defined(QPROCESS_USE_SPAWN)
+static int doSpawn(pid_t *ppid, const posix_spawn_file_actions_t *file_actions,
+ char **argv, char **envp, const char *workingDir, bool spawn_detached)
{
- // A multi threaded QNX Process can't fork so we call spawn() instead.
-
- struct inheritance inherit;
- memset(&inherit, 0, sizeof(inherit));
- inherit.flags |= SPAWN_SETSID;
- inherit.flags |= SPAWN_CHECK_SCRIPT;
- if (spawn_detached)
- inherit.flags |= SPAWN_NOZOMBIE;
- inherit.flags |= SPAWN_SETSIGDEF;
- sigaddset(&inherit.sigdefault, SIGPIPE); // reset the signal that we ignored
+ // A multi threaded QNX Process can't fork so we call spawnfd() instead.
+ posix_spawnattr_t attr;
+ posix_spawnattr_init(&attr);
+# ifdef Q_OS_QNX
+ posix_spawnattr_setxflags(&attr, POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETPGROUP
+ | (spawn_detached * POSIX_SPAWN_NOZOMBIE));
+# else
+ posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETPGROUP);
+# endif
+ posix_spawnattr_setpgroup(&attr, 0);
+
+ sigset_t sigdefault;
+ sigemptyset(&sigdefault);
+ sigaddset(&sigdefault, SIGPIPE); // reset the signal that we ignored
+ posix_spawnattr_setsigdefault(&attr, &sigdefault);
// enter the working directory
const char *oldWorkingDir = 0;
char buff[PATH_MAX + 1];
if (workingDir) {
+# ifdef Q_OS_QNX
//we need to freeze everyone in order to avoid race conditions with //chdir().
if (ThreadCtl(_NTO_TCTL_THREADS_HOLD, 0) == -1)
qWarning("ThreadCtl(): cannot hold threads: %s", qPrintable(qt_error_string(errno)));
+# endif
oldWorkingDir = QT_GETCWD(buff, PATH_MAX + 1);
if (QT_CHDIR(workingDir) == -1)
qWarning("ThreadCtl(): failed to chdir to %s", workingDir);
}
- pid_t childPid;
- EINTR_LOOP(childPid, ::spawn(argv[0], fd_count, fd_map, &inherit, argv, envp));
- if (childPid == -1) {
- inherit.flags |= SPAWN_SEARCH_PATH;
- EINTR_LOOP(childPid, ::spawn(argv[0], fd_count, fd_map, &inherit, argv, envp));
+ int fd;
+ if (spawn_detached) {
+ fd = ::posix_spawn(ppid, argv[0], file_actions, &attr, argv, envp);
+ if (fd == -1) {
+ fd = ::posix_spawnp(ppid, argv[0], file_actions, &attr, argv, envp);
+ }
+ } else {
+ // use spawnfd
+ fd = ::spawnfd(FFD_CLOEXEC | FFD_NONBLOCK, ppid, argv[0], file_actions, &attr, argv, envp);
+ if (fd == -1) {
+ fd = ::spawnfd(FFD_CLOEXEC | FFD_NONBLOCK | FFD_SPAWN_SEARCH_PATH, ppid, argv[0], file_actions,
+ &attr, argv, envp);
+ }
}
if (oldWorkingDir) {
if (QT_CHDIR(oldWorkingDir) == -1)
qWarning("ThreadCtl(): failed to chdir to %s", oldWorkingDir);
+# ifdef Q_OS_QNX
if (ThreadCtl(_NTO_TCTL_THREADS_CONT, 0) == -1)
qFatal("ThreadCtl(): cannot resume threads: %s", qPrintable(qt_error_string(errno)));
+# endif
}
- return childPid;
+ posix_spawnattr_destroy(&attr);
+ return fd;
}
-pid_t QProcessPrivate::spawnChild(const char *workingDir, char **argv, char **envp)
+pid_t QProcessPrivate::spawnChild(pid_t *ppid, const char *workingDir, char **argv, char **envp)
{
- // we need to manually fill in fd_map
- // to inherit the file descriptors from
- // the parent
- const int fd_count = sysconf(_SC_OPEN_MAX);
- QVarLengthArray<int, 1024> fd_map(fd_count);
-
- for (int i = 3; i < fd_count; ++i) {
- // here we rely that fcntl returns -1 and
- // sets errno to EBADF
- const int flags = ::fcntl(i, F_GETFD);
-
- fd_map[i] = ((flags >= 0) && !(flags & FD_CLOEXEC))
- ? i : SPAWN_FDCLOSED;
+ // posix_spawn causes all file descriptors with FD_CLOEXEC to be closed automatically;
+ // we only need to add the actions for our own pipes
+ posix_spawn_file_actions_t file_actions;
+ posix_spawn_file_actions_init(&file_actions);
+
+# ifdef Q_OS_QNX
+ static const bool OS_QNX = true;
+# else
+ static const bool OS_QNX = false;
+#endif
+
+ int fdmax = -1;
+
+ if (processChannelMode == QProcess::MergedChannels) {
+ // managed stderr == stdout
+ posix_spawn_file_actions_adddup2(&file_actions, stdoutChannel.pipe[1], STDERR_FILENO);
+
+ if (OS_QNX)
+ fdmax = qMax(fdmax, stdoutChannel.pipe[1]);
+ } else if (processChannelMode != QProcess::ForwardedChannels && processChannelMode != QProcess::ForwardedErrorChannel) {
+ // managed stderr
+ posix_spawn_file_actions_adddup2(&file_actions, stderrChannel.pipe[1], STDERR_FILENO);
+
+ if (OS_QNX)
+ fdmax = qMax(fdmax, stderrChannel.pipe[1]);
+ else
+ posix_spawn_file_actions_addclose(&file_actions, stderrChannel.pipe[1]);
+
}
- if (inputChannelMode == QProcess::ManagedInputChannel)
- fd_map[0] = stdinChannel.pipe[0];
- else
- fd_map[0] = QT_FILENO(stdin);
-
- switch (processChannelMode) {
- case QProcess::ForwardedChannels:
- fd_map[1] = QT_FILENO(stdout);
- fd_map[2] = QT_FILENO(stderr);
- break;
- case QProcess::ForwardedOutputChannel:
- fd_map[1] = QT_FILENO(stdout);
- fd_map[2] = stderrChannel.pipe[1];
- break;
- case QProcess::ForwardedErrorChannel:
- fd_map[1] = stdoutChannel.pipe[1];
- fd_map[2] = QT_FILENO(stderr);
- break;
- case QProcess::MergedChannels:
- fd_map[1] = stdoutChannel.pipe[1];
- fd_map[2] = stdoutChannel.pipe[1];
- break;
- case QProcess::SeparateChannels:
- fd_map[1] = stdoutChannel.pipe[1];
- fd_map[2] = stderrChannel.pipe[1];
- break;
+ if (processChannelMode != QProcess::ForwardedChannels && processChannelMode != QProcess::ForwardedOutputChannel) {
+ // managed stdout
+ posix_spawn_file_actions_adddup2(&file_actions, stdoutChannel.pipe[1], STDOUT_FILENO);
+
+ if (OS_QNX)
+ fdmax = qMax(fdmax, stdoutChannel.pipe[1]);
+ else
+ posix_spawn_file_actions_addclose(&file_actions, stdoutChannel.pipe[1]);
+
}
- pid_t childPid = doSpawn(fd_count, fd_map.data(), argv, envp, workingDir, false);
+ if (inputChannelMode == QProcess::ManagedInputChannel) {
+ posix_spawn_file_actions_adddup2(&file_actions, stdinChannel.pipe[0], STDIN_FILENO);
- if (childPid == -1) {
+ if (OS_QNX)
+ fdmax = qMax(fdmax, stdinChannel.pipe[0]);
+ else
+ posix_spawn_file_actions_addclose(&file_actions, stdinChannel.pipe[0]);
+ }
+
+ // Workaround: QNX's spawn implementation will actually dup all FD values
+ // LESS than fdmax - regardless of the FD_CLOEEXEC flag. So we need to add
+ // those to the list of files to close, otherwise dup will fail when some
+ // other thread closes the FD.
+ for (int i = 3; i <= fdmax; i++) {
+ if (::fcntl(i, F_GETFD) & FD_CLOEXEC)
+ posix_spawn_file_actions_addclose(&file_actions, i);
+ }
+
+ int retval = doSpawn(ppid, &file_actions, argv, envp, workingDir, false);
+
+ if (retval == -1) {
QString error = qt_error_string(errno);
qt_safe_write(childStartedPipe[1], error.data(), error.length() * sizeof(QChar));
qt_safe_close(childStartedPipe[1]);
childStartedPipe[1] = -1;
}
- return childPid;
+ posix_spawn_file_actions_destroy(&file_actions);
+ return retval;
}
#else
@@ -963,7 +761,7 @@ qint64 QProcessPrivate::bytesAvailableInChannel(const Channel *channel) const
if (::ioctl(channel->pipe[0], FIONREAD, (char *) &nbytes) >= 0)
available = (qint64) nbytes;
#if defined (QPROCESS_DEBUG)
- qDebug("QProcessPrivate::bytesAvailableInChannel(%d) == %lld", channel - &stdinChannel, available);
+ qDebug("QProcessPrivate::bytesAvailableInChannel(%d) == %lld", int(channel - &stdinChannel), available);
#endif
return available;
}
@@ -975,7 +773,7 @@ qint64 QProcessPrivate::readFromChannel(const Channel *channel, char *data, qint
#if defined QPROCESS_DEBUG
int save_errno = errno;
qDebug("QProcessPrivate::readFromChannel(%d, %p \"%s\", %lld) == %lld",
- channel - &stdinChannel,
+ int(channel - &stdinChannel),
data, qt_prettyDebug(data, bytesRead, 16).constData(), maxlen, bytesRead);
errno = save_errno;
#endif
@@ -1092,8 +890,8 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
- int nfds = deathPipe[0];
- FD_SET(deathPipe[0], &fdread);
+ int nfds = forkfd;
+ FD_SET(forkfd, &fdread);
if (processState == QProcess::Starting)
add_fd(nfds, childStartedPipe[0], &fdread);
@@ -1143,7 +941,7 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite))
_q_canWrite();
- if (deathPipe[0] == -1 || FD_ISSET(deathPipe[0], &fdread)) {
+ if (forkfd == -1 || FD_ISSET(forkfd, &fdread)) {
if (_q_processDied())
return false;
}
@@ -1172,8 +970,8 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
- int nfds = deathPipe[0];
- FD_SET(deathPipe[0], &fdread);
+ int nfds = forkfd;
+ FD_SET(forkfd, &fdread);
if (processState == QProcess::Starting)
add_fd(nfds, childStartedPipe[0], &fdread);
@@ -1217,7 +1015,7 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread))
_q_canReadStandardError();
- if (deathPipe[0] == -1 || FD_ISSET(deathPipe[0], &fdread)) {
+ if (forkfd == -1 || FD_ISSET(forkfd, &fdread)) {
if (_q_processDied())
return false;
}
@@ -1256,8 +1054,8 @@ bool QProcessPrivate::waitForFinished(int msecs)
if (stderrChannel.pipe[0] != -1)
add_fd(nfds, stderrChannel.pipe[0], &fdread);
- if (processState == QProcess::Running)
- add_fd(nfds, deathPipe[0], &fdread);
+ if (processState == QProcess::Running && forkfd != -1)
+ add_fd(nfds, forkfd, &fdread);
if (!stdinChannel.buffer.isEmpty() && stdinChannel.pipe[1] != -1)
add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
@@ -1290,7 +1088,7 @@ bool QProcessPrivate::waitForFinished(int msecs)
if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread))
_q_canReadStandardError();
- if (deathPipe[0] == -1 || FD_ISSET(deathPipe[0], &fdread)) {
+ if (forkfd == -1 || FD_ISSET(forkfd, &fdread)) {
if (_q_processDied())
return true;
}
@@ -1308,46 +1106,41 @@ bool QProcessPrivate::waitForWrite(int msecs)
void QProcessPrivate::findExitCode()
{
- Q_Q(QProcess);
- processManager()->remove(q);
}
bool QProcessPrivate::waitForDeadChild()
{
- Q_Q(QProcess);
+ if (forkfd == -1)
+ return true; // child has already exited
- // read a byte from the death pipe
- char c;
- qt_safe_read(deathPipe[0], &c, 1);
+ // read the process information from our fd
+ siginfo_t info;
+ qint64 ret = qt_safe_read(forkfd, &info, sizeof info);
+ Q_ASSERT(ret == sizeof info);
+ Q_UNUSED(ret);
+
+ Q_ASSERT(info.si_pid == pid_t(pid));
+
+ exitCode = info.si_status;
+ crashed = info.si_code != CLD_EXITED;
+
+ qt_safe_close(forkfd);
+ forkfd = -1; // Child is dead, don't try to kill it anymore
- // check if our process is dead
- int exitStatus;
- if (qt_safe_waitpid(pid_t(pid), &exitStatus, WNOHANG) > 0) {
- processManager()->remove(q);
- crashed = !WIFEXITED(exitStatus);
- exitCode = WEXITSTATUS(exitStatus);
-#if defined QPROCESS_DEBUG
- qDebug() << "QProcessPrivate::waitForDeadChild() dead with exitCode"
- << exitCode << ", crashed?" << crashed;
-#endif
- return true;
- }
#if defined QPROCESS_DEBUG
- qDebug() << "QProcessPrivate::waitForDeadChild() not dead!";
+ qDebug() << "QProcessPrivate::waitForDeadChild() dead with exitCode"
+ << exitCode << ", crashed?" << crashed;
#endif
- return false;
+ return true;
}
void QProcessPrivate::_q_notified()
{
}
-#if defined(Q_OS_QNX)
+#if defined(QPROCESS_USE_SPAWN)
bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory, qint64 *pid)
{
- const int fd_count = 3;
- int fd_map[fd_count] = { QT_FILENO(stdin), QT_FILENO(stdout), QT_FILENO(stderr) };
-
QList<QByteArray> enc_args;
enc_args.append(QFile::encodeName(program));
for (int i = 0; i < arguments.size(); ++i)
@@ -1369,19 +1162,18 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a
workingDirPtr = encodedWorkingDirectory.constData();
}
- pid_t childPid = doSpawn(fd_count, fd_map, raw_argv.data(), envp, workingDirPtr, true);
- if (pid && childPid != -1)
+ pid_t childPid;
+ int retval = doSpawn(&childPid, NULL, raw_argv.data(), envp, workingDirPtr, true);
+ if (pid && retval != -1)
*pid = childPid;
- return childPid != -1;
+ return retval != -1;
}
#else
bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory, qint64 *pid)
{
- processManager()->start();
-
QByteArray encodedWorkingDirectory = QFile::encodeName(workingDirectory);
// To catch the startup of the child
@@ -1496,13 +1288,6 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a
}
#endif
-void QProcessPrivate::initializeProcessManager()
-{
- (void) processManager();
-}
-
QT_END_NAMESPACE
-#include "qprocess_unix.moc"
-
#endif // QT_NO_PROCESS
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp
index ed6bfb4e0d..d9b51cd288 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -873,10 +873,16 @@ public:
inline QDynamicBufferResourceRoot(const QString &_root) : root(_root), buffer(0) { }
inline ~QDynamicBufferResourceRoot() { }
inline const uchar *mappingBuffer() const { return buffer; }
- virtual QString mappingRoot() const { return root; }
- virtual ResourceRootType type() const { return Resource_Buffer; }
+ virtual QString mappingRoot() const Q_DECL_OVERRIDE { return root; }
+ virtual ResourceRootType type() const Q_DECL_OVERRIDE { return Resource_Buffer; }
+
+ // size == -1 means "unknown"
+ bool registerSelf(const uchar *b, int size)
+ {
+ // 5 int "pointers"
+ if (size >= 0 && size < 20)
+ return false;
- bool registerSelf(const uchar *b) {
//setup the data now
int offset = 0;
@@ -903,6 +909,10 @@ public:
(b[offset+2] << 8) + (b[offset+3] << 0);
offset += 4;
+ // Some sanity checking for sizes. This is _not_ a security measure.
+ if (size >= 0 && (tree_offset >= size || data_offset >= size || name_offset >= size))
+ return false;
+
if(version == 0x01) {
buffer = b;
setSource(b+tree_offset, b+name_offset, b+data_offset);
@@ -950,7 +960,7 @@ public:
}
}
QString mappingFile() const { return fileName; }
- virtual ResourceRootType type() const { return Resource_File; }
+ virtual ResourceRootType type() const Q_DECL_OVERRIDE { return Resource_File; }
bool registerSelf(const QString &f) {
bool fromMM = false;
@@ -1009,7 +1019,7 @@ public:
}
fromMM = false;
}
- if(data && QDynamicBufferResourceRoot::registerSelf(data)) {
+ if (data && QDynamicBufferResourceRoot::registerSelf(data, data_len)) {
if(fromMM) {
unmapPointer = data;
unmapLength = data_len;
@@ -1124,7 +1134,7 @@ QResource::registerResource(const uchar *rccData, const QString &resourceRoot)
}
QDynamicBufferResourceRoot *root = new QDynamicBufferResourceRoot(r);
- if(root->registerSelf(rccData)) {
+ if (root->registerSelf(rccData, -1)) {
root->ref.ref();
QMutexLocker lock(resourceMutex());
resourceList()->append(root);
diff --git a/src/corelib/io/qresource_iterator_p.h b/src/corelib/io/qresource_iterator_p.h
index 451773ec63..dce298fb44 100644
--- a/src/corelib/io/qresource_iterator_p.h
+++ b/src/corelib/io/qresource_iterator_p.h
@@ -57,10 +57,10 @@ public:
QResourceFileEngineIterator(QDir::Filters filters, const QStringList &filterNames);
~QResourceFileEngineIterator();
- QString next();
- bool hasNext() const;
+ QString next() Q_DECL_OVERRIDE;
+ bool hasNext() const Q_DECL_OVERRIDE;
- QString currentFileName() const;
+ QString currentFileName() const Q_DECL_OVERRIDE;
private:
mutable QStringList entries;
diff --git a/src/corelib/io/qresource_p.h b/src/corelib/io/qresource_p.h
index 030d1587e5..11b2836215 100644
--- a/src/corelib/io/qresource_p.h
+++ b/src/corelib/io/qresource_p.h
@@ -58,52 +58,52 @@ public:
explicit QResourceFileEngine(const QString &path);
~QResourceFileEngine();
- virtual void setFileName(const QString &file);
+ virtual void setFileName(const QString &file) Q_DECL_OVERRIDE;
- virtual bool open(QIODevice::OpenMode flags) ;
- virtual bool close();
- virtual bool flush();
- virtual qint64 size() const;
- virtual qint64 pos() const;
+ virtual bool open(QIODevice::OpenMode flags) Q_DECL_OVERRIDE ;
+ virtual bool close() Q_DECL_OVERRIDE;
+ virtual bool flush() Q_DECL_OVERRIDE;
+ virtual qint64 size() const Q_DECL_OVERRIDE;
+ virtual qint64 pos() const Q_DECL_OVERRIDE;
virtual bool atEnd() const;
- virtual bool seek(qint64);
- virtual qint64 read(char *data, qint64 maxlen);
- virtual qint64 write(const char *data, qint64 len);
+ virtual bool seek(qint64) Q_DECL_OVERRIDE;
+ virtual qint64 read(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
+ virtual qint64 write(const char *data, qint64 len) Q_DECL_OVERRIDE;
- virtual bool remove();
- virtual bool copy(const QString &newName);
- virtual bool rename(const QString &newName);
- virtual bool link(const QString &newName);
+ virtual bool remove() Q_DECL_OVERRIDE;
+ virtual bool copy(const QString &newName) Q_DECL_OVERRIDE;
+ virtual bool rename(const QString &newName) Q_DECL_OVERRIDE;
+ virtual bool link(const QString &newName) Q_DECL_OVERRIDE;
- virtual bool isSequential() const;
+ virtual bool isSequential() const Q_DECL_OVERRIDE;
- virtual bool isRelativePath() const;
+ virtual bool isRelativePath() const Q_DECL_OVERRIDE;
- virtual bool mkdir(const QString &dirName, bool createParentDirectories) const;
- virtual bool rmdir(const QString &dirName, bool recurseParentDirectories) const;
+ virtual bool mkdir(const QString &dirName, bool createParentDirectories) const Q_DECL_OVERRIDE;
+ virtual bool rmdir(const QString &dirName, bool recurseParentDirectories) const Q_DECL_OVERRIDE;
- virtual bool setSize(qint64 size);
+ virtual bool setSize(qint64 size) Q_DECL_OVERRIDE;
- virtual QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const;
+ virtual QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const Q_DECL_OVERRIDE;
- virtual bool caseSensitive() const;
+ virtual bool caseSensitive() const Q_DECL_OVERRIDE;
- virtual FileFlags fileFlags(FileFlags type) const;
+ virtual FileFlags fileFlags(FileFlags type) const Q_DECL_OVERRIDE;
- virtual bool setPermissions(uint perms);
+ virtual bool setPermissions(uint perms) Q_DECL_OVERRIDE;
- virtual QString fileName(QAbstractFileEngine::FileName file) const;
+ virtual QString fileName(QAbstractFileEngine::FileName file) const Q_DECL_OVERRIDE;
- virtual uint ownerId(FileOwner) const;
- virtual QString owner(FileOwner) const;
+ virtual uint ownerId(FileOwner) const Q_DECL_OVERRIDE;
+ virtual QString owner(FileOwner) const Q_DECL_OVERRIDE;
- virtual QDateTime fileTime(FileTime time) const;
+ virtual QDateTime fileTime(FileTime time) const Q_DECL_OVERRIDE;
- virtual Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames);
- virtual Iterator *endEntryList();
+ virtual Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames) Q_DECL_OVERRIDE;
+ virtual Iterator *endEntryList() Q_DECL_OVERRIDE;
- bool extension(Extension extension, const ExtensionOption *option = 0, ExtensionReturn *output = 0);
- bool supportsExtension(Extension extension) const;
+ bool extension(Extension extension, const ExtensionOption *option = 0, ExtensionReturn *output = 0) Q_DECL_OVERRIDE;
+ bool supportsExtension(Extension extension) const Q_DECL_OVERRIDE;
};
QT_END_NAMESPACE
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index ebca7d57ff..baaa0dab53 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -1017,7 +1017,6 @@ static inline int pathHashKey(QSettings::Format format, QSettings::Scope scope)
static void initDefaultPaths(QMutexLocker *locker)
{
PathHash *pathHash = pathHashFunc();
- QString homePath = QDir::homePath();
QString systemPath;
locker->unlock();
@@ -1051,13 +1050,13 @@ static void initDefaultPaths(QMutexLocker *locker)
QString userPath;
char *env = getenv("XDG_CONFIG_HOME");
if (env == 0) {
- userPath = homePath;
+ userPath = QDir::homePath();
userPath += QLatin1Char('/');
userPath += QLatin1String(".config");
} else if (*env == '/') {
userPath = QFile::decodeName(env);
} else {
- userPath = homePath;
+ userPath = QDir::homePath();
userPath += QLatin1Char('/');
userPath += QFile::decodeName(env);
}
diff --git a/src/corelib/io/qsettings.h b/src/corelib/io/qsettings.h
index 4986c06896..1ce2865c63 100644
--- a/src/corelib/io/qsettings.h
+++ b/src/corelib/io/qsettings.h
@@ -177,7 +177,7 @@ public:
protected:
#ifndef QT_NO_QOBJECT
- bool event(QEvent *event);
+ bool event(QEvent *event) Q_DECL_OVERRIDE;
#endif
private:
diff --git a/src/corelib/io/qsettings_p.h b/src/corelib/io/qsettings_p.h
index 715f13530a..0525fab77a 100644
--- a/src/corelib/io/qsettings_p.h
+++ b/src/corelib/io/qsettings_p.h
@@ -270,17 +270,17 @@ public:
QConfFileSettingsPrivate(const QString &fileName, QSettings::Format format);
~QConfFileSettingsPrivate();
- void remove(const QString &key);
- void set(const QString &key, const QVariant &value);
- bool get(const QString &key, QVariant *value) const;
+ void remove(const QString &key) Q_DECL_OVERRIDE;
+ void set(const QString &key, const QVariant &value) Q_DECL_OVERRIDE;
+ bool get(const QString &key, QVariant *value) const Q_DECL_OVERRIDE;
- QStringList children(const QString &prefix, ChildSpec spec) const;
+ QStringList children(const QString &prefix, ChildSpec spec) const Q_DECL_OVERRIDE;
- void clear();
- void sync();
- void flush();
- bool isWritable() const;
- QString fileName() const;
+ void clear() Q_DECL_OVERRIDE;
+ void sync() Q_DECL_OVERRIDE;
+ void flush() Q_DECL_OVERRIDE;
+ bool isWritable() const Q_DECL_OVERRIDE;
+ QString fileName() const Q_DECL_OVERRIDE;
bool readIniFile(const QByteArray &data, UnparsedSettingsMap *unparsedIniSections);
static bool readIniSection(const QSettingsKey &section, const QByteArray &data,
diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp
index b41aee55d2..2e16c6d1ae 100644
--- a/src/corelib/io/qstandardpaths.cpp
+++ b/src/corelib/io/qstandardpaths.cpp
@@ -142,6 +142,10 @@ QT_BEGIN_NAMESPACE
\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.
+ \value AppConfigLocation Returns a directory location where user-specific
+ configuration files should be written. This is an application-specific directory,
+ and the returned path is never empty.
+ This enum value was added in Qt 5.5.
The following table gives examples of paths on different operating systems.
The first path is the writable path (unless noted). Other, additional
@@ -206,6 +210,9 @@ QT_BEGIN_NAMESPACE
\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"
+ \row \li AppConfigLocation
+ \li "~/Library/Preferences/<APPNAME>"
+ \li "C:/Users/<USER>/AppData/Local/<APPNAME>", "C:/ProgramData/<APPNAME>"
\endtable
\table
@@ -267,6 +274,9 @@ QT_BEGIN_NAMESPACE
\row \li AppLocalDataLocation
\li "<APPROOT>/data", "<APPROOT>/app/native/assets"
\li "~/.local/share/<APPNAME>", "/usr/local/share/<APPNAME>", "/usr/share/<APPNAME>"
+ \row \li AppConfigLocation
+ \li "<APPROOT>/data/Settings"
+ \li "~/.config/<APPNAME>", "/etc/xdg/<APPNAME>"
\endtable
\table
@@ -307,6 +317,8 @@ QT_BEGIN_NAMESPACE
\li "<APPROOT>/cache" (there is no shared cache)
\row \li AppDataLocation
\li "<APPROOT>/files", "<USER>/<APPNAME>/files"
+ \row \li AppConfigLocation
+ \li "<APPROOT>/files/settings"
\endtable
In the table above, \c <APPNAME> is usually the organization name, the
@@ -565,6 +577,8 @@ QString QStandardPaths::displayName(StandardLocation type)
case AppDataLocation:
case AppLocalDataLocation:
return QCoreApplication::translate("QStandardPaths", "Application Data");
+ case AppConfigLocation:
+ return QCoreApplication::translate("QStandardPaths", "Application Configuration");
}
// not reached
return QString();
@@ -585,7 +599,7 @@ QString QStandardPaths::displayName(StandardLocation type)
This affects the locations into which test programs might write files:
GenericDataLocation, DataLocation, ConfigLocation, GenericConfigLocation,
- GenericCacheLocation, CacheLocation.
+ AppConfigLocation, GenericCacheLocation, CacheLocation.
Other locations are not affected.
On Unix, \c XDG_DATA_HOME is set to \e ~/.qttest/share, \c XDG_CONFIG_HOME is
diff --git a/src/corelib/io/qstandardpaths.h b/src/corelib/io/qstandardpaths.h
index e305450240..60e53fe117 100644
--- a/src/corelib/io/qstandardpaths.h
+++ b/src/corelib/io/qstandardpaths.h
@@ -64,6 +64,7 @@ public:
GenericCacheLocation,
GenericConfigLocation,
AppDataLocation,
+ AppConfigLocation,
AppLocalDataLocation = DataLocation
};
diff --git a/src/corelib/io/qstandardpaths_android.cpp b/src/corelib/io/qstandardpaths_android.cpp
index 958b4ea486..b887e107e7 100644
--- a/src/corelib/io/qstandardpaths_android.cpp
+++ b/src/corelib/io/qstandardpaths_android.cpp
@@ -233,6 +233,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
return getExternalStoragePublicDirectory("DIRECTORY_DOWNLOADS");
case QStandardPaths::GenericConfigLocation:
case QStandardPaths::ConfigLocation:
+ case QStandardPaths::AppConfigLocation:
return getFilesDir() + testDir() + QLatin1String("/settings");
case QStandardPaths::GenericDataLocation:
return getExternalStorageDirectory() + testDir();
diff --git a/src/corelib/io/qstandardpaths_blackberry.cpp b/src/corelib/io/qstandardpaths_blackberry.cpp
index 02d7c110ae..473da7542c 100644
--- a/src/corelib/io/qstandardpaths_blackberry.cpp
+++ b/src/corelib/io/qstandardpaths_blackberry.cpp
@@ -69,6 +69,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
return QDir::homePath() + testModeInsert() + QLatin1String("/Cache");
case ConfigLocation:
case GenericConfigLocation:
+ case AppConfigLocation:
return QDir::homePath() + testModeInsert() + QLatin1String("/Settings");
case GenericDataLocation:
return sharedRoot + testModeInsert() + QLatin1String("/misc");
diff --git a/src/corelib/io/qstandardpaths_haiku.cpp b/src/corelib/io/qstandardpaths_haiku.cpp
new file mode 100644
index 0000000000..ac57686126
--- /dev/null
+++ b/src/corelib/io/qstandardpaths_haiku.cpp
@@ -0,0 +1,222 @@
+/***************************************************************************
+**
+** Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias Koenig <tobias.koenig@kdab.com>
+** 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$
+**
+****************************************************************************/
+
+#include "qstandardpaths.h"
+
+#ifndef QT_NO_STANDARDPATHS
+
+#ifndef QT_BOOTSTRAPPED
+#include <qcoreapplication.h>
+#endif
+
+#include <qfile.h>
+
+#include <FindDirectory.h>
+#include <Path.h>
+#include <PathFinder.h>
+#include <StringList.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+
+void appendOrganizationAndApp(QString &path)
+{
+#ifndef QT_BOOTSTRAPPED
+ const QString org = QCoreApplication::organizationName();
+ if (!org.isEmpty())
+ path += QLatin1Char('/') + org;
+ const QString appName = QCoreApplication::applicationName();
+ if (!appName.isEmpty())
+ path += QLatin1Char('/') + appName;
+#else
+ Q_UNUSED(path);
+#endif
+}
+
+/*
+ * Returns the generic standard path for given directory type.
+ */
+QString haikuStandardPath(directory_which which)
+{
+ BPath standardPath;
+
+ if (find_directory(which, &standardPath, false) != B_OK)
+ return QString();
+
+ return QFile::decodeName(standardPath.Path());
+}
+
+/*
+ * Returns the generic standard paths for given path type.
+ */
+QStringList haikuStandardPaths(path_base_directory baseDirectory)
+{
+ BStringList paths;
+
+ if (BPathFinder::FindPaths(baseDirectory, paths) != B_OK)
+ return QStringList();
+
+ QStringList standardPaths;
+ for (int i = 0; i < paths.CountStrings(); ++i) {
+ standardPaths << QFile::decodeName(paths.StringAt(i).String());
+ }
+
+ return standardPaths;
+}
+
+/*
+ * Returns the application specific standard path for given directory type.
+ */
+QString haikuAppStandardPath(directory_which which)
+{
+ QString path = haikuStandardPath(which);
+ if (!path.isEmpty())
+ appendOrganizationAndApp(path);
+
+ return path;
+}
+
+/*
+ * Returns the application specific standard paths for given path type.
+ */
+QStringList haikuAppStandardPaths(path_base_directory baseDirectory)
+{
+ QStringList paths = haikuStandardPaths(baseDirectory);
+ for (int i = 0; i < paths.count(); ++i)
+ appendOrganizationAndApp(paths[i]);
+
+ return paths;
+}
+
+} // namespace
+
+QString QStandardPaths::writableLocation(StandardLocation type)
+{
+ switch (type) {
+ case DesktopLocation:
+ return haikuStandardPath(B_DESKTOP_DIRECTORY);
+ case DocumentsLocation: // fall through
+ case PicturesLocation:
+ case MusicLocation:
+ case MoviesLocation:
+ case DownloadLocation:
+ case HomeLocation:
+ return haikuStandardPath(B_USER_DIRECTORY);
+ case FontsLocation:
+ return haikuStandardPath(B_USER_NONPACKAGED_FONTS_DIRECTORY);
+ case ApplicationsLocation:
+ return haikuStandardPath(B_USER_NONPACKAGED_BIN_DIRECTORY);
+ case TempLocation:
+ return haikuStandardPath(B_SYSTEM_TEMP_DIRECTORY);
+ case AppDataLocation: // fall through
+ case AppLocalDataLocation:
+ return haikuAppStandardPath(B_USER_NONPACKAGED_DATA_DIRECTORY);
+ case GenericDataLocation:
+ return haikuStandardPath(B_USER_NONPACKAGED_DATA_DIRECTORY);
+ case CacheLocation:
+ return haikuAppStandardPath(B_USER_CACHE_DIRECTORY);
+ case GenericCacheLocation:
+ return haikuStandardPath(B_USER_CACHE_DIRECTORY);
+ case ConfigLocation: // fall through
+ case AppConfigLocation:
+ return haikuAppStandardPath(B_USER_SETTINGS_DIRECTORY);
+ case GenericConfigLocation:
+ return haikuStandardPath(B_USER_SETTINGS_DIRECTORY);
+ default:
+ return QString();
+ }
+}
+
+QStringList QStandardPaths::standardLocations(StandardLocation type)
+{
+ QStringList paths;
+
+ const QString writablePath = writableLocation(type);
+ if (!writablePath.isEmpty())
+ paths += writablePath;
+
+ switch (type) {
+ case DocumentsLocation: // fall through
+ case PicturesLocation:
+ case MusicLocation:
+ case MoviesLocation:
+ case DownloadLocation:
+ case HomeLocation:
+ paths += haikuStandardPath(B_USER_NONPACKAGED_DIRECTORY);
+ break;
+ case FontsLocation:
+ paths += haikuStandardPaths(B_FIND_PATH_FONTS_DIRECTORY);
+ break;
+ case ApplicationsLocation:
+ paths += haikuStandardPaths(B_FIND_PATH_BIN_DIRECTORY);
+ paths += haikuStandardPaths(B_FIND_PATH_APPS_DIRECTORY);
+ break;
+ case AppDataLocation: // fall through
+ case AppLocalDataLocation:
+ paths += haikuAppStandardPaths(B_FIND_PATH_DATA_DIRECTORY);
+ break;
+ case GenericDataLocation:
+ paths += haikuStandardPaths(B_FIND_PATH_DATA_DIRECTORY);
+ break;
+ case CacheLocation:
+ paths += haikuAppStandardPath(B_SYSTEM_CACHE_DIRECTORY);
+ break;
+ case GenericCacheLocation:
+ paths += haikuStandardPath(B_SYSTEM_CACHE_DIRECTORY);
+ break;
+ case ConfigLocation: // fall through
+ case AppConfigLocation:
+ paths += haikuAppStandardPath(B_SYSTEM_SETTINGS_DIRECTORY);
+ break;
+ case GenericConfigLocation:
+ paths += haikuStandardPath(B_SYSTEM_SETTINGS_DIRECTORY);
+ break;
+ default:
+ break;
+ }
+
+ return paths;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_STANDARDPATHS
diff --git a/src/corelib/io/qstandardpaths_ios.mm b/src/corelib/io/qstandardpaths_ios.mm
index 9b500f4623..449c66fe0c 100644
--- a/src/corelib/io/qstandardpaths_ios.mm
+++ b/src/corelib/io/qstandardpaths_ios.mm
@@ -103,6 +103,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
break;
case ConfigLocation:
case GenericConfigLocation:
+ case AppConfigLocation:
location = pathForDirectory(NSDocumentDirectory);
break;
case DownloadLocation:
diff --git a/src/corelib/io/qstandardpaths_mac.mm b/src/corelib/io/qstandardpaths_mac.mm
index 13b864600e..9d5d6de6ad 100644
--- a/src/corelib/io/qstandardpaths_mac.mm
+++ b/src/corelib/io/qstandardpaths_mac.mm
@@ -53,6 +53,7 @@ OSType translateLocation(QStandardPaths::StandardLocation type)
switch (type) {
case QStandardPaths::ConfigLocation:
case QStandardPaths::GenericConfigLocation:
+ case QStandardPaths::AppConfigLocation:
return kPreferencesFolderType;
case QStandardPaths::DesktopLocation:
return kDesktopFolderType;
@@ -129,7 +130,8 @@ static QString macLocation(QStandardPaths::StandardLocation type, short domain)
QString path = getFullPath(ref);
- if (type == QStandardPaths::AppDataLocation || type == QStandardPaths::AppLocalDataLocation || type == QStandardPaths::CacheLocation)
+ if (type == QStandardPaths::AppDataLocation || type == QStandardPaths::AppLocalDataLocation ||
+ type == QStandardPaths::CacheLocation || type == QStandardPaths::AppConfigLocation)
appendOrganizationAndApp(path);
return path;
}
@@ -155,7 +157,11 @@ QString QStandardPaths::writableLocation(StandardLocation type)
return path;
case GenericConfigLocation:
case ConfigLocation:
- return qttestDir + QLatin1String("/Preferences");
+ case AppConfigLocation:
+ path = qttestDir + QLatin1String("/Preferences");
+ if (type == AppConfigLocation)
+ appendOrganizationAndApp(path);
+ return path;
default:
break;
}
diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp
index 2ad6dfa121..94dcbaff9a 100644
--- a/src/corelib/io/qstandardpaths_unix.cpp
+++ b/src/corelib/io/qstandardpaths_unix.cpp
@@ -97,6 +97,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
}
case ConfigLocation:
case GenericConfigLocation:
+ case AppConfigLocation:
{
// http://standards.freedesktop.org/basedir-spec/latest/
QString xdgConfigHome = QFile::decodeName(qgetenv("XDG_CONFIG_HOME"));
@@ -104,6 +105,8 @@ QString QStandardPaths::writableLocation(StandardLocation type)
xdgConfigHome = QDir::homePath() + QLatin1String("/.qttest/config");
if (xdgConfigHome.isEmpty())
xdgConfigHome = QDir::homePath() + QLatin1String("/.config");
+ if (type == AppConfigLocation)
+ appendOrganizationAndApp(xdgConfigHome);
return xdgConfigHome;
}
case RuntimeLocation:
@@ -278,21 +281,31 @@ static QStringList xdgDataDirs()
return dirs;
}
+static QStringList xdgConfigDirs()
+{
+ QStringList dirs;
+ // http://standards.freedesktop.org/basedir-spec/latest/
+ const QString xdgConfigDirs = QFile::decodeName(qgetenv("XDG_CONFIG_DIRS"));
+ if (xdgConfigDirs.isEmpty())
+ dirs.append(QString::fromLatin1("/etc/xdg"));
+ else
+ dirs = xdgConfigDirs.split(QLatin1Char(':'));
+ return dirs;
+}
+
QStringList QStandardPaths::standardLocations(StandardLocation type)
{
QStringList dirs;
switch (type) {
case ConfigLocation:
case GenericConfigLocation:
- {
- // http://standards.freedesktop.org/basedir-spec/latest/
- const QString xdgConfigDirs = QFile::decodeName(qgetenv("XDG_CONFIG_DIRS"));
- if (xdgConfigDirs.isEmpty())
- dirs.append(QString::fromLatin1("/etc/xdg"));
- else
- dirs = xdgConfigDirs.split(QLatin1Char(':'));
- }
- break;
+ dirs = xdgConfigDirs();
+ break;
+ case AppConfigLocation:
+ dirs = xdgConfigDirs();
+ for (int i = 0; i < dirs.count(); ++i)
+ appendOrganizationAndApp(dirs[i]);
+ break;
case GenericDataLocation:
dirs = xdgDataDirs();
break;
diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp
index 5e56db3797..8fe4be0d5c 100644
--- a/src/corelib/io/qstandardpaths_win.cpp
+++ b/src/corelib/io/qstandardpaths_win.cpp
@@ -98,6 +98,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
switch (type) {
case ConfigLocation: // same as AppLocalDataLocation, on Windows
case GenericConfigLocation: // same as GenericDataLocation on Windows
+ case AppConfigLocation:
case AppDataLocation:
case AppLocalDataLocation:
case GenericDataLocation:
@@ -195,6 +196,7 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
switch (type) {
case ConfigLocation: // same as AppLocalDataLocation, on Windows (oversight, but too late to fix it)
case GenericConfigLocation: // same as GenericDataLocation, on Windows
+ case AppConfigLocation: // same as AppLocalDataLocation, that one on purpose
case AppDataLocation:
case AppLocalDataLocation:
case GenericDataLocation:
diff --git a/src/corelib/io/qstandardpaths_winrt.cpp b/src/corelib/io/qstandardpaths_winrt.cpp
index 5c09b4814d..6aa31bf296 100644
--- a/src/corelib/io/qstandardpaths_winrt.cpp
+++ b/src/corelib/io/qstandardpaths_winrt.cpp
@@ -67,6 +67,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
switch (type) {
case ConfigLocation: // same as AppLocalDataLocation, on Windows
case GenericConfigLocation: // same as GenericDataLocation, on Windows
+ case AppConfigLocation:
case AppDataLocation:
case AppLocalDataLocation:
case GenericDataLocation: {
diff --git a/src/corelib/io/qstorageinfo_p.h b/src/corelib/io/qstorageinfo_p.h
index 9c8e51f475..dea25d440d 100644
--- a/src/corelib/io/qstorageinfo_p.h
+++ b/src/corelib/io/qstorageinfo_p.h
@@ -73,14 +73,14 @@ public:
protected:
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
- void retreiveVolumeInfo();
- void retreiveDiskFreeSpace();
+ void retrieveVolumeInfo();
+ void retrieveDiskFreeSpace();
#elif defined(Q_OS_MAC)
void retrievePosixInfo();
void retrieveUrlProperties(bool initRootPath = false);
void retrieveLabel();
#elif defined(Q_OS_UNIX)
- void retreiveVolumeInfo();
+ void retrieveVolumeInfo();
#endif
public:
diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp
index 857464f578..83d94bfe06 100644
--- a/src/corelib/io/qstorageinfo_unix.cpp
+++ b/src/corelib/io/qstorageinfo_unix.cpp
@@ -75,6 +75,9 @@
# if !defined(ST_RDONLY)
# define ST_RDONLY 1 // hack for missing define on Android
# endif
+#elif defined(Q_OS_HAIKU)
+# define QT_STATFSBUF struct statvfs
+# define QT_STATFS ::statvfs
#else
# if defined(QT_LARGEFILE_SUPPORT)
# define QT_STATFSBUF struct statvfs64
@@ -402,11 +405,11 @@ void QStorageInfoPrivate::doStat()
if (rootPath.isEmpty())
return;
- retreiveVolumeInfo();
+ retrieveVolumeInfo();
name = retrieveLabel(device);
}
-void QStorageInfoPrivate::retreiveVolumeInfo()
+void QStorageInfoPrivate::retrieveVolumeInfo()
{
QT_STATFSBUF statfs_buf;
int result;
diff --git a/src/corelib/io/qstorageinfo_win.cpp b/src/corelib/io/qstorageinfo_win.cpp
index 8c276b2798..51a268f58c 100644
--- a/src/corelib/io/qstorageinfo_win.cpp
+++ b/src/corelib/io/qstorageinfo_win.cpp
@@ -114,12 +114,12 @@ void QStorageInfoPrivate::doStat()
if (rootPath.isEmpty())
return;
- retreiveVolumeInfo();
+ retrieveVolumeInfo();
device = getDevice(rootPath);
- retreiveDiskFreeSpace();
+ retrieveDiskFreeSpace();
}
-void QStorageInfoPrivate::retreiveVolumeInfo()
+void QStorageInfoPrivate::retrieveVolumeInfo()
{
const UINT oldmode = ::SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
@@ -151,7 +151,7 @@ void QStorageInfoPrivate::retreiveVolumeInfo()
::SetErrorMode(oldmode);
}
-void QStorageInfoPrivate::retreiveDiskFreeSpace()
+void QStorageInfoPrivate::retrieveDiskFreeSpace()
{
const UINT oldmode = ::SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
index 4a9aafcf0b..c96d0504f4 100644
--- a/src/corelib/io/qtemporaryfile.cpp
+++ b/src/corelib/io/qtemporaryfile.cpp
@@ -222,6 +222,7 @@ static bool createFileFromTemplate(NativeFileHandle &file,
}
Q_ASSERT(false);
+ return false;
}
//************* QTemporaryFileEngine
diff --git a/src/corelib/io/qtemporaryfile.h b/src/corelib/io/qtemporaryfile.h
index 908cc231af..f21f87fd21 100644
--- a/src/corelib/io/qtemporaryfile.h
+++ b/src/corelib/io/qtemporaryfile.h
@@ -71,7 +71,7 @@ public:
// ### Hides open(flags)
bool open() { return open(QIODevice::ReadWrite); }
- QString fileName() const;
+ QString fileName() const Q_DECL_OVERRIDE;
QString fileTemplate() const;
void setFileTemplate(const QString &name);
#if QT_DEPRECATED_SINCE(5,1)
@@ -85,7 +85,7 @@ public:
static QTemporaryFile *createNativeFile(QFile &file);
protected:
- bool open(OpenMode flags);
+ bool open(OpenMode flags) Q_DECL_OVERRIDE;
private:
friend class QFile;
diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp
index 571875c508..fa455c0e8c 100644
--- a/src/corelib/io/qtextstream.cpp
+++ b/src/corelib/io/qtextstream.cpp
@@ -233,6 +233,7 @@ static const int QTEXTSTREAM_BUFFERSIZE = 16384;
#if defined QTEXTSTREAM_DEBUG
#include <ctype.h>
+#include "private/qtools_p.h"
QT_BEGIN_NAMESPACE
@@ -250,10 +251,16 @@ static QByteArray qt_prettyDebug(const char *data, int len, int maxSize)
case '\n': out += "\\n"; break;
case '\r': out += "\\r"; break;
case '\t': out += "\\t"; break;
- default:
- QString tmp;
- tmp.sprintf("\\x%x", (unsigned int)(unsigned char)c);
- out += tmp.toLatin1();
+ default: {
+ const char buf[] = {
+ '\\',
+ 'x',
+ QtMiscUtils::toHexLower(uchar(c) / 16),
+ QtMiscUtils::toHexLower(uchar(c) % 16),
+ 0
+ };
+ out += buf;
+ }
}
}
@@ -460,7 +467,7 @@ bool QTextStreamPrivate::fillReadBuffer(qint64 maxBytes)
#if defined (QTEXTSTREAM_DEBUG)
qDebug("QTextStreamPrivate::fillReadBuffer(), device->read(\"%s\", %d) == %d",
- qt_prettyDebug(buf, qMin(32,int(bytesRead)) , int(bytesRead)).constData(), sizeof(buf), int(bytesRead));
+ qt_prettyDebug(buf, qMin(32,int(bytesRead)) , int(bytesRead)).constData(), int(sizeof(buf)), int(bytesRead));
#endif
if (bytesRead <= 0)
@@ -681,15 +688,9 @@ bool QTextStreamPrivate::scan(const QChar **ptr, int *length, int maxlen, TokenD
&& (!maxlen || totalSize < maxlen)
&& (device && (canStillReadFromDevice = fillReadBuffer())));
- // if the token was not found, but we reached the end of input,
- // then we accept what we got. if we are not at the end of input,
- // we return false.
- if (!foundToken && (!maxlen || totalSize < maxlen)
- && (totalSize == 0
- || (string && stringOffset + totalSize < string->size())
- || (device && !device->atEnd() && canStillReadFromDevice))) {
+ if (totalSize == 0) {
#if defined (QTEXTSTREAM_DEBUG)
- qDebug("QTextStreamPrivate::scan() did not find the token.");
+ qDebug("QTextStreamPrivate::scan() reached the end of input.");
#endif
return false;
}
@@ -812,13 +813,28 @@ inline void QTextStreamPrivate::restoreToSavedConverterState()
/*!
\internal
*/
-inline void QTextStreamPrivate::write(const QString &data)
+void QTextStreamPrivate::write(const QChar *data, int len)
+{
+ if (string) {
+ // ### What about seek()??
+ string->append(data, len);
+ } else {
+ writeBuffer.append(data, len);
+ if (writeBuffer.size() > QTEXTSTREAM_BUFFERSIZE)
+ flushWriteBuffer();
+ }
+}
+
+/*!
+ \internal
+*/
+inline void QTextStreamPrivate::write(QChar ch)
{
if (string) {
// ### What about seek()??
- string->append(data);
+ string->append(ch);
} else {
- writeBuffer += data;
+ writeBuffer += ch;
if (writeBuffer.size() > QTEXTSTREAM_BUFFERSIZE)
flushWriteBuffer();
}
@@ -865,45 +881,53 @@ inline void QTextStreamPrivate::ungetChar(QChar ch)
/*!
\internal
*/
-inline void QTextStreamPrivate::putString(const QString &s, bool number)
+inline void QTextStreamPrivate::putChar(QChar ch)
+{
+ if (params.fieldWidth > 0)
+ putString(&ch, 1);
+ else
+ write(ch);
+}
+
+/*!
+ \internal
+*/
+void QTextStreamPrivate::putString(const QChar *data, int len, bool number)
{
- QString tmp = s;
+ QString pad;
+ int padLeft = 0, padRight = 0;
// handle padding
- int padSize = params.fieldWidth - s.size();
+ int padSize = params.fieldWidth - len;
if (padSize > 0) {
- QString pad(padSize, params.padChar);
+ pad = QString(padSize, params.padChar);
switch (params.fieldAlignment) {
case QTextStream::AlignLeft:
- tmp.append(pad);
+ padRight = padSize;
break;
case QTextStream::AlignRight:
case QTextStream::AlignAccountingStyle:
- tmp.prepend(pad);
+ padLeft = padSize;
if (params.fieldAlignment == QTextStream::AlignAccountingStyle && number) {
- const QChar sign = s.size() > 0 ? s.at(0) : QChar();
+ const QChar sign = len > 0 ? data[0] : QChar();
if (sign == locale.negativeSign() || sign == locale.positiveSign()) {
- QChar *data = tmp.data();
- data[padSize] = tmp.at(0);
- data[0] = sign;
+ // write the sign before the padding, then skip it later
+ write(&sign, 1);
+ ++data;
+ --len;
}
- }
+ }
break;
case QTextStream::AlignCenter:
- tmp.prepend(QString(padSize/2, params.padChar));
- tmp.append(QString(padSize - padSize/2, params.padChar));
+ padLeft = padSize/2;
+ padRight = padSize - padSize/2;
break;
}
}
-#if defined (QTEXTSTREAM_DEBUG)
- QByteArray a = s.toUtf8();
- QByteArray b = tmp.toUtf8();
- qDebug("QTextStreamPrivate::putString(\"%s\") calls write(\"%s\")",
- qt_prettyDebug(a.constData(), a.size(), qMax(16, a.size())).constData(),
- qt_prettyDebug(b.constData(), b.size(), qMax(16, b.size())).constData());
-#endif
- write(tmp);
+ write(pad.constData(), padLeft);
+ write(data, len);
+ write(pad.constData(), padRight);
}
/*!
@@ -1563,17 +1587,60 @@ QString QTextStream::readAll()
*/
QString QTextStream::readLine(qint64 maxlen)
{
+ QString line;
+
+ readLine(&line, maxlen);
+ return line;
+}
+
+/*!
+ \since 5.5
+
+ Reads one line of text from the stream into \a line.
+ If \a line is 0, the read line is not stored.
+
+ The maximum allowed line length is set to \a maxlen. If
+ the stream contains lines longer than this, then the lines will be
+ split after \a maxlen characters and returned in parts.
+
+ If \a maxlen is 0, the lines can be of any length.
+
+ The resulting line has no trailing end-of-line characters ("\\n"
+ or "\\r\\n"), so calling QString::trimmed() can be unnecessary.
+
+ If \a line has sufficient capacity for the data that is about to be
+ read, this function may not need to allocate new memory. Because of
+ this, it can be faster than the other readLine() overload.
+
+ Returns \c false if the stream has read to the end of the file or
+ an error has occurred; otherwise returns \c true. The contents in
+ \a line before the call are discarded in any case.
+
+ \sa readAll(), QIODevice::readLine()
+*/
+bool QTextStream::readLine(QString *line, qint64 maxlen)
+{
Q_D(QTextStream);
- CHECK_VALID_STREAM(QString());
+ // keep in sync with CHECK_VALID_STREAM
+ if (!d->string && !d->device) {
+ qWarning("QTextStream: No device");
+ if (line && !line->isNull())
+ line->resize(0);
+ return false;
+ }
const QChar *readPtr;
int length;
- if (!d->scan(&readPtr, &length, int(maxlen), QTextStreamPrivate::EndOfLine))
- return QString();
+ if (!d->scan(&readPtr, &length, int(maxlen), QTextStreamPrivate::EndOfLine)) {
+ if (line && !line->isNull())
+ line->resize(0);
+ return false;
+ }
- QString tmp = QString(readPtr, length);
+ if (Q_LIKELY(line))
+ line->setUnicode(readPtr, length);
d->consumeLastToken();
- return tmp;
+ return true;
}
/*!
@@ -2231,7 +2298,7 @@ QTextStream &QTextStream::operator<<(QChar c)
{
Q_D(QTextStream);
CHECK_VALID_STREAM(*this);
- d->putString(QString(c));
+ d->putChar(c);
return *this;
}
@@ -2244,7 +2311,7 @@ QTextStream &QTextStream::operator<<(char c)
{
Q_D(QTextStream);
CHECK_VALID_STREAM(*this);
- d->putString(QString(QChar::fromLatin1(c)));
+ d->putChar(QChar::fromLatin1(c));
return *this;
}
diff --git a/src/corelib/io/qtextstream.h b/src/corelib/io/qtextstream.h
index 5c75a006af..6f5e2473e4 100644
--- a/src/corelib/io/qtextstream.h
+++ b/src/corelib/io/qtextstream.h
@@ -124,6 +124,7 @@ public:
void skipWhiteSpace();
QString readLine(qint64 maxlen = 0);
+ bool readLine(QString *line, qint64 maxlen = 0);
QString readAll();
QString read(qint64 maxlen);
@@ -185,6 +186,7 @@ public:
private:
Q_DISABLE_COPY(QTextStream)
friend class QDebugStateSaverPrivate;
+ friend class QDebug;
QScopedPointer<QTextStreamPrivate> d_ptr;
};
diff --git a/src/corelib/io/qtextstream_p.h b/src/corelib/io/qtextstream_p.h
index 5f99f44cc2..f8c151b76c 100644
--- a/src/corelib/io/qtextstream_p.h
+++ b/src/corelib/io/qtextstream_p.h
@@ -165,8 +165,12 @@ public:
NumberParsingStatus getNumber(qulonglong *l);
bool getReal(double *f);
- inline void write(const QString &data);
- inline void putString(const QString &ch, bool number = false);
+ inline void write(const QString &data) { write(data.begin(), data.length()); }
+ inline void write(QChar ch);
+ void write(const QChar *data, int len);
+ inline void putString(const QString &ch, bool number = false) { putString(ch.constData(), ch.length(), number); }
+ void putString(const QChar *data, int len, bool number = false);
+ inline void putChar(QChar ch);
void putNumber(qulonglong number, bool negative);
// buffers
diff --git a/src/corelib/io/qtldurl.cpp b/src/corelib/io/qtldurl.cpp
index d0205c3be5..7ccab8abb1 100644
--- a/src/corelib/io/qtldurl.cpp
+++ b/src/corelib/io/qtldurl.cpp
@@ -48,7 +48,7 @@ static bool containsTLDEntry(const QString &entry)
// select the right chunk from the big table
short chunk = 0;
uint chunkIndex = tldIndices[index], offset = 0;
- while (tldIndices[index] >= tldChunks[chunk] && chunk < tldChunkCount) {
+ while (chunk < tldChunkCount && tldIndices[index] >= tldChunks[chunk]) {
chunkIndex -= tldChunks[chunk];
offset += tldChunks[chunk];
chunk++;
diff --git a/src/corelib/io/qurl.h b/src/corelib/io/qurl.h
index abf96f5fcd..a1f62925e2 100644
--- a/src/corelib/io/qurl.h
+++ b/src/corelib/io/qurl.h
@@ -173,14 +173,14 @@ public:
QUrl &operator=(const QString &url);
#endif
#ifdef Q_COMPILER_RVALUE_REFS
- QUrl(QUrl &&other) : d(0)
- { qSwap(d, other.d); }
- inline QUrl &operator=(QUrl &&other)
+ QUrl(QUrl &&other) Q_DECL_NOTHROW : d(other.d)
+ { other.d = Q_NULLPTR; }
+ inline QUrl &operator=(QUrl &&other) Q_DECL_NOTHROW
{ qSwap(d, other.d); return *this; }
#endif
~QUrl();
- inline void swap(QUrl &other) { qSwap(d, other.d); }
+ inline void swap(QUrl &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
void setUrl(const QString &url, ParsingMode mode = TolerantMode);
QString url(FormattingOptions options = FormattingOptions(PrettyDecoded)) const;
diff --git a/src/corelib/io/qurlrecode.cpp b/src/corelib/io/qurlrecode.cpp
index 9aad2a12bd..4cf471a248 100644
--- a/src/corelib/io/qurlrecode.cpp
+++ b/src/corelib/io/qurlrecode.cpp
@@ -33,6 +33,7 @@
#include "qurl.h"
#include "private/qutfcodec_p.h"
+#include "private/qtools_p.h"
QT_BEGIN_NAMESPACE
@@ -197,8 +198,7 @@ static inline ushort decodePercentEncoding(const ushort *input)
static inline ushort encodeNibble(ushort c)
{
- static const uchar hexnumbers[] = "0123456789ABCDEF";
- return hexnumbers[c & 0xf];
+ return ushort(QtMiscUtils::toHexUpper(c));
}
static void ensureDetached(QString &result, ushort *&output, const ushort *begin, const ushort *input, const ushort *end,