diff --git a/src/builtin_status.cpp b/src/builtin_status.cpp index fe253ecfd..455df9fe5 100644 --- a/src/builtin_status.cpp +++ b/src/builtin_status.cpp @@ -309,6 +309,7 @@ int builtin_status(parser_t &parser, io_streams_t &streams, wchar_t **argv) { streams.out.append_format(_(L"This is not a login shell\n")); } + auto job_control_mode = get_job_control_mode(); streams.out.append_format( _(L"Job control: %ls\n"), job_control_mode == job_control_t::interactive @@ -335,7 +336,7 @@ int builtin_status(parser_t &parser, io_streams_t &streams, wchar_t **argv) { opts.new_job_control_mode = new_mode; } assert(opts.new_job_control_mode && "Should have a new mode"); - job_control_mode = *opts.new_job_control_mode; + set_job_control_mode(*opts.new_job_control_mode); break; } case STATUS_FEATURES: { @@ -407,17 +408,17 @@ int builtin_status(parser_t &parser, io_streams_t &streams, wchar_t **argv) { } case STATUS_IS_FULL_JOB_CTRL: { CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) - retval = job_control_mode != job_control_t::all; + retval = get_job_control_mode() != job_control_t::all; break; } case STATUS_IS_INTERACTIVE_JOB_CTRL: { CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) - retval = job_control_mode != job_control_t::interactive; + retval = get_job_control_mode() != job_control_t::interactive; break; } case STATUS_IS_NO_JOB_CTRL: { CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) - retval = job_control_mode != job_control_t::none; + retval = get_job_control_mode() != job_control_t::none; break; } case STATUS_STACK_TRACE: { diff --git a/src/parse_execution.cpp b/src/parse_execution.cpp index abdb53497..2a5c4ad72 100644 --- a/src/parse_execution.cpp +++ b/src/parse_execution.cpp @@ -1228,6 +1228,7 @@ parse_execution_result_t parse_execution_context_t::run_1_job(tnode_t jo shared_ptr job = std::make_shared(acquire_job_id(), block_io, parent_job); job->tmodes = tmodes; + auto job_control_mode = get_job_control_mode(); job->set_flag(job_flag_t::JOB_CONTROL, (job_control_mode == job_control_t::all) || ((job_control_mode == job_control_t::interactive) && shell_is_interactive())); diff --git a/src/proc.cpp b/src/proc.cpp index c3f3b8492..238df7b76 100644 --- a/src/proc.cpp +++ b/src/proc.cpp @@ -38,6 +38,7 @@ #include "common.h" #include "event.h" #include "fallback.h" // IWYU pragma: keep +#include "global_safety.h" #include "io.h" #include "output.h" #include "parse_tree.h" @@ -70,10 +71,15 @@ bool is_block = false; bool is_breakpoint = false; bool is_login = false; int is_event = 0; -job_control_t job_control_mode = job_control_t::interactive; int no_exec = 0; bool have_proc_stat = false; +static relaxed_atomic_t job_control_mode{job_control_t::interactive}; + +job_control_t get_job_control_mode() { return job_control_mode; } + +void set_job_control_mode(job_control_t mode) { job_control_mode = mode; } + static int is_interactive = -1; bool shell_is_interactive() { diff --git a/src/proc.h b/src/proc.h index 573fd8aab..535f3db26 100644 --- a/src/proc.h +++ b/src/proc.h @@ -468,7 +468,8 @@ job_list_t &jobs(); /// The current job control mode. /// /// Must be one of job_control_t::all, job_control_t::interactive and job_control_t::none. -extern job_control_t job_control_mode; +job_control_t get_job_control_mode(); +void set_job_control_mode(job_control_t mode); /// If this flag is set, fish will never fork or run execve. It is used to put fish into a syntax /// verifier mode where fish tries to validate the syntax of a file but doesn't actually do