Add a property describing when a job is initially backgrounded

Track separately whether a job is in the background now, and whether
it was constructed in the background via the & syntax.
This commit is contained in:
ridiculousfish 2020-02-19 10:21:09 -07:00
parent 123f3e6f93
commit a4b66d948b
3 changed files with 13 additions and 3 deletions

View file

@ -1255,6 +1255,7 @@ end_execution_reason_t parse_execution_context_t::run_1_job(tnode_t<g::job> job_
job_t::properties_t props{};
props.wants_terminal = wants_job_control && !ld.is_event;
props.initial_background = job_node_is_background(job_node);
props.skip_notification =
ld.is_subshell || ld.is_block || ld.is_event || !parser->is_interactive();
props.from_event_handler = ld.is_event;
@ -1263,7 +1264,7 @@ end_execution_reason_t parse_execution_context_t::run_1_job(tnode_t<g::job> job_
shared_ptr<job_t> job = std::make_shared<job_t>(props);
job->tmodes = tmodes;
job->mut_flags().foreground = !job_node_is_background(job_node);
job->mut_flags().foreground = !props.initial_background;
// We are about to populate a job. One possible argument to the job is a command substitution
// which may be interested in the job that's populating it, via '--on-job-exit caller'. Record

View file

@ -270,8 +270,8 @@ void job_tree_t::populate_tree_for_job(job_t *job, const job_tree_ref_t &propose
// non-placeholder -> we are running as part of a real pipeline
// Decide if this job can use the placeholder tree.
// This is true if it's a simple foreground execution of an internal proc.
bool can_use_placeholder =
job->is_foreground() && job->processes.size() == 1 && job->processes.front()->is_internal();
bool can_use_placeholder = !job->is_initially_background() && job->processes.size() == 1 &&
job->processes.front()->is_internal();
bool needs_new_tree = false;
if (!proposed) {

View file

@ -389,6 +389,11 @@ class job_t {
/// Whether the job wants to own the terminal when in the foreground.
bool wants_terminal{};
/// Whether the job had the background ampersand when constructed, e.g. /bin/echo foo &
/// Note that a job may move between foreground and background; this just describes what the
/// initial state should be.
bool initial_background{};
/// Whether this job was created as part of an event handler.
bool from_event_handler{};
@ -523,6 +528,10 @@ class job_t {
/// \return if this job should own the terminal when it runs.
bool should_claim_terminal() const { return properties.wants_terminal && is_foreground(); }
/// \return whether this job is initially going to run in the background, because & was
/// specified.
bool is_initially_background() const { return properties.initial_background; }
/// Mark this job as constructed. The job must not have previously been marked as constructed.
void mark_constructed();