summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtem Khramov <akhramov@pm.me>2019-08-14 21:21:48 (GMT)
committerVictor Stinner <vstinner@redhat.com>2019-08-14 21:21:48 (GMT)
commit28146206578ebe1b84b48e6f255738a227058c04 (patch)
tree9d6e5c90cba99c1ec804d8999e0dd0b7b2e84b48
parentdcfe111eb5602333135b8776996332a8dcf59392 (diff)
downloadcpython-28146206578ebe1b84b48e6f255738a227058c04.zip
cpython-28146206578ebe1b84b48e6f255738a227058c04.tar.gz
cpython-28146206578ebe1b84b48e6f255738a227058c04.tar.bz2
bpo-37811: FreeBSD, OSX: fix poll(2) usage in sockets module (GH-15202)
FreeBSD implementation of poll(2) restricts the timeout argument to be either zero, or positive, or equal to INFTIM (-1). Unless otherwise overridden, socket timeout defaults to -1. This value is then converted to milliseconds (-1000) and used as argument to the poll syscall. poll returns EINVAL (22), and the connection fails. This bug was discovered during the EINTR handling testing, and the reproduction code can be found in https://bugs.python.org/issue23618 (see connect_eintr.py, attached). On GNU/Linux, the example runs as expected. This change is trivial: If the supplied timeout value is negative, truncate it to -1.
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS.d/next/Library/2019-08-14-21-41-07.bpo-37811.d1xYj7.rst4
-rwxr-xr-xModules/socketmodule.c11
3 files changed, 16 insertions, 0 deletions
diff --git a/Misc/ACKS b/Misc/ACKS
index 3b4cf85..52a5d70 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -837,6 +837,7 @@ Lawrence Kesteloot
Garvit Khatri
Vivek Khera
Dhiru Kholia
+Artem Khramov
Akshit Khurana
Sanyam Khurana
Mads Kiilerich
diff --git a/Misc/NEWS.d/next/Library/2019-08-14-21-41-07.bpo-37811.d1xYj7.rst b/Misc/NEWS.d/next/Library/2019-08-14-21-41-07.bpo-37811.d1xYj7.rst
new file mode 100644
index 0000000..662e7dc
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2019-08-14-21-41-07.bpo-37811.d1xYj7.rst
@@ -0,0 +1,4 @@
+Fix ``socket`` module's ``socket.connect(address)`` function being unable to
+establish connection in case of interrupted system call. The problem was
+observed on all OSes which ``poll(2)`` system call can take only
+non-negative integers and -1 as a timeout value.
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index f220c26..d4f2098 100755
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -789,6 +789,17 @@ internal_select(PySocketSockObject *s, int writing, _PyTime_t interval,
ms = _PyTime_AsMilliseconds(interval, _PyTime_ROUND_CEILING);
assert(ms <= INT_MAX);
+ /* On some OSes, typically BSD-based ones, the timeout parameter of the
+ poll() syscall, when negative, must be exactly INFTIM, where defined,
+ or -1. See issue 37811. */
+ if (ms < 0) {
+#ifdef INFTIM
+ ms = INFTIM;
+#else
+ ms = -1;
+#endif
+ }
+
Py_BEGIN_ALLOW_THREADS;
n = poll(&pollfd, 1, (int)ms);
Py_END_ALLOW_THREADS;