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.
This commit is contained in:
ridiculousfish 2020-07-27 15:51:37 -07:00
parent 3382bc70d2
commit 3506274ccf
4 changed files with 9 additions and 7 deletions

View file

@ -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;
}

View file

@ -1004,7 +1004,7 @@ bool exec_job(parser_t &parser, const shared_ptr<job_t> &j, const io_chain_t &bl
return false;
}
j->continue_job(parser);
j->continue_job(parser, !j->is_initially_background());
return true;
}

View file

@ -927,7 +927,7 @@ maybe_t<pid_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());
}

View file

@ -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.