Express the "nested job control" idea directly

Prior to this fix, we would infer that nested jobs need job control.
Just pass that along explicitly in the job lineage.
This commit is contained in:
ridiculousfish 2020-01-29 16:08:10 -08:00
parent 28a8d0dbf7
commit 40ff4215a8
3 changed files with 13 additions and 2 deletions

View File

@ -652,6 +652,7 @@ static proc_performer_t get_performer_for_process(process_t *p, job_t *job,
lineage.parent_pgid = (job->pgid == INVALID_PID ? none() : maybe_t<pid_t>(job->pgid));
lineage.block_io = io_chain;
lineage.root_constructed = job->root_constructed;
lineage.root_has_job_control = job->wants_job_control();
if (p->type == process_type_t::block_node) {
const parsed_source_ref_t &source = p->block_node_source;
@ -944,13 +945,18 @@ bool exec_job(parser_t &parser, const shared_ptr<job_t> &j, const job_lineage_t
assert(*lineage.parent_pgid != INVALID_PID &&
"parent pgid should be none, not INVALID_PID");
j->pgid = *lineage.parent_pgid;
j->mut_flags().job_control = true;
}
pid_t pgrp = getpgrp();
// Check to see if we should reclaim the foreground pgrp after the job finishes or stops.
const bool reclaim_foreground_pgrp = (tcgetpgrp(STDIN_FILENO) == pgrp);
// If we are running nested inside a function or block with job control, then we need job
// control too.
if (lineage.root_has_job_control) {
j->mut_flags().job_control = true;
}
if (j->pgid == INVALID_PID && should_claim_process_group_for_job(j)) {
j->pgid = pgrp;
}

View File

@ -1265,7 +1265,8 @@ end_execution_reason_t parse_execution_context_t::run_1_job(tnode_t<g::job> job_
auto job_control_mode = get_job_control_mode();
bool wants_job_control =
(job_control_mode == job_control_t::all) ||
((job_control_mode == job_control_t::interactive) && parser->is_interactive());
((job_control_mode == job_control_t::interactive) && parser->is_interactive()) ||
lineage.root_has_job_control;
job_t::properties_t props{};
props.wants_terminal = wants_job_control && !ld.is_event;

View File

@ -280,6 +280,10 @@ struct job_lineage_t {
/// is part of a pipeline, then this may be set.
maybe_t<pid_t> parent_pgid{};
/// Whether job control is on for the root.
/// This is set if our job is nested as part of a function or block execution.
bool root_has_job_control{false};
/// The IO chain associated with any block containing this job.
/// For example, in `begin; foo ; end < file.txt` this would have the 'file.txt' IO.
io_chain_t block_io{};