]> granicus.if.org Git - python/commitdiff
Patch #1019808 from Federico Schwindt: Return correct socket error when
authorAndrew M. Kuchling <amk@amk.ca>
Sat, 19 Jan 2008 20:47:59 +0000 (20:47 +0000)
committerAndrew M. Kuchling <amk@amk.ca>
Sat, 19 Jan 2008 20:47:59 +0000 (20:47 +0000)
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.

Misc/ACKS
Misc/NEWS
Modules/socketmodule.c

index 35ceceef728f707ccee05882b2fa717af5a3283e..5c87ed1292411b59a383dc07bf40ebcd399203cf 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -589,6 +589,7 @@ Chad J. Schroeder
 Sam Schulenburg
 Stefan Schwarzer
 Dietmar Schwertberger
+Federico Schwindt
 Barry Scott
 Steven Scott
 Nick Seidenman
index f7c7aac8e97e8251461bc44f983cce3bae2bde96..b20273d9b25f412408253296874c414cabf5f397 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -1120,6 +1120,9 @@ Extension Modules
 - 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
index 0ec4c0b27fd8180d2adcda0256029e47571da528..88d2a70a0fd9d72b42d9345466a288becd417dee 100644 (file)
@@ -1986,15 +1986,22 @@ internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen,
 #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 */
                }