diff --git a/src/parse_execution.cpp b/src/parse_execution.cpp index 0872b28fd..0ee92d3f1 100644 --- a/src/parse_execution.cpp +++ b/src/parse_execution.cpp @@ -786,7 +786,7 @@ parse_execution_result_t parse_execution_context_t::populate_plain_process( return parse_execution_errored; } else { - kill_background_jobs(); + hup_background_jobs(); } } } diff --git a/src/proc.cpp b/src/proc.cpp index c729c46da..1bbc540e9 100644 --- a/src/proc.cpp +++ b/src/proc.cpp @@ -225,7 +225,9 @@ bool job_t::signal(int signal) { if (pgid != getpgrp()) { if (killpg(pgid, signal) == -1) { - wperror(L"killpg"); + char buffer[512]; + sprintf(buffer, "killpg(%d, %s)", pgid, strsignal(signal)); + wperror(str2wcstring(buffer).c_str()); return false; } } else { @@ -1199,3 +1201,21 @@ pid_t proc_wait_any() { process_clean_after_marking(is_interactive); return pid; } + +void hup_background_jobs() { + job_iterator_t jobs; + + while (job_t *j = jobs.next()) { + // Make sure we don't try to SIGHUP the calling builtin + if (j->pgid == INVALID_PID || !j->get_flag(job_flag_t::JOB_CONTROL)) { + continue; + } + + if (!j->is_completed()) { + if (j->is_stopped()) { + j->signal(SIGCONT); + } + j->signal(SIGHUP); + } + } +} diff --git a/src/proc.h b/src/proc.h index 0d238a73e..b98632ab6 100644 --- a/src/proc.h +++ b/src/proc.h @@ -404,6 +404,9 @@ int proc_format_status(int status); /// Wait for any process finishing. pid_t proc_wait_any(); +/// Terminate all background jobs +void hup_background_jobs(); + /// Give ownership of the terminal to the specified job. /// /// \param j The job to give the terminal to. diff --git a/src/reader.cpp b/src/reader.cpp index 8cbafacd0..137bbe94f 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -1780,7 +1780,7 @@ static void reader_interactive_init() { // Try stopping us. int ret = killpg(shell_pgid, SIGTTIN); if (ret < 0) { - wperror(L"killpg"); + wperror(L"killpg(shell_pgid, SIGTTIN)"); exit_without_destructors(1); } } @@ -2251,16 +2251,6 @@ void reader_bg_job_warning() { fputws(_(L"Use 'disown PID' to remove jobs from the list without terminating them.\n"), stdout); } -void kill_background_jobs() { - job_iterator_t jobs; - while (job_t *j = jobs.next()) { - if (!j->is_completed()) { - if (j->is_stopped()) j->signal(SIGCONT); - j->signal(SIGHUP); - } - } -} - /// This function is called when the main loop notices that end_loop has been set while in /// interactive mode. It checks if it is ok to exit. static void handle_end_loop() { @@ -2293,7 +2283,7 @@ static void handle_end_loop() { } // Kill remaining jobs before exiting. - kill_background_jobs(); + hup_background_jobs(); } static bool selection_is_at_top() { diff --git a/src/reader.h b/src/reader.h index c9d2dd045..2d4338b76 100644 --- a/src/reader.h +++ b/src/reader.h @@ -227,9 +227,6 @@ wcstring completion_apply_to_command_line(const wcstring &val_str, complete_flag const wcstring &command_line, size_t *inout_cursor_pos, bool append_only); -/// Terminate all background jobs -void kill_background_jobs(); - /// Print warning with list of backgrounded jobs void reader_bg_job_warning();