Skip to content

Commit

Permalink
Place fish --interactive in its own process group
Browse files Browse the repository at this point in the history
  • Loading branch information
MathieuDuponchelle authored and krobelus committed Dec 19, 2019
1 parent ec11bd4 commit 6e8aea6
Show file tree
Hide file tree
Showing 6 changed files with 17 additions and 11 deletions.
4 changes: 2 additions & 2 deletions src/fish.cpp
Expand Up @@ -396,7 +396,7 @@ static int fish_parse_opt(int argc, char **argv, fish_cmd_opts_t *opts) {
// command or file to execute and stdin is a tty. Note that the -i or
// --interactive options also force interactive mode.
if (opts->batch_cmds.empty() && optind == argc && isatty(STDIN_FILENO)) {
set_interactive_session(true);
set_interactive_session(SESSION_INTERACTIVE);
}

return optind;
Expand Down Expand Up @@ -446,7 +446,7 @@ int main(int argc, char **argv) {
// Apply our options.
if (opts.is_login) mark_login();
if (opts.no_exec) mark_no_exec();
if (opts.is_interactive_session) set_interactive_session(true);
if (opts.is_interactive_session) set_interactive_session(SESSION_INTERACTIVE_EXPLICIT);

// Only save (and therefore restore) the fg process group if we are interactive. See issues
// #197 and #1002.
Expand Down
2 changes: 1 addition & 1 deletion src/fish_key_reader.cpp
Expand Up @@ -287,7 +287,7 @@ static void install_our_signal_handlers() {

/// Setup our environment (e.g., tty modes), process key strokes, then reset the environment.
static void setup_and_process_keys(bool continuous_mode) {
set_interactive_session(true); // by definition this program is interactive
set_interactive_session(SESSION_INTERACTIVE); // by definition this program is interactive
set_main_thread();
setup_fork_guards();
env_init();
Expand Down
4 changes: 2 additions & 2 deletions src/fish_tests.cpp
Expand Up @@ -1071,8 +1071,8 @@ static void test_cancellation() {
// Test for #3780
// Ugly hack - temporarily set is_interactive_session
// else we will SIGINT ourselves in response to our child death
bool iis = is_interactive_session();
set_interactive_session(true);
session_interactivity_t iis = is_interactive_session();
set_interactive_session(SESSION_INTERACTIVE);
const wchar_t *child_self_destructor = L"while true ; sh -c 'sleep .25; kill -s INT $$' ; end";
parser_t::principal_parser().eval(child_self_destructor, io_chain_t(), TOP);
set_interactive_session(iis);
Expand Down
6 changes: 3 additions & 3 deletions src/proc.cpp
Expand Up @@ -54,9 +54,9 @@
/// The signals that signify crashes to us.
static const int crashsignals[] = {SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGSYS};

static relaxed_atomic_bool_t s_is_interactive_session{false};
bool is_interactive_session() { return s_is_interactive_session; }
void set_interactive_session(bool flag) { s_is_interactive_session = flag; }
static relaxed_atomic_t<session_interactivity_t> s_is_interactive_session{SESSION_NON_INTERACTIVE};
session_interactivity_t is_interactive_session() { return s_is_interactive_session; }
void set_interactive_session(session_interactivity_t flag) { s_is_interactive_session = flag; }

static relaxed_atomic_bool_t s_is_login{false};
bool get_login() { return s_is_login; }
Expand Down
9 changes: 7 additions & 2 deletions src/proc.h
Expand Up @@ -475,8 +475,13 @@ class job_t {
};

/// Whether this shell is attached to the keyboard at all.
bool is_interactive_session();
void set_interactive_session(bool flag);
enum session_interactivity_t {
SESSION_NON_INTERACTIVE,
SESSION_INTERACTIVE,
SESSION_INTERACTIVE_EXPLICIT
};
session_interactivity_t is_interactive_session();
void set_interactive_session(session_interactivity_t flag);

/// Whether we are a login shell.
bool get_login();
Expand Down
3 changes: 2 additions & 1 deletion src/reader.cpp
Expand Up @@ -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 || is_interactive_session() == SESSION_INTERACTIVE_EXPLICIT) {
shell_pgid = getpid();
if (setpgid(shell_pgid, shell_pgid) < 0) {
FLOG(error, _(L"Failed to assign shell to its own process group"));
Expand Down

0 comments on commit 6e8aea6

Please sign in to comment.