From 39a65915076bb9c3719813f9d079925d661cdbd5 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Fri, 5 Nov 2010 19:47:27 +0000 Subject: [PATCH] Issue #10311: The signal module now restores errno before returning from its low-level signal handler. Patch by Hallvard B Furuseth. --- Misc/ACKS | 1 + Misc/NEWS | 3 +++ Modules/signalmodule.c | 36 +++++++++++++++++++++--------------- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/Misc/ACKS b/Misc/ACKS index c52ec4e4f18..5b1a79c6fab 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -285,6 +285,7 @@ Peter Funk Geoff Furnish Ulisses Furquim Hagen Fürstenau +Hallvard B Furuseth Achim Gaedke Martin von Gagern Lele Gaifax diff --git a/Misc/NEWS b/Misc/NEWS index 4608b8d61a4..af33d2838f2 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -65,6 +65,9 @@ Core and Builtins 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 #10283: Add a ``group_pattern`` argument to NNTP.list(). diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 46912853ffd..0e7fd65b04b 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -169,16 +169,20 @@ checksignals_witharg(void * unused) static void signal_handler(int sig_num) { -#ifdef WITH_THREAD -#ifdef WITH_PTH + int save_errno = errno; + +#if defined(WITH_THREAD) && defined(WITH_PTH) if (PyThread_get_thread_ident() != main_thread) { pth_raise(*(pth_t *) main_thread, sig_num); - return; } + else #endif + { +#ifdef WITH_THREAD /* See NOTES section above */ - if (getpid() == main_pid) { + if (getpid() == main_pid) #endif + { Handlers[sig_num].tripped = 1; /* Set is_tripped after setting .tripped, as it gets cleared in PyErr_CheckSignals() before .tripped. */ @@ -186,24 +190,26 @@ signal_handler(int sig_num) Py_AddPendingCall(checksignals_witharg, NULL); if (wakeup_fd != -1) write(wakeup_fd, "\0", 1); -#ifdef WITH_THREAD } -#endif -#ifdef SIGCHLD - if (sig_num == SIGCHLD) { - /* To avoid infinite recursion, this signal remains - reset until explicit re-instated. - Don't clear the 'func' field as it is our pointer - to the Python handler... */ - return; - } -#endif + #ifndef HAVE_SIGACTION +#ifdef SIGCHLD + /* To avoid infinite recursion, this signal remains + reset until explicit re-instated. + Don't clear the 'func' field as it is our pointer + to the Python handler... */ + if (sig_num != SIGCHLD) +#endif /* If the handler was not set up with sigaction, reinstall it. See * Python/pythonrun.c for the implementation of PyOS_setsig which * makes this true. See also issue8354. */ PyOS_setsig(sig_num, signal_handler); #endif + } + + /* Issue #10311: asynchronously executing signal handlers should not + mutate errno under the feet of unsuspecting C code. */ + errno = save_errno; }