1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** 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 https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QT_NO_NATIVE_POLL
#define QT_NO_NATIVE_POLL
#endif
#include <QtTest/QtTest>
#include <QtNetwork>
#include <private/qcore_unix_p.h>
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"
|