--- embedaddon/readline/signals.c 2014/07/30 08:16:45 1.1.1.1 +++ embedaddon/readline/signals.c 2021/03/17 01:01:01 1.1.1.2 @@ -1,6 +1,6 @@ /* signals.c -- signal handling support for readline. */ -/* Copyright (C) 1987-2011 Free Software Foundation, Inc. +/* Copyright (C) 1987-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -99,7 +99,6 @@ int rl_catch_sigwinch = 0; /* for the readline state s #endif /* Private variables. */ -int _rl_interrupt_immediately = 0; int volatile _rl_caught_signal = 0; /* should be sig_atomic_t, but that requires including everywhere */ /* If non-zero, print characters corresponding to received signals as long as @@ -113,6 +112,10 @@ int _rl_susp_char = 0; static int signals_set_flag; static int sigwinch_set_flag; +#if defined (HAVE_POSIX_SIGNALS) +sigset_t _rl_orig_sigset; +#endif /* !HAVE_POSIX_SIGNALS */ + /* **************************************************************** */ /* */ /* Signal Handling */ @@ -132,16 +135,17 @@ void *_rl_sigcleanarg; /* Readline signal handler functions. */ -/* Called from RL_CHECK_SIGNALS() macro */ +/* Called from RL_CHECK_SIGNALS() macro to run signal handling code. */ RETSIGTYPE -_rl_signal_handler (sig) - int sig; +_rl_signal_handler (int sig) { _rl_caught_signal = 0; /* XXX */ #if defined (SIGWINCH) if (sig == SIGWINCH) { + RL_SETSTATE(RL_STATE_SIGHANDLER); + rl_resize_terminal (); /* XXX - experimental for now */ /* Call a signal hook because though we called the original signal handler @@ -149,6 +153,8 @@ _rl_signal_handler (sig) ourselves. */ if (rl_signal_event_hook) (*rl_signal_event_hook) (); + + RL_UNSETSTATE(RL_STATE_SIGHANDLER); } else #endif @@ -158,26 +164,22 @@ _rl_signal_handler (sig) } static RETSIGTYPE -rl_signal_handler (sig) - int sig; +rl_signal_handler (int sig) { - if (_rl_interrupt_immediately) - { - _rl_interrupt_immediately = 0; - _rl_handle_signal (sig); - } - else - _rl_caught_signal = sig; - + _rl_caught_signal = sig; SIGHANDLER_RETURN; } +/* This is called to handle a signal when it is safe to do so (out of the + signal handler execution path). Called by _rl_signal_handler for all the + signals readline catches except SIGWINCH. */ static RETSIGTYPE -_rl_handle_signal (sig) - int sig; +_rl_handle_signal (int sig) { + int block_sig; + #if defined (HAVE_POSIX_SIGNALS) - sigset_t set; + sigset_t set, oset; #else /* !HAVE_POSIX_SIGNALS */ # if defined (HAVE_BSD_SIGNALS) long omask; @@ -207,31 +209,84 @@ _rl_handle_signal (sig) _rl_sigcleanup = 0; _rl_sigcleanarg = 0; } - + +#if defined (HAVE_POSIX_SIGNALS) + /* Get the current set of blocked signals. If we want to block a signal for + the duration of the cleanup functions, make sure to add it to SET and + set block_sig = 1 (see the SIGHUP case below). */ + block_sig = 0; /* sentinel to block signals with sigprocmask */ + sigemptyset (&set); + sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set); +#endif + switch (sig) { case SIGINT: _rl_reset_completion_state (); rl_free_line_state (); +#if defined (READLINE_CALLBACKS) + rl_callback_sigcleanup (); +#endif + /* FALLTHROUGH */ - case SIGTERM: - case SIGHUP: #if defined (SIGTSTP) case SIGTSTP: - case SIGTTOU: case SIGTTIN: + case SIGTTOU: +# if defined (HAVE_POSIX_SIGNALS) + /* Block SIGTTOU so we can restore the terminal settings to something + sane without stopping on SIGTTOU if we have been placed into the + background. Even trying to get the current terminal pgrp with + tcgetpgrp() will generate SIGTTOU, so we don't bother. We still do + this even if we've been stopped on SIGTTOU, since we handle signals + when we have returned from the signal handler and the signal is no + longer blocked. */ + sigaddset (&set, SIGTTOU); + block_sig = 1; +# endif #endif /* SIGTSTP */ + /* Any signals that should be blocked during cleanup should go here. */ +#if defined (SIGHUP) + case SIGHUP: +# if defined (_AIX) + if (block_sig == 0) + { + sigaddset (&set, sig); + block_sig = 1; + } +# endif // _AIX +#endif + /* Signals that don't require blocking during cleanup should go here. */ + case SIGTERM: #if defined (SIGALRM) case SIGALRM: #endif #if defined (SIGQUIT) case SIGQUIT: #endif + + if (block_sig) + sigprocmask (SIG_BLOCK, &set, &oset); + rl_echo_signal_char (sig); rl_cleanup_after_signal (); + /* At this point, the application's signal handler, if any, is the + current handler. */ + #if defined (HAVE_POSIX_SIGNALS) + /* Unblock any signal(s) blocked above */ + if (block_sig) + sigprocmask (SIG_UNBLOCK, &oset, (sigset_t *)NULL); +#endif + + /* We don't have to bother unblocking the signal because we are not + running in a signal handler context. */ +#if 0 +#if defined (HAVE_POSIX_SIGNALS) + /* Make sure this signal is not blocked when we resend it to the + calling application. */ sigemptyset (&set); sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set); sigdelset (&set, sig); @@ -240,6 +295,7 @@ _rl_handle_signal (sig) omask = sigblock (0); # endif /* HAVE_BSD_SIGNALS */ #endif /* !HAVE_POSIX_SIGNALS */ +#endif #if defined (__EMX__) signal (sig, SIG_ACK); @@ -251,7 +307,10 @@ _rl_handle_signal (sig) raise (sig); /* assume we have raise */ #endif - /* Let the signal that we just sent through. */ + /* We don't need to modify the signal mask now that this is not run in + a signal handler context. */ +#if 0 + /* Let the signal that we just sent through if it is blocked. */ #if defined (HAVE_POSIX_SIGNALS) sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL); #else /* !HAVE_POSIX_SIGNALS */ @@ -259,6 +318,7 @@ _rl_handle_signal (sig) sigsetmask (omask & ~(sigmask (sig))); # endif /* HAVE_BSD_SIGNALS */ #endif /* !HAVE_POSIX_SIGNALS */ +#endif rl_reset_after_signal (); } @@ -269,8 +329,7 @@ _rl_handle_signal (sig) #if defined (SIGWINCH) static RETSIGTYPE -rl_sigwinch_handler (sig) - int sig; +rl_sigwinch_handler (int sig) { SigHandler *oh; @@ -301,9 +360,7 @@ rl_sigwinch_handler (sig) #if !defined (HAVE_POSIX_SIGNALS) static int -rl_sigaction (sig, nh, oh) - int sig; - sighandler_cxt *nh, *oh; +rl_sigaction (int sig, sighandler_cxt *nh, sighandler_cxt *oh) { oh->sa_handler = signal (sig, nh->sa_handler); return 0; @@ -314,10 +371,7 @@ rl_sigaction (sig, nh, oh) information in OHANDLER. Return the old signal handler, like signal(). */ static SigHandler * -rl_set_sighandler (sig, handler, ohandler) - int sig; - SigHandler *handler; - sighandler_cxt *ohandler; +rl_set_sighandler (int sig, SigHandler *handler, sighandler_cxt *ohandler) { sighandler_cxt old_handler; #if defined (HAVE_POSIX_SIGNALS) @@ -348,10 +402,7 @@ rl_set_sighandler (sig, handler, ohandler) /* Set disposition of SIG to HANDLER, returning old state in OHANDLER. Don't change disposition if OHANDLER indicates the signal was ignored. */ static void -rl_maybe_set_sighandler (sig, handler, ohandler) - int sig; - SigHandler *handler; - sighandler_cxt *ohandler; +rl_maybe_set_sighandler (int sig, SigHandler *handler, sighandler_cxt *ohandler) { sighandler_cxt dummy; SigHandler *oh; @@ -368,9 +419,7 @@ rl_maybe_set_sighandler (sig, handler, ohandler) disposition was changed using rl_maybe_set_sighandler or for which the SIG_IGN check was performed inline (e.g., SIGALRM below). */ static void -rl_maybe_restore_sighandler (sig, handler) - int sig; - sighandler_cxt *handler; +rl_maybe_restore_sighandler (int sig, sighandler_cxt *handler) { sighandler_cxt dummy; @@ -381,7 +430,7 @@ rl_maybe_restore_sighandler (sig, handler) } int -rl_set_signals () +rl_set_signals (void) { sighandler_cxt dummy; SigHandler *oh; @@ -397,7 +446,9 @@ rl_set_signals () sigaddset (&bset, SIGINT); sigaddset (&bset, SIGTERM); +#if defined (SIGHUP) sigaddset (&bset, SIGHUP); +#endif #if defined (SIGQUIT) sigaddset (&bset, SIGQUIT); #endif @@ -420,13 +471,15 @@ rl_set_signals () if (rl_catch_signals && signals_set_flag == 0) { #if defined (HAVE_POSIX_SIGNALS) - sigemptyset (&oset); - sigprocmask (SIG_BLOCK, &bset, &oset); + sigemptyset (&_rl_orig_sigset); + sigprocmask (SIG_BLOCK, &bset, &_rl_orig_sigset); #endif rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int); rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term); +#if defined (SIGHUP) rl_maybe_set_sighandler (SIGHUP, rl_signal_handler, &old_hup); +#endif #if defined (SIGQUIT) rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit); #endif @@ -460,9 +513,16 @@ rl_set_signals () signals_set_flag = 1; #if defined (HAVE_POSIX_SIGNALS) - sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL); + sigprocmask (SIG_SETMASK, &_rl_orig_sigset, (sigset_t *)NULL); #endif } + else if (rl_catch_signals == 0) + { +#if defined (HAVE_POSIX_SIGNALS) + sigemptyset (&_rl_orig_sigset); + sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &_rl_orig_sigset); +#endif + } #if defined (SIGWINCH) if (rl_catch_sigwinch && sigwinch_set_flag == 0) @@ -476,14 +536,12 @@ rl_set_signals () } int -rl_clear_signals () +rl_clear_signals (void) { sighandler_cxt dummy; if (rl_catch_signals && signals_set_flag == 1) { - sigemptyset (&dummy.sa_mask); - /* Since rl_maybe_set_sighandler doesn't override a SIG_IGN handler, we should in theory not have to restore a handler where old_xxx.sa_handler == SIG_IGN. That's what rl_maybe_restore_sighandler @@ -491,7 +549,9 @@ rl_clear_signals () overhead */ rl_maybe_restore_sighandler (SIGINT, &old_int); rl_maybe_restore_sighandler (SIGTERM, &old_term); +#if defined (SIGHUP) rl_maybe_restore_sighandler (SIGHUP, &old_hup); +#endif #if defined (SIGQUIT) rl_maybe_restore_sighandler (SIGQUIT, &old_quit); #endif @@ -529,7 +589,7 @@ rl_clear_signals () /* Clean up the terminal and readline state after catching a signal, before resending it to the calling application. */ void -rl_cleanup_after_signal () +rl_cleanup_after_signal (void) { _rl_clean_up_for_exit (); if (rl_deprep_term_function) @@ -540,7 +600,7 @@ rl_cleanup_after_signal () /* Reset the terminal and readline state after a signal handler returns. */ void -rl_reset_after_signal () +rl_reset_after_signal (void) { if (rl_prep_term_function) (*rl_prep_term_function) (_rl_meta_flag); @@ -552,7 +612,7 @@ rl_reset_after_signal () numeric arguments in process) after catching a signal, before calling rl_cleanup_after_signal(). */ void -rl_free_line_state () +rl_free_line_state (void) { register HIST_ENTRY *entry; @@ -567,6 +627,17 @@ rl_free_line_state () _rl_reset_argument (); } +int +rl_pending_signal (void) +{ + return (_rl_caught_signal); +} + +void +rl_check_signals (void) +{ + RL_CHECK_SIGNALS (); +} #endif /* HANDLE_SIGNALS */ /* **************************************************************** */ @@ -591,7 +662,7 @@ static int sigwinch_blocked; /* Cause SIGINT to not be delivered until the corresponding call to release_sigint(). */ void -_rl_block_sigint () +_rl_block_sigint (void) { if (sigint_blocked) return; @@ -601,7 +672,7 @@ _rl_block_sigint () /* Allow SIGINT to be delivered. */ void -_rl_release_sigint () +_rl_release_sigint (void) { if (sigint_blocked == 0) return; @@ -613,7 +684,7 @@ _rl_release_sigint () /* Cause SIGWINCH to not be delivered until the corresponding call to release_sigwinch(). */ void -_rl_block_sigwinch () +_rl_block_sigwinch (void) { if (sigwinch_blocked) return; @@ -642,7 +713,7 @@ _rl_block_sigwinch () /* Allow SIGWINCH to be delivered. */ void -_rl_release_sigwinch () +_rl_release_sigwinch (void) { if (sigwinch_blocked == 0) return; @@ -672,8 +743,7 @@ _rl_release_sigwinch () /* */ /* **************************************************************** */ void -rl_echo_signal_char (sig) - int sig; +rl_echo_signal_char (int sig) { char cstr[3]; int cslen, c;