[Python-checkins] bpo-37811: FreeBSD, OSX: fix poll(2) usage in sockets module (GH-15202)

Miss Islington (bot) webhook-mailer at python.org
Wed Aug 14 17:48:09 EDT 2019


https://github.com/python/cpython/commit/b0b178a2b80974da910ce6a344d66cc4d9a2fcfa
commit: b0b178a2b80974da910ce6a344d66cc4d9a2fcfa
branch: 3.7
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: GitHub <noreply at github.com>
date: 2019-08-14T14:48:03-07:00
summary:

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.
(cherry picked from commit 28146206578ebe1b84b48e6f255738a227058c04)

Co-authored-by: Artem Khramov <akhramov at pm.me>

files:
A Misc/NEWS.d/next/Library/2019-08-14-21-41-07.bpo-37811.d1xYj7.rst
M Misc/ACKS
M Modules/socketmodule.c

diff --git a/Misc/ACKS b/Misc/ACKS
index 29b6690f2174..4d8f96acfe30 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -815,6 +815,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 000000000000..662e7dc41005
--- /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 65385e8974cf..a9ef7e2083d5 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -741,6 +741,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;



More information about the Python-checkins mailing list