summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS3
-rw-r--r--Modules/socketmodule.c25
3 files changed, 20 insertions, 9 deletions
diff --git a/Misc/ACKS b/Misc/ACKS
index 35cecee..5c87ed1 100644
--- 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
diff --git a/Misc/NEWS b/Misc/NEWS
index f7c7aac..b20273d 100644
--- 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
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 */
}