mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-14 22:14:53 +00:00
Fix hup_background_jobs
(née kill_background_jobs
) implementation
This was introduced in 1b1bc28c0a
but did
not cause any problems until the job control refactor, which caused it
to attempt to signal the calling `exec` builtin's own (invalid) pgrp
with SIGHUP.
Also improved debugging for `j->signal()` failures by printing the
signal we tried sending in case of error, rename the function to
`hup_background_jobs`, and move it from `reader.h`/`reader.cpp` to
`proc.h`/`proc.cpp`.
This commit is contained in:
parent
4d3b56c151
commit
0d8334a31b
5 changed files with 27 additions and 17 deletions
|
@ -786,7 +786,7 @@ parse_execution_result_t parse_execution_context_t::populate_plain_process(
|
||||||
return parse_execution_errored;
|
return parse_execution_errored;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
kill_background_jobs();
|
hup_background_jobs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
22
src/proc.cpp
22
src/proc.cpp
|
@ -225,7 +225,9 @@ bool job_t::signal(int signal) {
|
||||||
|
|
||||||
if (pgid != getpgrp()) {
|
if (pgid != getpgrp()) {
|
||||||
if (killpg(pgid, signal) == -1) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1199,3 +1201,21 @@ pid_t proc_wait_any() {
|
||||||
process_clean_after_marking(is_interactive);
|
process_clean_after_marking(is_interactive);
|
||||||
return pid;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -404,6 +404,9 @@ int proc_format_status(int status);
|
||||||
/// Wait for any process finishing.
|
/// Wait for any process finishing.
|
||||||
pid_t proc_wait_any();
|
pid_t proc_wait_any();
|
||||||
|
|
||||||
|
/// Terminate all background jobs
|
||||||
|
void hup_background_jobs();
|
||||||
|
|
||||||
/// Give ownership of the terminal to the specified job.
|
/// Give ownership of the terminal to the specified job.
|
||||||
///
|
///
|
||||||
/// \param j The job to give the terminal to.
|
/// \param j The job to give the terminal to.
|
||||||
|
|
|
@ -1780,7 +1780,7 @@ static void reader_interactive_init() {
|
||||||
// Try stopping us.
|
// Try stopping us.
|
||||||
int ret = killpg(shell_pgid, SIGTTIN);
|
int ret = killpg(shell_pgid, SIGTTIN);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
wperror(L"killpg");
|
wperror(L"killpg(shell_pgid, SIGTTIN)");
|
||||||
exit_without_destructors(1);
|
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);
|
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
|
/// 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.
|
/// interactive mode. It checks if it is ok to exit.
|
||||||
static void handle_end_loop() {
|
static void handle_end_loop() {
|
||||||
|
@ -2293,7 +2283,7 @@ static void handle_end_loop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kill remaining jobs before exiting.
|
// Kill remaining jobs before exiting.
|
||||||
kill_background_jobs();
|
hup_background_jobs();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool selection_is_at_top() {
|
static bool selection_is_at_top() {
|
||||||
|
|
|
@ -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,
|
const wcstring &command_line, size_t *inout_cursor_pos,
|
||||||
bool append_only);
|
bool append_only);
|
||||||
|
|
||||||
/// Terminate all background jobs
|
|
||||||
void kill_background_jobs();
|
|
||||||
|
|
||||||
/// Print warning with list of backgrounded jobs
|
/// Print warning with list of backgrounded jobs
|
||||||
void reader_bg_job_warning();
|
void reader_bg_job_warning();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue