summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShane Kearns <ext-shane.2.kearns@nokia.com>2012-05-15 15:41:01 +0100
committerQt by Nokia <qt-info@nokia.com>2012-05-18 11:08:06 +0200
commitdbcbd4708b8fdabdbf80ad8405bcb871ebf23ccc (patch)
tree5b9ddbdb4915ff04822ff2a406b1bc0156a2d0dc
parenta56ee60791538e5442b3d97b75270b25dc4986db (diff)
Make the windows socket handle non inheritable
This is for behaviour consistency with Qt on unix, as well as the socket close issues described in the task. Task-number: QTBUG-4465 Change-Id: Ida95650d8a9bd7b5bc3d3926d22e20a6d7eeb30b Reviewed-by: Robin Burchell <robin+qt@viroteck.net> Reviewed-by: Joerg Bornemann <joerg.bornemann@nokia.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp24
1 files changed, 23 insertions, 1 deletions
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index bd9550e207..db6ace1d46 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -309,9 +309,18 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc
int protocol = (socketProtocol == QAbstractSocket::IPv6Protocol
|| (socketProtocol == QAbstractSocket::AnyIPProtocol && QSysInfo::windowsVersion() >= QSysInfo::WV_6_0)) ? AF_INET6 : AF_INET;
int type = (socketType == QAbstractSocket::UdpSocket) ? SOCK_DGRAM : SOCK_STREAM;
+
// MSDN KB179942 states that on winnt 4 WSA_FLAG_OVERLAPPED is needed if socket is to be non blocking
// and recomends alwasy doing it for cross windows version comapablity.
- SOCKET socket = ::WSASocket(protocol, type, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
+
+ // WSA_FLAG_NO_HANDLE_INHERIT is atomic (like linux O_CLOEXEC), but requires windows 7 SP 1 or later
+ // SetHandleInformation is supported since W2K but isn't atomic
+ // According to the MS docs, we can use the new flag and call GetHandleInformation to see if it was successful
+#ifndef WSA_FLAG_NO_HANDLE_INHERIT
+#define WSA_FLAG_NO_HANDLE_INHERIT 0x80
+#endif
+
+ SOCKET socket = ::WSASocket(protocol, type, 0, NULL, 0, WSA_FLAG_NO_HANDLE_INHERIT | WSA_FLAG_OVERLAPPED);
if (socket == INVALID_SOCKET) {
int err = WSAGetLastError();
@@ -337,6 +346,19 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc
return false;
}
+#ifdef HANDLE_FLAG_INHERIT
+ // check if the WSASocket was successful or not at creating a non inheritable socket
+ DWORD handleFlags = 0xFF;
+ if (GetHandleInformation((HANDLE)socket, &handleFlags) && (handleFlags & HANDLE_FLAG_INHERIT)) {
+ // make non inheritable the old way
+ if (SetHandleInformation((HANDLE)socket, HANDLE_FLAG_INHERIT, 0))
+ handleFlags = 0;
+ }
+#ifdef QNATIVESOCKETENGINE_DEBUG
+ qDebug() << "QNativeSocketEnginePrivate::createNewSocket - set inheritable" << handleFlags;
+#endif
+#endif
+
#if !defined(Q_OS_WINCE)
if (socketType == QAbstractSocket::UdpSocket) {
// enable new behavior using