Commit 39a65915 authored by Antoine Pitrou's avatar Antoine Pitrou

Issue #10311: The signal module now restores errno before returning from

its low-level signal handler.  Patch by Hallvard B Furuseth.
parent a0781154
...@@ -285,6 +285,7 @@ Peter Funk ...@@ -285,6 +285,7 @@ Peter Funk
Geoff Furnish Geoff Furnish
Ulisses Furquim Ulisses Furquim
Hagen Fürstenau Hagen Fürstenau
Hallvard B Furuseth
Achim Gaedke Achim Gaedke
Martin von Gagern Martin von Gagern
Lele Gaifax Lele Gaifax
......
...@@ -65,6 +65,9 @@ Core and Builtins ...@@ -65,6 +65,9 @@ Core and Builtins
Library Library
------- -------
- Issue #10311: The signal module now restores errno before returning from
its low-level signal handler. Patch by Hallvard B Furuseth.
- Issue #10282: Add a ``nntp_implementation`` attribute to NNTP objects. - Issue #10282: Add a ``nntp_implementation`` attribute to NNTP objects.
- Issue #10283: Add a ``group_pattern`` argument to NNTP.list(). - Issue #10283: Add a ``group_pattern`` argument to NNTP.list().
......
...@@ -169,16 +169,20 @@ checksignals_witharg(void * unused) ...@@ -169,16 +169,20 @@ checksignals_witharg(void * unused)
static void static void
signal_handler(int sig_num) signal_handler(int sig_num)
{ {
#ifdef WITH_THREAD int save_errno = errno;
#ifdef WITH_PTH
#if defined(WITH_THREAD) && defined(WITH_PTH)
if (PyThread_get_thread_ident() != main_thread) { if (PyThread_get_thread_ident() != main_thread) {
pth_raise(*(pth_t *) main_thread, sig_num); pth_raise(*(pth_t *) main_thread, sig_num);
return;
} }
else
#endif #endif
{
#ifdef WITH_THREAD
/* See NOTES section above */ /* See NOTES section above */
if (getpid() == main_pid) { if (getpid() == main_pid)
#endif #endif
{
Handlers[sig_num].tripped = 1; Handlers[sig_num].tripped = 1;
/* Set is_tripped after setting .tripped, as it gets /* Set is_tripped after setting .tripped, as it gets
cleared in PyErr_CheckSignals() before .tripped. */ cleared in PyErr_CheckSignals() before .tripped. */
...@@ -186,24 +190,26 @@ signal_handler(int sig_num) ...@@ -186,24 +190,26 @@ signal_handler(int sig_num)
Py_AddPendingCall(checksignals_witharg, NULL); Py_AddPendingCall(checksignals_witharg, NULL);
if (wakeup_fd != -1) if (wakeup_fd != -1)
write(wakeup_fd, "\0", 1); write(wakeup_fd, "\0", 1);
#ifdef WITH_THREAD
} }
#endif
#ifndef HAVE_SIGACTION
#ifdef SIGCHLD #ifdef SIGCHLD
if (sig_num == SIGCHLD) { /* To avoid infinite recursion, this signal remains
/* To avoid infinite recursion, this signal remains reset until explicit re-instated.
reset until explicit re-instated. Don't clear the 'func' field as it is our pointer
Don't clear the 'func' field as it is our pointer to the Python handler... */
to the Python handler... */ if (sig_num != SIGCHLD)
return;
}
#endif #endif
#ifndef HAVE_SIGACTION
/* If the handler was not set up with sigaction, reinstall it. See /* If the handler was not set up with sigaction, reinstall it. See
* Python/pythonrun.c for the implementation of PyOS_setsig which * Python/pythonrun.c for the implementation of PyOS_setsig which
* makes this true. See also issue8354. */ * makes this true. See also issue8354. */
PyOS_setsig(sig_num, signal_handler); PyOS_setsig(sig_num, signal_handler);
#endif #endif
}
/* Issue #10311: asynchronously executing signal handlers should not
mutate errno under the feet of unsuspecting C code. */
errno = save_errno;
} }
......
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