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; child_spawned = true;
on_process_created(j, p->pid); on_process_created(j, p->pid);
//We explicitly don't call set_child_group() for spawned processes because that // 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 // 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 #if defined(__GLIBC__)
//See fish-shell/fish-shell#4778, blocked by Microsoft/WSL#2997 // Unfortunately, using posix_spawn() is not the panacea it would appear to be, glibc has
if (is_windows_subsystem_for_linux()) { // 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); set_child_group(j, p->pid);
} }
else { #else
//in do_fork, the pid of the child process is used as the group leader if j->pgid == 2 // 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 // 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: // so this is what we do instead of calling set_child_group:
if (j->pgid == -2) { if (j->pgid == -2) {
j->pgid = pid; j->pgid = pid;
}
} }
#endif
maybe_assign_terminal(j); maybe_assign_terminal(j);
} else } else