diff options
| author | Andrew M. Kuchling <amk@amk.ca> | 2008-01-19 20:47:59 (GMT) | 
|---|---|---|
| committer | Andrew M. Kuchling <amk@amk.ca> | 2008-01-19 20:47:59 (GMT) | 
| commit | 060e6855a802a9e9bf2e6905342f704f64a3a26d (patch) | |
| tree | 4e7aacd975ced3b4a7c73c29e985983bc6cda79f | |
| parent | e3979f776a3837716aa7e566e388332d85314ceb (diff) | |
| download | cpython-060e6855a802a9e9bf2e6905342f704f64a3a26d.zip cpython-060e6855a802a9e9bf2e6905342f704f64a3a26d.tar.gz cpython-060e6855a802a9e9bf2e6905342f704f64a3a26d.tar.bz2  | |
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.
| -rw-r--r-- | Misc/ACKS | 1 | ||||
| -rw-r--r-- | Misc/NEWS | 3 | ||||
| -rw-r--r-- | Modules/socketmodule.c | 25 | 
3 files changed, 20 insertions, 9 deletions
@@ -589,6 +589,7 @@ Chad J. Schroeder  Sam Schulenburg  Stefan Schwarzer  Dietmar Schwertberger +Federico Schwindt  Barry Scott  Steven Scott  Nick Seidenman @@ -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 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 @@ 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 */  		}  | 
