Mercurial > cpython-lru_cache-weakref
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 */ }
