diff options
author | Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> | 2015-06-01 19:44:29 +0200 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> | 2015-06-01 19:44:29 +0200 |
commit | 6e008cd57955c8029671c4c92250b86767f8ec1f (patch) | |
tree | ad5fe258f7203a733fbdd231918acd540727a2fb /src/corelib | |
parent | 275709fb43c154ccb1d95391f4829bd1aecebb12 (diff) | |
parent | 6fba3c1904aa7601722a70099d88126191cf60cf (diff) |
Merge 5.5 into 5.5.0
Change-Id: I27921a25a0fc56afb5429e40fc1e9b4b9a645a9a
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/global/qlogging.cpp | 2 | ||||
-rw-r--r-- | src/corelib/global/qtypetraits.h | 21 | ||||
-rw-r--r-- | src/corelib/io/qiodevice.cpp | 53 | ||||
-rw-r--r-- | src/corelib/io/qlockfile.cpp | 12 | ||||
-rw-r--r-- | src/corelib/io/qlockfile_p.h | 1 | ||||
-rw-r--r-- | src/corelib/io/qlockfile_unix.cpp | 48 | ||||
-rw-r--r-- | src/corelib/io/qlockfile_win.cpp | 45 | ||||
-rw-r--r-- | src/corelib/io/qstorageinfo_unix.cpp | 24 | ||||
-rw-r--r-- | src/corelib/kernel/qmetatype.h | 14 | ||||
-rw-r--r-- | src/corelib/kernel/qobjectdefs.h | 1 | ||||
-rw-r--r-- | src/corelib/tools/qdatetimeparser.cpp | 14 | ||||
-rw-r--r-- | src/corelib/tools/qdatetimeparser_p.h | 3 |
12 files changed, 195 insertions, 43 deletions
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 447a875655..88882bbe8f 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -1737,7 +1737,7 @@ void qErrnoWarning(int code, const char *msg, ...) Example: \code - QT_MESSAGE_PATTERN="[%{time yyyyMMdd h:mm:ss.zzz t} %{if-debug}D{%endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{file}:%{line} - %{message}" + QT_MESSAGE_PATTERN="[%{time yyyyMMdd h:mm:ss.zzz t} %{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{file}:%{line} - %{message}" \endcode The default \a pattern is "%{if-category}%{category}: %{endif}%{message}". diff --git a/src/corelib/global/qtypetraits.h b/src/corelib/global/qtypetraits.h index 3a305713e6..488e257e0f 100644 --- a/src/corelib/global/qtypetraits.h +++ b/src/corelib/global/qtypetraits.h @@ -506,6 +506,27 @@ Q_STATIC_ASSERT((!is_unsigned<qint64>::value)); Q_STATIC_ASSERT((!is_signed<quint64>::value)); Q_STATIC_ASSERT(( is_signed<qint64>::value)); +template<class T = void> struct is_default_constructible; + +template<> struct is_default_constructible<void> +{ +protected: + template<bool> struct test { typedef char type; }; +public: + static bool const value = false; +}; +template<> struct is_default_constructible<>::test<true> { typedef double type; }; + +template<class T> struct is_default_constructible : is_default_constructible<> +{ +private: + template<class U> static typename test<!!sizeof(::new U())>::type sfinae(U*); + template<class U> static char sfinae(...); +public: + static bool const value = sizeof(sfinae<T>(0)) > 1; +}; + + } // namespace QtPrivate QT_END_NAMESPACE diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index e73a200fb4..b908ae3145 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -38,9 +38,9 @@ #include "qiodevice_p.h" #include "qfile.h" #include "qstringlist.h" +#include "qdir.h" #include <algorithm> -#include <limits.h> #ifdef QIODEVICE_DEBUG # include <ctype.h> @@ -80,10 +80,29 @@ void debugBinaryString(const char *data, qint64 maxlen) #define Q_VOID +static void checkWarnMessage(const QIODevice *device, const char *function, const char *what) +{ + QDebug d = qWarning(); + d.noquote(); + d.nospace(); + d << "QIODevice::" << function; +#ifndef QT_NO_QOBJECT + d << " (" << device->metaObject()->className(); + if (!device->objectName().isEmpty()) + d << ", \"" << device->objectName() << '"'; + if (const QFile *f = qobject_cast<const QFile *>(device)) + d << ", \"" << QDir::toNativeSeparators(f->fileName()) << '"'; + d << ')'; +#else + Q_UNUSED(device) +#endif // !QT_NO_QOBJECT + d << ": " << what; +} + #define CHECK_MAXLEN(function, returnType) \ do { \ if (maxSize < 0) { \ - qWarning("QIODevice::"#function": Called with maxSize < 0"); \ + checkWarnMessage(this, #function, "Called with maxSize < 0"); \ return returnType; \ } \ } while (0) @@ -92,10 +111,10 @@ void debugBinaryString(const char *data, qint64 maxlen) do { \ if ((d->openMode & WriteOnly) == 0) { \ if (d->openMode == NotOpen) { \ - qWarning("QIODevice::"#function": device not open"); \ + checkWarnMessage(this, #function, "device not open"); \ return returnType; \ } \ - qWarning("QIODevice::"#function": ReadOnly device"); \ + checkWarnMessage(this, #function, "ReadOnly device"); \ return returnType; \ } \ } while (0) @@ -104,10 +123,10 @@ void debugBinaryString(const char *data, qint64 maxlen) do { \ if ((d->openMode & ReadOnly) == 0) { \ if (d->openMode == NotOpen) { \ - qWarning("QIODevice::"#function": device not open"); \ + checkWarnMessage(this, #function, "device not open"); \ return returnType; \ } \ - qWarning("QIODevice::"#function": WriteOnly device"); \ + checkWarnMessage(this, #function, "WriteOnly device"); \ return returnType; \ } \ } while (0) @@ -462,7 +481,7 @@ void QIODevice::setTextModeEnabled(bool enabled) { Q_D(QIODevice); if (!isOpen()) { - qWarning("QIODevice::setTextModeEnabled: The device is not open"); + checkWarnMessage(this, "setTextModeEnabled", "The device is not open"); return; } if (enabled) @@ -621,11 +640,11 @@ bool QIODevice::seek(qint64 pos) { Q_D(QIODevice); if (d->isSequential()) { - qWarning("QIODevice::seek: Cannot call seek on a sequential device"); + checkWarnMessage(this, "seek", "Cannot call seek on a sequential device"); return false; } if (d->openMode == NotOpen) { - qWarning("QIODevice::seek: The device is not open"); + checkWarnMessage(this, "seek", "The device is not open"); return false; } if (pos < 0) { @@ -922,9 +941,9 @@ QByteArray QIODevice::read(qint64 maxSize) Q_UNUSED(d); #endif - if (maxSize != qint64(int(maxSize))) { - qWarning("QIODevice::read: maxSize argument exceeds QByteArray size limit"); - maxSize = INT_MAX; + if (quint64(maxSize) >= QByteArray::MaxSize) { + checkWarnMessage(this, "read", "maxSize argument exceeds QByteArray size limit"); + maxSize = QByteArray::MaxSize - 1; } qint64 readBytes = 0; @@ -976,7 +995,7 @@ QByteArray QIODevice::readAll() // flush internal read buffer if (!(d->openMode & Text) && !d->buffer.isEmpty()) { - if (d->buffer.size() >= INT_MAX) + if (quint64(d->buffer.size()) >= QByteArray::MaxSize) return QByteArray(); result = d->buffer.readAll(); readBytes = result.size(); @@ -1055,7 +1074,7 @@ qint64 QIODevice::readLine(char *data, qint64 maxSize) { Q_D(QIODevice); if (maxSize < 2) { - qWarning("QIODevice::readLine: Called with maxSize < 2"); + checkWarnMessage(this, "readLine", "Called with maxSize < 2"); return qint64(-1); } @@ -1159,9 +1178,9 @@ QByteArray QIODevice::readLine(qint64 maxSize) Q_UNUSED(d); #endif - if (maxSize > INT_MAX) { + if (quint64(maxSize) >= QByteArray::MaxSize) { qWarning("QIODevice::read: maxSize argument exceeds QByteArray size limit"); - maxSize = INT_MAX; + maxSize = QByteArray::MaxSize - 1; } result.resize(int(maxSize)); @@ -1169,7 +1188,7 @@ QByteArray QIODevice::readLine(qint64 maxSize) if (!result.size()) { // If resize fails or maxSize == 0, read incrementally if (maxSize == 0) - maxSize = INT_MAX; + maxSize = QByteArray::MaxSize - 1; // The first iteration needs to leave an extra byte for the terminating null result.resize(1); diff --git a/src/corelib/io/qlockfile.cpp b/src/corelib/io/qlockfile.cpp index 4f5aeff395..2bd996d213 100644 --- a/src/corelib/io/qlockfile.cpp +++ b/src/corelib/io/qlockfile.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 David Faure <faure+bluesystems@kde.org> +** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -66,9 +67,12 @@ QT_BEGIN_NAMESPACE If the process holding the lock crashes, the lock file stays on disk and can prevent any other process from accessing the shared resource, ever. For this reason, QLockFile - tries to detect such a "stale" lock file, based on the process ID written into the file, - and (in case that process ID got reused meanwhile), on the last modification time of - the lock file (30s by default, for the use case of a short-lived operation). + tries to detect such a "stale" lock file, based on the process ID written into the file. + To cover the situation that the process ID got reused meanwhile, the current process name is + compared to the name of the process that corresponds to the process ID from the lock file. + If the process names differ, the lock file is considered stale. + Additionally, the last modification time of the lock file (30s by default, for the use case of a + short-lived operation) is taken into account. If the lock file is found to be stale, it will be deleted. For the use case of protecting a resource over a long time, you should therefore call @@ -122,7 +126,7 @@ QLockFile::~QLockFile() The value of \a staleLockTime is used by lock() and tryLock() in order to determine when an existing lock file is considered stale, i.e. left over by a crashed process. This is useful for the case where the PID got reused - meanwhile, so the only way to detect a stale lock file is by the fact that + meanwhile, so one way to detect a stale lock file is by the fact that it has been around for a long time. \sa staleLockTime() diff --git a/src/corelib/io/qlockfile_p.h b/src/corelib/io/qlockfile_p.h index 0cfaa42849..168062f467 100644 --- a/src/corelib/io/qlockfile_p.h +++ b/src/corelib/io/qlockfile_p.h @@ -75,6 +75,7 @@ public: // Returns \c true if the lock belongs to dead PID, or is old. // The attempt to delete it will tell us if it was really stale or not, though. bool isApparentlyStale() const; + static QString processNameByPid(qint64 pid); #ifdef Q_OS_UNIX static int checkFcntlWorksAfterFlock(); diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp index d1804f2cb6..d6ea2f1f2d 100644 --- a/src/corelib/io/qlockfile_unix.cpp +++ b/src/corelib/io/qlockfile_unix.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 David Faure <faure+bluesystems@kde.org> +** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -48,6 +49,15 @@ #include <signal.h> // kill #include <unistd.h> // gethostname +#if defined(Q_OS_OSX) +# include <libproc.h> +#elif defined(Q_OS_LINUX) +# include <unistd.h> +# include <cstdio> +#elif defined(Q_OS_BSD4) && !defined(Q_OS_IOS) +# include <sys/user.h> +#endif + QT_BEGIN_NAMESPACE static QByteArray localHostName() // from QHostInfo::localHostName(), modified to return a QByteArray @@ -189,12 +199,50 @@ bool QLockFilePrivate::isApparentlyStale() const if (hostname.isEmpty() || hostname == QString::fromLocal8Bit(localHostName())) { if (::kill(pid, 0) == -1 && errno == ESRCH) return true; // PID doesn't exist anymore + const QString processName = processNameByPid(pid); + if (!processName.isEmpty()) { + QFileInfo fi(appname); + if (fi.isSymLink()) + fi.setFile(fi.symLinkTarget()); + if (processName != fi.fileName()) + return true; // PID got reused by a different application. + } } } const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime()); return staleLockTime > 0 && age > staleLockTime; } +QString QLockFilePrivate::processNameByPid(qint64 pid) +{ +#if defined(Q_OS_OSX) + char name[1024]; + proc_name(pid, name, sizeof(name) / sizeof(char)); + return QString::fromUtf8(name); +#elif defined(Q_OS_LINUX) + if (!QFile::exists(QStringLiteral("/proc/version"))) + return QString(); + char exePath[64]; + char buf[PATH_MAX]; + memset(buf, 0, sizeof(buf)); + sprintf(exePath, "/proc/%lld/exe", pid); + if (readlink(exePath, buf, sizeof(buf)) < 0) { + // The pid is gone. Return some invalid process name to fail the test. + return QStringLiteral("/ERROR/"); + } + return QFileInfo(QString::fromUtf8(buf)).fileName(); +#elif defined(Q_OS_BSD4) && !defined(Q_OS_IOS) + kinfo_proc *proc = kinfo_getproc(pid); + if (!proc) + return QString(); + QString name = QString::fromUtf8(proc->ki_comm); + free(proc); + return name; +#else + return QString(); +#endif +} + void QLockFile::unlock() { Q_D(QLockFile); diff --git a/src/corelib/io/qlockfile_win.cpp b/src/corelib/io/qlockfile_win.cpp index 4e0d8134ec..8cbe0a9dfd 100644 --- a/src/corelib/io/qlockfile_win.cpp +++ b/src/corelib/io/qlockfile_win.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 David Faure <faure+bluesystems@kde.org> +** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -140,6 +141,9 @@ bool QLockFilePrivate::isApparentlyStale() const ::CloseHandle(procHandle); if (dwR == WAIT_TIMEOUT) return true; + const QString processName = processNameByPid(pid); + if (!processName.isEmpty() && processName != appname) + return true; // PID got reused by a different application. } } #else // !Q_OS_WINRT @@ -151,6 +155,47 @@ bool QLockFilePrivate::isApparentlyStale() const return staleLockTime > 0 && age > staleLockTime; } +QString QLockFilePrivate::processNameByPid(qint64 pid) +{ +#if !defined(Q_OS_WINRT) && !defined(Q_OS_WINCE) + typedef DWORD (WINAPI *GetModuleFileNameExFunc)(HANDLE, HMODULE, LPTSTR, DWORD); + + HMODULE hPsapi = LoadLibraryA("psapi"); + if (!hPsapi) + return QString(); + + GetModuleFileNameExFunc qGetModuleFileNameEx + = (GetModuleFileNameExFunc)GetProcAddress(hPsapi, "GetModuleFileNameExW"); + if (!qGetModuleFileNameEx) { + FreeLibrary(hPsapi); + return QString(); + } + + HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, DWORD(pid)); + if (!hProcess) { + FreeLibrary(hPsapi); + return QString(); + } + wchar_t buf[MAX_PATH]; + const DWORD length = qGetModuleFileNameEx(hProcess, NULL, buf, sizeof(buf) / sizeof(wchar_t)); + CloseHandle(hProcess); + FreeLibrary(hPsapi); + if (!length) + return QString(); + QString name = QString::fromWCharArray(buf, length); + int i = name.lastIndexOf(QLatin1Char('\\')); + if (i >= 0) + name.remove(0, i + 1); + i = name.lastIndexOf(QLatin1Char('.')); + if (i >= 0) + name.truncate(i); + return name; +#else + Q_UNUSED(pid); + return QString(); +#endif +} + void QLockFile::unlock() { Q_D(QLockFile); diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp index 7b8f608050..d170e7c0c0 100644 --- a/src/corelib/io/qstorageinfo_unix.cpp +++ b/src/corelib/io/qstorageinfo_unix.cpp @@ -67,8 +67,20 @@ #endif #if defined(Q_OS_BSD4) -# define QT_STATFSBUF struct statvfs -# define QT_STATFS ::statvfs +# if defined(Q_OS_NETBSD) + define QT_STATFSBUF struct statvfs + define QT_STATFS ::statvfs +# else +# define QT_STATFSBUF struct statfs +# define QT_STATFS ::statfs +# endif + +# if !defined(ST_RDONLY) +# define ST_RDONLY MNT_RDONLY +# endif +# if !defined(_STATFS_F_FLAGS) +# define _STATFS_F_FLAGS 1 +# endif #elif defined(Q_OS_ANDROID) # define QT_STATFS ::statfs # define QT_STATFSBUF struct statfs @@ -122,11 +134,7 @@ public: inline QByteArray device() const; private: #if defined(Q_OS_BSD4) -# if defined(Q_OS_NETBSD) - struct statvfs *stat_buf; -# else - struct statfs *stat_buf; -# endif + QT_STATFSBUF *stat_buf; int entryCount; int currentIndex; #elif defined(Q_OS_SOLARIS) @@ -501,7 +509,7 @@ void QStorageInfoPrivate::retrieveVolumeInfo() bytesTotal = statfs_buf.f_blocks * statfs_buf.f_bsize; bytesFree = statfs_buf.f_bfree * statfs_buf.f_bsize; bytesAvailable = statfs_buf.f_bavail * statfs_buf.f_bsize; -#if defined(Q_OS_ANDROID) +#if defined(Q_OS_ANDROID) || defined (Q_OS_BSD4) #if defined(_STATFS_F_FLAGS) readOnly = (statfs_buf.f_flags & ST_RDONLY) != 0; #endif diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index b854dc16fd..1b214e9f74 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -1357,12 +1357,16 @@ namespace QtPrivate enum { Value = sizeof(checkType(static_cast<T*>(0))) == sizeof(yes_type) }; }; + template<typename T, typename Enable = void> + struct IsGadgetHelper { enum { Value = false }; }; + template<typename T> - struct IsGadgetHelper + struct IsGadgetHelper<T, typename T::QtGadgetHelper> { - template<typename X> static typename X::QtGadgetHelper *checkType(X*); - static char checkType(void*); - enum { Value = sizeof(checkType(static_cast<T*>(0))) == sizeof(void*) }; + template <typename X> + static char checkType(void (X::*)()); + static void *checkType(void (T::*)()); + enum { Value = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *) }; }; @@ -1769,7 +1773,7 @@ template <typename T> struct QMetaTypeIdQObject<T, QMetaType::IsGadget> { enum { - Defined = 1 + Defined = QtPrivate::is_default_constructible<T>::value }; static int qt_metatype_id() diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index 31e8a670e9..4d01264906 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -172,6 +172,7 @@ private: \ #define Q_GADGET \ public: \ static const QMetaObject staticMetaObject; \ + void qt_check_for_QGADGET_macro(); \ typedef void QtGadgetHelper; \ private: \ Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index 255e9557e2..eaa695ef27 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -1362,11 +1362,11 @@ int QDateTimeParser::findDay(const QString &str1, int startDay, int sectionIndex \internal returns - 0 if str == QDateTimeEdit::tr("AM") - 1 if str == QDateTimeEdit::tr("PM") - 2 if str can become QDateTimeEdit::tr("AM") - 3 if str can become QDateTimeEdit::tr("PM") - 4 if str can become QDateTimeEdit::tr("PM") and can become QDateTimeEdit::tr("AM") + 0 if str == tr("AM") + 1 if str == tr("PM") + 2 if str can become tr("AM") + 3 if str can become tr("PM") + 4 if str can become tr("PM") and can become tr("AM") -1 can't become anything sensible */ @@ -1737,9 +1737,9 @@ QDateTime QDateTimeParser::getMaximum() const QString QDateTimeParser::getAmPmText(AmPm ap, Case cs) const { if (ap == AmText) { - return (cs == UpperCase ? QLatin1String("AM") : QLatin1String("am")); + return (cs == UpperCase ? tr("AM") : tr("am")); } else { - return (cs == UpperCase ? QLatin1String("PM") : QLatin1String("pm")); + return (cs == UpperCase ? tr("PM") : tr("pm")); } } diff --git a/src/corelib/tools/qdatetimeparser_p.h b/src/corelib/tools/qdatetimeparser_p.h index 55dc3bf7a0..9457e35ad5 100644 --- a/src/corelib/tools/qdatetimeparser_p.h +++ b/src/corelib/tools/qdatetimeparser_p.h @@ -54,7 +54,7 @@ # include "QtCore/qvariant.h" #endif #include "QtCore/qvector.h" - +#include "QtCore/qcoreapplication.h" #define QDATETIMEEDIT_TIME_MIN QTime(0, 0, 0, 0) #define QDATETIMEEDIT_TIME_MAX QTime(23, 59, 59, 999) @@ -72,6 +72,7 @@ QT_BEGIN_NAMESPACE class Q_CORE_EXPORT QDateTimeParser { + Q_DECLARE_TR_FUNCTIONS(QDateTimeParser) public: enum Context { FromString, |