diff Modules/socketmodule.c @ 23818:8a0a14e3725e legacy-trunk

Fix non-blocking connect() for Windows. Refactored the code that retries the connect() call in timeout mode so it can be shared between connect() and connect_ex(), and needs only a single #ifdef. The test for this was doing funky stuff I don't approve of, so I removed it in favor of a simpler test. This allowed me to implement a simpler, "purer" form of the timeout retry code. Hopefully that's enough (if you want to be fancy, use non-blocking mode and decode the errors yourself, like before).
author Guido van Rossum <guido@python.org>
date Thu, 13 Jun 2002 16:07:04 +0000
parents 203d1412a7e8
children ed1ba37a46b7
line wrap: on
line diff
--- a/Modules/socketmodule.c	Thu Jun 13 15:14:10 2002 +0000
+++ b/Modules/socketmodule.c	Thu Jun 13 16:07:04 2002 +0000
@@ -1270,6 +1270,43 @@
 \n\
 Close the socket.  It cannot be used after this call.";
 
+static int
+internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen)
+{
+	int res;
+
+	res = connect(s->sock_fd, addr, addrlen);
+
+#ifdef MS_WINDOWS
+
+	if (s->sock_timeout > 0.0) {
+		if (res < 0 && WSAGetLastError() == WSAEWOULDBLOCK) {
+			internal_select(s, 1);
+			res = connect(s->sock_fd, addr, addrlen);
+			if (res < 0 && WSAGetLastError() == WSAEISCONN)
+				res = 0;
+		}
+	}
+
+	if (res < 0)
+		res = WSAGetLastError();
+
+#else
+
+	if (s->sock_timeout > 0.0) {
+		if (res < 0 && errno == EINPROGRESS) {
+			internal_select(s, 1);
+			res = connect(s->sock_fd, addr, addrlen);
+		}
+	}
+
+	if (res < 0)
+		res = errno;
+
+#endif
+
+	return res;
+}
 
 /* s.connect(sockaddr) method */
 
@@ -1284,18 +1321,10 @@
 		return NULL;
 
 	Py_BEGIN_ALLOW_THREADS
-	if (s->sock_timeout > 0.0) {
-		res = connect(s->sock_fd, addr, addrlen);
-		if (res == EINPROGRESS) {
-			internal_select(s, 1);
-			res = connect(s->sock_fd, addr, addrlen);
-		}
-	}
-	else
-		res = connect(s->sock_fd, addr, addrlen);
+	res = internal_connect(s, addr, addrlen);
 	Py_END_ALLOW_THREADS
 
-	if (res < 0)
+	if (res != 0)
 		return s->errorhandler();
 	Py_INCREF(Py_None);
 	return Py_None;
@@ -1321,25 +1350,9 @@
 		return NULL;
 
 	Py_BEGIN_ALLOW_THREADS
-	if (s->sock_timeout > 0.0) {
-		res = connect(s->sock_fd, addr, addrlen);
-		if (res == EINPROGRESS) {
-			internal_select(s, 1);
-			res = connect(s->sock_fd, addr, addrlen);
-		}
-	}
-	else
-		res = connect(s->sock_fd, addr, addrlen);
+	res = internal_connect(s, addr, addrlen);
 	Py_END_ALLOW_THREADS
 
-	if (res != 0) {
-#ifdef MS_WINDOWS
-		res = WSAGetLastError();
-#else
-		res = errno;
-#endif
-	}
-
 	return PyInt_FromLong((long) res);
 }