Eliminate pgroup_provenance_t

Now that job trees are a single source of truth for a job's pgid, we no
longer need fancy logic around how the pgroup is assigned.
This commit is contained in:
ridiculousfish
2020-05-29 15:28:53 -07:00
parent f37a44db16
commit b119c4b3bb
6 changed files with 27 additions and 88 deletions

View File

@@ -52,35 +52,6 @@
/// Number of calls to fork() or posix_spawn().
static relaxed_atomic_t<int> s_fork_count{0};
pgroup_provenance_t get_pgroup_provenance(const shared_ptr<job_t> &j) {
bool first_proc_is_internal = j->processes.front()->is_internal();
bool has_internal = j->has_internal_proc();
bool has_external = j->has_external_proc();
assert(first_proc_is_internal ? has_internal : has_external);
if (j->job_tree->get_pgid().has_value()) {
// Our job tree already has a pgid.
return pgroup_provenance_t::lineage;
} else if (!j->wants_job_control()) {
// This job doesn't need job control, it can just live in the fish pgroup.
return pgroup_provenance_t::fish_itself;
} else if (has_external && !first_proc_is_internal) {
// The first process is external, it will own the pgroup.
return pgroup_provenance_t::first_external_proc;
} else if (has_external && first_proc_is_internal) {
// The terminal owner has to be the process which is permitted to read from stdin.
// This is the first process in the pipeline. When executing, a process in the job will
// claim the pgrp if it's not set; therefore set it according to the first process.
// Only do this if there's an external process - see #6011.
return pgroup_provenance_t::fish_itself;
} else {
assert(has_internal && !has_external && "Should be internal only");
// This job consists of only internal functions or builtins; we do not need to assign a
// pgroup (yet).
return pgroup_provenance_t::unassigned;
}
}
/// This function is executed by the child process created by a call to fork(). It should be called
/// after \c child_setup_process. It calls execve to replace the fish process image with the command
/// specified in \c p. It never returns. Called in a forked child! Do not allocate memory, etc.
@@ -204,11 +175,11 @@ static void internal_exec(env_stack_t &vars, job_t *j, const io_chain_t &block_i
/// If our pgroup assignment mode wants us to use the first external proc, then apply it here.
/// \returns the job's pgid, which should always be set to something valid after this call.
static pid_t maybe_assign_pgid_from_child(const std::shared_ptr<job_t> &j, pid_t child_pid) {
if (j->pgroup_provenance == pgroup_provenance_t::first_external_proc &&
!j->job_tree->get_pgid()) {
j->job_tree->set_pgid(child_pid);
auto &jt = j->job_tree;
if (jt->needs_pgid_assignment()) {
jt->set_pgid(child_pid);
}
return *j->job_tree->get_pgid();
return *jt->get_pgid();
}
/// Construct an internal process for the process p. In the background, write the data \p outdata to
@@ -951,26 +922,6 @@ bool exec_job(parser_t &parser, const shared_ptr<job_t> &j, const io_chain_t &bl
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);
// Perhaps we know our pgroup already.
switch (j->pgroup_provenance) {
case pgroup_provenance_t::lineage: {
break;
}
case pgroup_provenance_t::fish_itself:
// TODO: should not need this 'if' here. Rationalize this.
if (! j->job_tree->is_placeholder()) {
j->job_tree->set_pgid(pgrp);
}
break;
// The remaining cases are all deferred until later.
case pgroup_provenance_t::unassigned:
case pgroup_provenance_t::first_external_proc:
break;
}
const size_t stdout_read_limit = parser.libdata().read_limit;
// Get the list of all FDs so we can ensure our pipes do not conflict.