From 123f6c4914827c4ced65d032fab74de62db31cd6 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 14 Aug 2019 14:47:43 -0700 Subject: 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 --- Misc/ACKS | 1 + .../next/Library/2019-08-14-21-41-07.bpo-37811.d1xYj7.rst | 4 ++++ Modules/socketmodule.c | 11 +++++++++++ 3 files changed, 16 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2019-08-14-21-41-07.bpo-37811.d1xYj7.rst diff --git a/Misc/ACKS b/Misc/ACKS index 3e53429..311259f 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -832,6 +832,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 0470f38..910e2bd 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -780,6 +780,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; -- cgit v0.12