diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index 2395898010214d..a3be75a2a76d60 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -293,17 +293,39 @@ The following type-oriented macros are provided for convenience. Note that Same as :c:func:`PyMem_Free`. -In addition, the following macro sets are provided for calling the Python memory -allocator directly, without involving the C API functions listed above. However, -note that their use does not preserve binary compatibility across Python -versions and is therefore deprecated in extension modules. - -* ``PyMem_MALLOC(size)`` -* ``PyMem_NEW(type, size)`` -* ``PyMem_REALLOC(ptr, size)`` -* ``PyMem_RESIZE(ptr, type, size)`` -* ``PyMem_FREE(ptr)`` -* ``PyMem_DEL(ptr)`` + +Deprecated aliases +------------------ + +These are :term:`soft deprecated` aliases to existing functions and macros. +They exist solely for backwards compatibility. + +.. list-table:: + :widths: auto + :header-rows: 1 + + * * Deprecated alias + * Corresponding function or macro + * * .. c:macro:: PyMem_MALLOC(size) + * :c:func:`PyMem_Malloc` + * * .. c:macro:: PyMem_NEW(type, size) + * :c:macro:`PyMem_New` + * * .. c:macro:: PyMem_REALLOC(ptr, size) + * :c:func:`PyMem_Realloc` + * * .. c:macro:: PyMem_RESIZE(ptr, type, size) + * :c:macro:`PyMem_Resize` + * * .. c:macro:: PyMem_FREE(ptr) + * :c:func:`PyMem_Free` + * * .. c:macro:: PyMem_DEL(ptr) + * :c:func:`PyMem_Free` + +.. versionchanged:: 3.4 + + The macros are now aliases of the corresponding functions and macros. + Previously, their behavior was the same, but their use did not necessarily + preserve binary compatibility across Python versions. + +.. deprecated:: 2.0 .. _objectinterface: diff --git a/Doc/library/select.rst b/Doc/library/select.rst index 62b5161fb80634..ce4e92654d5932 100644 --- a/Doc/library/select.rst +++ b/Doc/library/select.rst @@ -478,6 +478,8 @@ linearly scanned again. :c:func:`!select` is *O*\ (*highest file descriptor*), w .. versionchanged:: 3.15 Accepts any real number as *timeout*, not only integer or float. + If ``ppoll()`` function is available, *timeout* has a resolution + of ``1`` ns (``1e-6`` ms) instead of ``1`` ms. .. _kqueue-objects: diff --git a/Lib/_pyio.py b/Lib/_pyio.py index 77c44addabf225..3306c8a274760b 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -952,20 +952,21 @@ def write(self, b): if isinstance(b, str): raise TypeError("can't write str to binary stream") with memoryview(b) as view: - n = view.nbytes # Size of any bytes-like object if self.closed: raise ValueError("write to closed file") - if n == 0: - return 0 - with self._lock: - pos = self._pos - if pos > len(self._buffer): - # Pad buffer to pos with null bytes. - self._buffer.resize(pos) - self._buffer[pos:pos + n] = b - self._pos += n - return n + n = view.nbytes # Size of any bytes-like object + if n == 0: + return 0 + + with self._lock: + pos = self._pos + if pos > len(self._buffer): + # Pad buffer to pos with null bytes. + self._buffer.resize(pos) + self._buffer[pos:pos + n] = view + self._pos += n + return n def seek(self, pos, whence=0): if self.closed: diff --git a/Lib/test/test_io/test_memoryio.py b/Lib/test/test_io/test_memoryio.py index f730e38a5d6485..482b183da23ffa 100644 --- a/Lib/test/test_io/test_memoryio.py +++ b/Lib/test/test_io/test_memoryio.py @@ -629,6 +629,28 @@ def __buffer__(self, flags): memio = self.ioclass() self.assertRaises(BufferError, memio.writelines, [B()]) + def test_write_mutating_buffer(self): + # Test that buffer is exported only once during write(). + # See: https://github.com/python/cpython/issues/143602. + class B: + count = 0 + def __buffer__(self, flags): + self.count += 1 + if self.count == 1: + return memoryview(b"AAA") + else: + return memoryview(b"BBBBBBBBB") + + memio = self.ioclass(b'0123456789') + memio.seek(2) + b = B() + n = memio.write(b) + + self.assertEqual(b.count, 1) + self.assertEqual(n, 3) + self.assertEqual(memio.getvalue(), b"01AAA56789") + self.assertEqual(memio.tell(), 5) + class TextIOTestMixin: diff --git a/Lib/test/test_poll.py b/Lib/test/test_poll.py index 5675db8d1cab6e..a15612b91458fa 100644 --- a/Lib/test/test_poll.py +++ b/Lib/test/test_poll.py @@ -173,17 +173,25 @@ def test_poll3(self): @cpython_only def test_poll_c_limits(self): try: + import _testcapi from _testcapi import USHRT_MAX, INT_MAX, UINT_MAX + HAVE_PPOLL = getattr(_testcapi, 'HAVE_PPOLL', False) except ImportError: raise unittest.SkipTest("requires _testcapi") + pollster = select.poll() pollster.register(1) # Issues #15989, #17919 self.assertRaises(OverflowError, pollster.register, 0, USHRT_MAX + 1) self.assertRaises(OverflowError, pollster.modify, 1, USHRT_MAX + 1) - self.assertRaises(OverflowError, pollster.poll, INT_MAX + 1) - self.assertRaises(OverflowError, pollster.poll, UINT_MAX + 1) + if HAVE_PPOLL: + MS_TO_NS = 1_000_000 + tmax = _testcapi.INT64_MAX // MS_TO_NS + self.assertRaises(OverflowError, pollster.poll, tmax + 1) + else: + self.assertRaises(OverflowError, pollster.poll, INT_MAX + 1) + self.assertRaises(OverflowError, pollster.poll, UINT_MAX + 1) @threading_helper.reap_threads def test_threaded_poll(self): diff --git a/Misc/NEWS.d/next/Library/2026-01-07-19-01-59.gh-issue-142434.SHRS5p.rst b/Misc/NEWS.d/next/Library/2026-01-07-19-01-59.gh-issue-142434.SHRS5p.rst new file mode 100644 index 00000000000000..cb6990a463bdd9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-01-07-19-01-59.gh-issue-142434.SHRS5p.rst @@ -0,0 +1,3 @@ +Use ``ppoll()`` if available in :func:`select.poll` to have a timeout +resolution of 1 nanosecond, instead of a resolution of 1 ms. Patch by Victor +Stinner. diff --git a/Misc/NEWS.d/next/Library/2026-01-09-12-37-19.gh-issue-143602.V8vQpj.rst b/Misc/NEWS.d/next/Library/2026-01-09-12-37-19.gh-issue-143602.V8vQpj.rst new file mode 100644 index 00000000000000..0eaec9029221ba --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-01-09-12-37-19.gh-issue-143602.V8vQpj.rst @@ -0,0 +1,2 @@ +Fix a inconsistency issue in :meth:`~io.RawIOBase.write` that leads to +unexpected buffer overwrite by deduplicating the buffer exports. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index de6d3cbce54fbe..c0ab35cda191c8 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -3359,6 +3359,12 @@ _testcapi_exec(PyObject *m) PyModule_AddObject(m, "INT64_MAX", PyLong_FromInt64(INT64_MAX)); PyModule_AddObject(m, "UINT64_MAX", PyLong_FromUInt64(UINT64_MAX)); +#ifdef HAVE_PPOLL + if (PyModule_AddObjectRef(m, "HAVE_PPOLL", Py_True) < 0) { + return -1; + } +#endif + if (PyModule_AddIntMacro(m, _Py_STACK_GROWS_DOWN)) { return -1; } diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h index 26ddc6ffba75bf..3952054e9e32bf 100644 --- a/Modules/clinic/selectmodule.c.h +++ b/Modules/clinic/selectmodule.c.h @@ -70,7 +70,7 @@ select_select(PyObject *module, PyObject *const *args, Py_ssize_t nargs) return return_value; } -#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) +#if ((defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL)) PyDoc_STRVAR(select_poll_register__doc__, "register($self, fd,\n" @@ -119,9 +119,9 @@ select_poll_register(PyObject *self, PyObject *const *args, Py_ssize_t nargs) return return_value; } -#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) */ +#endif /* ((defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL)) */ -#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) +#if ((defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL)) PyDoc_STRVAR(select_poll_modify__doc__, "modify($self, fd, eventmask, /)\n" @@ -166,9 +166,9 @@ select_poll_modify(PyObject *self, PyObject *const *args, Py_ssize_t nargs) return return_value; } -#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) */ +#endif /* ((defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL)) */ -#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) +#if ((defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL)) PyDoc_STRVAR(select_poll_unregister__doc__, "unregister($self, fd, /)\n" @@ -200,9 +200,9 @@ select_poll_unregister(PyObject *self, PyObject *arg) return return_value; } -#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) */ +#endif /* ((defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL)) */ -#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) +#if ((defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL)) PyDoc_STRVAR(select_poll_poll__doc__, "poll($self, timeout=None, /)\n" @@ -245,9 +245,9 @@ select_poll_poll(PyObject *self, PyObject *const *args, Py_ssize_t nargs) return return_value; } -#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) */ +#endif /* ((defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL)) */ -#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) +#if ((defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) PyDoc_STRVAR(select_devpoll_register__doc__, "register($self, fd,\n" @@ -298,9 +298,9 @@ select_devpoll_register(PyObject *self, PyObject *const *args, Py_ssize_t nargs) return return_value; } -#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ +#endif /* ((defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ -#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) +#if ((defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) PyDoc_STRVAR(select_devpoll_modify__doc__, "modify($self, fd,\n" @@ -351,9 +351,9 @@ select_devpoll_modify(PyObject *self, PyObject *const *args, Py_ssize_t nargs) return return_value; } -#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ +#endif /* ((defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ -#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) +#if ((defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) PyDoc_STRVAR(select_devpoll_unregister__doc__, "unregister($self, fd, /)\n" @@ -385,9 +385,9 @@ select_devpoll_unregister(PyObject *self, PyObject *arg) return return_value; } -#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ +#endif /* ((defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ -#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) +#if ((defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) PyDoc_STRVAR(select_devpoll_poll__doc__, "poll($self, timeout=None, /)\n" @@ -430,9 +430,9 @@ select_devpoll_poll(PyObject *self, PyObject *const *args, Py_ssize_t nargs) return return_value; } -#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ +#endif /* ((defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ -#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) +#if ((defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) PyDoc_STRVAR(select_devpoll_close__doc__, "close($self, /)\n" @@ -460,9 +460,9 @@ select_devpoll_close(PyObject *self, PyObject *Py_UNUSED(ignored)) return return_value; } -#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ +#endif /* ((defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ -#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) +#if ((defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) PyDoc_STRVAR(select_devpoll_fileno__doc__, "fileno($self, /)\n" @@ -488,9 +488,9 @@ select_devpoll_fileno(PyObject *self, PyObject *Py_UNUSED(ignored)) return return_value; } -#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ +#endif /* ((defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ -#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) +#if ((defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL)) PyDoc_STRVAR(select_poll__doc__, "poll($module, /)\n" @@ -513,9 +513,9 @@ select_poll(PyObject *module, PyObject *Py_UNUSED(ignored)) return select_poll_impl(module); } -#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) */ +#endif /* ((defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL)) */ -#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) +#if ((defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) PyDoc_STRVAR(select_devpoll__doc__, "devpoll($module, /)\n" @@ -538,7 +538,7 @@ select_devpoll(PyObject *module, PyObject *Py_UNUSED(ignored)) return select_devpoll_impl(module); } -#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ +#endif /* ((defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ #if defined(HAVE_EPOLL) @@ -1399,4 +1399,4 @@ select_kqueue_control(PyObject *self, PyObject *const *args, Py_ssize_t nargs) #ifndef SELECT_KQUEUE_CONTROL_METHODDEF #define SELECT_KQUEUE_CONTROL_METHODDEF #endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */ -/*[clinic end generated code: output=ae54d65938513132 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=52e3be5cc66cf1b6 input=a9049054013a1b77]*/ diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 19fe509ec5e32a..137bf2ca55bbf8 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -427,7 +427,7 @@ select_select_impl(PyObject *module, PyObject *rlist, PyObject *wlist, return ret; } -#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL) +#if (defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL) /* * poll() support */ @@ -626,7 +626,7 @@ select_poll_poll_impl(pollObject *self, PyObject *timeout_obj) PyObject *result_list = NULL; int poll_result, i, j; PyObject *value = NULL, *num = NULL; - PyTime_t timeout = -1, ms = -1, deadline = 0; + PyTime_t timeout = -1, deadline = 0; int async_err = 0; if (timeout_obj != Py_None) { @@ -639,15 +639,28 @@ select_poll_poll_impl(pollObject *self, PyObject *timeout_obj) } return NULL; } + } - ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT); - if (ms < INT_MIN || ms > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, "timeout is too large"); +#ifdef HAVE_PPOLL + struct timespec ts, *ts_p = NULL; + + if (timeout_obj != Py_None) { + if (_PyTime_AsTimespec(timeout, &ts) < 0) { return NULL; } if (timeout >= 0) { - deadline = _PyDeadline_Init(timeout); + ts_p = &ts; + } + } +#else + PyTime_t ms = -1; + + if (timeout_obj != Py_None) { + ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT); + if (ms < INT_MIN || ms > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, "timeout is too large"); + return NULL; } } @@ -661,6 +674,11 @@ select_poll_poll_impl(pollObject *self, PyObject *timeout_obj) ms = -1; #endif } +#endif + + if (timeout >= 0) { + deadline = _PyDeadline_Init(timeout); + } /* Avoid concurrent poll() invocation, issue 8865 */ if (self->poll_running) { @@ -681,7 +699,11 @@ select_poll_poll_impl(pollObject *self, PyObject *timeout_obj) do { Py_BEGIN_ALLOW_THREADS errno = 0; +#ifdef HAVE_PPOLL + poll_result = ppoll(self->ufds, self->ufd_len, ts_p, NULL); +#else poll_result = poll(self->ufds, self->ufd_len, (int)ms); +#endif Py_END_ALLOW_THREADS if (errno != EINTR) @@ -699,8 +721,16 @@ select_poll_poll_impl(pollObject *self, PyObject *timeout_obj) poll_result = 0; break; } +#ifdef HAVE_PPOLL + if (_PyTime_AsTimespec(timeout, &ts) < 0) { + poll_result = -1; + break; + } + assert(ts_p == &ts); +#else ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING); - /* retry poll() with the recomputed timeout */ +#endif + /* retry poll()/ppoll() with the recomputed timeout */ } } while (1); @@ -2466,7 +2496,7 @@ static PyGetSetDef kqueue_queue_getsetlist[] = { #include "clinic/selectmodule.c.h" -#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL) +#if (defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL) static PyMethodDef poll_methods[] = { SELECT_POLL_REGISTER_METHODDEF @@ -2661,7 +2691,7 @@ _select_exec(PyObject *m) ADD_INT(PIPE_BUF); #endif -#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL) +#if (defined(HAVE_POLL) || defined(HAVE_PPOLL)) && !defined(HAVE_BROKEN_POLL) #ifdef __APPLE__ if (select_have_broken_poll()) { if (PyObject_DelAttrString(m, "poll") == -1) { diff --git a/configure b/configure index 9d7fe6c52a418a..c826a1bb85667b 100755 --- a/configure +++ b/configure @@ -19811,6 +19811,12 @@ if test "x$ac_cv_func_poll" = xyes then : printf "%s\n" "#define HAVE_POLL 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "ppoll" "ac_cv_func_ppoll" +if test "x$ac_cv_func_ppoll" = xyes +then : + printf "%s\n" "#define HAVE_PPOLL 1" >>confdefs.h + fi ac_fn_c_check_func "$LINENO" "posix_fadvise" "ac_cv_func_posix_fadvise" if test "x$ac_cv_func_posix_fadvise" = xyes diff --git a/configure.ac b/configure.ac index 8c421c2a2baaf6..322d33dd0e3c99 100644 --- a/configure.ac +++ b/configure.ac @@ -5253,7 +5253,7 @@ AC_CHECK_FUNCS([ \ getspnam getuid getwd grantpt if_nameindex initgroups kill killpg lchown linkat \ lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \ mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \ - pipe2 plock poll posix_fadvise posix_fallocate posix_openpt posix_spawn posix_spawnp \ + pipe2 plock poll ppoll posix_fadvise posix_fallocate posix_openpt posix_spawn posix_spawnp \ posix_spawn_file_actions_addclosefrom_np \ pread preadv preadv2 process_vm_readv \ pthread_cond_timedwait_relative_np pthread_condattr_setclock pthread_init \ diff --git a/pyconfig.h.in b/pyconfig.h.in index aabf9f0be8da55..4ae2abeabf1d41 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -979,6 +979,9 @@ function. */ #undef HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSEFROM_NP +/* Define to 1 if you have the 'ppoll' function. */ +#undef HAVE_PPOLL + /* Define to 1 if you have the 'pread' function. */ #undef HAVE_PREAD