Place fish in its own process group when launched with -i

Fixes #5909
This commit is contained in:
Mathieu Duponchelle
2019-12-12 13:50:33 +01:00
committed by Johannes Altmanninger
parent c19407ab0f
commit 15c1b3ed4b
10 changed files with 30 additions and 23 deletions

View File

@@ -1734,7 +1734,7 @@ static void reader_interactive_init(parser_t &parser) {
owner = tcgetpgrp(STDIN_FILENO);
}
if (owner == -1 && errno == ENOTTY) {
if (!is_interactive_session()) {
if (session_interactivity() == session_interactivity_t::not_interactive) {
// It's OK if we're not able to take control of the terminal. We handle
// the fallout from this in a few other places.
break;
@@ -1772,7 +1772,8 @@ static void reader_interactive_init(parser_t &parser) {
// It shouldn't be necessary to place fish in its own process group and force control
// of the terminal, but that works around fish being started with an invalid pgroup,
// such as when launched via firejail (#5295)
if (shell_pgid == 0) {
// Also become the process group leader if flag -i/--interactive was given (#5909).
if (shell_pgid == 0 || session_interactivity() == session_interactivity_t::explicit_) {
shell_pgid = getpid();
if (setpgid(shell_pgid, shell_pgid) < 0) {
FLOG(error, _(L"Failed to assign shell to its own process group"));
@@ -3239,7 +3240,7 @@ maybe_t<wcstring> reader_data_t::readline(int nchars_or_0) {
// This check is required to work around certain issues with fish's approach to
// terminal control when launching interactive processes while in non-interactive
// mode. See #4178 for one such example.
if (err != ENOTTY || is_interactive_session()) {
if (err != ENOTTY || session_interactivity() != session_interactivity_t::not_interactive) {
wperror(L"tcsetattr");
}
}
@@ -3342,7 +3343,8 @@ maybe_t<wcstring> reader_data_t::readline(int nchars_or_0) {
if (!reader_exit_forced()) {
// The order of the two conditions below is important. Try to restore the mode
// in all cases, but only complain if interactive.
if (tcsetattr(0, TCSANOW, &old_modes) == -1 && is_interactive_session()) {
if (tcsetattr(0, TCSANOW, &old_modes) == -1 &&
session_interactivity() != session_interactivity_t::not_interactive) {
if (errno == EIO) redirect_tty_output();
wperror(L"tcsetattr"); // return to previous mode
}