diff --git a/src/fish_tests.cpp b/src/fish_tests.cpp index caef8be7f..a2407bba7 100644 --- a/src/fish_tests.cpp +++ b/src/fish_tests.cpp @@ -757,6 +757,15 @@ static void test_cancellation() { test_1_cancellation(L"while true ; echo nothing > /dev/null; end"); test_1_cancellation(L"for i in (while true ; end) ; end"); + // Ensure that if child processes SIGINT, we exit our loops + // Test for #3780 + // Ugly hack - temporarily set is_interactive_session + // else we will SIGINT ourselves in response to our child death + scoped_push iis(&is_interactive_session, 1); + const wchar_t *child_self_destructor = L"while true ; sh -c 'sleep .25; kill -s INT $$' ; end"; + parser_t::principal_parser().eval(child_self_destructor, io_chain_t(), TOP); + iis.restore(); + // Restore signal handling. proc_pop_interactive(); signal_reset_handlers(); diff --git a/src/proc.cpp b/src/proc.cpp index 7028c6696..4c4f92826 100644 --- a/src/proc.cpp +++ b/src/proc.cpp @@ -299,9 +299,8 @@ void job_mark_process_as_failed(job_t *job, const process_t *failed_proc) { /// \param pid the pid of the process whose status changes /// \param status the status as returned by wait static void handle_child_status(pid_t pid, int status) { - bool found_proc = false; job_t *j = NULL; - process_t *p = NULL; + const process_t *found_proc = NULL; job_iterator_t jobs; while (!found_proc && (j = jobs.next())) { @@ -312,7 +311,7 @@ static void handle_child_status(pid_t pid, int status) { if (p->completed && prev && !prev->completed && prev->pid) { kill(prev->pid, SIGPIPE); } - found_proc = true; + found_proc = p.get(); break; } prev = p.get(); @@ -327,7 +326,7 @@ static void handle_child_status(pid_t pid, int status) { if (is_interactive_session) { // In an interactive session, tell the principal parser to skip all blocks we're executing // so control-C returns control to the user. - if (p && found_proc) parser_t::skip_all_blocks(); + if (found_proc) parser_t::skip_all_blocks(); } else { // Deliver the SIGINT or SIGQUIT signal to ourself since we're not interactive. struct sigaction act;