From 46e4a9d5231e2d9e35424259858713ca539b8e30 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Mon, 20 Feb 2012 18:48:10 +0000 Subject: 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 Reviewed-by: Friedemann Kleint Reviewed-by: Andreas Holzammer --- src/network/socket/qnativesocketengine_win.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index d7bbe7eb86..93a470c77f 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -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; -- cgit v1.2.3