From 20ef56dbc88f517ebf60d89577fc89870d9fe888 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 5 Sep 2012 14:33:53 -0700 Subject: Fix race conditions with signal handlers and errno. Be more systematic about preserving errno whenever a signal handler returns, even if it's not in the main thread. Do this by renaming signal handlers to distinguish between signal delivery and signal handling. All uses changed. * atimer.c (deliver_alarm_signal): Rename from alarm_signal_handler. * data.c (deliver_arith_signal): Rename from arith_error. * dispnew.c (deliver_window_change_signal): Rename from window_change_signal. * emacs.c (deliver_error_signal): Rename from fatal_error_signal. (deliver_danger_signal) [SIGDANGER]: Rename from memory_warning_signal. * keyboard.c (deliver_input_available_signal): Rename from input_available_signal. (deliver_user_signal): Rename from handle_user_signal. (deliver_interrupt_signal): Rename from interrupt_signal. * process.c (deliver_pipe_signal): Rename from send_process_trap. (deliver_child_signal): Rename from sigchld_handler. * atimer.c (handle_alarm_signal): * data.c (handle_arith_signal): * dispnew.c (handle_window_change_signal): * emacs.c (handle_fatal_signal, handle_danger_signal): * keyboard.c (handle_input_available_signal): * keyboard.c (handle_user_signal, handle_interrupt_signal): * process.c (handle_pipe_signal, handle_child_signal): New functions, with the actual signal-handling code taken from the original respective signal handlers, sans the sporadic attempts to preserve errno, since that's now done by handle_on_main_thread. * atimer.c (alarm_signal_handler): Remove unnecessary decl. * emacs.c, floatfns.c, lisp.h: Remove unused FLOAT_CATCH_SIGKILL cruft. * emacs.c (main_thread) [FORWARD_SIGNAL_TO_MAIN_THREAD]: Move to sysdep.c. (main) [FORWARD_SIGNAL_TO_MAIN_THREAD]: Move initialization of main_thread to sysdep.c's init_signals. * process.c (waitpid) [!WNOHANG]: #define to wait; that's good enough for our usage, and simplifies the mainline code. (record_child_status_change): New static function, as a helper for handle_child_signal, and with most of the old child handler's contents. (CAN_HANDLE_MULTIPLE_CHILDREN): New constant. (handle_child_signal): Use the above. * sysdep.c (main_thread) [FORWARD_SIGNAL_TO_MAIN_THREAD]: Moved here from emacs.c. (init_signals) [FORWARD_SIGNAL_TO_MAIN_THREAD]: Initialize it; code moved here from emacs.c's main function. * sysdep.c, syssignal.h (handle_on_main_thread): New function, replacing the old SIGNAL_THREAD_CHECK. All uses changed. This lets callers save and restore errno properly. --- src/atimer.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'src/atimer.c') diff --git a/src/atimer.c b/src/atimer.c index eb3136ae55d..060dead9b17 100644 --- a/src/atimer.c +++ b/src/atimer.c @@ -41,7 +41,7 @@ static struct atimer *stopped_atimers; static struct atimer *atimers; -/* Non-zero means alarm_signal_handler has found ripe timers but +/* Non-zero means alarm signal handler has found ripe timers but interrupt_input_blocked was non-zero. In this case, timer functions are not called until the next UNBLOCK_INPUT because timer functions are expected to call X, and X cannot be assumed to be @@ -60,8 +60,6 @@ static void set_alarm (void); static void schedule_atimer (struct atimer *); static struct atimer *append_atimer_lists (struct atimer *, struct atimer *); -static void alarm_signal_handler (int signo); - /* Start a new atimer of type TYPE. TIME specifies when the timer is ripe. FN is the function to call when the timer fires. @@ -374,13 +372,9 @@ run_timers (void) /* Signal handler for SIGALRM. SIGNO is the signal number, i.e. SIGALRM. */ -void -alarm_signal_handler (int signo) +static void +handle_alarm_signal (int sig) { -#ifndef SYNC_INPUT - SIGNAL_THREAD_CHECK (signo); -#endif - pending_atimers = 1; #ifdef SYNC_INPUT pending_signals = 1; @@ -389,8 +383,14 @@ alarm_signal_handler (int signo) #endif } +static void +deliver_alarm_signal (int sig) +{ + handle_on_main_thread (sig, handle_alarm_signal); +} + -/* Call alarm_signal_handler for pending timers. */ +/* Call alarm signal handler for pending timers. */ void do_pending_atimers (void) @@ -412,7 +412,7 @@ turn_on_atimers (bool on) { if (on) { - signal (SIGALRM, alarm_signal_handler); + signal (SIGALRM, deliver_alarm_signal); set_alarm (); } else @@ -426,5 +426,5 @@ init_atimer (void) free_atimers = stopped_atimers = atimers = NULL; pending_atimers = 0; /* pending_signals is initialized in init_keyboard.*/ - signal (SIGALRM, alarm_signal_handler); + signal (SIGALRM, deliver_alarm_signal); } -- cgit v1.2.3