From 68351b75e8a973e82b2e85a87d0da999d1f5c65d Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Apr 10 2018 05:42:18 +0000 Subject: import qt5-qtbase-5.9.2-3.el7 --- diff --git a/.gitignore b/.gitignore index 622df0c..2b534a6 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/qtbase-opensource-src-5.6.2.tar.xz +SOURCES/qtbase-opensource-src-5.9.2.tar.xz diff --git a/.qt5-qtbase.metadata b/.qt5-qtbase.metadata index 6d94cb7..fa94b6a 100644 --- a/.qt5-qtbase.metadata +++ b/.qt5-qtbase.metadata @@ -1 +1 @@ -f728a6b8a50e12d7da9b70c8093c484d48b33ca8 SOURCES/qtbase-opensource-src-5.6.2.tar.xz +65332ea9fbeb31384a87fd22ff5ad2d6251bf893 SOURCES/qtbase-opensource-src-5.9.2.tar.xz diff --git a/SOURCES/10-qt5-check-opengl2.sh b/SOURCES/10-qt5-check-opengl2.sh index 57071d4..4601542 100755 --- a/SOURCES/10-qt5-check-opengl2.sh +++ b/SOURCES/10-qt5-check-opengl2.sh @@ -1,6 +1,6 @@ #!/bin/bash -if [ -z "$QT_XCB_FORCE_SOFTWARE_OPENGL" ]; then +if [ -z "${QT_XCB_FORCE_SOFTWARE_OPENGL-}" ]; then QT5_CHECK_OPENGL_VERSION=`LANG=C glxinfo 2> /dev/null | grep '^OpenGL version string: ' | head -n 1 | sed -e 's/^OpenGL version string: \([0-9]\).*$/\1/g'` ||: diff --git a/SOURCES/macros.qt5 b/SOURCES/macros.qt5 index 9fb7807..5db5c70 100644 --- a/SOURCES/macros.qt5 +++ b/SOURCES/macros.qt5 @@ -9,10 +9,12 @@ %_qt5_docdir %{_docdir}/qt5 %_qt5_examplesdir %{_qt5_prefix}/examples %_qt5_headerdir %{_includedir}/qt5 +%_qt5_includedir %{_includedir}/qt5 %_qt5_importdir %{_qt5_archdatadir}/imports %_qt5_libdir %{_libdir} %_qt5_libexecdir %{_qt5_archdatadir}/libexec %_qt5_plugindir %{_qt5_archdatadir}/plugins +%_qt5_qmldir %{_qt5_archdatadir}/qml %_qt5_qmake %{_qt5_bindir}/qmake %_qt5_settingsdir %{_sysconfdir}/xdg %_qt5_sysconfdir %{_qt5_settingsdir} diff --git a/SOURCES/qt5-poll.patch b/SOURCES/qt5-poll.patch deleted file mode 100644 index 97e0c67..0000000 --- a/SOURCES/qt5-poll.patch +++ /dev/null @@ -1,2313 +0,0 @@ -diff --git a/config.tests/unix/poll/poll.cpp b/config.tests/unix/poll/poll.cpp -new file mode 100644 -index 0000000..06ae038 ---- /dev/null -+++ b/config.tests/unix/poll/poll.cpp -@@ -0,0 +1,45 @@ -+/**************************************************************************** -+** -+** Copyright (C) 2015 The Qt Company Ltd. -+** Contact: http://www.qt.io/licensing/ -+** -+** This file is part of the config.tests of the Qt Toolkit. -+** -+** $QT_BEGIN_LICENSE:LGPL21$ -+** 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 The Qt Company. For licensing terms -+** and conditions see http://www.qt.io/terms-conditions. For further -+** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free -+** Software Foundation and appearing in the file LICENSE.LGPLv21 and -+** LICENSE.LGPLv3 included in the packaging of this file. Please review the -+** following information to ensure the GNU Lesser General Public License -+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -+** -+** As a special exception, The Qt Company gives you certain additional -+** rights. These rights are described in The Qt Company LGPL Exception -+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -+** -+** $QT_END_LICENSE$ -+** -+****************************************************************************/ -+ -+#include -+ -+int main() -+{ -+ struct pollfd pfd; -+ -+ pfd.fd = -1; -+ pfd.events = 0; -+ pfd.revents = 0; -+ -+ return ::poll(&pfd, 1, 0); -+} -diff --git a/config.tests/unix/poll/poll.pro b/config.tests/unix/poll/poll.pro -new file mode 100644 -index 0000000..70121b4 ---- /dev/null -+++ b/config.tests/unix/poll/poll.pro -@@ -0,0 +1,2 @@ -+SOURCES = poll.cpp -+CONFIG -= qt -diff --git a/config.tests/unix/pollts/poll/poll.cpp b/config.tests/unix/pollts/poll/poll.cpp -new file mode 100644 -index 0000000..06ae038 ---- /dev/null -+++ b/config.tests/unix/pollts/poll/poll.cpp -@@ -0,0 +1,45 @@ -+/**************************************************************************** -+** -+** Copyright (C) 2015 The Qt Company Ltd. -+** Contact: http://www.qt.io/licensing/ -+** -+** This file is part of the config.tests of the Qt Toolkit. -+** -+** $QT_BEGIN_LICENSE:LGPL21$ -+** 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 The Qt Company. For licensing terms -+** and conditions see http://www.qt.io/terms-conditions. For further -+** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free -+** Software Foundation and appearing in the file LICENSE.LGPLv21 and -+** LICENSE.LGPLv3 included in the packaging of this file. Please review the -+** following information to ensure the GNU Lesser General Public License -+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -+** -+** As a special exception, The Qt Company gives you certain additional -+** rights. These rights are described in The Qt Company LGPL Exception -+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -+** -+** $QT_END_LICENSE$ -+** -+****************************************************************************/ -+ -+#include -+ -+int main() -+{ -+ struct pollfd pfd; -+ -+ pfd.fd = -1; -+ pfd.events = 0; -+ pfd.revents = 0; -+ -+ return ::poll(&pfd, 1, 0); -+} -diff --git a/config.tests/unix/pollts/poll/poll.pro b/config.tests/unix/pollts/poll/poll.pro -new file mode 100644 -index 0000000..70121b4 ---- /dev/null -+++ b/config.tests/unix/pollts/poll/poll.pro -@@ -0,0 +1,2 @@ -+SOURCES = poll.cpp -+CONFIG -= qt -diff --git a/config.tests/unix/pollts/pollts.cpp b/config.tests/unix/pollts/pollts.cpp -new file mode 100644 -index 0000000..c2d1940 ---- /dev/null -+++ b/config.tests/unix/pollts/pollts.cpp -@@ -0,0 +1,51 @@ -+/**************************************************************************** -+** -+** Copyright (C) 2015 The Qt Company Ltd. -+** Contact: http://www.qt.io/licensing/ -+** -+** This file is part of the config.tests of the Qt Toolkit. -+** -+** $QT_BEGIN_LICENSE:LGPL21$ -+** 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 The Qt Company. For licensing terms -+** and conditions see http://www.qt.io/terms-conditions. For further -+** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free -+** Software Foundation and appearing in the file LICENSE.LGPLv21 and -+** LICENSE.LGPLv3 included in the packaging of this file. Please review the -+** following information to ensure the GNU Lesser General Public License -+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -+** -+** As a special exception, The Qt Company gives you certain additional -+** rights. These rights are described in The Qt Company LGPL Exception -+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -+** -+** $QT_END_LICENSE$ -+** -+****************************************************************************/ -+ -+#include -+#include -+#include -+ -+int main() -+{ -+ struct pollfd pfd; -+ struct timespec ts; -+ -+ pfd.fd = -1; -+ pfd.events = 0; -+ pfd.revents = 0; -+ -+ ts.tv_sec = 0; -+ ts.tv_nsec = 0; -+ -+ return ::pollts(&pfd, 1, &ts, nullptr); -+} -diff --git a/config.tests/unix/pollts/pollts/poll/poll.cpp b/config.tests/unix/pollts/pollts/poll/poll.cpp -new file mode 100644 -index 0000000..06ae038 ---- /dev/null -+++ b/config.tests/unix/pollts/pollts/poll/poll.cpp -@@ -0,0 +1,45 @@ -+/**************************************************************************** -+** -+** Copyright (C) 2015 The Qt Company Ltd. -+** Contact: http://www.qt.io/licensing/ -+** -+** This file is part of the config.tests of the Qt Toolkit. -+** -+** $QT_BEGIN_LICENSE:LGPL21$ -+** 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 The Qt Company. For licensing terms -+** and conditions see http://www.qt.io/terms-conditions. For further -+** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free -+** Software Foundation and appearing in the file LICENSE.LGPLv21 and -+** LICENSE.LGPLv3 included in the packaging of this file. Please review the -+** following information to ensure the GNU Lesser General Public License -+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -+** -+** As a special exception, The Qt Company gives you certain additional -+** rights. These rights are described in The Qt Company LGPL Exception -+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -+** -+** $QT_END_LICENSE$ -+** -+****************************************************************************/ -+ -+#include -+ -+int main() -+{ -+ struct pollfd pfd; -+ -+ pfd.fd = -1; -+ pfd.events = 0; -+ pfd.revents = 0; -+ -+ return ::poll(&pfd, 1, 0); -+} -diff --git a/config.tests/unix/pollts/pollts/poll/poll.pro b/config.tests/unix/pollts/pollts/poll/poll.pro -new file mode 100644 -index 0000000..70121b4 ---- /dev/null -+++ b/config.tests/unix/pollts/pollts/poll/poll.pro -@@ -0,0 +1,2 @@ -+SOURCES = poll.cpp -+CONFIG -= qt -diff --git a/config.tests/unix/pollts/pollts/pollts.cpp b/config.tests/unix/pollts/pollts/pollts.cpp -new file mode 100644 -index 0000000..8b13789 ---- /dev/null -+++ b/config.tests/unix/pollts/pollts/pollts.cpp -@@ -0,0 +1 @@ -+ -diff --git a/config.tests/unix/pollts/pollts/pollts.pro b/config.tests/unix/pollts/pollts/pollts.pro -new file mode 100644 -index 0000000..5109dc3 ---- /dev/null -+++ b/config.tests/unix/pollts/pollts/pollts.pro -@@ -0,0 +1,2 @@ -+SOURCES = pollts.cpp -+CONFIG -= qt -diff --git a/config.tests/unix/ppoll/ppoll.cpp b/config.tests/unix/ppoll/ppoll.cpp -new file mode 100644 -index 0000000..5b0cc4d ---- /dev/null -+++ b/config.tests/unix/ppoll/ppoll.cpp -@@ -0,0 +1,51 @@ -+/**************************************************************************** -+** -+** Copyright (C) 2015 The Qt Company Ltd. -+** Contact: http://www.qt.io/licensing/ -+** -+** This file is part of the config.tests of the Qt Toolkit. -+** -+** $QT_BEGIN_LICENSE:LGPL21$ -+** 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 The Qt Company. For licensing terms -+** and conditions see http://www.qt.io/terms-conditions. For further -+** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free -+** Software Foundation and appearing in the file LICENSE.LGPLv21 and -+** LICENSE.LGPLv3 included in the packaging of this file. Please review the -+** following information to ensure the GNU Lesser General Public License -+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -+** -+** As a special exception, The Qt Company gives you certain additional -+** rights. These rights are described in The Qt Company LGPL Exception -+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -+** -+** $QT_END_LICENSE$ -+** -+****************************************************************************/ -+ -+#include -+#include -+ -+int main() -+{ -+ struct pollfd pfd; -+ struct timespec ts; -+ -+ pfd.fd = -1; -+ pfd.events = 0; -+ pfd.revents = 0; -+ -+ ts.tv_sec = 0; -+ ts.tv_nsec = 0; -+ -+ return ::ppoll(&pfd, 1, &ts, nullptr); -+} -+ -diff --git a/config.tests/unix/ppoll/ppoll.pro b/config.tests/unix/ppoll/ppoll.pro -new file mode 100644 -index 0000000..d08a8a0 ---- /dev/null -+++ b/config.tests/unix/ppoll/ppoll.pro -@@ -0,0 +1,2 @@ -+SOURCES = ppoll.cpp -+CONFIG -= qt -diff --git a/configure b/configure -index 0b8b417..f63daef 100755 ---- a/configure -+++ b/configure -@@ -745,6 +745,7 @@ CFG_GETIFADDRS=auto - CFG_INOTIFY=auto - CFG_EVENTFD=auto - CFG_CLOEXEC=no -+CFG_POLL=auto - CFG_RPATH=yes - CFG_FRAMEWORK=auto - CFG_USE_GOLD_LINKER=auto -@@ -6068,6 +6069,16 @@ if compileTest unix/cloexec "cloexec"; then - CFG_CLOEXEC=yes - fi - -+if compileTest unix/ppoll "ppoll"; then -+ CFG_POLL="ppoll" -+elif compileTest unix/pollts "pollts"; then -+ CFG_POLL="pollts" -+elif compileTest unix/poll "poll"; then -+ CFG_POLL="poll" -+else -+ CFG_POLL="select" -+fi -+ - if [ "$XPLATFORM_MAC" = "yes" ] && [ "$CFG_SECURETRANSPORT" != "no" ] && ([ "$CFG_OPENSSL" = "no" ] || [ "$CFG_OPENSSL" = "auto" ]); then - CFG_SECURETRANSPORT=yes - CFG_OPENSSL=no -@@ -6379,6 +6390,10 @@ fi - if [ "$CFG_CLOEXEC" = "yes" ]; then - QT_CONFIG="$QT_CONFIG threadsafe-cloexec" - fi -+if [ "$CFG_POLL" = "select" ]; then -+ QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_NATIVE_POLL" -+fi -+QT_CONFIG="$QT_CONFIG poll_$CFG_POLL" - if [ "$CFG_LIBJPEG" = "no" ]; then - CFG_JPEG="no" - elif [ "$CFG_LIBJPEG" = "system" ]; then -diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp -index fda9178..89e4665 100644 ---- a/src/corelib/io/qprocess_unix.cpp -+++ b/src/corelib/io/qprocess_unix.cpp -@@ -115,11 +115,52 @@ QT_BEGIN_NAMESPACE - // so we will use 512 - static const int errorBufferMax = 512; - --static inline void add_fd(int &nfds, int fd, fd_set *fdset) -+namespace { -+struct QProcessPoller - { -- FD_SET(fd, fdset); -- if ((fd) > nfds) -- nfds = fd; -+ QProcessPoller(const QProcessPrivate &proc); -+ -+ int poll(int timeout); -+ -+ pollfd &stdinPipe() { return pfds[0]; } -+ pollfd &stdoutPipe() { return pfds[1]; } -+ pollfd &stderrPipe() { return pfds[2]; } -+ pollfd &forkfd() { return pfds[3]; } -+ pollfd &childStartedPipe() { return pfds[4]; } -+ -+ enum { n_pfds = 5 }; -+ pollfd pfds[n_pfds]; -+}; -+ -+QProcessPoller::QProcessPoller(const QProcessPrivate &proc) -+{ -+ for (int i = 0; i < n_pfds; i++) -+ pfds[i] = qt_make_pollfd(-1, POLLIN); -+ -+ stdoutPipe().fd = proc.stdoutChannel.pipe[0]; -+ stderrPipe().fd = proc.stderrChannel.pipe[0]; -+ -+ if (!proc.stdinChannel.buffer.isEmpty()) { -+ stdinPipe().fd = proc.stdinChannel.pipe[1]; -+ stdinPipe().events = POLLOUT; -+ } -+ -+ forkfd().fd = proc.forkfd; -+ -+ if (proc.processState == QProcess::Starting) -+ childStartedPipe().fd = proc.childStartedPipe[0]; -+} -+ -+int QProcessPoller::poll(int timeout) -+{ -+ const nfds_t nfds = (childStartedPipe().fd == -1) ? 4 : 5; -+ return qt_poll_msecs(pfds, nfds, timeout); -+} -+} // anonymous namespace -+ -+static bool qt_pollfd_check(const pollfd &pfd, short revents) -+{ -+ return pfd.fd >= 0 && (pfd.revents & (revents | POLLHUP | POLLERR | POLLNVAL)) != 0; - } - - static int qt_create_pipe(int *pipe) -@@ -677,10 +718,9 @@ bool QProcessPrivate::waitForStarted(int msecs) - childStartedPipe[0]); - #endif - -- fd_set fds; -- FD_ZERO(&fds); -- FD_SET(childStartedPipe[0], &fds); -- if (qt_select_msecs(childStartedPipe[0] + 1, &fds, 0, msecs) == 0) { -+ pollfd pfd = qt_make_pollfd(childStartedPipe[0], POLLIN); -+ -+ if (qt_poll_msecs(&pfd, 1, msecs) == 0) { - setError(QProcess::Timedout); - #if defined (QPROCESS_DEBUG) - qDebug("QProcessPrivate::waitForStarted(%d) == false (timed out)", msecs); -@@ -720,31 +760,13 @@ bool QProcessPrivate::waitForReadyRead(int msecs) - #endif - - forever { -- fd_set fdread; -- fd_set fdwrite; -- -- FD_ZERO(&fdread); -- FD_ZERO(&fdwrite); -- -- int nfds = forkfd; -- FD_SET(forkfd, &fdread); -- -- if (processState == QProcess::Starting) -- add_fd(nfds, childStartedPipe[0], &fdread); -- -- if (stdoutChannel.pipe[0] != -1) -- add_fd(nfds, stdoutChannel.pipe[0], &fdread); -- if (stderrChannel.pipe[0] != -1) -- add_fd(nfds, stderrChannel.pipe[0], &fdread); -- -- if (!stdinChannel.buffer.isEmpty() && stdinChannel.pipe[1] != -1) -- add_fd(nfds, stdinChannel.pipe[1], &fdwrite); -+ QProcessPoller poller(*this); - - int timeout = qt_subtract_from_timeout(msecs, stopWatch.elapsed()); - #ifdef Q_OS_BLACKBERRY - int ret = bb_select(notifiers, nfds + 1, &fdread, &fdwrite, timeout); - #else -- int ret = qt_select_msecs(nfds + 1, &fdread, &fdwrite, timeout); -+ int ret = poller.poll(timeout); - #endif - if (ret < 0) { - break; -@@ -754,18 +776,18 @@ bool QProcessPrivate::waitForReadyRead(int msecs) - return false; - } - -- if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) { -+ if (qt_pollfd_check(poller.childStartedPipe(), POLLIN)) { - if (!_q_startupNotification()) - return false; - } - - bool readyReadEmitted = false; -- if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread)) { -+ if (qt_pollfd_check(poller.stdoutPipe(), POLLIN)) { - bool canRead = _q_canReadStandardOutput(); - if (processChannel == QProcess::StandardOutput && canRead) - readyReadEmitted = true; - } -- if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread)) { -+ if (qt_pollfd_check(poller.stderrPipe(), POLLIN)) { - bool canRead = _q_canReadStandardError(); - if (processChannel == QProcess::StandardError && canRead) - readyReadEmitted = true; -@@ -773,10 +795,10 @@ bool QProcessPrivate::waitForReadyRead(int msecs) - if (readyReadEmitted) - return true; - -- if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite)) -+ if (qt_pollfd_check(poller.stdinPipe(), POLLOUT)) - _q_canWrite(); - -- if (forkfd == -1 || FD_ISSET(forkfd, &fdread)) { -+ if (qt_pollfd_check(poller.forkfd(), POLLIN)) { - if (_q_processDied()) - return false; - } -@@ -798,32 +820,13 @@ bool QProcessPrivate::waitForBytesWritten(int msecs) - #endif - - while (!stdinChannel.buffer.isEmpty()) { -- fd_set fdread; -- fd_set fdwrite; -- -- FD_ZERO(&fdread); -- FD_ZERO(&fdwrite); -- -- int nfds = forkfd; -- FD_SET(forkfd, &fdread); -- -- if (processState == QProcess::Starting) -- add_fd(nfds, childStartedPipe[0], &fdread); -- -- if (stdoutChannel.pipe[0] != -1) -- add_fd(nfds, stdoutChannel.pipe[0], &fdread); -- if (stderrChannel.pipe[0] != -1) -- add_fd(nfds, stderrChannel.pipe[0], &fdread); -- -- -- if (!stdinChannel.buffer.isEmpty() && stdinChannel.pipe[1] != -1) -- add_fd(nfds, stdinChannel.pipe[1], &fdwrite); -+ QProcessPoller poller(*this); - - int timeout = qt_subtract_from_timeout(msecs, stopWatch.elapsed()); - #ifdef Q_OS_BLACKBERRY - int ret = bb_select(notifiers, nfds + 1, &fdread, &fdwrite, timeout); - #else -- int ret = qt_select_msecs(nfds + 1, &fdread, &fdwrite, timeout); -+ int ret = poller.poll(timeout); - #endif - if (ret < 0) { - break; -@@ -834,21 +837,21 @@ bool QProcessPrivate::waitForBytesWritten(int msecs) - return false; - } - -- if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) { -+ if (qt_pollfd_check(poller.childStartedPipe(), POLLIN)) { - if (!_q_startupNotification()) - return false; - } - -- if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite)) -+ if (qt_pollfd_check(poller.stdinPipe(), POLLOUT)) - return _q_canWrite(); - -- if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread)) -+ if (qt_pollfd_check(poller.stdoutPipe(), POLLIN)) - _q_canReadStandardOutput(); - -- if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread)) -+ if (qt_pollfd_check(poller.stderrPipe(), POLLIN)) - _q_canReadStandardError(); - -- if (forkfd == -1 || FD_ISSET(forkfd, &fdread)) { -+ if (qt_pollfd_check(poller.forkfd(), POLLIN)) { - if (_q_processDied()) - return false; - } -@@ -871,32 +874,13 @@ bool QProcessPrivate::waitForFinished(int msecs) - #endif - - forever { -- fd_set fdread; -- fd_set fdwrite; -- int nfds = -1; -- -- FD_ZERO(&fdread); -- FD_ZERO(&fdwrite); -- -- if (processState == QProcess::Starting) -- add_fd(nfds, childStartedPipe[0], &fdread); -- -- if (stdoutChannel.pipe[0] != -1) -- add_fd(nfds, stdoutChannel.pipe[0], &fdread); -- if (stderrChannel.pipe[0] != -1) -- add_fd(nfds, stderrChannel.pipe[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); -+ QProcessPoller poller(*this); - - int timeout = qt_subtract_from_timeout(msecs, stopWatch.elapsed()); - #ifdef Q_OS_BLACKBERRY - int ret = bb_select(notifiers, nfds + 1, &fdread, &fdwrite, timeout); - #else -- int ret = qt_select_msecs(nfds + 1, &fdread, &fdwrite, timeout); -+ int ret = poller.poll(timeout); - #endif - if (ret < 0) { - break; -@@ -906,20 +890,20 @@ bool QProcessPrivate::waitForFinished(int msecs) - return false; - } - -- if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) { -+ if (qt_pollfd_check(poller.childStartedPipe(), POLLIN)) { - if (!_q_startupNotification()) - return false; - } -- if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite)) -+ if (qt_pollfd_check(poller.stdinPipe(), POLLOUT)) - _q_canWrite(); - -- if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread)) -+ if (qt_pollfd_check(poller.stdoutPipe(), POLLIN)) - _q_canReadStandardOutput(); - -- if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread)) -+ if (qt_pollfd_check(poller.stderrPipe(), POLLIN)) - _q_canReadStandardError(); - -- if (forkfd == -1 || FD_ISSET(forkfd, &fdread)) { -+ if (qt_pollfd_check(poller.forkfd(), POLLIN)) { - if (_q_processDied()) - return true; - } -@@ -929,10 +913,8 @@ bool QProcessPrivate::waitForFinished(int msecs) - - bool QProcessPrivate::waitForWrite(int msecs) - { -- fd_set fdwrite; -- FD_ZERO(&fdwrite); -- FD_SET(stdinChannel.pipe[1], &fdwrite); -- return qt_select_msecs(stdinChannel.pipe[1] + 1, 0, &fdwrite, msecs < 0 ? 0 : msecs) == 1; -+ pollfd pfd = qt_make_pollfd(stdinChannel.pipe[1], POLLOUT); -+ return qt_poll_msecs(&pfd, 1, msecs < 0 ? 0 : msecs) == 1; - } - - void QProcessPrivate::findExitCode() -diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri -index bc93791..ff64b4e 100644 ---- a/src/corelib/kernel/kernel.pri -+++ b/src/corelib/kernel/kernel.pri -@@ -143,8 +143,14 @@ unix|integrity { - kernel/qcore_unix_p.h \ - kernel/qcrashhandler_p.h \ - kernel/qeventdispatcher_unix_p.h \ -+ kernel/qpoll_p.h \ - kernel/qtimerinfo_unix_p.h - -+ contains(QT_CONFIG, poll_select): SOURCES += kernel/qpoll.cpp -+ contains(QT_CONFIG, poll_poll): DEFINES += QT_HAVE_POLL -+ contains(QT_CONFIG, poll_ppoll): DEFINES += QT_HAVE_POLL QT_HAVE_PPOLL -+ contains(QT_CONFIG, poll_pollts): DEFINES += QT_HAVE_POLL QT_HAVE_POLLTS -+ - contains(QT_CONFIG, glib) { - SOURCES += \ - kernel/qeventdispatcher_glib.cpp -diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp -index 1bcb472..3a3990c 100644 ---- a/src/corelib/kernel/qcore_unix.cpp -+++ b/src/corelib/kernel/qcore_unix.cpp -@@ -46,6 +46,11 @@ - - QT_BEGIN_NAMESPACE - -+#if !defined(QT_HAVE_PPOLL) && defined(QT_HAVE_POLLTS) -+# define ppoll pollts -+# define QT_HAVE_PPOLL -+#endif -+ - static inline bool time_update(struct timespec *tv, const struct timespec &start, - const struct timespec &timeout) - { -@@ -75,9 +80,7 @@ int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, - #ifndef Q_OS_QNX - ret = ::pselect(nfds, fdread, fdwrite, fdexcept, &timeout, 0); - #else -- timeval timeoutVal; -- timeoutVal.tv_sec = timeout.tv_sec; -- timeoutVal.tv_usec = timeout.tv_nsec / 1000; -+ timeval timeoutVal = timespecToTimeval(timeout); - ret = ::select(nfds, fdread, fdwrite, fdexcept, &timeoutVal); - #endif - if (ret != -1 || errno != EINTR) -@@ -92,17 +95,82 @@ int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, - } - } - -+static inline struct timespec millisecsToTimespec(const unsigned int ms) -+{ -+ struct timespec tv; -+ -+ tv.tv_sec = ms / 1000; -+ tv.tv_nsec = (ms % 1000) * 1000 * 1000; -+ -+ return tv; -+} -+ - int qt_select_msecs(int nfds, fd_set *fdread, fd_set *fdwrite, int timeout) - { - if (timeout < 0) - return qt_safe_select(nfds, fdread, fdwrite, 0, 0); - -- struct timespec tv; -- tv.tv_sec = timeout / 1000; -- tv.tv_nsec = (timeout % 1000) * 1000 * 1000; -+ struct timespec tv = millisecsToTimespec(timeout); - return qt_safe_select(nfds, fdread, fdwrite, 0, &tv); - } - -+#if !defined(QT_HAVE_PPOLL) && defined(QT_HAVE_POLL) -+static inline int timespecToMillisecs(const struct timespec *ts) -+{ -+ return (ts == NULL) ? -1 : -+ (ts->tv_sec * 1000) + (ts->tv_nsec / 1000000); -+} -+#endif -+ -+// defined in qpoll.cpp -+int qt_poll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts); -+ -+static inline int qt_ppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts) -+{ -+#if defined(QT_HAVE_PPOLL) -+ return ::ppoll(fds, nfds, timeout_ts, Q_NULLPTR); -+#elif defined(QT_HAVE_POLL) -+ return ::poll(fds, nfds, timespecToMillisecs(timeout_ts)); -+#else -+ return qt_poll(fds, nfds, timeout_ts); -+#endif -+} -+ -+ -+/*! -+ \internal -+ -+ Behaves as close to POSIX poll(2) as practical but may be implemented -+ using select(2) where necessary. In that case, returns -1 and sets errno -+ to EINVAL if passed any descriptor greater than or equal to FD_SETSIZE. -+*/ -+int qt_safe_poll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts) -+{ -+ if (!timeout_ts) { -+ // no timeout -> block forever -+ int ret; -+ EINTR_LOOP(ret, qt_ppoll(fds, nfds, Q_NULLPTR)); -+ return ret; -+ } -+ -+ timespec start = qt_gettime(); -+ timespec timeout = *timeout_ts; -+ -+ // loop and recalculate the timeout as needed -+ forever { -+ const int ret = qt_ppoll(fds, nfds, &timeout); -+ if (ret != -1 || errno != EINTR) -+ return ret; -+ -+ // recalculate the timeout -+ if (!time_update(&timeout, start, *timeout_ts)) { -+ // timeout during update -+ // or clock reset, fake timeout error -+ return 0; -+ } -+ } -+} -+ - #ifdef Q_OS_BLACKBERRY - // The BlackBerry event dispatcher uses bps_get_event. Unfortunately, already registered - // socket notifiers are disabled by a call to select. This is to rearm the standard streams. -diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h -index 07725b8..64f62f5 100644 ---- a/src/corelib/kernel/qcore_unix_p.h -+++ b/src/corelib/kernel/qcore_unix_p.h -@@ -80,6 +80,12 @@ - # include - #endif - -+#ifdef QT_NO_NATIVE_POLL -+# include "qpoll_p.h" -+#else -+# include -+#endif -+ - struct sockaddr; - - #define EINTR_LOOP(var, cmd) \ -@@ -136,6 +142,14 @@ inline timespec operator*(const timespec &t1, int mul) - return normalizedTimespec(tmp); - } - -+inline timeval timespecToTimeval(const timespec &ts) -+{ -+ timeval tv; -+ tv.tv_sec = ts.tv_sec; -+ tv.tv_usec = ts.tv_nsec / 1000; -+ return tv; -+} -+ - inline void qt_ignore_sigpipe() - { - // Set to ignore SIGPIPE once only. -@@ -317,6 +331,27 @@ static inline pid_t qt_safe_waitpid(pid_t pid, int *status, int options) - timespec qt_gettime() Q_DECL_NOTHROW; - void qt_nanosleep(timespec amount); - -+Q_CORE_EXPORT int qt_safe_poll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts); -+ -+static inline int qt_poll_msecs(struct pollfd *fds, nfds_t nfds, int timeout) -+{ -+ timespec ts, *pts = Q_NULLPTR; -+ -+ if (timeout >= 0) { -+ ts.tv_sec = timeout / 1000; -+ ts.tv_nsec = (timeout % 1000) * 1000 * 1000; -+ pts = &ts; -+ } -+ -+ return qt_safe_poll(fds, nfds, pts); -+} -+ -+static inline struct pollfd qt_make_pollfd(int fd, short events) -+{ -+ struct pollfd pfd = { fd, events, 0 }; -+ return pfd; -+} -+ - Q_CORE_EXPORT int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, - const struct timespec *tv); - -diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp -index 155f7b7..9567e29 100644 ---- a/src/corelib/kernel/qeventdispatcher_unix.cpp -+++ b/src/corelib/kernel/qeventdispatcher_unix.cpp -@@ -59,7 +59,7 @@ - # define _POSIX_MONOTONIC_CLOCK 1 - # endif - # include --# include -+# include - #endif - - #if (_POSIX_MONOTONIC_CLOCK-0 <= 0) || defined(QT_BOOTSTRAPPED) -@@ -68,6 +68,20 @@ - - QT_BEGIN_NAMESPACE - -+static const char *socketType(QSocketNotifier::Type type) -+{ -+ switch (type) { -+ case QSocketNotifier::Read: -+ return "Read"; -+ case QSocketNotifier::Write: -+ return "Write"; -+ case QSocketNotifier::Exception: -+ return "Exception"; -+ } -+ -+ Q_UNREACHABLE(); -+} -+ - #if defined(Q_OS_INTEGRITY) || defined(Q_OS_VXWORKS) - static void initThreadPipeFD(int fd) - { -@@ -137,8 +151,6 @@ QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate() - - if (pipefail) - qFatal("QEventDispatcherUNIXPrivate(): Can not continue without a thread pipe"); -- -- sn_highest = -1; - } - - QEventDispatcherUNIXPrivate::~QEventDispatcherUNIXPrivate() -@@ -163,116 +175,11 @@ QEventDispatcherUNIXPrivate::~QEventDispatcherUNIXPrivate() - qDeleteAll(timerList); - } - --int QEventDispatcherUNIXPrivate::doSelect(QEventLoop::ProcessEventsFlags flags, timespec *timeout) --{ -- Q_Q(QEventDispatcherUNIX); -- -- // needed in QEventDispatcherUNIX::select() -- timerList.updateCurrentTime(); -- -- int nsel; -- do { -- // Process timers and socket notifiers - the common UNIX stuff -- int highest = 0; -- if (! (flags & QEventLoop::ExcludeSocketNotifiers) && (sn_highest >= 0)) { -- // return the highest fd we can wait for input on -- sn_vec[0].select_fds = sn_vec[0].enabled_fds; -- sn_vec[1].select_fds = sn_vec[1].enabled_fds; -- sn_vec[2].select_fds = sn_vec[2].enabled_fds; -- highest = sn_highest; -- } else { -- FD_ZERO(&sn_vec[0].select_fds); -- FD_ZERO(&sn_vec[1].select_fds); -- FD_ZERO(&sn_vec[2].select_fds); -- } -- -- int wakeUpFd = initThreadWakeUp(); -- highest = qMax(highest, wakeUpFd); -- -- nsel = q->select(highest + 1, -- &sn_vec[0].select_fds, -- &sn_vec[1].select_fds, -- &sn_vec[2].select_fds, -- timeout); -- } while (nsel == -1 && (errno == EINTR || errno == EAGAIN)); -- -- if (nsel == -1) { -- if (errno == EBADF) { -- // it seems a socket notifier has a bad fd... find out -- // which one it is and disable it -- fd_set fdset; -- timeval tm; -- tm.tv_sec = tm.tv_usec = 0l; -- -- for (int type = 0; type < 3; ++type) { -- QSockNotType::List &list = sn_vec[type].list; -- if (list.size() == 0) -- continue; -- -- for (int i = 0; i < list.size(); ++i) { -- QSockNot *sn = list[i]; -- -- FD_ZERO(&fdset); -- FD_SET(sn->fd, &fdset); -- -- int ret = -1; -- do { -- switch (type) { -- case 0: // read -- ret = select(sn->fd + 1, &fdset, 0, 0, &tm); -- break; -- case 1: // write -- ret = select(sn->fd + 1, 0, &fdset, 0, &tm); -- break; -- case 2: // except -- ret = select(sn->fd + 1, 0, 0, &fdset, &tm); -- break; -- } -- } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); -- -- if (ret == -1 && errno == EBADF) { -- // disable the invalid socket notifier -- static const char *t[] = { "Read", "Write", "Exception" }; -- qWarning("QSocketNotifier: Invalid socket %d and type '%s', disabling...", -- sn->fd, t[type]); -- sn->obj->setEnabled(false); -- } -- } -- } -- } else { -- // EINVAL... shouldn't happen, so let's complain to stderr -- // and hope someone sends us a bug report -- perror("select"); -- } -- } -- -- int nevents = processThreadWakeUp(nsel); -- -- // activate socket notifiers -- if (! (flags & QEventLoop::ExcludeSocketNotifiers) && nsel > 0 && sn_highest >= 0) { -- // if select says data is ready on any socket, then set the socket notifier -- // to pending -- for (int i=0; i<3; i++) { -- QSockNotType::List &list = sn_vec[i].list; -- for (int j = 0; j < list.size(); ++j) { -- QSockNot *sn = list[j]; -- if (FD_ISSET(sn->fd, &sn_vec[i].select_fds)) -- q->setSocketNotifierPending(sn->obj); -- } -- } -- } -- return (nevents + q->activateSocketNotifiers()); --} -- --int QEventDispatcherUNIXPrivate::initThreadWakeUp() -+int QEventDispatcherUNIXPrivate::processThreadWakeUp(const pollfd &pfd) - { -- FD_SET(thread_pipe[0], &sn_vec[0].select_fds); -- return thread_pipe[0]; --} -+ Q_ASSERT(pfd.fd == thread_pipe[0]); - --int QEventDispatcherUNIXPrivate::processThreadWakeUp(int nsel) --{ -- if (nsel > 0 && FD_ISSET(thread_pipe[0], &sn_vec[0].select_fds)) { -+ if (pfd.revents & POLLIN) { - // some other thread woke us up... consume the data on the thread pipe so that - // select doesn't immediately return next time - #if defined(Q_OS_VXWORKS) -@@ -302,6 +209,80 @@ int QEventDispatcherUNIXPrivate::processThreadWakeUp(int nsel) - return 0; - } - -+void QEventDispatcherUNIXPrivate::setSocketNotifierPending(QSocketNotifier *notifier) -+{ -+ Q_ASSERT(notifier); -+ -+ if (pendingNotifiers.contains(notifier)) -+ return; -+ -+ pendingNotifiers << notifier; -+} -+ -+int QEventDispatcherUNIXPrivate::activateTimers() -+{ -+ return timerList.activateTimers(); -+} -+ -+void QEventDispatcherUNIXPrivate::markPendingSocketNotifiers() -+{ -+ foreach (const pollfd &pfd, pollfds) { -+ if (pfd.fd < 0 || pfd.revents == 0) -+ continue; -+ -+ auto it = socketNotifiers.find(pfd.fd); -+ Q_ASSERT(it != socketNotifiers.end()); -+ -+ const QSocketNotifierSetUNIX &sn_set = it.value(); -+ -+ static const struct { -+ QSocketNotifier::Type type; -+ short flags; -+ } notifiers[] = { -+ { QSocketNotifier::Read, POLLIN | POLLHUP | POLLERR }, -+ { QSocketNotifier::Write, POLLOUT | POLLHUP | POLLERR }, -+ { QSocketNotifier::Exception, POLLPRI | POLLHUP | POLLERR } -+ }; -+ -+ for (const auto &n : notifiers) { -+ QSocketNotifier *notifier = sn_set.notifiers[n.type]; -+ -+ if (!notifier) -+ continue; -+ -+ if (pfd.revents & POLLNVAL) { -+ qWarning("QSocketNotifier: Invalid socket %d with type %s, disabling...", -+ it.key(), socketType(n.type)); -+ notifier->setEnabled(false); -+ } -+ -+ if (pfd.revents & n.flags) -+ setSocketNotifierPending(notifier); -+ } -+ } -+ -+ pollfds.resize(0); -+} -+ -+int QEventDispatcherUNIXPrivate::activateSocketNotifiers() -+{ -+ markPendingSocketNotifiers(); -+ -+ if (pendingNotifiers.isEmpty()) -+ return 0; -+ -+ int n_activated = 0; -+ QEvent event(QEvent::SockAct); -+ -+ while (!pendingNotifiers.isEmpty()) { -+ QSocketNotifier *notifier = pendingNotifiers.takeFirst(); -+ QCoreApplication::sendEvent(notifier, &event); -+ ++n_activated; -+ } -+ -+ return n_activated; -+} -+ - QEventDispatcherUNIX::QEventDispatcherUNIX(QObject *parent) - : QAbstractEventDispatcher(*new QEventDispatcherUNIXPrivate, parent) - { } -@@ -311,14 +292,7 @@ QEventDispatcherUNIX::QEventDispatcherUNIX(QEventDispatcherUNIXPrivate &dd, QObj - { } - - QEventDispatcherUNIX::~QEventDispatcherUNIX() --{ --} -- --int QEventDispatcherUNIX::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, -- timespec *timeout) --{ -- return qt_safe_select(nfds, readfds, writefds, exceptfds, timeout); --} -+{ } - - /*! - \internal -@@ -390,22 +364,6 @@ QEventDispatcherUNIX::registeredTimers(QObject *object) const - } - - /***************************************************************************** -- Socket notifier type -- *****************************************************************************/ --QSockNotType::QSockNotType() --{ -- FD_ZERO(&select_fds); -- FD_ZERO(&enabled_fds); -- FD_ZERO(&pending_fds); --} -- --QSockNotType::~QSockNotType() --{ -- for (int i = 0; i < list.size(); ++i) -- delete list[i]; --} -- --/***************************************************************************** - QEventDispatcher implementations for UNIX - *****************************************************************************/ - -@@ -413,160 +371,57 @@ void QEventDispatcherUNIX::registerSocketNotifier(QSocketNotifier *notifier) - { - Q_ASSERT(notifier); - int sockfd = notifier->socket(); -- int type = notifier->type(); -+ QSocketNotifier::Type type = notifier->type(); - #ifndef QT_NO_DEBUG -- if (sockfd < 0 -- || unsigned(sockfd) >= FD_SETSIZE) { -- qWarning("QSocketNotifier: Internal error"); -- return; -- } else if (notifier->thread() != thread() -- || thread() != QThread::currentThread()) { -+ if (notifier->thread() != thread() || thread() != QThread::currentThread()) { - qWarning("QSocketNotifier: socket notifiers cannot be enabled from another thread"); - return; - } - #endif - - Q_D(QEventDispatcherUNIX); -- QSockNotType::List &list = d->sn_vec[type].list; -- fd_set *fds = &d->sn_vec[type].enabled_fds; -- QSockNot *sn; -- -- sn = new QSockNot; -- sn->obj = notifier; -- sn->fd = sockfd; -- sn->queue = &d->sn_vec[type].pending_fds; -- -- int i; -- for (i = 0; i < list.size(); ++i) { -- QSockNot *p = list[i]; -- if (p->fd < sockfd) -- break; -- if (p->fd == sockfd) { -- static const char *t[] = { "Read", "Write", "Exception" }; -- qWarning("QSocketNotifier: Multiple socket notifiers for " -- "same socket %d and type %s", sockfd, t[type]); -- } -- } -- list.insert(i, sn); -+ QSocketNotifierSetUNIX &sn_set = d->socketNotifiers[sockfd]; -+ -+ if (sn_set.notifiers[type] && sn_set.notifiers[type] != notifier) -+ qWarning("%s: Multiple socket notifiers for same socket %d and type %s", -+ Q_FUNC_INFO, sockfd, socketType(type)); - -- FD_SET(sockfd, fds); -- d->sn_highest = qMax(d->sn_highest, sockfd); -+ sn_set.notifiers[type] = notifier; - } - - void QEventDispatcherUNIX::unregisterSocketNotifier(QSocketNotifier *notifier) - { - Q_ASSERT(notifier); - int sockfd = notifier->socket(); -- int type = notifier->type(); -+ QSocketNotifier::Type type = notifier->type(); - #ifndef QT_NO_DEBUG -- if (sockfd < 0 -- || unsigned(sockfd) >= FD_SETSIZE) { -- qWarning("QSocketNotifier: Internal error"); -- return; -- } else if (notifier->thread() != thread() -- || thread() != QThread::currentThread()) { -+ if (notifier->thread() != thread() || thread() != QThread::currentThread()) { - qWarning("QSocketNotifier: socket notifiers cannot be disabled from another thread"); - return; - } - #endif - - Q_D(QEventDispatcherUNIX); -- QSockNotType::List &list = d->sn_vec[type].list; -- fd_set *fds = &d->sn_vec[type].enabled_fds; -- QSockNot *sn = 0; -- int i; -- for (i = 0; i < list.size(); ++i) { -- sn = list[i]; -- if(sn->obj == notifier && sn->fd == sockfd) -- break; -- } -- if (i == list.size()) // not found -- return; -+ d->pendingNotifiers.removeOne(notifier); - -- FD_CLR(sockfd, fds); // clear fd bit -- FD_CLR(sockfd, sn->queue); -- d->sn_pending_list.removeAll(sn); // remove from activation list -- list.removeAt(i); // remove notifier found above -- delete sn; -- -- if (d->sn_highest == sockfd) { // find highest fd -- d->sn_highest = -1; -- for (int i=0; i<3; i++) { -- if (!d->sn_vec[i].list.isEmpty()) -- d->sn_highest = qMax(d->sn_highest, // list is fd-sorted -- d->sn_vec[i].list[0]->fd); -- } -- } --} -- --void QEventDispatcherUNIX::setSocketNotifierPending(QSocketNotifier *notifier) --{ -- Q_ASSERT(notifier); -- int sockfd = notifier->socket(); -- int type = notifier->type(); --#ifndef QT_NO_DEBUG -- if (sockfd < 0 -- || unsigned(sockfd) >= FD_SETSIZE) { -- qWarning("QSocketNotifier: Internal error"); -+ auto i = d->socketNotifiers.find(sockfd); -+ if (i == d->socketNotifiers.end()) - return; -- } -- Q_ASSERT(notifier->thread() == thread() && thread() == QThread::currentThread()); --#endif -+ QSocketNotifierSetUNIX &sn_set = i.value(); - -- Q_D(QEventDispatcherUNIX); -- QSockNotType::List &list = d->sn_vec[type].list; -- QSockNot *sn = 0; -- int i; -- for (i = 0; i < list.size(); ++i) { -- sn = list[i]; -- if(sn->obj == notifier && sn->fd == sockfd) -- break; -- } -- if (i == list.size()) // not found -+ if (sn_set.notifiers[type] == nullptr) - return; - -- // We choose a random activation order to be more fair under high load. -- // If a constant order is used and a peer early in the list can -- // saturate the IO, it might grab our attention completely. -- // Also, if we're using a straight list, the callback routines may -- // delete other entries from the list before those other entries are -- // processed. -- if (! FD_ISSET(sn->fd, sn->queue)) { -- if (d->sn_pending_list.isEmpty()) { -- d->sn_pending_list.append(sn); -- } else { -- d->sn_pending_list.insert((qrand() & 0xff) % -- (d->sn_pending_list.size()+1), sn); -- } -- FD_SET(sn->fd, sn->queue); -+ if (sn_set.notifiers[type] != notifier) { -+ qWarning("%s: Multiple socket notifiers for same socket %d and type %s", -+ Q_FUNC_INFO, sockfd, socketType(type)); -+ return; - } --} -- --int QEventDispatcherUNIX::activateTimers() --{ -- Q_ASSERT(thread() == QThread::currentThread()); -- Q_D(QEventDispatcherUNIX); -- return d->timerList.activateTimers(); --} - --int QEventDispatcherUNIX::activateSocketNotifiers() --{ -- Q_D(QEventDispatcherUNIX); -- if (d->sn_pending_list.isEmpty()) -- return 0; -+ sn_set.notifiers[type] = nullptr; - -- // activate entries -- int n_act = 0; -- QEvent event(QEvent::SockAct); -- while (!d->sn_pending_list.isEmpty()) { -- QSockNot *sn = d->sn_pending_list.takeFirst(); -- if (FD_ISSET(sn->fd, sn->queue)) { -- FD_CLR(sn->fd, sn->queue); -- QCoreApplication::sendEvent(sn->obj, &event); -- ++n_act; -- } -- } -- return n_act; -+ if (sn_set.isEmpty()) -+ d->socketNotifiers.erase(i); - } - - bool QEventDispatcherUNIX::processEvents(QEventLoop::ProcessEventsFlags flags) -@@ -578,39 +433,54 @@ bool QEventDispatcherUNIX::processEvents(QEventLoop::ProcessEventsFlags flags) - emit awake(); - QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData); - -- int nevents = 0; -+ const bool include_timers = (flags & QEventLoop::X11ExcludeTimers) == 0; -+ const bool include_notifiers = (flags & QEventLoop::ExcludeSocketNotifiers) == 0; -+ const bool wait_for_events = flags & QEventLoop::WaitForMoreEvents; -+ - const bool canWait = (d->threadData->canWaitLocked() - && !d->interrupt.load() -- && (flags & QEventLoop::WaitForMoreEvents)); -+ && wait_for_events); - - if (canWait) - emit aboutToBlock(); - -- if (!d->interrupt.load()) { -- // return the maximum time we can wait for an event. -- timespec *tm = 0; -- timespec wait_tm = { 0l, 0l }; -- if (!(flags & QEventLoop::X11ExcludeTimers)) { -- if (d->timerList.timerWait(wait_tm)) -- tm = &wait_tm; -- } -+ if (d->interrupt.load()) -+ return false; - -- if (!canWait) { -- if (!tm) -- tm = &wait_tm; -+ timespec *tm = nullptr; -+ timespec wait_tm = { 0, 0 }; - -- // no time to wait -- tm->tv_sec = 0l; -- tm->tv_nsec = 0l; -- } -+ if (!canWait || (include_timers && d->timerList.timerWait(wait_tm))) -+ tm = &wait_tm; - -- nevents = d->doSelect(flags, tm); -+ d->pollfds.reserve(1 + (include_notifiers ? d->socketNotifiers.size() : 0)); -+ d->pollfds.resize(0); - -- // activate timers -- if (! (flags & QEventLoop::X11ExcludeTimers)) { -- nevents += activateTimers(); -- } -+ if (include_notifiers) -+ for (auto it = d->socketNotifiers.cbegin(); it != d->socketNotifiers.cend(); ++it) -+ d->pollfds.append(qt_make_pollfd(it.key(), it.value().events())); -+ -+ // This must be last, as it's popped off the end below -+ d->pollfds.append(qt_make_pollfd(d->thread_pipe[0], POLLIN)); -+ -+ int nevents = 0; -+ -+ switch (qt_safe_poll(d->pollfds.data(), d->pollfds.size(), tm)) { -+ case -1: -+ perror("qt_safe_poll"); -+ break; -+ case 0: -+ break; -+ default: -+ nevents += d->processThreadWakeUp(d->pollfds.takeLast()); -+ if (include_notifiers) -+ nevents += d->activateSocketNotifiers(); -+ break; - } -+ -+ if (include_timers) -+ nevents += d->activateTimers(); -+ - // return true if we handled events, false otherwise - return (nevents > 0); - } -diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h -index 32c9de0..8a0a0e2 100644 ---- a/src/corelib/kernel/qeventdispatcher_unix_p.h -+++ b/src/corelib/kernel/qeventdispatcher_unix_p.h -@@ -53,35 +53,18 @@ - #include "QtCore/qvarlengtharray.h" - #include "private/qtimerinfo_unix_p.h" - --#if !defined(Q_OS_VXWORKS) --# include --# if (!defined(Q_OS_HPUX) || defined(__ia64)) && !defined(Q_OS_NACL) --# include --# endif --#endif -- - QT_BEGIN_NAMESPACE - --struct QSockNot --{ -- QSocketNotifier *obj; -- int fd; -- fd_set *queue; --}; -+class QEventDispatcherUNIXPrivate; - --class QSockNotType -+struct Q_CORE_EXPORT QSocketNotifierSetUNIX Q_DECL_FINAL - { --public: -- QSockNotType(); -- ~QSockNotType(); -+ inline QSocketNotifierSetUNIX() Q_DECL_NOTHROW; - -- typedef QPodList List; -- -- List list; -- fd_set select_fds; -- fd_set enabled_fds; -- fd_set pending_fds; -+ inline bool isEmpty() const Q_DECL_NOTHROW; -+ inline short events() const Q_DECL_NOTHROW; - -+ QSocketNotifier *notifiers[3]; - }; - - #ifdef check -@@ -89,7 +72,7 @@ public: - # undef check - #endif - --class QEventDispatcherUNIXPrivate; -+Q_DECLARE_TYPEINFO(QSocketNotifierSetUNIX, Q_PRIMITIVE_TYPE); - - #ifdef Q_OS_QNX - # define FINAL_EXCEPT_BLACKBERRY -@@ -125,15 +108,6 @@ public: - - protected: - QEventDispatcherUNIX(QEventDispatcherUNIXPrivate &dd, QObject *parent = 0); -- -- void setSocketNotifierPending(QSocketNotifier *notifier); -- -- int activateTimers(); -- int activateSocketNotifiers(); -- -- virtual int select(int nfds, -- fd_set *readfds, fd_set *writefds, fd_set *exceptfds, -- timespec *timeout); - }; - - class Q_CORE_EXPORT QEventDispatcherUNIXPrivate : public QAbstractEventDispatcherPrivate -@@ -144,9 +118,13 @@ public: - QEventDispatcherUNIXPrivate(); - ~QEventDispatcherUNIXPrivate(); - -- int doSelect(QEventLoop::ProcessEventsFlags flags, timespec *timeout); -- virtual int initThreadWakeUp() FINAL_EXCEPT_BLACKBERRY; -- virtual int processThreadWakeUp(int nsel) FINAL_EXCEPT_BLACKBERRY; -+ int processThreadWakeUp(const pollfd &pfd); -+ -+ int activateTimers(); -+ -+ void markPendingSocketNotifiers(); -+ int activateSocketNotifiers(); -+ void setSocketNotifierPending(QSocketNotifier *notifier); - - bool mainThread; - -@@ -154,15 +132,12 @@ public: - // if thread_pipe[1] is -1, then eventfd(7) is in use and is stored in thread_pipe[0] - int thread_pipe[2]; - -- // highest fd for all socket notifiers -- int sn_highest; -- // 3 socket notifier types - read, write and exception -- QSockNotType sn_vec[3]; -+ QVector pollfds; - -- QTimerInfoList timerList; -+ QHash socketNotifiers; -+ QVector pendingNotifiers; - -- // pending socket notifiers list -- QSockNotType::List sn_pending_list; -+ QTimerInfoList timerList; - - QAtomicInt wakeUps; - QAtomicInt interrupt; // bool -@@ -170,6 +145,34 @@ public: - - #undef FINAL_EXCEPT_BLACKBERRY - -+inline QSocketNotifierSetUNIX::QSocketNotifierSetUNIX() Q_DECL_NOTHROW -+{ -+ notifiers[0] = 0; -+ notifiers[1] = 0; -+ notifiers[2] = 0; -+} -+ -+inline bool QSocketNotifierSetUNIX::isEmpty() const Q_DECL_NOTHROW -+{ -+ return !notifiers[0] && !notifiers[1] && !notifiers[2]; -+} -+ -+inline short QSocketNotifierSetUNIX::events() const Q_DECL_NOTHROW -+{ -+ short result = 0; -+ -+ if (notifiers[0]) -+ result |= POLLIN; -+ -+ if (notifiers[1]) -+ result |= POLLOUT; -+ -+ if (notifiers[2]) -+ result |= POLLPRI; -+ -+ return result; -+} -+ - QT_END_NAMESPACE - - #endif // QEVENTDISPATCHER_UNIX_P_H -diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h.patch b/src/corelib/kernel/qeventdispatcher_unix_p.h.patch -new file mode 100644 -index 0000000..ad568c9 ---- /dev/null -+++ b/src/corelib/kernel/qeventdispatcher_unix_p.h.patch -@@ -0,0 +1,48 @@ -+--- src/corelib/kernel/qeventdispatcher_unix_p.h -++++ src/corelib/kernel/qeventdispatcher_unix_p.h -+@@ -53,38 +53,21 @@ -+ #include "QtCore/qvarlengtharray.h" -+ #include "private/qtimerinfo_unix_p.h" -+ -+-#if !defined(Q_OS_VXWORKS) -+-# include -+-# if (!defined(Q_OS_HPUX) || defined(__ia64)) && !defined(Q_OS_NACL) -+-# include -+-# endif -+-#endif -+- -+ QT_BEGIN_NAMESPACE -+ -+-struct QSockNot -+-{ -+- QSocketNotifier *obj; -+- int fd; -+- fd_set *queue; -+-}; -++class QEventDispatcherUNIXPrivate; -+ -+-class QSockNotType -++struct Q_CORE_EXPORT QSocketNotifierSetUNIX Q_DECL_FINAL -+ { -+-public: -+- QSockNotType(); -+- ~QSockNotType(); -++ inline QSocketNotifierSetUNIX() Q_DECL_NOTHROW; -+ -+- typedef QPodList List; -+- -+- List list; -+- fd_set select_fds; -+- fd_set enabled_fds; -+- fd_set pending_fds; -++ inline bool isEmpty() const Q_DECL_NOTHROW; -++ inline short events() const Q_DECL_NOTHROW; -+ -++ QSocketNotifier *notifiers[3]; -+ }; -+ -+-class QEventDispatcherUNIXPrivate; -++Q_DECLARE_TYPEINFO(QSocketNotifierSetUNIX, Q_PRIMITIVE_TYPE); -+ -+ #ifdef Q_OS_QNX -+ # define FINAL_EXCEPT_BLACKBERRY -diff --git a/src/corelib/kernel/qpoll.cpp b/src/corelib/kernel/qpoll.cpp -new file mode 100644 -index 0000000..b152518 ---- /dev/null -+++ b/src/corelib/kernel/qpoll.cpp -@@ -0,0 +1,220 @@ -+/**************************************************************************** -+** -+** 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. -+** -+** $QT_BEGIN_LICENSE:LGPL21$ -+** 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 The Qt Company. For licensing terms -+** and conditions see http://www.qt.io/terms-conditions. For further -+** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free -+** Software Foundation and appearing in the file LICENSE.LGPLv21 and -+** LICENSE.LGPLv3 included in the packaging of this file. Please review the -+** following information to ensure the GNU Lesser General Public License -+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -+** -+** As a special exception, The Qt Company gives you certain additional -+** rights. These rights are described in The Qt Company LGPL Exception -+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -+** -+** $QT_END_LICENSE$ -+** -+****************************************************************************/ -+ -+#include "qcore_unix_p.h" -+ -+QT_BEGIN_NAMESPACE -+ -+#define QT_POLL_READ_MASK (POLLIN | POLLRDNORM) -+#define QT_POLL_WRITE_MASK (POLLOUT | POLLWRNORM | POLLWRBAND) -+#define QT_POLL_EXCEPT_MASK (POLLPRI | POLLRDBAND) -+#define QT_POLL_ERROR_MASK (POLLERR | POLLNVAL) -+#define QT_POLL_EVENTS_MASK (QT_POLL_READ_MASK | QT_POLL_WRITE_MASK | QT_POLL_EXCEPT_MASK) -+ -+static inline int qt_poll_prepare(struct pollfd *fds, nfds_t nfds, -+ fd_set *read_fds, fd_set *write_fds, fd_set *except_fds) -+{ -+ int max_fd = -1; -+ -+ FD_ZERO(read_fds); -+ FD_ZERO(write_fds); -+ FD_ZERO(except_fds); -+ -+ for (nfds_t i = 0; i < nfds; i++) { -+ if (fds[i].fd >= FD_SETSIZE) { -+ errno = EINVAL; -+ return -1; -+ } -+ -+ if ((fds[i].fd < 0) || (fds[i].revents & QT_POLL_ERROR_MASK)) -+ continue; -+ -+ if (fds[i].events & QT_POLL_READ_MASK) -+ FD_SET(fds[i].fd, read_fds); -+ -+ if (fds[i].events & QT_POLL_WRITE_MASK) -+ FD_SET(fds[i].fd, write_fds); -+ -+ if (fds[i].events & QT_POLL_EXCEPT_MASK) -+ FD_SET(fds[i].fd, except_fds); -+ -+ if (fds[i].events & QT_POLL_EVENTS_MASK) -+ max_fd = qMax(max_fd, fds[i].fd); -+ } -+ -+ return max_fd + 1; -+} -+ -+static inline void qt_poll_examine_ready_read(struct pollfd &pfd) -+{ -+ int res; -+ char data; -+ -+ EINTR_LOOP(res, ::recv(pfd.fd, &data, sizeof(data), MSG_PEEK)); -+ const int error = (res < 0) ? errno : 0; -+ -+ if (res == 0) { -+ pfd.revents |= POLLHUP; -+ } else if (res > 0 || error == ENOTSOCK || error == ENOTCONN) { -+ pfd.revents |= QT_POLL_READ_MASK & pfd.events; -+ } else { -+ switch (error) { -+ case ESHUTDOWN: -+ case ECONNRESET: -+ case ECONNABORTED: -+ case ENETRESET: -+ pfd.revents |= POLLHUP; -+ break; -+ default: -+ pfd.revents |= POLLERR; -+ break; -+ } -+ } -+} -+ -+static inline int qt_poll_sweep(struct pollfd *fds, nfds_t nfds, -+ fd_set *read_fds, fd_set *write_fds, fd_set *except_fds) -+{ -+ int result = 0; -+ -+ for (nfds_t i = 0; i < nfds; i++) { -+ if (fds[i].fd < 0) -+ continue; -+ -+ if (FD_ISSET(fds[i].fd, read_fds)) -+ qt_poll_examine_ready_read(fds[i]); -+ -+ if (FD_ISSET(fds[i].fd, write_fds)) -+ fds[i].revents |= QT_POLL_WRITE_MASK & fds[i].events; -+ -+ if (FD_ISSET(fds[i].fd, except_fds)) -+ fds[i].revents |= QT_POLL_EXCEPT_MASK & fds[i].events; -+ -+ if (fds[i].revents != 0) -+ result++; -+ } -+ -+ return result; -+} -+ -+static inline bool qt_poll_is_bad_fd(int fd) -+{ -+ int ret; -+ EINTR_LOOP(ret, fcntl(fd, F_GETFD)); -+ return (ret == -1 && errno == EBADF); -+} -+ -+static inline int qt_poll_mark_bad_fds(struct pollfd *fds, const nfds_t nfds) -+{ -+ int n_marked = 0; -+ -+ for (nfds_t i = 0; i < nfds; i++) { -+ if (fds[i].fd < 0) -+ continue; -+ -+ if (fds[i].revents & QT_POLL_ERROR_MASK) -+ continue; -+ -+ if (qt_poll_is_bad_fd(fds[i].fd)) { -+ fds[i].revents |= POLLNVAL; -+ n_marked++; -+ } -+ } -+ -+ return n_marked; -+} -+ -+int qt_poll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts) -+{ -+ if (!fds && nfds) { -+ errno = EFAULT; -+ return -1; -+ } -+ -+ fd_set read_fds, write_fds, except_fds; -+ struct timeval tv, *ptv = 0; -+ -+ if (timeout_ts) { -+ tv = timespecToTimeval(*timeout_ts); -+ ptv = &tv; -+ } -+ -+ int n_bad_fds = 0; -+ -+ for (nfds_t i = 0; i < nfds; i++) { -+ fds[i].revents = 0; -+ -+ if (fds[i].fd < 0) -+ continue; -+ -+ if (fds[i].events & QT_POLL_EVENTS_MASK) -+ continue; -+ -+ if (qt_poll_is_bad_fd(fds[i].fd)) { -+ // Mark bad file descriptors that have no event flags set -+ // here, as we won't be passing them to select below and therefore -+ // need to do the check ourselves -+ fds[i].revents = POLLNVAL; -+ n_bad_fds++; -+ } -+ } -+ -+ forever { -+ const int max_fd = qt_poll_prepare(fds, nfds, &read_fds, &write_fds, &except_fds); -+ -+ if (max_fd < 0) -+ return max_fd; -+ -+ if (n_bad_fds > 0) { -+ tv.tv_sec = 0; -+ tv.tv_usec = 0; -+ ptv = &tv; -+ } -+ -+ const int ret = ::select(max_fd, &read_fds, &write_fds, &except_fds, ptv); -+ -+ if (ret == 0) -+ return n_bad_fds; -+ -+ if (ret > 0) -+ return qt_poll_sweep(fds, nfds, &read_fds, &write_fds, &except_fds); -+ -+ if (errno != EBADF) -+ return -1; -+ -+ // We have at least one bad file descriptor that we waited on, find out which and try again -+ n_bad_fds += qt_poll_mark_bad_fds(fds, nfds); -+ } -+} -+ -+QT_END_NAMESPACE -diff --git a/src/corelib/kernel/qpoll_p.h b/src/corelib/kernel/qpoll_p.h -new file mode 100644 -index 0000000..497058a ---- /dev/null -+++ b/src/corelib/kernel/qpoll_p.h -@@ -0,0 +1,79 @@ -+/**************************************************************************** -+** -+** 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. -+** -+** $QT_BEGIN_LICENSE:LGPL21$ -+** 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 The Qt Company. For licensing terms -+** and conditions see http://www.qt.io/terms-conditions. For further -+** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free -+** Software Foundation and appearing in the file LICENSE.LGPLv21 and -+** LICENSE.LGPLv3 included in the packaging of this file. Please review the -+** following information to ensure the GNU Lesser General Public License -+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -+** -+** As a special exception, The Qt Company gives you certain additional -+** rights. These rights are described in The Qt Company LGPL Exception -+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -+** -+** $QT_END_LICENSE$ -+** -+****************************************************************************/ -+ -+#ifndef QPOLL_P_H -+#define QPOLL_P_H -+ -+// -+// W A R N I N G -+// ------------- -+// -+// This file is not part of the Qt API. It exists for the convenience -+// of Qt code on Unix. This header file may change from version to -+// version without notice, or even be removed. -+// -+// We mean it. -+// -+ -+#include -+ -+QT_BEGIN_NAMESPACE -+ -+#ifdef QT_NO_NATIVE_POLL -+ -+#include -+#include -+ -+struct pollfd { -+ int fd; -+ short events, revents; -+}; -+ -+typedef unsigned long int nfds_t; -+ -+#define POLLIN 0x001 -+#define POLLPRI 0x002 -+#define POLLOUT 0x004 -+#define POLLERR 0x008 -+#define POLLHUP 0x010 -+#define POLLNVAL 0x020 -+#define POLLRDNORM 0x040 -+#define POLLRDBAND 0x080 -+#define POLLWRNORM 0x100 -+#define POLLWRBAND 0x200 -+ -+#endif // QT_NO_NATIVE_POLL -+ -+QT_END_NAMESPACE -+ -+#endif // QPOLL_P_H -diff --git a/src/network/socket/qlocalserver_unix.cpp b/src/network/socket/qlocalserver_unix.cpp -index a356e21..79b9b9c 100644 ---- a/src/network/socket/qlocalserver_unix.cpp -+++ b/src/network/socket/qlocalserver_unix.cpp -@@ -277,24 +277,27 @@ void QLocalServerPrivate::_q_onNewConnection() - - void QLocalServerPrivate::waitForNewConnection(int msec, bool *timedOut) - { -- fd_set readfds; -- FD_ZERO(&readfds); -- FD_SET(listenSocket, &readfds); -+ pollfd pfd = qt_make_pollfd(listenSocket, POLLIN); - -- struct timespec timeout; -- timeout.tv_sec = msec / 1000; -- timeout.tv_nsec = (msec % 1000) * 1000 * 1000; -+ switch (qt_poll_msecs(&pfd, 1, msec)) { -+ case 0: -+ if (timedOut) -+ *timedOut = true; -+ return; -+ break; -+ default: -+ if ((pfd.revents & POLLNVAL) == 0) { -+ _q_onNewConnection(); -+ return; -+ } - -- int result = -1; -- result = qt_safe_select(listenSocket + 1, &readfds, 0, 0, (msec == -1) ? 0 : &timeout); -- if (-1 == result) { -+ errno = EBADF; -+ // FALLTHROUGH -+ case -1: - setError(QLatin1String("QLocalServer::waitForNewConnection")); - closeServer(); -+ break; - } -- if (result > 0) -- _q_onNewConnection(); -- if (timedOut) -- *timedOut = (result == 0); - } - - void QLocalServerPrivate::setError(const QString &function) -diff --git a/src/network/socket/qlocalsocket_unix.cpp b/src/network/socket/qlocalsocket_unix.cpp -index bb0f11f..4b5686e 100644 ---- a/src/network/socket/qlocalsocket_unix.cpp -+++ b/src/network/socket/qlocalsocket_unix.cpp -@@ -507,36 +507,25 @@ void QLocalSocket::setReadBufferSize(qint64 size) - bool QLocalSocket::waitForConnected(int msec) - { - Q_D(QLocalSocket); -+ - if (state() != ConnectingState) - return (state() == ConnectedState); - -- fd_set fds; -- FD_ZERO(&fds); -- FD_SET(d->connectingSocket, &fds); -+ QElapsedTimer timer; -+ timer.start(); - -- timeval timeout; -- timeout.tv_sec = msec / 1000; -- timeout.tv_usec = (msec % 1000) * 1000; -+ pollfd pfd = qt_make_pollfd(d->connectingSocket, POLLIN); - -- // timeout can not be 0 or else select will return an error. -- if (0 == msec) -- timeout.tv_usec = 1000; -+ do { -+ const int timeout = (msec > 0) ? qMax(msec - timer.elapsed(), Q_INT64_C(0)) : msec; -+ const int result = qt_poll_msecs(&pfd, 1, timeout); - -- int result = -1; -- // on Linux timeout will be updated by select, but _not_ on other systems. -- QElapsedTimer timer; -- timer.start(); -- while (state() == ConnectingState -- && (-1 == msec || timer.elapsed() < msec)) { -- result = ::select(d->connectingSocket + 1, &fds, 0, 0, &timeout); -- if (-1 == result && errno != EINTR) { -- d->errorOccurred( QLocalSocket::UnknownSocketError, -- QLatin1String("QLocalSocket::waitForConnected")); -- break; -- } -- if (result > 0) -+ if (result == -1) -+ d->errorOccurred(QLocalSocket::UnknownSocketError, -+ QLatin1String("QLocalSocket::waitForConnected")); -+ else if (result > 0) - d->_q_connectToSocket(); -- } -+ } while (state() == ConnectingState && !timer.hasExpired(msec)); - - return (state() == ConnectedState); - } -diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp -index 1ce12ed..f8b3663 100644 ---- a/src/network/socket/qnativesocketengine_unix.cpp -+++ b/src/network/socket/qnativesocketengine_unix.cpp -@@ -1257,47 +1257,36 @@ int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool checkRead, bool c - - int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool selectForRead) const - { -- fd_set fds; -- FD_ZERO(&fds); -- FD_SET(socketDescriptor, &fds); -- -- struct timespec tv; -- tv.tv_sec = timeout / 1000; -- tv.tv_nsec = (timeout % 1000) * 1000 * 1000; -- -- int retval; -- if (selectForRead) -- retval = qt_safe_select(socketDescriptor + 1, &fds, 0, 0, timeout < 0 ? 0 : &tv); -- else -- retval = qt_safe_select(socketDescriptor + 1, 0, &fds, 0, timeout < 0 ? 0 : &tv); -- -- return retval; -+ bool dummy; -+ return nativeSelect(timeout, selectForRead, !selectForRead, &dummy, &dummy); - } - - int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool checkRead, bool checkWrite, - bool *selectForRead, bool *selectForWrite) const - { -- fd_set fdread; -- FD_ZERO(&fdread); -+ pollfd pfd = qt_make_pollfd(socketDescriptor, 0); -+ - if (checkRead) -- FD_SET(socketDescriptor, &fdread); -+ pfd.events |= POLLIN; - -- fd_set fdwrite; -- FD_ZERO(&fdwrite); - if (checkWrite) -- FD_SET(socketDescriptor, &fdwrite); -+ pfd.events |= POLLOUT; - -- struct timespec tv; -- tv.tv_sec = timeout / 1000; -- tv.tv_nsec = (timeout % 1000) * 1000 * 1000; -- -- int ret; -- ret = qt_safe_select(socketDescriptor + 1, &fdread, &fdwrite, 0, timeout < 0 ? 0 : &tv); -+ const int ret = qt_poll_msecs(&pfd, 1, timeout); - - if (ret <= 0) - return ret; -- *selectForRead = FD_ISSET(socketDescriptor, &fdread); -- *selectForWrite = FD_ISSET(socketDescriptor, &fdwrite); -+ -+ if (pfd.revents & POLLNVAL) { -+ errno = EBADF; -+ return -1; -+ } -+ -+ static const short read_flags = POLLIN | POLLHUP | POLLERR; -+ static const short write_flags = POLLOUT | POLLERR; -+ -+ *selectForRead = ((pfd.revents & read_flags) != 0); -+ *selectForWrite = ((pfd.revents & write_flags) != 0); - - return ret; - } -diff --git a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp -index 7e057f3..020fe52 100644 ---- a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp -+++ b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp -@@ -48,6 +48,7 @@ private slots: - void memberFunctions(); - void implicitConvertibleTypes(); - void runWaitLoop(); -+ void pollForIsFinished(); - void recursive(); - #ifndef QT_NO_EXCEPTIONS - void exceptions(); -@@ -353,6 +354,33 @@ void tst_QtConcurrentRun::runWaitLoop() - run(fn).waitForFinished(); - } - -+static bool allFinished(const QList > &futures) -+{ -+ auto hasNotFinished = [](const QFuture &future) { return !future.isFinished(); }; -+ return std::find_if(futures.cbegin(), futures.cend(), hasNotFinished) -+ == futures.constEnd(); -+} -+ -+static void runFunction() -+{ -+ QEventLoop loop; -+ QTimer::singleShot(20, &loop, &QEventLoop::quit); -+ loop.exec(); -+} -+ -+void tst_QtConcurrentRun::pollForIsFinished() -+{ -+ const int numThreads = std::max(4, 2 * QThread::idealThreadCount()); -+ QThreadPool::globalInstance()->setMaxThreadCount(numThreads); -+ -+ QFutureSynchronizer synchronizer; -+ for (int i = 0; i < numThreads; ++i) -+ synchronizer.addFuture(QtConcurrent::run(&runFunction)); -+ -+ // same as synchronizer.waitForFinished() but with a timeout -+ QTRY_VERIFY(allFinished(synchronizer.futures())); -+} -+ - QAtomicInt count; - - void recursiveRun(int level) -diff --git a/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp b/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp -index c8bb4cd..9b2bada 100644 ---- a/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp -+++ b/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp -@@ -430,11 +430,8 @@ public slots: - dataSent = serverSocket->waitForBytesWritten(-1); - - if (dataSent) { -- fd_set fdread; -- int fd = socket->socketDescriptor(); -- FD_ZERO(&fdread); -- FD_SET(fd, &fdread); -- dataReadable = (1 == qt_safe_select(fd + 1, &fdread, 0, 0, 0)); -+ pollfd pfd = qt_make_pollfd(socket->socketDescriptor(), POLLIN); -+ dataReadable = (1 == qt_safe_poll(&pfd, 1, nullptr)); - } - - if (!dataReadable) { -diff --git a/tests/manual/qt_poll/qt_poll.pro b/tests/manual/qt_poll/qt_poll.pro -new file mode 100644 -index 0000000..beea4d1 ---- /dev/null -+++ b/tests/manual/qt_poll/qt_poll.pro -@@ -0,0 +1,7 @@ -+CONFIG += testcase -+TARGET = tst_qt_poll -+QT = core-private network testlib -+INCLUDEPATH += ../../../src/corelib/kernel -+SOURCES += \ -+ tst_qt_poll.cpp \ -+ ../../../src/corelib/kernel/qpoll.cpp -diff --git a/tests/manual/qt_poll/tst_qt_poll.cpp b/tests/manual/qt_poll/tst_qt_poll.cpp -new file mode 100644 -index 0000000..56e41e4 ---- /dev/null -+++ b/tests/manual/qt_poll/tst_qt_poll.cpp -@@ -0,0 +1,155 @@ -+/**************************************************************************** -+** -+** Copyright (C) 2015 The Qt Company Ltd. -+** Contact: http://www.qt.io/licensing/ -+** -+** This file is part of the test suite of the Qt Toolkit. -+** -+** $QT_BEGIN_LICENSE:LGPL21$ -+** 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 The Qt Company. For licensing terms -+** and conditions see http://www.qt.io/terms-conditions. For further -+** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free -+** Software Foundation and appearing in the file LICENSE.LGPLv21 and -+** LICENSE.LGPLv3 included in the packaging of this file. Please review the -+** following information to ensure the GNU Lesser General Public License -+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -+** -+** As a special exception, The Qt Company gives you certain additional -+** rights. These rights are described in The Qt Company LGPL Exception -+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -+** -+** $QT_END_LICENSE$ -+** -+****************************************************************************/ -+ -+#ifndef QT_NO_NATIVE_POLL -+#define QT_NO_NATIVE_POLL -+#endif -+ -+#include -+#include -+ -+#include -+ -+QT_BEGIN_NAMESPACE -+// defined in qpoll.cpp -+int qt_poll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts); -+QT_END_NAMESPACE -+ -+class tst_qt_poll : public QObject -+{ -+ Q_OBJECT -+ -+private slots: -+ void pollout(); -+ void pollin(); -+ void pollnval(); -+ void pollprihup(); -+}; -+ -+void tst_qt_poll::pollout() -+{ -+ int fds[2]; -+ QCOMPARE(pipe(fds), 0); -+ -+ struct pollfd pfd = { fds[1], POLLOUT, 0 }; -+ const int nready = qt_poll(&pfd, 1, NULL); -+ -+ QCOMPARE(nready, 1); -+ QCOMPARE(pfd.revents, short(POLLOUT)); -+ -+ qt_safe_close(fds[0]); -+ qt_safe_close(fds[1]); -+} -+ -+void tst_qt_poll::pollin() -+{ -+ int fds[2]; -+ QCOMPARE(pipe(fds), 0); -+ -+ const char data = 'Q'; -+ QCOMPARE(qt_safe_write(fds[1], &data, 1), 1); -+ -+ struct pollfd pfd = { fds[0], POLLIN, 0 }; -+ const int nready = qt_poll(&pfd, 1, NULL); -+ -+ QCOMPARE(nready, 1); -+ QCOMPARE(pfd.revents, short(POLLIN)); -+ -+ qt_safe_close(fds[0]); -+ qt_safe_close(fds[1]); -+} -+ -+void tst_qt_poll::pollnval() -+{ -+ struct pollfd pfd = { 42, POLLOUT, 0 }; -+ -+ int nready = qt_poll(&pfd, 1, NULL); -+ QCOMPARE(nready, 1); -+ QCOMPARE(pfd.revents, short(POLLNVAL)); -+ -+ pfd.events = 0; -+ pfd.revents = 0; -+ -+ nready = qt_poll(&pfd, 1, NULL); -+ QCOMPARE(nready, 1); -+ QCOMPARE(pfd.revents, short(POLLNVAL)); -+} -+ -+void tst_qt_poll::pollprihup() -+{ -+ QTcpServer server; -+ QTcpSocket client_socket; -+ -+ QVERIFY(server.listen(QHostAddress::LocalHost)); -+ -+ const quint16 server_port = server.serverPort(); -+ client_socket.connectToHost(server.serverAddress(), server_port); -+ -+ QVERIFY(client_socket.waitForConnected()); -+ QVERIFY(server.waitForNewConnection()); -+ -+ QTcpSocket *server_socket = server.nextPendingConnection(); -+ server.close(); -+ -+ // TCP supports only a single byte of urgent data -+ static const char oob_out = 'Q'; -+ QCOMPARE(::send(server_socket->socketDescriptor(), &oob_out, 1, MSG_OOB), -+ ssize_t(1)); -+ -+ struct pollfd pfd = { -+ int(client_socket.socketDescriptor()), -+ POLLPRI | POLLIN, -+ 0 -+ }; -+ int res = qt_poll(&pfd, 1, NULL); -+ -+ QCOMPARE(res, 1); -+ QCOMPARE(pfd.revents, short(POLLPRI | POLLIN)); -+ -+ char oob_in = 0; -+ // We do not specify MSG_OOB here as SO_OOBINLINE is turned on by default -+ // in the native socket engine -+ QCOMPARE(::recv(client_socket.socketDescriptor(), &oob_in, 1, 0), -+ ssize_t(1)); -+ QCOMPARE(oob_in, oob_out); -+ -+ server_socket->close(); -+ pfd.events = POLLIN; -+ res = qt_poll(&pfd, 1, NULL); -+ -+ QCOMPARE(res, 1); -+ QCOMPARE(pfd.revents, short(POLLHUP)); -+} -+ -+QTEST_APPLESS_MAIN(tst_qt_poll) -+#include "tst_qt_poll.moc" -diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp -index 88dcd81..9d41381 100644 ---- a/tools/configure/configureapp.cpp -+++ b/tools/configure/configureapp.cpp -@@ -1749,6 +1749,7 @@ void Configure::applySpecSpecifics() - dictionary[ "QT_EVDEV" ] = "no"; - dictionary[ "QT_MTDEV" ] = "no"; - dictionary[ "FONT_CONFIG" ] = "auto"; -+ dictionary[ "POLL" ] = "poll"; - dictionary[ "ANGLE" ] = "no"; - - dictionary["DECORATIONS"] = "default windows styled"; -@@ -1776,6 +1777,7 @@ void Configure::applySpecSpecifics() - dictionary[ "QT_XKBCOMMON" ] = "no"; - dictionary["ANDROID_STYLE_ASSETS"] = "yes"; - dictionary[ "STYLE_ANDROID" ] = "yes"; -+ dictionary[ "POLL" ] = "poll"; - } - } - -@@ -3094,6 +3096,9 @@ void Configure::generateOutputVars() - if (dictionary["REDUCE_EXPORTS"] == "yes") - qtConfig += "reduce_exports"; - -+ if (!dictionary["POLL"].isEmpty()) -+ qtConfig += "poll_" + dictionary["POLL"]; -+ - // We currently have no switch for QtConcurrent, so add it unconditionally. - qtConfig += "concurrent"; - diff --git a/SOURCES/qt5-qtbase-5.9.1-firebird.patch b/SOURCES/qt5-qtbase-5.9.1-firebird.patch new file mode 100644 index 0000000..a141e2a --- /dev/null +++ b/SOURCES/qt5-qtbase-5.9.1-firebird.patch @@ -0,0 +1,27 @@ +diff --git a/src/plugins/sqldrivers/configure.json b/src/plugins/sqldrivers/configure.json +index 234f880..d53f035 100644 +--- a/src/plugins/sqldrivers/configure.json ++++ b/src/plugins/sqldrivers/configure.json +@@ -54,7 +54,8 @@ + }, + "sources": [ + { "libs": "-lgds32_ms", "condition": "config.win32" }, +- { "libs": "-lgds", "condition": "!config.win32" } ++ { "libs": "-lgds", "condition": "!config.win32" }, ++ { "libs": "-lfbclient", "condition": "!config.win32" } + ] + }, + "mysql": { +diff --git a/src/plugins/sqldrivers/ibase/qsql_ibase_p.h b/src/plugins/sqldrivers/ibase/qsql_ibase_p.h +index c7cee41..6a9c56c 100644 +--- a/src/plugins/sqldrivers/ibase/qsql_ibase_p.h ++++ b/src/plugins/sqldrivers/ibase/qsql_ibase_p.h +@@ -52,7 +52,7 @@ + // + + #include +-#include ++#include + + #ifdef QT_PLUGIN + #define Q_EXPORT_SQLDRIVER_IBASE diff --git a/SOURCES/qt5-qtbase-cxxflag.patch b/SOURCES/qt5-qtbase-cxxflag.patch index d428c6f..321f051 100644 --- a/SOURCES/qt5-qtbase-cxxflag.patch +++ b/SOURCES/qt5-qtbase-cxxflag.patch @@ -1,12 +1,13 @@ -diff -up qtbase-opensource-src-5.6.0/mkspecs/common/gcc-base.conf.than qtbase-opensource-src-5.6.0/mkspecs/common/gcc-base.conf ---- qtbase-opensource-src-5.6.0/mkspecs/common/gcc-base.conf.than 2016-06-02 17:30:07.249027901 +0200 -+++ qtbase-opensource-src-5.6.0/mkspecs/common/gcc-base.conf 2016-06-02 17:30:14.681748012 +0200 +diff --git a/mkspecs/common/gcc-base.conf b/mkspecs/common/gcc-base.conf +index e7e6ee1..ff2a939 100644 +--- a/mkspecs/common/gcc-base.conf ++++ b/mkspecs/common/gcc-base.conf @@ -32,7 +32,7 @@ # QMAKE_CFLAGS_OPTIMIZE = -O2 -QMAKE_CFLAGS_OPTIMIZE_FULL = -O3 +QMAKE_CFLAGS_OPTIMIZE_FULL = -O2 + QMAKE_CFLAGS_OPTIMIZE_DEBUG = -Og + QMAKE_CFLAGS_OPTIMIZE_SIZE = -Os - QMAKE_CFLAGS += -pipe - QMAKE_CFLAGS_DEPS += -M diff --git a/SOURCES/qtbase-hidpi_scale_at_192.patch b/SOURCES/qtbase-hidpi_scale_at_192.patch new file mode 100644 index 0000000..c6c377d --- /dev/null +++ b/SOURCES/qtbase-hidpi_scale_at_192.patch @@ -0,0 +1,13 @@ +diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp +index 5e136b5..0ad2842 100644 +--- a/src/plugins/platforms/xcb/qxcbscreen.cpp ++++ b/src/plugins/platforms/xcb/qxcbscreen.cpp +@@ -620,7 +620,7 @@ void QXcbScreen::updateGeometry(const QRect &geom, uint8_t rotation) + m_sizeMillimeters = sizeInMillimeters(xGeometry.size(), virtualDpi()); + + qreal dpi = xGeometry.width() / physicalSize().width() * qreal(25.4); +- m_pixelDensity = qMax(1, qRound(dpi/96)); ++ m_pixelDensity = qMax(1, (int) (dpi/96)); // instead of rounding at 1.5, round at 2.0 (same as GNOME) + m_geometry = QRect(xGeometry.topLeft(), xGeometry.size()); + m_availableGeometry = xGeometry & m_virtualDesktop->workArea(); + QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), m_geometry, m_availableGeometry); diff --git a/SOURCES/qtbase-opensource-src-5.6.0-moc_WORDSIZE.patch b/SOURCES/qtbase-opensource-src-5.6.0-moc_WORDSIZE.patch deleted file mode 100644 index 62d1e9c..0000000 --- a/SOURCES/qtbase-opensource-src-5.6.0-moc_WORDSIZE.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff -up qtbase-opensource-src-5.6.0-beta/src/tools/moc/main.cpp.moc_WORDSIZE qtbase-opensource-src-5.6.0-beta/src/tools/moc/main.cpp ---- qtbase-opensource-src-5.6.0-beta/src/tools/moc/main.cpp.moc_WORDSIZE 2015-12-04 18:05:24.000000000 -0600 -+++ qtbase-opensource-src-5.6.0-beta/src/tools/moc/main.cpp 2015-12-15 20:57:55.554485416 -0600 -@@ -184,6 +184,10 @@ int runMoc(int argc, char **argv) - Moc moc; - pp.macros["Q_MOC_RUN"]; - pp.macros["__cplusplus"]; -+ Macro macro; -+ macro.symbols = Preprocessor::tokenize(QByteArray::number(Q_PROCESSOR_WORDSIZE*8), 1, Preprocessor::TokenizeDefine); -+ macro.symbols.removeLast(); // remove the EOF symbol -+ pp.macros.insert("__WORDSIZE", macro); - - // Don't stumble over GCC extensions - Macro dummyVariadicFunctionMacro; diff --git a/SOURCES/qtbase-opensource-src-5.6.2-arm.patch b/SOURCES/qtbase-opensource-src-5.6.2-arm.patch deleted file mode 100644 index 90483e5..0000000 --- a/SOURCES/qtbase-opensource-src-5.6.2-arm.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff -up qtbase-opensource-src-5.6.2/configure.arm qtbase-opensource-src-5.6.2/configure ---- qtbase-opensource-src-5.6.2/configure.arm 2016-09-16 00:49:42.000000000 -0500 -+++ qtbase-opensource-src-5.6.2/configure 2016-10-16 08:41:20.583267295 -0500 -@@ -4373,6 +4373,9 @@ if [ "$QMAKESPEC" != "$XQMAKESPEC" ]; th - else - # not cross compiling, host == target - CFG_HOST_ARCH="$CFG_ARCH" -+ if [ "$CFG_ARCH" = "arm" ] ; then -+ CFG_CPUFEATURES="neon" -+ fi - CFG_HOST_CPUFEATURES="$CFG_CPUFEATURES" - fi - unset OUTFILE diff --git a/SOURCES/qtbase-opensource-src-5.6.2-moc_system_defines.patch b/SOURCES/qtbase-opensource-src-5.6.2-moc_system_defines.patch deleted file mode 100644 index b718b60..0000000 --- a/SOURCES/qtbase-opensource-src-5.6.2-moc_system_defines.patch +++ /dev/null @@ -1,325 +0,0 @@ -diff -up qtbase-opensource-src-5.6.2/mkspecs/features/moc.prf.moc_system_defines qtbase-opensource-src-5.6.2/mkspecs/features/moc.prf ---- qtbase-opensource-src-5.6.2/mkspecs/features/moc.prf.moc_system_defines 2016-09-16 00:49:42.000000000 -0500 -+++ qtbase-opensource-src-5.6.2/mkspecs/features/moc.prf 2016-10-16 08:42:20.561694271 -0500 -@@ -24,8 +24,25 @@ win32:count(MOC_INCLUDEPATH, 40, >) { - write_file($$absolute_path($$WIN_INCLUDETEMP, $$OUT_PWD), WIN_INCLUDETEMP_CONT)|error("Aborting.") - } - -+# QNX's compiler sets "gcc" config, but does not support the -dM option; -+# iOS builds are multi-arch, so this feature cannot possibly work. -+if(gcc|intel_icl|msvc):!rim_qcc:!ios { -+ moc_predefs.CONFIG = no_link -+ gcc: moc_predefs.commands = $$QMAKE_CXX $$QMAKE_CXXFLAGS -dM -E -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN} -+ else:intel_icl: moc_predefs.commands = $$QMAKE_CXX $$QMAKE_CXXFLAGS -QdM -P -Fi${QMAKE_FILE_OUT} ${QMAKE_FILE_IN} -+ else:msvc { -+ # make sure that our bin dir is first in path, so qmake is found -+ moc_predefs.commands = PATH $$shell_path($$[QT_INSTALL_BINS/src]);%PATH%& -+ moc_predefs.commands += $$QMAKE_CXX -Bxqmake $$QMAKE_CXXFLAGS -E ${QMAKE_FILE_IN} 2>NUL >${QMAKE_FILE_OUT} -+ } else: error("Oops, I messed up") -+ moc_predefs.output = $$MOC_DIR/moc_predefs.h -+ moc_predefs.input = MOC_PREDEF_FILE -+ silent: moc_predefs.commands = @echo generating $$moc_predefs.output$$escape_expand(\n\t)@$$moc_predefs.commands -+ QMAKE_EXTRA_COMPILERS += moc_predefs -+ MOC_PREDEF_FILE = $$[QT_HOST_DATA/src]/mkspecs/features/data/dummy.cpp -+} -+ - defineReplace(mocCmdBase) { -- RET = - !isEmpty(WIN_INCLUDETEMP) { - incvar = @$$WIN_INCLUDETEMP - } else { -@@ -34,7 +51,13 @@ defineReplace(mocCmdBase) { - incvar += -I$$shell_quote($$inc) - incvar += $$QMAKE_FRAMEWORKPATH_FLAGS - } -- RET += $$QMAKE_MOC $(DEFINES) $$join(QMAKE_COMPILER_DEFINES, " -D", -D) $$incvar $$QMAKE_MOC_OPTIONS -+ -+ RET = $$QMAKE_MOC $(DEFINES) -+ -+ isEmpty(MOC_PREDEF_FILE): RET += $$join(QMAKE_COMPILER_DEFINES, " -D", -D) -+ else: RET += --include $$moc_predefs.output -+ -+ RET += $$incvar $$QMAKE_MOC_OPTIONS - return($$RET) - } - -@@ -46,7 +69,7 @@ moc_header.output = $$MOC_DIR/$${QMAKE_H - moc_header.input = HEADERS - moc_header.variable_out = SOURCES - moc_header.name = MOC ${QMAKE_FILE_IN} --moc_header.depends += $$WIN_INCLUDETEMP -+moc_header.depends += $$WIN_INCLUDETEMP $$moc_predefs.output - silent:moc_header.commands = @echo moc ${QMAKE_FILE_IN} && $$moc_header.commands - QMAKE_EXTRA_COMPILERS += moc_header - INCREDIBUILD_XGE += moc_header -@@ -58,7 +81,7 @@ moc_source.commands = ${QMAKE_FUNC_mocCm - moc_source.output = $$MOC_DIR/$${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}$${QMAKE_EXT_CPP_MOC} - moc_source.input = SOURCES OBJECTIVE_SOURCES - moc_source.name = MOC ${QMAKE_FILE_IN} --moc_source.depends += $$WIN_INCLUDETEMP -+moc_source.depends += $$WIN_INCLUDETEMP $$moc_predefs.output - silent:moc_source.commands = @echo moc ${QMAKE_FILE_IN} && $$moc_source.commands - QMAKE_EXTRA_COMPILERS += moc_source - INCREDIBUILD_XGE += moc_source -diff -up qtbase-opensource-src-5.6.2/qmake/main.cpp.moc_system_defines qtbase-opensource-src-5.6.2/qmake/main.cpp ---- qtbase-opensource-src-5.6.2/qmake/main.cpp.moc_system_defines 2016-09-16 00:49:42.000000000 -0500 -+++ qtbase-opensource-src-5.6.2/qmake/main.cpp 2016-10-16 08:42:20.561694271 -0500 -@@ -1,6 +1,7 @@ - /**************************************************************************** - ** - ** Copyright (C) 2015 The Qt Company Ltd. -+** Copyright (C) 2015 Intel Corporation. - ** Contact: http://www.qt.io/licensing/ - ** - ** This file is part of the qmake application of the Qt Toolkit. -@@ -47,6 +48,10 @@ - #include - #include - -+#ifdef Q_OS_WIN -+# include -+#endif -+ - QT_BEGIN_NAMESPACE - - #ifdef Q_OS_WIN -@@ -246,6 +251,30 @@ static int doInstall(int argc, char **ar - return 3; - } - -+static int dumpMacros(const wchar_t *cmdline) -+{ -+ // from http://stackoverflow.com/questions/3665537/how-to-find-out-cl-exes-built-in-macros -+ int argc; -+ wchar_t **argv = CommandLineToArgvW(cmdline, &argc); -+ if (!argv) -+ return 2; -+ for (int i = 0; i < argc; ++i) { -+ if (argv[i][0] != L'-' || argv[i][1] != 'D') -+ continue; -+ -+ wchar_t *value = wcschr(argv[i], L'='); -+ if (value) { -+ *value = 0; -+ ++value; -+ } else { -+ // point to the NUL at the end, so we don't print anything -+ value = argv[i] + wcslen(argv[i]); -+ } -+ wprintf(L"#define %Ls %Ls\n", argv[i] + 2, value); -+ } -+ return 0; -+} -+ - #endif // Q_OS_WIN - - /* This is to work around lame implementation on Darwin. It has been noted that the getpwd(3) function -@@ -280,6 +309,15 @@ int runQMake(int argc, char **argv) - // Workaround for inferior/missing command line tools on Windows: make our own! - if (argc >= 2 && !strcmp(argv[1], "-install")) - return doInstall(argc - 2, argv + 2); -+ -+ { -+ // Support running as Visual C++'s compiler -+ const wchar_t *cmdline = _wgetenv(L"MSC_CMD_FLAGS"); -+ if (!cmdline || !*cmdline) -+ cmdline = _wgetenv(L"MSC_IDE_FLAGS"); -+ if (cmdline && *cmdline) -+ return dumpMacros(cmdline); -+ } - #endif - - QMakeVfs vfs; -diff -up qtbase-opensource-src-5.6.2/src/tools/moc/main.cpp.moc_system_defines qtbase-opensource-src-5.6.2/src/tools/moc/main.cpp ---- qtbase-opensource-src-5.6.2/src/tools/moc/main.cpp.moc_system_defines 2016-10-16 08:42:20.558694249 -0500 -+++ qtbase-opensource-src-5.6.2/src/tools/moc/main.cpp 2016-10-16 08:42:20.562694278 -0500 -@@ -263,6 +263,11 @@ int runMoc(int argc, char **argv) - prependIncludeOption.setValueName(QStringLiteral("file")); - parser.addOption(prependIncludeOption); - -+ QCommandLineOption includeOption(QStringLiteral("include")); -+ includeOption.setDescription(QStringLiteral("Parse as an #include before the main source(s).")); -+ includeOption.setValueName(QStringLiteral("file")); -+ parser.addOption(includeOption); -+ - QCommandLineOption noNotesWarningsCompatOption(QStringLiteral("n")); - noNotesWarningsCompatOption.setDescription(QStringLiteral("Do not display notes (-nn) or warnings (-nw). Compatibility option.")); - noNotesWarningsCompatOption.setValueName(QStringLiteral("which")); -@@ -412,7 +417,16 @@ int runMoc(int argc, char **argv) - moc.includes = pp.includes; - - // 1. preprocess -- moc.symbols = pp.preprocessed(moc.filename, &in); -+ foreach (const QString &includeName, parser.values(includeOption)) { -+ QByteArray rawName = pp.resolveInclude(QFile::encodeName(includeName), moc.filename); -+ QFile f(QFile::decodeName(rawName)); -+ if (f.open(QIODevice::ReadOnly)) { -+ moc.symbols += Symbol(0, MOC_INCLUDE_BEGIN, rawName); -+ moc.symbols += pp.preprocessed(rawName, &f); -+ moc.symbols += Symbol(0, MOC_INCLUDE_END, rawName); -+ } -+ } -+ moc.symbols += pp.preprocessed(moc.filename, &in); - - if (!pp.preprocessOnly) { - // 2. parse -diff -up qtbase-opensource-src-5.6.2/src/tools/moc/preprocessor.cpp.moc_system_defines qtbase-opensource-src-5.6.2/src/tools/moc/preprocessor.cpp ---- qtbase-opensource-src-5.6.2/src/tools/moc/preprocessor.cpp.moc_system_defines 2016-09-16 00:49:42.000000000 -0500 -+++ qtbase-opensource-src-5.6.2/src/tools/moc/preprocessor.cpp 2016-10-16 08:42:20.562694278 -0500 -@@ -1007,6 +1007,37 @@ static void mergeStringLiterals(Symbols - } - } - -+QByteArray Preprocessor::resolveInclude(const QByteArray &include, const QByteArray &relativeTo) -+{ -+ // #### stringery -+ QFileInfo fi; -+ if (!relativeTo.isEmpty()) -+ fi.setFile(QFileInfo(QString::fromLocal8Bit(relativeTo.constData())).dir(), QString::fromLocal8Bit(include.constData())); -+ for (int j = 0; j < Preprocessor::includes.size() && !fi.exists(); ++j) { -+ const IncludePath &p = Preprocessor::includes.at(j); -+ if (p.isFrameworkPath) { -+ const int slashPos = include.indexOf('/'); -+ if (slashPos == -1) -+ continue; -+ QByteArray frameworkCandidate = include.left(slashPos); -+ frameworkCandidate.append(".framework/Headers/"); -+ fi.setFile(QString::fromLocal8Bit(QByteArray(p.path + '/' + frameworkCandidate).constData()), QString::fromLocal8Bit(include.mid(slashPos + 1).constData())); -+ } else { -+ fi.setFile(QString::fromLocal8Bit(p.path.constData()), QString::fromLocal8Bit(include.constData())); -+ } -+ // try again, maybe there's a file later in the include paths with the same name -+ // (186067) -+ if (fi.isDir()) { -+ fi = QFileInfo(); -+ continue; -+ } -+ } -+ -+ if (!fi.exists() || fi.isDir()) -+ return QByteArray(); -+ return fi.canonicalFilePath().toLocal8Bit(); -+} -+ - void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed) - { - currentFilenames.push(filename); -@@ -1027,33 +1058,9 @@ void Preprocessor::preprocess(const QByt - continue; - until(PP_NEWLINE); - -- // #### stringery -- QFileInfo fi; -- if (local) -- fi.setFile(QFileInfo(QString::fromLocal8Bit(filename.constData())).dir(), QString::fromLocal8Bit(include.constData())); -- for (int j = 0; j < Preprocessor::includes.size() && !fi.exists(); ++j) { -- const IncludePath &p = Preprocessor::includes.at(j); -- if (p.isFrameworkPath) { -- const int slashPos = include.indexOf('/'); -- if (slashPos == -1) -- continue; -- QByteArray frameworkCandidate = include.left(slashPos); -- frameworkCandidate.append(".framework/Headers/"); -- fi.setFile(QString::fromLocal8Bit(QByteArray(p.path + '/' + frameworkCandidate).constData()), QString::fromLocal8Bit(include.mid(slashPos + 1).constData())); -- } else { -- fi.setFile(QString::fromLocal8Bit(p.path.constData()), QString::fromLocal8Bit(include.constData())); -- } -- // try again, maybe there's a file later in the include paths with the same name -- // (186067) -- if (fi.isDir()) { -- fi = QFileInfo(); -- continue; -- } -- } -- -- if (!fi.exists() || fi.isDir()) -+ include = resolveInclude(include, local ? filename : QByteArray()); -+ if (include.isNull()) - continue; -- include = fi.canonicalFilePath().toLocal8Bit(); - - if (Preprocessor::preprocessedIncludes.contains(include)) - continue; -@@ -1208,6 +1215,7 @@ Symbols Preprocessor::preprocessed(const - input = cleaned(input); - - // phase 2: tokenize for the preprocessor -+ index = 0; - symbols = tokenize(input); - - #if 0 -diff -up qtbase-opensource-src-5.6.2/src/tools/moc/preprocessor.h.moc_system_defines qtbase-opensource-src-5.6.2/src/tools/moc/preprocessor.h ---- qtbase-opensource-src-5.6.2/src/tools/moc/preprocessor.h.moc_system_defines 2016-09-16 00:49:42.000000000 -0500 -+++ qtbase-opensource-src-5.6.2/src/tools/moc/preprocessor.h 2016-10-16 08:42:20.562694278 -0500 -@@ -67,6 +67,7 @@ public: - QList frameworks; - QSet preprocessedIncludes; - Macros macros; -+ QByteArray resolveInclude(const QByteArray &filename, const QByteArray &relativeTo); - Symbols preprocessed(const QByteArray &filename, QFile *device); - - void parseDefineArguments(Macro *m); -diff -up qtbase-opensource-src-5.6.2/tests/auto/tools/moc/subdir/extradefines.h.moc_system_defines qtbase-opensource-src-5.6.2/tests/auto/tools/moc/subdir/extradefines.h ---- qtbase-opensource-src-5.6.2/tests/auto/tools/moc/subdir/extradefines.h.moc_system_defines 2016-10-16 08:42:20.562694278 -0500 -+++ qtbase-opensource-src-5.6.2/tests/auto/tools/moc/subdir/extradefines.h 2016-10-16 08:42:20.562694278 -0500 -@@ -0,0 +1 @@ -+#define FOO 1 -diff -up qtbase-opensource-src-5.6.2/tests/auto/tools/moc/tst_moc.cpp.moc_system_defines qtbase-opensource-src-5.6.2/tests/auto/tools/moc/tst_moc.cpp ---- qtbase-opensource-src-5.6.2/tests/auto/tools/moc/tst_moc.cpp.moc_system_defines 2016-09-16 00:49:42.000000000 -0500 -+++ qtbase-opensource-src-5.6.2/tests/auto/tools/moc/tst_moc.cpp 2016-10-16 08:42:20.562694278 -0500 -@@ -581,6 +581,8 @@ private slots: - void frameworkSearchPath(); - void cstyleEnums(); - void defineMacroViaCmdline(); -+ void defineMacroViaForcedInclude(); -+ void defineMacroViaForcedIncludeRelative(); - void specifyMetaTagsFromCmdline(); - void invokable(); - void singleFunctionKeywordSignalAndSlot(); -@@ -1248,6 +1250,46 @@ void tst_Moc::defineMacroViaCmdline() - args << m_sourceDirectory + QStringLiteral("/macro-on-cmdline.h"); - - proc.start(m_moc, args); -+ QVERIFY(proc.waitForFinished()); -+ QCOMPARE(proc.exitCode(), 0); -+ QCOMPARE(proc.readAllStandardError(), QByteArray()); -+ QByteArray mocOut = proc.readAllStandardOutput(); -+ QVERIFY(!mocOut.isEmpty()); -+#else -+ QSKIP("Only tested on linux/gcc"); -+#endif -+} -+ -+void tst_Moc::defineMacroViaForcedInclude() -+{ -+#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) -+ QProcess proc; -+ -+ QStringList args; -+ args << "--include" << m_sourceDirectory + QLatin1String("/subdir/extradefines.h"); -+ args << m_sourceDirectory + QStringLiteral("/macro-on-cmdline.h"); -+ -+ proc.start(m_moc, args); -+ QVERIFY(proc.waitForFinished()); -+ QCOMPARE(proc.exitCode(), 0); -+ QCOMPARE(proc.readAllStandardError(), QByteArray()); -+ QByteArray mocOut = proc.readAllStandardOutput(); -+ QVERIFY(!mocOut.isEmpty()); -+#else -+ QSKIP("Only tested on linux/gcc"); -+#endif -+} -+ -+void tst_Moc::defineMacroViaForcedIncludeRelative() -+{ -+#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) -+ QProcess proc; -+ -+ QStringList args; -+ args << "--include" << QStringLiteral("extradefines.h") << "-I" + m_sourceDirectory + "/subdir"; -+ args << m_sourceDirectory + QStringLiteral("/macro-on-cmdline.h"); -+ -+ proc.start(m_moc, args); - QVERIFY(proc.waitForFinished()); - QCOMPARE(proc.exitCode(), 0); - QCOMPARE(proc.readAllStandardError(), QByteArray()); diff --git a/SOURCES/qtbase-opensource-src-5.7.1-moc_macros.patch b/SOURCES/qtbase-opensource-src-5.7.1-moc_macros.patch new file mode 100644 index 0000000..75dc9ff --- /dev/null +++ b/SOURCES/qtbase-opensource-src-5.7.1-moc_macros.patch @@ -0,0 +1,15 @@ +diff -up qtbase-opensource-src-5.7.1/src/tools/moc/main.cpp.moc_WORDSIZE qtbase-opensource-src-5.7.1/src/tools/moc/main.cpp +--- qtbase-opensource-src-5.7.1/src/tools/moc/main.cpp.moc_WORDSIZE 2016-12-01 02:17:04.000000000 -0600 ++++ qtbase-opensource-src-5.7.1/src/tools/moc/main.cpp 2016-12-08 12:37:28.931589338 -0600 +@@ -179,6 +179,11 @@ int runMoc(int argc, char **argv) + Moc moc; + pp.macros["Q_MOC_RUN"]; + pp.macros["__cplusplus"]; ++ pp.macros["_SYS_SYSMACROS_H_OUTER"]; ++ Macro macro; ++ macro.symbols = Preprocessor::tokenize(QByteArray::number(Q_PROCESSOR_WORDSIZE*8), 1, Preprocessor::TokenizeDefine); ++ macro.symbols.removeLast(); // remove the EOF symbol ++ pp.macros.insert("__WORDSIZE", macro); + + // Don't stumble over GCC extensions + Macro dummyVariadicFunctionMacro; diff --git a/SOURCES/qtbase-opensource-src-5.8.0-QT_VERSION_CHECK.patch b/SOURCES/qtbase-opensource-src-5.8.0-QT_VERSION_CHECK.patch new file mode 100644 index 0000000..d94caf4 --- /dev/null +++ b/SOURCES/qtbase-opensource-src-5.8.0-QT_VERSION_CHECK.patch @@ -0,0 +1,11 @@ +--- qtbase-opensource-src-5.8.0/src/corelib/global/qglobal.h.orig 2017-01-26 10:45:40.905010896 +0100 ++++ qtbase-opensource-src-5.8.0/src/corelib/global/qglobal.h 2017-01-26 10:46:50.299858887 +0100 +@@ -55,7 +55,7 @@ + /* + can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) + */ +-#define QT_VERSION_CHECK(major, minor, patch) ((major<<16)|(minor<<8)|(patch)) ++#define QT_VERSION_CHECK(qt_version_check_major, qt_version_check_minor, qt_version_check_patch) ((qt_version_check_major<<16)|(qt_version_check_minor<<8)|(qt_version_check_patch)) + + #ifdef QT_BOOTSTRAPPED + #include diff --git a/SOURCES/qtbase-opensource-src-5.9.0-mysql.patch b/SOURCES/qtbase-opensource-src-5.9.0-mysql.patch new file mode 100644 index 0000000..c190ca6 --- /dev/null +++ b/SOURCES/qtbase-opensource-src-5.9.0-mysql.patch @@ -0,0 +1,12 @@ +diff -up qtbase-opensource-src-5.9.0/src/plugins/sqldrivers/mysql/qsql_mysql.cpp.than qtbase-opensource-src-5.9.0/src/plugins/sqldrivers/mysql/qsql_mysql.cpp +diff -up qtbase-opensource-src-5.9.0/src/plugins/sqldrivers/mysql/qsql_mysql_p.h.than qtbase-opensource-src-5.9.0/src/plugins/sqldrivers/mysql/qsql_mysql_p.h +--- qtbase-opensource-src-5.9.0/src/plugins/sqldrivers/mysql/qsql_mysql_p.h.than 2017-07-14 13:43:50.831203768 +0200 ++++ qtbase-opensource-src-5.9.0/src/plugins/sqldrivers/mysql/qsql_mysql_p.h 2017-07-14 13:44:24.364948006 +0200 +@@ -58,6 +58,7 @@ + #endif + + #include ++#include + + #ifdef QT_PLUGIN + #define Q_EXPORT_SQLDRIVER_MYSQL diff --git a/SPECS/qt5-qtbase.spec b/SPECS/qt5-qtbase.spec index b895c64..42c9b1f 100644 --- a/SPECS/qt5-qtbase.spec +++ b/SPECS/qt5-qtbase.spec @@ -1,16 +1,18 @@ # See http://bugzilla.redhat.com/223663 -%define multilib_archs x86_64 %{ix86} %{?mips} ppc64 ppc s390x s390 sparc64 sparcv9 -%define multilib_basearchs x86_64 %{?mips64} ppc64 s390x sparc64 +%global multilib_archs x86_64 %{ix86} %{?mips} ppc64 ppc s390x s390 sparc64 sparcv9 +%global multilib_basearchs x86_64 %{?mips64} ppc64 s390x sparc64 # support qtchooser (adds qtchooser .conf file) -%define qtchooser 0 +%global qtchooser 0 %if 0%{?qtchooser} -%define priority 10 +%global priority 10 %ifarch %{multilib_basearchs} -%define priority 15 +%global priority 15 %endif %endif +%global platform linux-g++ + %global qt_module qtbase %global rpm_macros_dir %(d=%{_rpmconfigdir}/macros.d; [ -d $d ] || d=%{_sysconfdir}/rpm; echo $d) @@ -54,13 +56,13 @@ BuildRequires: pkgconfig(libsystemd) Summary: Qt5 - QtBase components Name: qt5-qtbase -Version: 5.6.2 -Release: 1%{?dist} +Version: 5.9.2 +Release: 3%{?dist} # See LGPL_EXCEPTIONS.txt, for exception details License: LGPLv2 with exceptions or GPLv3 with exceptions Url: http://qt-project.org/ -Source0: http://download.qt.io/official_releases/qt/5.6/%{version}/submodules/%{qt_module}-opensource-src-%{version}.tar.xz +Source0: http://download.qt.io/official_releases/qt/5.9/%{version}/submodules/%{qt_module}-opensource-src-%{version}.tar.xz # https://bugzilla.redhat.com/show_bug.cgi?id=1227295 Source1: qtlogging.ini @@ -80,54 +82,58 @@ Patch2: qtbase-multilib_optflags.patch Patch4: qtbase-opensource-src-5.6.2-QTBUG-35459.patch # upstreamable patches -# support poll -# https://bugreports.qt-project.org/browse/QTBUG-27195 -Patch50: qt5-poll.patch +# namespace QT_VERSION_CHECK to workaround major/minor being pre-defined (#1396755) +Patch50: qtbase-opensource-src-5.8.0-QT_VERSION_CHECK.patch + +# 1381828 - Broken window scaling for some QT5 applications (#1381828) +# This patch moves the threshold for 2x scaling from the DPI of 144 to 192, +# the same value GNOME uses. It's not a complete solution... +Patch51: qtbase-hidpi_scale_at_192.patch -# Workaround moc/multilib issues +# 1. Workaround moc/multilib issues # https://bugzilla.redhat.com/show_bug.cgi?id=1290020 # https://bugreports.qt.io/browse/QTBUG-49972 -Patch52: qtbase-opensource-src-5.6.0-moc_WORDSIZE.patch - -# arm patch -Patch54: qtbase-opensource-src-5.6.2-arm.patch - -# recently passed code review, not integrated yet -# https://codereview.qt-project.org/126102/ -Patch60: qtbase-opensource-src-5.6.2-moc_system_defines.patch +# 2. Workaround sysmacros.h (pre)defining major/minor a breaking stuff +Patch52: qtbase-opensource-src-5.7.1-moc_macros.patch # drop -O3 and make -O2 by default Patch61: qt5-qtbase-cxxflag.patch -## upstream patches +# support firebird version 3.x +Patch62: qt5-qtbase-5.9.1-firebird.patch -# macros, be mindful to keep sync'd with macros.qt5 -Source10: macros.qt5 -%define _qt5 %{name} -%define _qt5_prefix %{_libdir}/qt5 -%define _qt5_archdatadir %{_libdir}/qt5 -# -devel bindir items (still) conflict with qt4 -# at least until this is all implemented, -# http://lists.qt-project.org/pipermail/development/2012-November/007990.html -%define _qt5_bindir %{_qt5_prefix}/bin -%define _qt5_datadir %{_datadir}/qt5 -%define _qt5_docdir %{_docdir}/qt5 -%define _qt5_examplesdir %{_qt5_prefix}/examples -%define _qt5_headerdir %{_includedir}/qt5 -%define _qt5_importdir %{_qt5_archdatadir}/imports -%define _qt5_libdir %{_libdir} -%define _qt5_libexecdir %{_qt5_archdatadir}/libexec -%define _qt5_plugindir %{_qt5_archdatadir}/plugins -%define _qt5_settingsdir %{_sysconfdir}/xdg -%define _qt5_sysconfdir %{_qt5_settingsdir} -%define _qt5_translationdir %{_datadir}/qt5/translations +# fix for new mariadb +Patch63: qtbase-opensource-src-5.9.0-mysql.patch # Do not check any files in %%{_qt5_plugindir}/platformthemes/ for requires. # Those themes are there for platform integration. If the required libraries are # not there, the platform to integrate with isn't either. Then Qt will just # silently ignore the plugin that fails to load. Thus, there is no need to let -# RPM drag in gtk2 as a dependency for the GTK+ 2 dialog support. +# RPM drag in gtk3 as a dependency for the GTK+3 dialog support. %global __requires_exclude_from ^%{_qt5_plugindir}/platformthemes/.*$ +# filter plugin provides +%global __provides_exclude_from ^%{_qt5_plugindir}/.*\\.so$ + +# macros, be mindful to keep sync'd with macros.qt5 +Source10: macros.qt5 +%global _qt5 %{name} +%global _qt5_prefix %{_libdir}/qt5 +%global _qt5_archdatadir %{_libdir}/qt5 +# -devel bindir items (still) conflict with qt4 +# at least until this is all implemented, +# http://lists.qt-project.org/pipermail/development/2012-November/007990.html +%global _qt5_bindir %{_qt5_prefix}/bin +%global _qt5_datadir %{_datadir}/qt5 +%global _qt5_docdir %{_docdir}/qt5 +%global _qt5_examplesdir %{_qt5_prefix}/examples +%global _qt5_headerdir %{_includedir}/qt5 +%global _qt5_importdir %{_qt5_archdatadir}/imports +%global _qt5_libdir %{_libdir} +%global _qt5_libexecdir %{_qt5_archdatadir}/libexec +%global _qt5_plugindir %{_qt5_archdatadir}/plugins +%global _qt5_settingsdir %{_sysconfdir}/xdg +%global _qt5_sysconfdir %{_qt5_settingsdir} +%global _qt5_translationdir %{_datadir}/qt5/translations # for %%check BuildRequires: cmake @@ -138,6 +144,8 @@ BuildRequires: libjpeg-devel BuildRequires: libmng-devel BuildRequires: libtiff-devel BuildRequires: pkgconfig(alsa) +# required for -accessibility +BuildRequires: pkgconfig(atspi-2) # http://bugzilla.redhat.com/1196359 %if 0%{?fedora} || 0%{?rhel} > 6 %global dbus -dbus-linked @@ -147,7 +155,7 @@ BuildRequires: pkgconfig(libdrm) BuildRequires: pkgconfig(fontconfig) BuildRequires: pkgconfig(gl) BuildRequires: pkgconfig(glib-2.0) -BuildRequires: pkgconfig(gtk+-2.0) +BuildRequires: pkgconfig(gtk+-3.0) BuildRequires: pkgconfig(libproxy-1.0) # xcb-sm BuildRequires: pkgconfig(ice) pkgconfig(sm) @@ -172,7 +180,7 @@ Provides: bundled(libxkbcommon) = 0.4.1 %endif BuildRequires: pkgconfig(xkeyboard-config) %if 0%{?fedora} || 0%{?rhel} > 6 -%define egl 1 +%global egl 1 BuildRequires: pkgconfig(egl) BuildRequires: pkgconfig(gbm) BuildRequires: pkgconfig(glesv2) @@ -182,13 +190,13 @@ BuildRequires: pkgconfig(sqlite3) >= 3.7 %global harfbuzz -system-harfbuzz BuildRequires: pkgconfig(harfbuzz) >= 0.9.42 %endif -BuildRequires: pkgconfig(icu-i18n) -BuildRequires: pkgconfig(libpcre) >= 8.30 -%define pcre -system-pcre +BuildRequires: pkgconfig(libpcre2-posix) >= 10.20 +BuildRequires: pkgconfig(libpcre) >= 8.0 +%global pcre -system-pcre BuildRequires: pkgconfig(xcb-xkb) %else BuildRequires: libicu-devel -%define pcre -qt-pcre +%global pcre -qt-pcre %endif BuildRequires: pkgconfig(xcb) pkgconfig(xcb-glx) pkgconfig(xcb-icccm) pkgconfig(xcb-image) pkgconfig(xcb-keysyms) pkgconfig(xcb-renderutil) BuildRequires: pkgconfig(zlib) @@ -220,8 +228,8 @@ Requires: %{name}-common = %{version}-%{release} ## Sql drivers %if 0%{?rhel} -%define ibase -no-sql-ibase -%define tds -no-sql-tds +%global ibase -no-sql-ibase +%global tds -no-sql-tds %endif %description @@ -257,7 +265,8 @@ License: GFDL Requires: %{name} = %{version}-%{release} BuildRequires: qt5-qhelpgenerator BuildRequires: qt5-qdoc -BuildArch: noarch +## noarch build currently FTBFS, see https://bugzilla.redhat.com/1437522 +# BuildArch: noarch %description doc %{summary}. %endif @@ -353,21 +362,15 @@ RPM macros for building Qt5 packages. %patch4 -p1 -b .QTBUG-35459 -%patch50 -p1 -b .qt5-poll.patch -%patch52 -p1 -b .moc_WORDSIZE -%patch54 -p1 -b .arm -## FTBFS, omit for now -%patch60 -p1 -b .moc_system_defines +%patch50 -p1 -b .QT_VERSION_CHECK +%patch51 -p1 -b .hidpi_scale_at_192 +%patch52 -p1 -b .moc_macros %patch61 -p1 -b .qt5-qtbase-cxxflag - -%define platform linux-g++ +%patch62 -p1 -b .firebird +%patch63 -p1 -b .mysql %if 0%{?inject_optflags} ## adjust $RPM_OPT_FLAGS -# remove -fexceptions -RPM_OPT_FLAGS=`echo $RPM_OPT_FLAGS | sed 's|-fexceptions||g'` -# these flags are for qtbase build only, no need to propogate elsewhere -#RPM_OPT_FLAGS="$RPM_OPT_FLAGS %{?qt5_deprecated_flag} %{?qt5_arm_flag}" %patch2 -p1 -b .multilib_optflags # drop backup file(s), else they get installed too, http://bugzilla.redhat.com/639463 @@ -401,6 +404,16 @@ popd # check to ensure that can't happen -- rex test -x configure || chmod +x configure +# use proper perl interpretter so autodeps work as expected +sed -i -e "s|^#!/usr/bin/env perl$|#!%{__perl}|" \ + bin/fixqt4headers.pl \ + bin/syncqt.pl \ + mkspecs/features/data/unix/findclasslist.pl + +# Fix missing private includes https://bugreports.qt.io/browse/QTBUG-37417 +sed -e '/CMAKE_NO_PRIVATE_INCLUDES\ \=\ true/d' -i \ + mkspecs/features/create_cmake.prf + %build ## adjust $RPM_OPT_FLAGS @@ -414,18 +427,19 @@ export LDFLAGS="$LDFLAGS $RPM_LD_FLAGS" export MAKEFLAGS="%{?_smp_mflags}" ./configure -v \ + -verbose \ -confirm-license \ -opensource \ -prefix %{_qt5_prefix} \ -archdatadir %{_qt5_archdatadir} \ -bindir %{_qt5_bindir} \ + -libdir %{_qt5_libdir} \ + -libexecdir %{_qt5_libexecdir} \ -datadir %{_qt5_datadir} \ -docdir %{_qt5_docdir} \ -examplesdir %{_qt5_examplesdir} \ -headerdir %{_qt5_headerdir} \ -importdir %{_qt5_importdir} \ - -libdir %{_qt5_libdir} \ - -libexecdir %{_qt5_libexecdir} \ -plugindir %{_qt5_plugindir} \ -sysconfdir %{_qt5_sysconfdir} \ -translationdir %{_qt5_translationdir} \ @@ -436,9 +450,8 @@ export MAKEFLAGS="%{?_smp_mflags}" %{?dbus}%{!?dbus:-dbus-runtime} \ -fontconfig \ -glib \ - -gtkstyle \ + -gtk \ %{?ibase} \ - -iconv \ -icu \ %{?journald} \ %{?openssl} \ @@ -581,6 +594,23 @@ popd install -p -m755 -D %{SOURCE6} %{buildroot}%{_sysconfdir}/X11/xinit/xinitrc.d/10-qt5-check-opengl2.sh +# fix bz#1442553 multilib issue +privat_header_file=%{buildroot}%{_qt5_headerdir}/QtCore/%{version}/QtCore/private/qconfig_p.h +grep -v QT_FEATURE_sse2 $privat_header_file > ${privat_header_file}.me +mv ${privat_header_file}.me ${privat_header_file} +cat >>${privat_header_file}< - 5.9.2-3 +- Rebuild due to missing RELRO (fixed in binutils) + Resolves: bz#1534987 + +* Thu Jan 11 2018 Jan Grulich - 5.9.2-2 +- Avoid error about unbound variable + Resolves: bz#1533040 + +* Fri Oct 06 2017 Jan Grulich - 5.9.2-1 +- Update to 5.9.2 + Resolves: bz#1479097 + +* Mon Sep 04 2017 Jan Grulich - 5.9.1-3 +- Add more rpm macros + Resolves: bz#1479097 + +* Mon Sep 04 2017 Jan Grulich - 5.9.1-2 +- Enable documentation + Resolves: bz#1479097 + +* Fri Aug 18 2017 Jan Grulich - 5.9.1-1 +- Update to 5.9.1 + sync with Fedora + Resolves: bz#1479097 + * Wed Jan 11 2017 Jan Grulich - 5.6.2-1 - Update to 5.6.2 Resolves: bz#1384812