Commit 28146206 authored by Artem Khramov's avatar Artem Khramov Committed by Victor Stinner

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.
parent dcfe111e
...@@ -837,6 +837,7 @@ Lawrence Kesteloot ...@@ -837,6 +837,7 @@ Lawrence Kesteloot
Garvit Khatri Garvit Khatri
Vivek Khera Vivek Khera
Dhiru Kholia Dhiru Kholia
Artem Khramov
Akshit Khurana Akshit Khurana
Sanyam Khurana Sanyam Khurana
Mads Kiilerich Mads Kiilerich
......
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.
...@@ -789,6 +789,17 @@ internal_select(PySocketSockObject *s, int writing, _PyTime_t interval, ...@@ -789,6 +789,17 @@ internal_select(PySocketSockObject *s, int writing, _PyTime_t interval,
ms = _PyTime_AsMilliseconds(interval, _PyTime_ROUND_CEILING); ms = _PyTime_AsMilliseconds(interval, _PyTime_ROUND_CEILING);
assert(ms <= INT_MAX); 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; Py_BEGIN_ALLOW_THREADS;
n = poll(&pollfd, 1, (int)ms); n = poll(&pollfd, 1, (int)ms);
Py_END_ALLOW_THREADS; Py_END_ALLOW_THREADS;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment