Iron out situation with setpgid() calls after posix_spawn()

Closes #4715. Ticks off a box in #4154.
This commit is contained in:
Mahmoud Al-Qudsi 2018-05-16 19:34:45 -05:00
parent 18a163dc24
commit 0dd2607cac

View file

@ -1083,22 +1083,27 @@ void exec_job(parser_t &parser, job_t *j) {
child_spawned = true;
on_process_created(j, p->pid);
//We explicitly don't call set_child_group() for spawned processes because that
//a) isn't necessary, and b) causes issues like fish-shell/fish-shell#4715
// We explicitly don't call set_child_group() for spawned processes because that
// a) isn't necessary, and b) causes issues like fish-shell/fish-shell#4715
//However, on WSL `posix_spawn` does not correctly set the pgroup for the child process
//See fish-shell/fish-shell#4778, blocked by Microsoft/WSL#2997
if (is_windows_subsystem_for_linux()) {
#if defined(__GLIBC__)
// Unfortunately, using posix_spawn() is not the panacea it would appear to be, glibc has
// a penchant for using fork() instead of vfork() when posix_spawn() is called, meaning that
// atomicity is not guaranteed and we can get here before the child group has been set.
// See discussion here: https://github.com/Microsoft/WSL/issues/2997
// And confirmation that this persists past glibc 2.24+ here:
// https://github.com/fish-shell/fish-shell/issues/4715
if (j->get_flag(JOB_CONTROL) && getpgid(p->pid) != j->pgid) {
set_child_group(j, p->pid);
}
else {
//in do_fork, the pid of the child process is used as the group leader if j->pgid == 2
//above, posix_spawn assigned the new group a pgid equal to its own id if j->pgid == 2
//so this is what we do instead of calling set_child_group:
if (j->pgid == -2) {
j->pgid = pid;
}
#else
// In do_fork, the pid of the child process is used as the group leader if j->pgid == 2
// above, posix_spawn assigned the new group a pgid equal to its own id if j->pgid == 2
// so this is what we do instead of calling set_child_group:
if (j->pgid == -2) {
j->pgid = pid;
}
#endif
maybe_assign_terminal(j);
} else