Latch signal handlers

Now that our interactive signal handlers are a strict superset of
non-interactive ones, there is no reason to "reset" signals or take action
when becoming non-interactive. Clean up how signal handlers get installed.
This commit is contained in:
ridiculousfish 2019-05-26 18:04:03 -07:00
parent ead7f28026
commit 7ed1022cf4
5 changed files with 20 additions and 9 deletions

View File

@ -1012,7 +1012,7 @@ static void test_cancellation() {
// Enable fish's signal handling here. We need to make this interactive for fish to install its
// signal handlers.
proc_push_interactive(1);
signal_set_handlers();
signal_set_handlers(true);
// This tests that we can correctly ctrl-C out of certain loop constructs, and that nothing gets
// printed if we do.

View File

@ -942,18 +942,15 @@ void proc_sanity_check(const parser_t &parser) {
void proc_push_interactive(int value) {
ASSERT_IS_MAIN_THREAD();
int old = is_interactive;
interactive_stack.push_back(is_interactive);
is_interactive = value;
if (old != value) signal_set_handlers();
signal_set_handlers_once(is_interactive);
}
void proc_pop_interactive() {
ASSERT_IS_MAIN_THREAD();
int old = is_interactive;
is_interactive = interactive_stack.back();
interactive_stack.pop_back();
if (is_interactive != old) signal_set_handlers();
}
void proc_wait_any(parser_t &parser) {

View File

@ -1738,7 +1738,7 @@ static void reader_interactive_init() {
}
}
signal_set_handlers();
signal_set_handlers(shell_is_interactive());
}
// It shouldn't be necessary to place fish in its own process group and force control

View File

@ -325,7 +325,7 @@ static void set_interactive_handlers() {
}
/// Sets up appropriate signal handlers.
void signal_set_handlers() {
void signal_set_handlers(bool interactive) {
struct sigaction act;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
@ -354,11 +354,19 @@ void signal_set_handlers() {
FATAL_EXIT();
}
if (shell_is_interactive()) {
if (interactive) {
set_interactive_handlers();
}
}
void signal_set_handlers_once(bool interactive) {
static std::once_flag s_noninter_once;
std::call_once(s_noninter_once, signal_set_handlers, false);
static std::once_flag s_inter_once;
if (interactive) std::call_once(s_inter_once, set_interactive_handlers);
}
void signal_handle(int sig, int do_handle) {
struct sigaction act;

View File

@ -17,7 +17,13 @@ const wchar_t *signal_get_desc(int sig);
void signal_reset_handlers();
/// Set signal handlers to fish default handlers.
void signal_set_handlers();
/// If \p interactive is set, apply interactive handlers as well.
/// Note interactive handlers, once applied, are not cleared; they are a strict superset of
/// non-interactive handlers.
void signal_set_handlers(bool interactive);
/// Latch function. This sets signal handlers, but only the first time it is called.
void signal_set_handlers_once(bool interactive);
/// Tell fish what to do on the specified signal.
///