From 3506274ccffbdd929ec8e1b3c3f2e1c3fc07b57b Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Mon, 27 Jul 2020 15:51:37 -0700 Subject: [PATCH] Make in_foreground an explicit param to continue_job This moves us slightly closer towards fish code in the background. The idea is that a background job may still have "foreground" sub-jobs, example: begin ; sleep 5 ; end & The begin/end job runs in the background but should wait for `sleep`. Prior to this fix, fish would see the overall job group is in the background and not wait for any of its processes. With this change we detach waiting from is_foreground. --- src/builtin_bg.cpp | 2 +- src/exec.cpp | 2 +- src/proc.cpp | 8 ++++---- src/proc.h | 4 +++- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/builtin_bg.cpp b/src/builtin_bg.cpp index ca05442fd..64b0ec5c8 100644 --- a/src/builtin_bg.cpp +++ b/src/builtin_bg.cpp @@ -32,7 +32,7 @@ static int send_to_bg(parser_t &parser, io_streams_t &streams, job_t *j) { j->command_wcstr()); parser.job_promote(j); j->group->set_is_foreground(false); - j->continue_job(parser); + j->continue_job(parser, false /* not in_foreground */); return STATUS_CMD_OK; } diff --git a/src/exec.cpp b/src/exec.cpp index c995594ce..c38a13887 100644 --- a/src/exec.cpp +++ b/src/exec.cpp @@ -1004,7 +1004,7 @@ bool exec_job(parser_t &parser, const shared_ptr &j, const io_chain_t &bl return false; } - j->continue_job(parser); + j->continue_job(parser, !j->is_initially_background()); return true; } diff --git a/src/proc.cpp b/src/proc.cpp index b24613e98..a44ef90d8 100644 --- a/src/proc.cpp +++ b/src/proc.cpp @@ -927,7 +927,7 @@ maybe_t job_t::get_pgid() const { return group->get_pgid(); } job_id_t job_t::job_id() const { return group->get_id(); } -void job_t::continue_job(parser_t &parser) { +void job_t::continue_job(parser_t &parser, bool in_foreground) { // Put job first in the job list. parser.job_promote(this); mut_flags().notified = false; @@ -984,7 +984,7 @@ void job_t::continue_job(parser_t &parser) { } } - if (is_foreground()) { + if (in_foreground) { // Wait for the status of our own job to change. while (!reader_exit_forced() && !is_stopped() && !is_completed()) { process_mark_finished_children(parser, true); @@ -992,10 +992,10 @@ void job_t::continue_job(parser_t &parser) { } } - if (is_foreground() && is_completed()) { + if (in_foreground && is_completed()) { // Set $status only if we are in the foreground and the last process in the job has // finished. - auto &p = processes.back(); + const auto &p = processes.back(); if (p->status.normal_exited() || p->status.signal_exited()) { parser.set_last_statuses(get_statuses()); } diff --git a/src/proc.h b/src/proc.h index 2541d85eb..2700d4610 100644 --- a/src/proc.h +++ b/src/proc.h @@ -456,7 +456,9 @@ class job_t { /// Continues running a job, which may be stopped, or may just have started. /// This will send SIGCONT if the job is stopped. - void continue_job(parser_t &parser); + /// If \p in_foreground is set, then wait for the job to stop or complete; + /// otherwise do not wait for the job. + void continue_job(parser_t &parser, bool in_foreground = true); /// Send the specified signal to all processes in this job. /// \return true on success, false on failure.