Be less aggressive about reclaiming the foreground pgrp

Prior to this fix, in every call to job_continue, fish would reclaim the
foreground pgrp. This would cause other jobs in the pipeline (which may
have another pgrp) to receive SIGTTIN / SIGTTOU.

Only reclaim the foreground pgrp if it was held at the point of job_continue.

This partially addresses #5765
This commit is contained in:
ridiculousfish 2019-04-06 20:00:52 -07:00
parent 23d88e0e03
commit 39a9740997
5 changed files with 12 additions and 7 deletions

View file

@ -30,7 +30,7 @@ static int send_to_bg(parser_t &parser, io_streams_t &streams, job_t *j) {
j->command_wcstr());
j->promote();
j->set_flag(job_flag_t::FOREGROUND, false);
j->continue_job(j->is_stopped());
j->continue_job(true, j->is_stopped());
return STATUS_CMD_OK;
}

View file

@ -106,6 +106,6 @@ int builtin_fg(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
job->promote();
job->set_flag(job_flag_t::FOREGROUND, true);
job->continue_job(job->is_stopped());
job->continue_job(true, job->is_stopped());
return STATUS_CMD_OK;
}

View file

@ -1021,6 +1021,9 @@ bool exec_job(parser_t &parser, shared_ptr<job_t> j) {
return true;
}
// Check to see if we should reclaim the foreground pgrp after the job finishes or stops.
const bool reclaim_foreground_pgrp = (tcgetpgrp(STDIN_FILENO) == getpgrp());
const std::shared_ptr<job_t> parent_job = j->get_parent();
// Perhaps inherit our parent's pgid and job control flag.
@ -1120,7 +1123,7 @@ bool exec_job(parser_t &parser, shared_ptr<job_t> j) {
return false;
}
j->continue_job(false);
j->continue_job(reclaim_foreground_pgrp, false);
return true;
}

View file

@ -827,7 +827,7 @@ return false;
return true;
}
void job_t::continue_job(bool send_sigcont) {
void job_t::continue_job(bool reclaim_foreground_pgrp, bool send_sigcont) {
// Put job first in the job list.
promote();
set_flag(job_flag_t::NOTIFIED, false);
@ -839,7 +839,7 @@ void job_t::continue_job(bool send_sigcont) {
// Make sure we retake control of the terminal before leaving this function.
bool term_transferred = false;
cleanup_t take_term_back([&]() {
if (term_transferred) {
if (term_transferred && reclaim_foreground_pgrp) {
terminal_return_from_job(this);
}
});

View file

@ -408,8 +408,10 @@ class job_t {
/// saved terminal modes and send the process group a SIGCONT signal to wake it up before we
/// block.
///
/// \param send_sigcont Whether SIGCONT should be sent to the job if it is in the foreground.
void continue_job(bool send_sigcont);
/// \param reclaim_foreground_pgrp whether, when the job finishes or stops, to reclaim the
/// foreground pgrp (via tcsetpgrp). \param send_sigcont Whether SIGCONT should be sent to the
/// job if it is in the foreground.
void continue_job(bool reclaim_foreground_pgrp, bool send_sigcont);
/// Promotes the job to the front of the job list.
void promote();