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.
This commit is contained in:
Andrew M. Kuchling 2008-01-19 20:47:59 +00:00
parent e3979f776a
commit 060e6855a8
3 changed files with 20 additions and 9 deletions

View File

@ -589,6 +589,7 @@ Chad J. Schroeder
Sam Schulenburg Sam Schulenburg
Stefan Schwarzer Stefan Schwarzer
Dietmar Schwertberger Dietmar Schwertberger
Federico Schwindt
Barry Scott Barry Scott
Steven Scott Steven Scott
Nick Seidenman Nick Seidenman

View File

@ -1120,6 +1120,9 @@ Extension Modules
- Patch #1544279: Improve thread-safety of the socket module by moving - Patch #1544279: Improve thread-safety of the socket module by moving
the sock_addr_t storage out of the socket object. 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. - Speed up function calls into the math module.
- Bug #1588217: don't parse "= " as a soft line break in binascii's - Bug #1588217: don't parse "= " as a soft line break in binascii's

View File

@ -1986,15 +1986,22 @@ internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen,
#else #else
if (s->sock_timeout > 0.0) { if (s->sock_timeout > 0.0) {
if (res < 0 && errno == EINPROGRESS && IS_SELECTABLE(s)) { if (res < 0 && errno == EINPROGRESS && IS_SELECTABLE(s)) {
timeout = internal_select(s, 1); timeout = internal_select(s, 1);
if (timeout == 0) { if (timeout == 0) {
res = connect(s->sock_fd, addr, addrlen); /* Bug #1019808: in case of an EINPROGRESS,
if (res < 0 && errno == EISCONN) use getsockopt(SO_ERROR) to get the real
res = 0; error. */
} socklen_t res_size = sizeof res;
else if (timeout == -1) (void)getsockopt(s->sock_fd, SOL_SOCKET,
res = errno; /* had error */ SO_ERROR, &res, &res_size);
if (res == EISCONN)
res = 0;
errno = res;
}
else if (timeout == -1) {
res = errno; /* had error */
}
else else
res = EWOULDBLOCK; /* timed out */ res = EWOULDBLOCK; /* timed out */
} }