diff --git a/src/env.h b/src/env.h index 96e94ac39..ecb528b57 100644 --- a/src/env.h +++ b/src/env.h @@ -309,7 +309,7 @@ class env_stack_t final : public environment_t { static env_stack_t &globals(); }; -extern bool g_use_posix_spawn; +bool get_use_posix_spawn(); extern bool term_has_xn; // does the terminal have the "eat_newline_glitch" diff --git a/src/env_dispatch.cpp b/src/env_dispatch.cpp index bfa845b75..21c846c0c 100644 --- a/src/env_dispatch.cpp +++ b/src/env_dispatch.cpp @@ -260,11 +260,18 @@ static void handle_curses_change(const environment_t &vars) { init_curses(vars); } +/// Whether to use posix_spawn when possible. +static relaxed_atomic_bool_t g_use_posix_spawn{false}; + +bool get_use_posix_spawn() { return g_use_posix_spawn; } + static void handle_fish_use_posix_spawn_change(const environment_t &vars) { - // note this defaults to true - auto use_posix_spawn = vars.get(L"fish_use_posix_spawn"); - g_use_posix_spawn = - use_posix_spawn.missing_or_empty() ? true : bool_from_string(use_posix_spawn->as_string()); + // Note if the variable is missing or empty, we default to true. + if (auto var = vars.get(L"fish_use_posix_spawn")) { + g_use_posix_spawn = var->empty() || bool_from_string(var->as_string()); + } else { + g_use_posix_spawn = true; + } } /// Allow the user to override the limit on how much data the `read` command will process. @@ -570,9 +577,6 @@ static void init_locale(const environment_t &vars) { /// Returns true if we think the terminal supports setting its title. bool term_supports_setting_title() { return can_set_term_title; } -/// Miscellaneous variables. -bool g_use_posix_spawn = false; - // Limit `read` to 100 MiB (bytes not wide chars) by default. This can be overridden by the // fish_read_limit variable. size_t read_byte_limit = 100 * 1024 * 1024; diff --git a/src/exec.cpp b/src/exec.cpp index 9a7172974..c4b123a70 100644 --- a/src/exec.cpp +++ b/src/exec.cpp @@ -207,6 +207,9 @@ bool is_thompson_shell_script(const char *path) { // we use fork(), we can call tcsetpgrp after the fork, before the exec, and avoid the race). static bool can_use_posix_spawn_for_job(const std::shared_ptr &job, const dup2_list_t &dup2s) { + // Is it globally disabled? + if (!get_use_posix_spawn()) return false; + // Hack - do not use posix_spawn if there are self-fd redirections. // For example if you were to write: // cmd 6< /dev/null @@ -545,8 +548,7 @@ static launch_result_t exec_external_command(parser_t &parser, const std::shared #if FISH_USE_POSIX_SPAWN // Prefer to use posix_spawn, since it's faster on some systems like OS X. - bool use_posix_spawn = g_use_posix_spawn && can_use_posix_spawn_for_job(j, dup2s); - if (use_posix_spawn) { + if (can_use_posix_spawn_for_job(j, dup2s)) { s_fork_count++; // spawn counts as a fork+exec posix_spawner_t spawner(j.get(), dup2s);