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.
diff --git a/Misc/ACKS b/Misc/ACKS
index 35cecee..5c87ed1 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -589,6 +589,7 @@
 Sam Schulenburg
 Stefan Schwarzer
 Dietmar Schwertberger
+Federico Schwindt
 Barry Scott
 Steven Scott
 Nick Seidenman
diff --git a/Misc/NEWS b/Misc/NEWS
index f7c7aac..b20273d 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -1120,6 +1120,9 @@
 - Patch #1544279: Improve thread-safety of the socket module by moving
   the sock_addr_t storage out of the socket object.
 
+- Patch #1019808: fix bug that causes an incorrect error to be returned 
+  when a socket timeout is set and a connection attempt fails.
+
 - Speed up function calls into the math module.
 
 - Bug #1588217: don't parse "= " as a soft line break in binascii's
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 0ec4c0b..88d2a70 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -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 */
 		}