Windows - fix getsockopt calls for narrower than int options
Windows unhelpfully writes to only one byte of the output buffer when getsockopt is called for a boolean option. Therefore we have to zero initialise the int rather than initialising to -1 as was done before. This in general only works for little endian architecture, because the word would look like 0x01000000 on big endian. So I have added some compile time asserts in the assumption that windows is always little endian. This is ok for comparisons with 0/false, but not comparisons with true or nonzero values. In the case of IPV6_V6ONLY, it is documented as DWORD (unsigned int) but on some windows versions it is returned as a boolean triggering the warning. I removed the warning, as the conversion to int works on both LE and BE since it is only compared with zero. Task-number: QTBUG-23488 Change-Id: I3c586d1ada76465fc045a82661f289920c657a4c Reviewed-by: Richard J. Moore <rich@kde.org> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com> Reviewed-by: Andreas Holzammer <andreas.holzammer@kdab.com>
This commit is contained in:
parent
b147da00c5
commit
46e4a9d523
@ -427,10 +427,14 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co
|
||||
break;
|
||||
}
|
||||
|
||||
int v = -1;
|
||||
#if Q_BYTE_ORDER != Q_LITTLE_ENDIAN
|
||||
#error code assumes windows is little endian
|
||||
#endif
|
||||
int v = 0; //note: windows doesn't write to all bytes if the option type is smaller than int
|
||||
QT_SOCKOPTLEN_T len = sizeof(v);
|
||||
if (getsockopt(socketDescriptor, level, n, (char *) &v, &len) != -1)
|
||||
if (getsockopt(socketDescriptor, level, n, (char *) &v, &len) == 0)
|
||||
return v;
|
||||
WS_ERROR_DEBUG(WSAGetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -563,12 +567,10 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters()
|
||||
#if defined (IPV6_V6ONLY)
|
||||
// determine if local address is dual mode
|
||||
DWORD ipv6only = 0;
|
||||
int optlen = sizeof(ipv6only);
|
||||
QT_SOCKOPTLEN_T optlen = sizeof(ipv6only);
|
||||
if (localAddress == QHostAddress::AnyIPv6
|
||||
&& QSysInfo::windowsVersion() >= QSysInfo::WV_6_0
|
||||
&& !getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&ipv6only, &optlen )) {
|
||||
if (optlen != sizeof(ipv6only))
|
||||
qWarning("unexpected size of IPV6_V6ONLY socket option");
|
||||
if (!ipv6only) {
|
||||
socketProtocol = QAbstractSocket::AnyIPProtocol;
|
||||
localAddress = QHostAddress::Any;
|
||||
|
@ -201,6 +201,8 @@ private slots:
|
||||
|
||||
void qtbug14268_peek();
|
||||
|
||||
void setSocketOption();
|
||||
|
||||
|
||||
protected slots:
|
||||
void nonBlockingIMAP_hostFound();
|
||||
@ -2699,7 +2701,41 @@ void tst_QTcpSocket::qtbug14268_peek()
|
||||
QVERIFY(incoming->read(128*1024) == QByteArray("abc\ndef\nghi\n"));
|
||||
}
|
||||
|
||||
void tst_QTcpSocket::setSocketOption()
|
||||
{
|
||||
QFETCH_GLOBAL(bool, setProxy);
|
||||
if (setProxy)
|
||||
return;
|
||||
|
||||
SocketPair socketPair;
|
||||
QVERIFY(socketPair.create());
|
||||
QTcpSocket *outgoing = socketPair.endPoints[0];
|
||||
QTcpSocket *incoming = socketPair.endPoints[1];
|
||||
|
||||
QVERIFY(incoming->state() == QTcpSocket::ConnectedState);
|
||||
QVERIFY(outgoing->state() == QTcpSocket::ConnectedState);
|
||||
|
||||
outgoing->setSocketOption(QAbstractSocket::LowDelayOption, true);
|
||||
QVariant v = outgoing->socketOption(QAbstractSocket::LowDelayOption);
|
||||
QVERIFY(v.isValid() && v.toBool());
|
||||
outgoing->setSocketOption(QAbstractSocket::KeepAliveOption, true);
|
||||
v = outgoing->socketOption(QAbstractSocket::KeepAliveOption);
|
||||
QVERIFY(v.isValid() && v.toBool());
|
||||
|
||||
outgoing->setSocketOption(QAbstractSocket::LowDelayOption, false);
|
||||
v = outgoing->socketOption(QAbstractSocket::LowDelayOption);
|
||||
QVERIFY(v.isValid() && !v.toBool());
|
||||
outgoing->setSocketOption(QAbstractSocket::KeepAliveOption, false);
|
||||
v = outgoing->socketOption(QAbstractSocket::KeepAliveOption);
|
||||
QVERIFY(v.isValid() && !v.toBool());
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
QEXPECT_FAIL("", "QTBUG-23323", Abort);
|
||||
#endif
|
||||
outgoing->setSocketOption(QAbstractSocket::TypeOfServiceOption, 32); //high priority
|
||||
v = outgoing->socketOption(QAbstractSocket::TypeOfServiceOption);
|
||||
QVERIFY(v.isValid() && v.toInt() == 32);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QTcpSocket)
|
||||
#include "tst_qtcpsocket.moc"
|
||||
|
Loading…
Reference in New Issue
Block a user