diff Modules/socketmodule.c @ 44789:3c9ccc32da9a legacy-trunk

Patch #1019808 from Federico Schwindt: Return correct socket error when a default timeout has been set, by using getsockopt() to get the error condition (instead of trying another connect() call, which seems to be a Linuxism). 2.5 bugfix candidate, assuming no one reports any problems with this change.
author Andrew M. Kuchling <amk@amk.ca>
date Sat, 19 Jan 2008 20:47:59 +0000
parents 9468e6063617
children dfd21793a5b5
line wrap: on
line diff
--- a/Modules/socketmodule.c	Sat Jan 19 20:40:24 2008 +0000
+++ b/Modules/socketmodule.c	Sat Jan 19 20:47:59 2008 +0000
@@ -1986,15 +1986,22 @@
 #else
 
 	if (s->sock_timeout > 0.0) {
-		if (res < 0 && errno == EINPROGRESS && IS_SELECTABLE(s)) {
-			timeout = internal_select(s, 1);
-			if (timeout == 0) {
-				res = connect(s->sock_fd, addr, addrlen);
-				if (res < 0 && errno == EISCONN)
-					res = 0;
-			}
-			else if (timeout == -1)
-				res = errno;		/* had error */
+                if (res < 0 && errno == EINPROGRESS && IS_SELECTABLE(s)) {
+                        timeout = internal_select(s, 1);
+                        if (timeout == 0) {
+                                /* Bug #1019808: in case of an EINPROGRESS, 
+                                   use getsockopt(SO_ERROR) to get the real 
+                                   error. */
+                                socklen_t res_size = sizeof res;
+                                (void)getsockopt(s->sock_fd, SOL_SOCKET, 
+                                                 SO_ERROR, &res, &res_size);
+                                if (res == EISCONN)
+                                        res = 0;
+                                errno = res;
+                        }
+                        else if (timeout == -1) {
+                                res = errno;            /* had error */
+                        }
 			else
 				res = EWOULDBLOCK;	/* timed out */
 		}