diff --git a/src/builtin_eval.cpp b/src/builtin_eval.cpp index 589525dad..6dc190ba9 100644 --- a/src/builtin_eval.cpp +++ b/src/builtin_eval.cpp @@ -27,7 +27,8 @@ int builtin_eval(parser_t &parser, io_streams_t &streams, wchar_t **argv) { const auto cached_exec_count = parser.libdata().exec_count; int status = STATUS_CMD_OK; if (argc > 1) { - if (parser.eval(new_cmd, *streams.io_chain) != eval_result_t::ok) { + if (parser.eval(new_cmd, *streams.io_chain, block_type_t::top, streams.parent_pgid) != + eval_result_t::ok) { status = STATUS_CMD_ERROR; } else if (cached_exec_count == parser.libdata().exec_count) { // Issue #5692, in particular, to catch `eval ""`, `eval "begin; end;"`, etc. diff --git a/src/exec.cpp b/src/exec.cpp index ee7568543..bd24f5281 100644 --- a/src/exec.cpp +++ b/src/exec.cpp @@ -911,6 +911,7 @@ static bool exec_process_in_job(parser_t &parser, process_t *p, const std::share case process_type_t::builtin: { io_streams_t builtin_io_streams{stdout_read_limit}; + if (j->pgid != INVALID_PID) builtin_io_streams.parent_pgid = j->pgid; if (!exec_internal_builtin_proc(parser, j, p, pipe_read.get(), process_net_io_chain, builtin_io_streams)) { return false; diff --git a/src/io.h b/src/io.h index 7503b664e..14ee9bb95 100644 --- a/src/io.h +++ b/src/io.h @@ -454,6 +454,11 @@ struct io_streams_t { // Actual IO redirections. This is only used by the source builtin. Unowned. const io_chain_t *io_chain{nullptr}; + // The pgid 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. + maybe_t parent_pgid{}; + // io_streams_t cannot be copied. io_streams_t(const io_streams_t &) = delete; void operator=(const io_streams_t &) = delete; diff --git a/tests/checks/pipeline-pgroup.fish b/tests/checks/pipeline-pgroup.fish index 3b59ce702..c6b0d7d30 100644 --- a/tests/checks/pipeline-pgroup.fish +++ b/tests/checks/pipeline-pgroup.fish @@ -37,3 +37,8 @@ end and echo "All pgroups agreed" or echo "Pgroups disagreed. Found $a0 $a1 $a2, and $b0 $b1 $b2" # CHECK: All pgroups agreed + +# Ensure that eval retains pgroups - #6806. +# Our regex will capture the first pgroup and use a positive lookahead on the second. +$fth print_pgrp | tr \n ' ' 1>&2 | eval '$fth print_pgrp' 1>&2 +# CHECKERR: {{(\d+) (?=\1)\d+}}