Thread pgroups into builtin_eval

Ensure that if eval is invoked as part of a pipeline, any jobs spawned
by eval will have the same pgroup as the parent job.

cherry-pick of 82f2d86718

Partially fixes #6806
This commit is contained in:
ridiculousfish 2020-04-25 17:11:36 -07:00
parent 2d3c914a9d
commit de180689e4
4 changed files with 13 additions and 1 deletions

View file

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

View file

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

View file

@ -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<pid_t> parent_pgid{};
// io_streams_t cannot be copied.
io_streams_t(const io_streams_t &) = delete;
void operator=(const io_streams_t &) = delete;

View file

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