diff --git a/src/event.cpp b/src/event.cpp index c81472420..d9791fd6f 100644 --- a/src/event.cpp +++ b/src/event.cpp @@ -288,6 +288,8 @@ void event_fire_delayed(parser_t &parser) { auto &ld = parser.libdata(); // Do not invoke new event handlers from within event handlers. if (ld.is_event) return; + // Do not invoke new event handlers if we are unwinding (#6649). + if (parser.get_cancel_signal()) return; std::vector> to_send; to_send.swap(ld.blocked_events); diff --git a/src/parser.h b/src/parser.h index bcea710fb..872986bfc 100644 --- a/src/parser.h +++ b/src/parser.h @@ -376,6 +376,9 @@ class parser_t : public std::enable_shared_from_this { void get_backtrace(const wcstring &src, const parse_error_list_t &errors, wcstring &output) const; + /// \return the signal triggering cancellation, or 0 if none. + int get_cancel_signal() const { return cancellation_signal; } + /// Output profiling data to the given filename. void emit_profiling(const char *path) const; diff --git a/tests/signals.expect b/tests/signals.expect index dc7991b8b..8fba5b7c8 100644 --- a/tests/signals.expect +++ b/tests/signals.expect @@ -2,11 +2,17 @@ # # Test signal handling for interactive shells. +set pid [spawn $fish] +expect_prompt + +send_line "function stuffs --on-signal INT; echo SIGINT spotted; end" +expect_prompt +exec -- kill -INT $pid +expect "SIGINT spotted" + # Verify that sending SIGHUP to the shell, such as will happen when the tty is # closed by the terminal, terminates the shell and the foreground command and # any background commands run from that shell. -set pid [spawn $fish] -expect_prompt send "sleep 130 &\r" expect_prompt send "sleep 131 &\r"