Don't wait for disowned pgids if they are special

If a job is disowned that, for some reason, has a pgid that is special
to waitpid, like 0 (process with pgid of the calling process), -1 (any
process), or our actual pgid, that would lead to us waiting for too
many processes when we later try to reap the disowned processes (to
stop zombies from appearing).

And that means we'd snag away the processes we actually do want to
wait for, which would end with us in a waiting loop.

This is tough to reproduce, the easiest I've found was

    fish -ic 'sleep 5 &; disown; set -g __fish_git_prompt_showupstream auto; __fish_git_prompt'

in a git repo.

What we do is to not allow special pgids in the disowned_pids list.
That means we might leave a zombie around (though we probably wait on
0 somewhere), but that's preferable to infinitely looping.

See #5426.
This commit is contained in:
Fabian Homborg 2018-12-30 16:04:57 +01:00
parent 1d80028e24
commit da44ee1d08

View file

@ -354,7 +354,12 @@ typedef unsigned int process_generation_count_t;
static std::vector<pid_t> s_disowned_pids;
void add_disowned_pgid(pid_t pgid) {
s_disowned_pids.push_back(pgid * -1);
// NEVER add our own pgid, or one of the special values,
// or waiting for it will
// snag other processes away.
if (pgid != getpgrp() && (pgid > 0 || pgid < -1)) {
s_disowned_pids.push_back(pgid * -1);
}
}
/// A static value tracking how many SIGCHLDs we have seen, which is used in a heurstic to