diff --git a/src/exec.cpp b/src/exec.cpp index a69d7b904..2a9614a86 100644 --- a/src/exec.cpp +++ b/src/exec.cpp @@ -655,16 +655,16 @@ static proc_performer_t get_performer_for_process(process_t *p, job_t *job, const io_chain_t &io_chain) { assert((p->type == process_type_t::function || p->type == process_type_t::block_node) && "Unexpected process type"); - // Make a lineage for our children. - job_lineage_t lineage; - lineage.job_tree = job->job_tree; - lineage.block_io = io_chain; + // We want to capture the job tree. + job_tree_ref_t job_tree = job->job_tree; if (p->type == process_type_t::block_node) { const parsed_source_ref_t &source = p->block_node_source; tnode_t node = p->internal_block_node; assert(source && node && "Process is missing node info"); - return [=](parser_t &parser) { return parser.eval_node(source, node, lineage).status; }; + return [=](parser_t &parser) { + return parser.eval_node(source, node, io_chain, job_tree).status; + }; } else { assert(p->type == process_type_t::function); auto props = function_get_properties(p->argv0()); @@ -677,7 +677,7 @@ static proc_performer_t get_performer_for_process(process_t *p, job_t *job, // Pull out the job list from the function. tnode_t body = props->func_node.child<1>(); const block_t *fb = function_prepare_environment(parser, *argv, *props); - auto res = parser.eval_node(props->parsed_source, body, lineage); + auto res = parser.eval_node(props->parsed_source, body, io_chain, job_tree); function_restore_environment(parser, fb); // If the function did not execute anything, treat it as success. diff --git a/src/io.h b/src/io.h index 92cfa2dfd..f5777ae7d 100644 --- a/src/io.h +++ b/src/io.h @@ -466,7 +466,7 @@ struct io_streams_t { // The job tree of the job, if any. This enables builtins which run more code like eval() to // share pgid. - // TODO: this is awkwardly placed, consider just embedding a lineage here. + // TODO: this is awkwardly placed. std::shared_ptr job_tree{}; // io_streams_t cannot be copied. diff --git a/src/parser.cpp b/src/parser.cpp index d2dec0b1e..302612199 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -665,12 +665,9 @@ eval_res_t parser_t::eval(const parsed_source_ref_t &ps, const io_chain_t &io, const job_tree_ref_t &job_tree, enum block_type_t block_type) { assert(block_type == block_type_t::top || block_type == block_type_t::subst); if (!ps->tree.empty()) { - job_lineage_t lineage; - lineage.block_io = io; - lineage.job_tree = job_tree; // Execute the first node. tnode_t start{&ps->tree, &ps->tree.front()}; - return this->eval_node(ps, start, std::move(lineage), block_type); + return this->eval_node(ps, start, io, job_tree, block_type); } else { auto status = proc_status_t::from_exit_code(get_last_status()); bool break_expand = false; @@ -681,7 +678,8 @@ eval_res_t parser_t::eval(const parsed_source_ref_t &ps, const io_chain_t &io, template eval_res_t parser_t::eval_node(const parsed_source_ref_t &ps, tnode_t node, - job_lineage_t lineage, block_type_t block_type) { + const io_chain_t &block_io, const job_tree_ref_t &job_tree, + block_type_t block_type) { static_assert( std::is_same::value || std::is_same::value, "Unexpected node type"); @@ -706,12 +704,12 @@ eval_res_t parser_t::eval_node(const parsed_source_ref_t &ps, tnode_t node, block_t *scope_block = this->push_block(block_t::scope_block(block_type)); // Propogate our job tree. - op_ctx.job_tree = lineage.job_tree; + op_ctx.job_tree = job_tree; // Create and set a new execution context. using exc_ctx_ref_t = std::unique_ptr; - scoped_push exc( - &execution_context, make_unique(ps, op_ctx, lineage.block_io)); + scoped_push exc(&execution_context, + make_unique(ps, op_ctx, block_io)); // Check the exec count so we know if anything got executed. const size_t prev_exec_count = libdata().exec_count; @@ -736,9 +734,9 @@ eval_res_t parser_t::eval_node(const parsed_source_ref_t &ps, tnode_t node, // Explicit instantiations. TODO: use overloads instead? template eval_res_t parser_t::eval_node(const parsed_source_ref_t &, tnode_t, - job_lineage_t, block_type_t); + const io_chain_t &, const job_tree_ref_t &, block_type_t); template eval_res_t parser_t::eval_node(const parsed_source_ref_t &, tnode_t, - job_lineage_t, block_type_t); + const io_chain_t &, const job_tree_ref_t &, block_type_t); void parser_t::get_backtrace(const wcstring &src, const parse_error_list_t &errors, wcstring &output) const { diff --git a/src/parser.h b/src/parser.h index 1cb378a23..772d0369e 100644 --- a/src/parser.h +++ b/src/parser.h @@ -301,7 +301,8 @@ class parser_t : public std::enable_shared_from_this { /// Evaluates a node. /// The node type must be grammar::statement or grammar::job_list. template - eval_res_t eval_node(const parsed_source_ref_t &ps, tnode_t node, job_lineage_t lineage, + eval_res_t eval_node(const parsed_source_ref_t &ps, tnode_t node, const io_chain_t &block_io, + const job_tree_ref_t &job_tree, block_type_t block_type = block_type_t::top); /// Evaluate line as a list of parameters, i.e. tokenize it and perform parameter expansion and diff --git a/src/proc.h b/src/proc.h index 79fe8f3f9..ebd428e2f 100644 --- a/src/proc.h +++ b/src/proc.h @@ -343,20 +343,6 @@ using job_id_t = int; job_id_t acquire_job_id(void); void release_job_id(job_id_t jid); -/// Information about where a job comes from. -/// This should be safe to copy across threads; in particular that means this cannot contain a -/// job_t. It is also important that job_t not contain this: because it stores block IO, it will -/// extend the life of the IO which may prevent pipes from closing in a timely manner. See #6397. -struct job_lineage_t { - /// The job tree. - /// If our job is "nested" as part of a function or block execution, and that function or block - /// is part of a pipeline, then this may be set. - job_tree_ref_t job_tree{}; - - /// 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{}; -}; /// A job has a mode which describes how its pgroup is assigned (before the value is known). /// This is a constant property of the job.