mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-15 06:24:01 +00:00
Improve support for job control in non-interactive scenarios
Avoid complaining about ENOTTY results from tcsetpgrp, and ensure we ignore SIGTTOU the first time job control is enabled.
This commit is contained in:
parent
9735a18add
commit
97c456a986
2 changed files with 31 additions and 4 deletions
17
src/proc.cpp
17
src/proc.cpp
|
@ -78,7 +78,19 @@ static relaxed_atomic_t<job_control_t> job_control_mode{job_control_t::interacti
|
||||||
|
|
||||||
job_control_t get_job_control_mode() { return job_control_mode; }
|
job_control_t get_job_control_mode() { return job_control_mode; }
|
||||||
|
|
||||||
void set_job_control_mode(job_control_t mode) { job_control_mode = mode; }
|
void set_job_control_mode(job_control_t mode) {
|
||||||
|
job_control_mode = mode;
|
||||||
|
|
||||||
|
// HACK: when fish (or any shell) launches a job with job control, it will put the job into its
|
||||||
|
// own pgroup and call tcsetpgrp() to allow that pgroup to own the terminal (making fish a
|
||||||
|
// background process). When the job finishes, fish will try to reclaim the terminal via
|
||||||
|
// tcsetpgrp(), but as fish is now a background process it will receive SIGTTOU and stop! Ensure
|
||||||
|
// that doesn't happen by ignoring SIGTTOU.
|
||||||
|
// Note that if we become interactive, we also ignore SIGTTOU.
|
||||||
|
if (mode == job_control_t::all) {
|
||||||
|
signal(SIGTTOU, SIG_IGN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void proc_init() { signal_set_handlers_once(false); }
|
void proc_init() { signal_set_handlers_once(false); }
|
||||||
|
|
||||||
|
@ -776,10 +788,11 @@ int terminal_maybe_give_to_job(const job_t *j, bool continuing_from_stopped) {
|
||||||
} else {
|
} else {
|
||||||
if (errno == ENOTTY) {
|
if (errno == ENOTTY) {
|
||||||
redirect_tty_output();
|
redirect_tty_output();
|
||||||
}
|
} else {
|
||||||
FLOGF(warning, _(L"Could not send job %d ('%ls') with pgid %d to foreground"),
|
FLOGF(warning, _(L"Could not send job %d ('%ls') with pgid %d to foreground"),
|
||||||
j->job_id(), j->command_wcstr(), j->pgid);
|
j->job_id(), j->command_wcstr(), j->pgid);
|
||||||
wperror(L"tcsetpgrp");
|
wperror(L"tcsetpgrp");
|
||||||
|
}
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
tests/checks/job-control-noninteractive.fish
Normal file
14
tests/checks/job-control-noninteractive.fish
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#RUN: env fth=%fish_test_helper %fish %s
|
||||||
|
|
||||||
|
# Ensure job control works in non-interactive environments.
|
||||||
|
|
||||||
|
status job-control full
|
||||||
|
/bin/echo hello
|
||||||
|
#CHECK: hello
|
||||||
|
|
||||||
|
$fth print_pgrp | read first
|
||||||
|
$fth print_pgrp | read second
|
||||||
|
test $first -ne $second
|
||||||
|
and echo "pgroups differed, meaning job control worked"
|
||||||
|
or echo "pgroups were the same, job control did not work"
|
||||||
|
#CHECK: pgroups differed, meaning job control worked
|
Loading…
Reference in a new issue