mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-28 13:53:10 +00:00
Make $pipestatus thread safe and other misc cleanup
This commit is contained in:
parent
2c8abdf5cb
commit
2c3214cabd
7 changed files with 24 additions and 33 deletions
10
src/env.cpp
10
src/env.cpp
|
@ -1392,13 +1392,13 @@ maybe_t<env_var_t> env_stack_t::get(const wcstring &key, env_mode_flags_t mode)
|
||||||
if (history) history->get_history(result);
|
if (history) history->get_history(result);
|
||||||
return env_var_t(L"history", result);
|
return env_var_t(L"history", result);
|
||||||
} else if (key == L"pipestatus") {
|
} else if (key == L"pipestatus") {
|
||||||
const auto& js = proc_get_last_job_statuses();
|
const auto js = proc_get_last_job_statuses();
|
||||||
wcstring_list_t result;
|
wcstring_list_t result;
|
||||||
result.reserve(js->size());
|
result.reserve(js.size());
|
||||||
for (auto&& i : *js) {
|
for (int i : js) {
|
||||||
result.emplace_back(to_string(i));
|
result.push_back(to_string(i));
|
||||||
}
|
}
|
||||||
return env_var_t(L"pipestatus", result);
|
return env_var_t(L"pipestatus", std::move(result));
|
||||||
} else if (key == L"status") {
|
} else if (key == L"status") {
|
||||||
return env_var_t(L"status", to_string(proc_get_last_status()));
|
return env_var_t(L"status", to_string(proc_get_last_status()));
|
||||||
} else if (key == L"umask") {
|
} else if (key == L"umask") {
|
||||||
|
|
|
@ -275,7 +275,7 @@ static void event_fire_internal(const event_t &event) {
|
||||||
// non-interactive.
|
// non-interactive.
|
||||||
proc_push_interactive(0);
|
proc_push_interactive(0);
|
||||||
int prev_status = proc_get_last_status();
|
int prev_status = proc_get_last_status();
|
||||||
const auto& saved_job_statuses = proc_get_last_job_statuses();
|
auto saved_job_statuses = proc_get_last_job_statuses();
|
||||||
parser_t &parser = parser_t::principal_parser();
|
parser_t &parser = parser_t::principal_parser();
|
||||||
|
|
||||||
event_block_t *b = parser.push_block<event_block_t>(event);
|
event_block_t *b = parser.push_block<event_block_t>(event);
|
||||||
|
|
|
@ -1066,7 +1066,7 @@ static int exec_subshell_internal(const wcstring &cmd, parser_t &parser, wcstrin
|
||||||
ASSERT_IS_MAIN_THREAD();
|
ASSERT_IS_MAIN_THREAD();
|
||||||
bool prev_subshell = is_subshell;
|
bool prev_subshell = is_subshell;
|
||||||
const int prev_status = proc_get_last_status();
|
const int prev_status = proc_get_last_status();
|
||||||
const auto& prev_job_statuses = proc_get_last_job_statuses();
|
auto prev_job_statuses = proc_get_last_job_statuses();
|
||||||
bool split_output = false;
|
bool split_output = false;
|
||||||
|
|
||||||
const auto ifs = parser.vars().get(L"IFS");
|
const auto ifs = parser.vars().get(L"IFS");
|
||||||
|
|
|
@ -367,7 +367,7 @@ static void input_mapping_execute(const input_mapping_t &m, bool allow_commands)
|
||||||
// FIXME(snnw): if commands add stuff to input queue (e.g. commandline -f execute), we won't
|
// FIXME(snnw): if commands add stuff to input queue (e.g. commandline -f execute), we won't
|
||||||
// see that until all other commands have also been run.
|
// see that until all other commands have also been run.
|
||||||
int last_status = proc_get_last_status();
|
int last_status = proc_get_last_status();
|
||||||
const auto& last_job_statuses = proc_get_last_job_statuses();
|
auto last_job_statuses = proc_get_last_job_statuses();
|
||||||
for (const wcstring &cmd : m.commands) {
|
for (const wcstring &cmd : m.commands) {
|
||||||
parser_t::principal_parser().eval(cmd, io_chain_t(), TOP);
|
parser_t::principal_parser().eval(cmd, io_chain_t(), TOP);
|
||||||
}
|
}
|
||||||
|
|
|
@ -717,8 +717,9 @@ parse_execution_result_t parse_execution_context_t::handle_command_not_found(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the last proc status appropriately.
|
// Set the last proc status appropriately.
|
||||||
proc_set_last_status(err_code == ENOENT ? STATUS_CMD_UNKNOWN : STATUS_NOT_EXECUTABLE);
|
int status = err_code == ENOENT ? STATUS_CMD_UNKNOWN : STATUS_NOT_EXECUTABLE;
|
||||||
proc_set_last_job_statuses(proc_get_last_status());
|
proc_set_last_status(status);
|
||||||
|
proc_set_last_job_statuses({status});
|
||||||
|
|
||||||
return parse_execution_errored;
|
return parse_execution_errored;
|
||||||
}
|
}
|
||||||
|
|
29
src/proc.cpp
29
src/proc.cpp
|
@ -54,7 +54,7 @@
|
||||||
static int last_status = 0;
|
static int last_status = 0;
|
||||||
|
|
||||||
/// Statuses of last job's processes to exit - ensure we start off with one entry of 0.
|
/// Statuses of last job's processes to exit - ensure we start off with one entry of 0.
|
||||||
static std::shared_ptr<std::vector<int>> last_job_statuses = std::make_shared<std::vector<int>>(1);
|
static owning_lock<std::vector<int>> last_job_statuses{std::vector<int>(1u, 0)};
|
||||||
|
|
||||||
/// The signals that signify crashes to us.
|
/// The signals that signify crashes to us.
|
||||||
static const int crashsignals[] = {SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGSYS};
|
static const int crashsignals[] = {SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGSYS};
|
||||||
|
@ -144,30 +144,21 @@ int proc_get_last_status() { return last_status; }
|
||||||
|
|
||||||
void proc_set_last_job_statuses(const job_t &last_job) {
|
void proc_set_last_job_statuses(const job_t &last_job) {
|
||||||
ASSERT_IS_MAIN_THREAD();
|
ASSERT_IS_MAIN_THREAD();
|
||||||
auto ljs = std::make_shared<std::vector<int>>();
|
std::vector<int> ljs;
|
||||||
ljs->reserve(last_job.processes.size());
|
ljs.reserve(last_job.processes.size());
|
||||||
for (auto &&p : last_job.processes) {
|
for (const auto &p : last_job.processes) {
|
||||||
ljs->emplace_back(p->pid ? proc_format_status(p->status) : p->status);
|
ljs.push_back(p->pid ? proc_format_status(p->status) : p->status);
|
||||||
}
|
}
|
||||||
last_job_statuses = std::move(ljs);
|
proc_set_last_job_statuses(std::move(ljs));
|
||||||
}
|
}
|
||||||
|
|
||||||
void proc_set_last_job_statuses(std::shared_ptr<std::vector<int>> job_statuses) {
|
void proc_set_last_job_statuses(std::vector<int> statuses) {
|
||||||
ASSERT_IS_MAIN_THREAD();
|
ASSERT_IS_MAIN_THREAD();
|
||||||
last_job_statuses = std::move(job_statuses);
|
auto vals = last_job_statuses.acquire();
|
||||||
|
*vals = std::move(statuses);
|
||||||
}
|
}
|
||||||
|
|
||||||
void proc_set_last_job_statuses(const int job_status) {
|
std::vector<int> proc_get_last_job_statuses() { return *last_job_statuses.acquire(); }
|
||||||
ASSERT_IS_MAIN_THREAD();
|
|
||||||
auto ljs = std::make_shared<std::vector<int>>(1);
|
|
||||||
(*ljs)[0] = job_status;
|
|
||||||
last_job_statuses = std::move(ljs);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<std::vector<int>> proc_get_last_job_statuses() {
|
|
||||||
ASSERT_IS_MAIN_THREAD();
|
|
||||||
return last_job_statuses;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Basic thread safe job IDs. The vector consumed_job_ids has a true value wherever the job ID
|
// Basic thread safe job IDs. The vector consumed_job_ids has a true value wherever the job ID
|
||||||
// corresponding to that slot is in use. The job ID corresponding to slot 0 is 1.
|
// corresponding to that slot is in use. The job ID corresponding to slot 0 is 1.
|
||||||
|
|
|
@ -418,11 +418,10 @@ int proc_get_last_status();
|
||||||
|
|
||||||
/// Sets the status of the last job's processes to exit from last_job.
|
/// Sets the status of the last job's processes to exit from last_job.
|
||||||
void proc_set_last_job_statuses(const job_t &last_job);
|
void proc_set_last_job_statuses(const job_t &last_job);
|
||||||
void proc_set_last_job_statuses(std::shared_ptr<std::vector<int>>);
|
void proc_set_last_job_statuses(std::vector<int> statuses);
|
||||||
void proc_set_last_job_statuses(const int); // for errors where pipe is unknown
|
|
||||||
|
|
||||||
/// Returns the status of the last job's processes to exit.
|
/// Returns the statuses of the last job's processes to exit.
|
||||||
std::shared_ptr<std::vector<int>> proc_get_last_job_statuses();
|
std::vector<int> proc_get_last_job_statuses();
|
||||||
|
|
||||||
/// Notify the user about stopped or terminated jobs. Delete terminated jobs from the job list.
|
/// Notify the user about stopped or terminated jobs. Delete terminated jobs from the job list.
|
||||||
///
|
///
|
||||||
|
|
Loading…
Reference in a new issue