From 8a8b2513b5c4f917997a24ccce77c791783b94e6 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 4 May 2019 22:12:31 -0700 Subject: [PATCH] Eliminate the global jobs() function All job lists are attached to a parser now. --- src/builtin_bg.cpp | 7 ++--- src/builtin_disown.cpp | 2 +- src/builtin_fg.cpp | 6 ++--- src/builtin_jobs.cpp | 5 ++-- src/builtin_wait.cpp | 29 +++++++++++--------- src/exec.cpp | 2 +- src/fish.cpp | 1 - src/fish_tests.cpp | 2 -- src/parse_execution.cpp | 14 +++++----- src/parser.cpp | 10 +++---- src/parser.h | 5 ++-- src/proc.cpp | 60 ++++++++++++++--------------------------- src/proc.h | 21 ++++----------- src/reader.cpp | 21 +++++++-------- src/reader.h | 2 +- src/sanity.cpp | 6 ----- src/sanity.h | 3 --- 17 files changed, 79 insertions(+), 117 deletions(-) diff --git a/src/builtin_bg.cpp b/src/builtin_bg.cpp index f8ee41558..de5dce4b6 100644 --- a/src/builtin_bg.cpp +++ b/src/builtin_bg.cpp @@ -12,6 +12,7 @@ #include "common.h" #include "fallback.h" // IWYU pragma: keep #include "io.h" +#include "parser.h" #include "proc.h" #include "wutil.h" // IWYU pragma: keep @@ -28,9 +29,9 @@ static int send_to_bg(parser_t &parser, io_streams_t &streams, job_t *j) { streams.err.append_format(_(L"Send job %d '%ls' to background\n"), j->job_id, j->command_wcstr()); - j->promote(); + parser.job_promote(j); j->set_flag(job_flag_t::FOREGROUND, false); - j->continue_job(true, j->is_stopped()); + j->continue_job(parser, true, j->is_stopped()); return STATUS_CMD_OK; } @@ -52,7 +53,7 @@ int builtin_bg(parser_t &parser, io_streams_t &streams, wchar_t **argv) { if (optind == argc) { // No jobs were specified so use the most recent (i.e., last) job. job_t *job = nullptr; - for (const auto &j : jobs()) { + for (const auto &j : parser.jobs()) { if (j->is_stopped() && j->get_flag(job_flag_t::JOB_CONTROL) && (!j->is_completed())) { job = j.get(); break; diff --git a/src/builtin_disown.cpp b/src/builtin_disown.cpp index 09906a94c..622d1373f 100644 --- a/src/builtin_disown.cpp +++ b/src/builtin_disown.cpp @@ -61,7 +61,7 @@ int builtin_disown(parser_t &parser, io_streams_t &streams, wchar_t **argv) { // Foreground jobs can be disowned. // Even jobs that aren't under job control can be disowned! job_t *job = nullptr; - for (const auto &j : jobs()) { + for (const auto &j : parser.jobs()) { if (j->is_constructed() && (!j->is_completed())) { job = j.get(); break; diff --git a/src/builtin_fg.cpp b/src/builtin_fg.cpp index ad37f9c67..42c1bc4f1 100644 --- a/src/builtin_fg.cpp +++ b/src/builtin_fg.cpp @@ -38,7 +38,7 @@ int builtin_fg(parser_t &parser, io_streams_t &streams, wchar_t **argv) { // Select last constructed job (i.e. first job in the job queue) that can be brought // to the foreground. - for (const auto &j : jobs()) { + for (const auto &j : parser.jobs()) { if (j->is_constructed() && (!j->is_completed()) && ((j->is_stopped() || (!j->is_foreground())) && j->get_flag(job_flag_t::JOB_CONTROL))) { @@ -103,9 +103,9 @@ int builtin_fg(parser_t &parser, io_streams_t &streams, wchar_t **argv) { if (!ft.empty()) parser.vars().set_one(L"_", ENV_EXPORT, ft); reader_write_title(job->command(), parser); - job->promote(); + parser.job_promote(job); job->set_flag(job_flag_t::FOREGROUND, true); - job->continue_job(true, job->is_stopped()); + job->continue_job(parser, true, job->is_stopped()); return STATUS_CMD_OK; } diff --git a/src/builtin_jobs.cpp b/src/builtin_jobs.cpp index 2f5c264a0..905a7db8d 100644 --- a/src/builtin_jobs.cpp +++ b/src/builtin_jobs.cpp @@ -9,6 +9,7 @@ #include "common.h" #include "fallback.h" // IWYU pragma: keep #include "io.h" +#include "parser.h" #include "proc.h" #include "wgetopt.h" #include "wutil.h" // IWYU pragma: keep @@ -170,7 +171,7 @@ int builtin_jobs(parser_t &parser, io_streams_t &streams, wchar_t **argv) { if (print_last) { // Ignore unconstructed jobs, i.e. ourself. - for (const auto &j : jobs()) { + for (const auto &j : parser.jobs()) { if (j->is_visible()) { builtin_jobs_print(j.get(), mode, !streams.out_is_redirected, streams); return STATUS_CMD_ERROR; @@ -212,7 +213,7 @@ int builtin_jobs(parser_t &parser, io_streams_t &streams, wchar_t **argv) { } } } else { - for (const auto &j : jobs()) { + for (const auto &j : parser.jobs()) { // Ignore unconstructed jobs, i.e. ourself. if (j->is_visible()) { builtin_jobs_print(j.get(), mode, !found && !streams.out_is_redirected, diff --git a/src/builtin_wait.cpp b/src/builtin_wait.cpp index 5a2f9b291..74e1e08c2 100644 --- a/src/builtin_wait.cpp +++ b/src/builtin_wait.cpp @@ -5,6 +5,7 @@ #include "builtin.h" #include "builtin_wait.h" #include "common.h" +#include "parser.h" #include "proc.h" #include "reader.h" #include "wgetopt.h" @@ -15,8 +16,8 @@ /// Return the job id to which the process with pid belongs. /// If a specified process has already finished but the job hasn't, parser_t::job_get_from_pid() /// doesn't work properly, so use this function in wait command. -static job_id_t get_job_id_from_pid(pid_t pid) { - for (const auto &j : jobs()) { +static job_id_t get_job_id_from_pid(pid_t pid, const parser_t &parser) { + for (const auto &j : parser.jobs()) { if (j->pgid == pid) { return j->job_id; } @@ -30,8 +31,8 @@ static job_id_t get_job_id_from_pid(pid_t pid) { return 0; } -static bool all_jobs_finished() { - for (const auto &j : jobs()) { +static bool all_jobs_finished(const parser_t &parser) { + for (const auto &j : parser.jobs()) { // If any job is not completed, return false. // If there are stopped jobs, they are ignored. if (j->is_constructed() && !j->is_completed() && !j->is_stopped()) { @@ -41,14 +42,14 @@ static bool all_jobs_finished() { return true; } -static bool any_jobs_finished(size_t jobs_len) { +static bool any_jobs_finished(size_t jobs_len, const parser_t &parser) { bool no_jobs_running = true; // If any job is removed from list, return true. - if (jobs_len != jobs().size()) { + if (jobs_len != parser.jobs().size()) { return true; } - for (const auto &j : jobs()) { + for (const auto &j : parser.jobs()) { // If any job is completed, return true. if (j->is_constructed() && (j->is_completed() || j->is_stopped())) { return true; @@ -65,9 +66,10 @@ static bool any_jobs_finished(size_t jobs_len) { } static int wait_for_backgrounds(parser_t &parser, bool any_flag) { - size_t jobs_len = jobs().size(); + size_t jobs_len = parser.jobs().size(); - while ((!any_flag && !all_jobs_finished()) || (any_flag && !any_jobs_finished(jobs_len))) { + while ((!any_flag && !all_jobs_finished(parser)) || + (any_flag && !any_jobs_finished(jobs_len, parser))) { if (reader_test_interrupted()) { return 128 + SIGINT; } @@ -137,10 +139,11 @@ static bool match_pid(const wcstring &cmd, const wchar_t *proc) { } /// It should search the job list for something matching the given proc. -static bool find_job_by_name(const wchar_t *proc, std::vector &ids) { +static bool find_job_by_name(const wchar_t *proc, std::vector &ids, + const parser_t &parser) { bool found = false; - for (const auto &j : jobs()) { + for (const auto &j : parser.jobs()) { if (j->command_is_empty()) continue; if (match_pid(j->command(), proc)) { @@ -219,7 +222,7 @@ int builtin_wait(parser_t &parser, io_streams_t &streams, wchar_t **argv) { argv[i]); continue; } - if (job_id_t id = get_job_id_from_pid(pid)) { + if (job_id_t id = get_job_id_from_pid(pid, parser)) { waited_job_ids.push_back(id); } else { streams.err.append_format( @@ -227,7 +230,7 @@ int builtin_wait(parser_t &parser, io_streams_t &streams, wchar_t **argv) { } } else { // argument is process name - if (!find_job_by_name(argv[i], waited_job_ids)) { + if (!find_job_by_name(argv[i], waited_job_ids, parser)) { streams.err.append_format( _(L"%ls: Could not find child processes with the name '%ls'\n"), cmd, argv[i]); diff --git a/src/exec.cpp b/src/exec.cpp index f5d2003a0..3ab657338 100644 --- a/src/exec.cpp +++ b/src/exec.cpp @@ -1120,7 +1120,7 @@ bool exec_job(parser_t &parser, shared_ptr j) { return false; } - j->continue_job(reclaim_foreground_pgrp, false); + j->continue_job(parser, reclaim_foreground_pgrp, false); return true; } diff --git a/src/fish.cpp b/src/fish.cpp index 34d231cd0..7de13d2ad 100644 --- a/src/fish.cpp +++ b/src/fish.cpp @@ -491,7 +491,6 @@ int main(int argc, char **argv) { } history_save_all(); - proc_destroy(); if (opts.print_rusage_self) { print_rusage_self(stderr); } diff --git a/src/fish_tests.cpp b/src/fish_tests.cpp index 9f995b990..88e51d328 100644 --- a/src/fish_tests.cpp +++ b/src/fish_tests.cpp @@ -5327,8 +5327,6 @@ int main(int argc, char **argv) { say(L"Encountered %d errors in low-level tests", err_count); if (s_test_run_count == 0) say(L"*** No Tests Were Actually Run! ***"); - proc_destroy(); - if (err_count != 0) { return 1; } diff --git a/src/parse_execution.cpp b/src/parse_execution.cpp index acd7579fd..aed94c42f 100644 --- a/src/parse_execution.cpp +++ b/src/parse_execution.cpp @@ -797,7 +797,7 @@ parse_execution_result_t parse_execution_context_t::populate_plain_process( // Protect against exec with background processes running if (process_type == process_type_t::exec && shell_is_interactive()) { bool have_bg = false; - for (const auto &bg : jobs()) { + for (const auto &bg : parser->jobs()) { // The assumption here is that if it is a foreground job, // it's related to us. // This stops us from asking if we're doing `exec` inside a function. @@ -811,11 +811,11 @@ parse_execution_result_t parse_execution_context_t::populate_plain_process( uint64_t current_run_count = reader_run_count(); uint64_t &last_exec_run_count = parser->libdata().last_exec_run_counter; if (isatty(STDIN_FILENO) && current_run_count - 1 != last_exec_run_count) { - reader_bg_job_warning(); + reader_bg_job_warning(*parser); last_exec_run_count = current_run_count; return parse_execution_errored; } else { - hup_background_jobs(); + hup_background_jobs(*parser); } } } @@ -1142,10 +1142,10 @@ parse_execution_result_t parse_execution_context_t::populate_job_from_job_node( return result; } -static bool remove_job(job_t *job) { - for (auto j = jobs().begin(); j != jobs().end(); ++j) { +static bool remove_job(parser_t &parser, job_t *job) { + for (auto j = parser.jobs().begin(); j != parser.jobs().end(); ++j) { if (j->get() == job) { - jobs().erase(j); + parser.jobs().erase(j); return true; } } @@ -1276,7 +1276,7 @@ parse_execution_result_t parse_execution_context_t::run_1_job(tnode_t jo // Actually execute the job. if (!exec_job(*this->parser, job)) { - remove_job(job.get()); + remove_job(*this->parser, job.get()); } // Update universal vaiables on external conmmands. diff --git a/src/parser.cpp b/src/parser.cpp index c0c62f03f..ec3a0665b 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -571,24 +571,24 @@ wcstring parser_t::current_line() { void parser_t::job_add(shared_ptr job) { assert(job != NULL); assert(!job->processes.empty()); - this->my_job_list.push_front(std::move(job)); + job_list.push_front(std::move(job)); } void parser_t::job_promote(job_t *job) { job_list_t::iterator loc; - for (loc = my_job_list.begin(); loc != my_job_list.end(); ++loc) { + for (loc = job_list.begin(); loc != job_list.end(); ++loc) { if (loc->get() == job) { break; } } - assert(loc != my_job_list.end()); + assert(loc != job_list.end()); // Move the job to the beginning. - std::rotate(my_job_list.begin(), loc, my_job_list.end()); + std::rotate(job_list.begin(), loc, job_list.end()); } job_t *parser_t::job_get(job_id_t id) { - for (const auto &job : my_job_list) { + for (const auto &job : job_list) { if (id <= 0 || job->job_id == id) return job.get(); } return NULL; diff --git a/src/parser.h b/src/parser.h index 6554d1aa5..2fc425e34 100644 --- a/src/parser.h +++ b/src/parser.h @@ -172,7 +172,7 @@ class parser_t : public std::enable_shared_from_this { /// List of called functions, used to help prevent infinite recursion. wcstring_list_t forbidden_function; /// The jobs associated with this parser. - job_list_t my_job_list; + job_list_t job_list; /// The list of blocks std::vector> block_stack; /// The 'depth' of the fish call stack. @@ -274,7 +274,8 @@ class parser_t : public std::enable_shared_from_this { size_t block_count() const { return block_stack.size(); } /// Get the list of jobs. - job_list_t &job_list() { return my_job_list; } + job_list_t &jobs() { return job_list; } + const job_list_t &jobs() const { return job_list; } /// Get the variables. env_stack_t &vars() { return variables; } diff --git a/src/proc.cpp b/src/proc.cpp index 997217ef4..7a615c5c4 100644 --- a/src/proc.cpp +++ b/src/proc.cpp @@ -55,16 +55,6 @@ static owning_lock last_statuses{statuses_t::just(0)}; /// The signals that signify crashes to us. static const int crashsignals[] = {SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGSYS}; -bool job_list_is_empty() { - ASSERT_IS_MAIN_THREAD(); - return parser_t::principal_parser().job_list().empty(); -} - -job_list_t &jobs() { - ASSERT_IS_MAIN_THREAD(); - return parser_t::principal_parser().job_list(); -} - bool is_interactive_session = false; bool is_subshell = false; bool is_block = false; @@ -96,18 +86,6 @@ static std::vector interactive_stack; void proc_init() { proc_push_interactive(0); } -void job_t::promote() { - ASSERT_IS_MAIN_THREAD(); - parser_t::principal_parser().job_promote(this); -} - -void proc_destroy() { - for (const auto &job : jobs()) { - debug(2, L"freeing leaked job %ls", job->command_wcstr()); - } - jobs().clear(); -} - void proc_set_last_statuses(statuses_t s) { ASSERT_IS_MAIN_THREAD(); *last_statuses.acquire() = std::move(s); @@ -332,7 +310,7 @@ void add_disowned_pgid(pid_t pgid) { /// See if any reapable processes have exited, and mark them accordingly. /// \param block_ok if no reapable processes have exited, block until one is (or until we receive a /// signal). -static void process_mark_finished_children(bool block_ok) { +static void process_mark_finished_children(parser_t &parser, bool block_ok) { ASSERT_IS_MAIN_THREAD(); // Get the exit and signal generations of all reapable processes. @@ -342,7 +320,7 @@ static void process_mark_finished_children(bool block_ok) { topic_set_t reaptopics{}; generation_list_t gens{}; gens.fill(invalid_generation); - for (const auto j : jobs()) { + for (const auto &j : parser.jobs()) { for (const auto &proc : j->processes) { if (auto mtopic = j->reap_topic_for_process(proc.get())) { topic_t topic = *mtopic; @@ -367,7 +345,7 @@ static void process_mark_finished_children(bool block_ok) { // We got some changes. Since we last checked we received SIGCHLD, and or HUP/INT. // Update the hup/int generations and reap any reapable processes. - for (const auto &j : jobs()) { + for (const auto &j : parser.jobs()) { for (const auto &proc : j->processes) { if (auto mtopic = j->reap_topic_for_process(proc.get())) { // Update the signal hup/int gen. @@ -575,15 +553,15 @@ static bool process_clean_after_marking(parser_t &parser, bool allow_interactive const bool interactive = allow_interactive && cur_term != NULL; // Remove all disowned jobs. - remove_disowned_jobs(jobs()); + remove_disowned_jobs(parser.jobs()); // Accumulate exit events into a new list, which we fire after the list manipulation is // complete. std::vector exit_events; // Print status messages for completed or stopped jobs. - const bool only_one_job = jobs().size() == 1; - for (const auto &j : jobs()) { + const bool only_one_job = parser.jobs().size() == 1; + for (const auto &j : parser.jobs()) { // Skip unconstructed jobs. if (!j->is_constructed()) { continue; @@ -625,7 +603,8 @@ static bool process_clean_after_marking(parser_t &parser, bool allow_interactive // Do this before calling out to user code in the event handler below, to ensure an event // handler doesn't remove jobs on our behalf. auto is_complete = [](const shared_ptr &j) { return j->is_completed(); }; - jobs().erase(std::remove_if(jobs().begin(), jobs().end(), is_complete), jobs().end()); + auto &jobs = parser.jobs(); + jobs.erase(std::remove_if(jobs.begin(), jobs.end(), is_complete), jobs.end()); // Post pending exit events. for (const auto &evt : exit_events) { @@ -641,7 +620,7 @@ static bool process_clean_after_marking(parser_t &parser, bool allow_interactive bool job_reap(parser_t &parser, bool allow_interactive) { ASSERT_IS_MAIN_THREAD(); - process_mark_finished_children(false); + process_mark_finished_children(parser, false); // Preserve the exit status. auto saved_statuses = proc_get_last_statuses(); @@ -693,8 +672,8 @@ unsigned long proc_get_jiffies(process_t *p) { } /// Update the CPU time for all jobs. -void proc_update_jiffies() { - for (const auto &job : jobs()) { +void proc_update_jiffies(parser_t &parser) { + for (const auto &job : parser.jobs()) { for (process_ptr_t &p : job->processes) { gettimeofday(&p->last_time, 0); p->last_jiffies = proc_get_jiffies(p.get()); @@ -858,9 +837,9 @@ return false; return true; } -void job_t::continue_job(bool reclaim_foreground_pgrp, bool send_sigcont) { +void job_t::continue_job(parser_t &parser, bool reclaim_foreground_pgrp, bool send_sigcont) { // Put job first in the job list. - promote(); + parser.job_promote(this); set_flag(job_flag_t::NOTIFIED, false); debug(4, L"%ls job %d, gid %d (%ls), %ls, %ls", send_sigcont ? L"Continue" : L"Start", job_id, @@ -909,7 +888,7 @@ void job_t::continue_job(bool reclaim_foreground_pgrp, bool send_sigcont) { if (is_foreground()) { // Wait for the status of our own job to change. while (!reader_exit_forced() && !is_stopped() && !is_completed()) { - process_mark_finished_children(true); + process_mark_finished_children(parser, true); } } } @@ -924,10 +903,10 @@ void job_t::continue_job(bool reclaim_foreground_pgrp, bool send_sigcont) { } } -void proc_sanity_check() { +void proc_sanity_check(const parser_t &parser) { const job_t *fg_job = NULL; - for (const auto &j : jobs()) { + for (const auto &j : parser.jobs()) { if (!j->is_constructed()) continue; // More than one foreground job? @@ -979,12 +958,13 @@ void proc_pop_interactive() { void proc_wait_any(parser_t &parser) { ASSERT_IS_MAIN_THREAD(); - process_mark_finished_children(true /* block_ok */); + process_mark_finished_children(parser, true /* block_ok */); process_clean_after_marking(parser, is_interactive); } -void hup_background_jobs() { - for (const auto &j : jobs()) { +void hup_background_jobs(const parser_t &parser) { + // TODO: we should probably hup all jobs across all parsers here. + for (const auto &j : parser.jobs()) { // Make sure we don't try to SIGHUP the calling builtin if (j->pgid == INVALID_PID || !j->get_flag(job_flag_t::JOB_CONTROL)) { continue; diff --git a/src/proc.h b/src/proc.h index e17131cfe..dd5275403 100644 --- a/src/proc.h +++ b/src/proc.h @@ -153,6 +153,7 @@ class internal_proc_t { /// /// If the process is of type process_type_t::function, argv is the argument vector, and argv[0] is /// the name of the shellscript function. +class parser_t; class process_t { private: null_terminated_array_t argv_array; @@ -406,7 +407,6 @@ class job_t { /// \return whether this job and its parent chain are fully constructed. bool job_chain_is_fully_constructed() const; - // (This function would just be called `continue` but that's obviously a reserved keyword) /// Resume a (possibly) stopped job. Puts job in the foreground. If cont is true, restore the /// saved terminal modes and send the process group a SIGCONT signal to wake it up before we /// block. @@ -414,10 +414,7 @@ class job_t { /// \param reclaim_foreground_pgrp whether, when the job finishes or stops, to reclaim the /// foreground pgrp (via tcsetpgrp). \param send_sigcont Whether SIGCONT should be sent to the /// job if it is in the foreground. - void continue_job(bool reclaim_foreground_pgrp, bool send_sigcont); - - /// Promotes the job to the front of the job list. - void promote(); + void continue_job(parser_t &parser, bool reclaim_foreground_pgrp, bool send_sigcont); /// Send the specified signal to all processes in this job. /// \return true on success, false on failure. @@ -459,11 +456,6 @@ extern int is_event; // List of jobs. typedef std::deque> job_list_t; -bool job_list_is_empty(void); - -/// A helper function to more easily access the job list -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. @@ -497,11 +489,11 @@ unsigned long proc_get_jiffies(process_t *p); /// Update process time usage for all processes by calling the proc_get_jiffies function for every /// process of every job. -void proc_update_jiffies(); +void proc_update_jiffies(parser_t &parser); /// Perform a set of simple sanity checks on the job list. This includes making sure that only one /// job is in the foreground, that every process is in a valid state, etc. -void proc_sanity_check(); +void proc_sanity_check(const parser_t &parser); /// Create a process/job exit event notification. event_t proc_create_event(const wchar_t *msg, event_type_t type, pid_t pid, int status); @@ -509,9 +501,6 @@ event_t proc_create_event(const wchar_t *msg, event_type_t type, pid_t pid, int /// Initializations. void proc_init(); -/// Clean up before exiting. -void proc_destroy(); - /// Set new value for is_interactive flag, saving previous value. If needed, update signal handlers. void proc_push_interactive(int value); @@ -528,7 +517,7 @@ void set_is_within_fish_initialization(bool flag); bool is_within_fish_initialization(); /// Terminate all background jobs -void hup_background_jobs(); +void hup_background_jobs(const parser_t &parser); /// Give ownership of the terminal to the specified job. /// diff --git a/src/reader.cpp b/src/reader.cpp index f03da5e81..21c1cc365 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -1972,7 +1972,7 @@ void reader_run_command(parser_t &parser, const wcstring &cmd) { parser.vars().set_one(L"_", ENV_GLOBAL, program_name); if (have_proc_stat) { - proc_update_jiffies(); + proc_update_jiffies(parser); } } @@ -2190,11 +2190,11 @@ void reader_import_history_if_necessary() { bool shell_is_exiting() { return should_exit(); } -void reader_bg_job_warning() { +void reader_bg_job_warning(const parser_t &parser) { std::fputws(_(L"There are still jobs active:\n"), stdout); std::fputws(_(L"\n PID Command\n"), stdout); - for (const auto &j : jobs()) { + for (const auto &j : parser.jobs()) { if (!j->is_completed()) { std::fwprintf(stdout, L"%6d %ls\n", j->processes[0]->pid, j->command_wcstr()); } @@ -2206,9 +2206,8 @@ void reader_bg_job_warning() { /// This function is called when the main loop notices that end_loop has been set while in /// interactive mode. It checks if it is ok to exit. -static void handle_end_loop() { +static void handle_end_loop(const parser_t &parser) { if (!reader_exit_forced()) { - const parser_t &parser = parser_t::principal_parser(); for (size_t i = 0; i < parser.block_count(); i++) { if (parser.block_at_index(i)->type() == BREAKPOINT) { // We're executing within a breakpoint so we do not want to terminate the shell and @@ -2218,7 +2217,7 @@ static void handle_end_loop() { } bool bg_jobs = false; - for (const auto &j : jobs()) { + for (const auto &j : parser.jobs()) { if (!j->is_completed()) { bg_jobs = true; break; @@ -2227,7 +2226,7 @@ static void handle_end_loop() { reader_data_t *data = current_data(); if (!data->prev_end_loop && bg_jobs) { - reader_bg_job_warning(); + reader_bg_job_warning(parser); reader_set_end_loop(false); data->prev_end_loop = 1; return; @@ -2235,7 +2234,7 @@ static void handle_end_loop() { } // Kill remaining jobs before exiting. - hup_background_jobs(); + hup_background_jobs(parser); } static bool selection_is_at_top() { @@ -2269,7 +2268,7 @@ static int read_i() { reader_data_t *data = current_data(); data->prev_end_loop = 0; - while (!shell_is_exiting() && (!sanity_check())) { + while (!shell_is_exiting()) { event_fire_generic(L"fish_prompt"); run_count++; @@ -2292,7 +2291,7 @@ static int read_i() { maybe_t tmp = reader_readline(0); if (shell_is_exiting()) { - handle_end_loop(); + handle_end_loop(parser); } else if (tmp) { const wcstring command = tmp.acquire(); data->update_buff_pos(&data->command_line, 0); @@ -2307,7 +2306,7 @@ static int read_i() { data->history->resolve_pending(); } if (shell_is_exiting()) { - handle_end_loop(); + handle_end_loop(parser); } else { data->prev_end_loop = 0; } diff --git a/src/reader.h b/src/reader.h index 59cbbbc68..445dc8880 100644 --- a/src/reader.h +++ b/src/reader.h @@ -232,7 +232,7 @@ wcstring completion_apply_to_command_line(const wcstring &val_str, complete_flag bool append_only); /// Print warning with list of backgrounded jobs -void reader_bg_job_warning(); +void reader_bg_job_warning(const parser_t &parser); /// Return the current interactive reads loop count. Useful for determining how many commands have /// been executed between invocations of code. diff --git a/src/sanity.cpp b/src/sanity.cpp index 4b173539f..804665151 100644 --- a/src/sanity.cpp +++ b/src/sanity.cpp @@ -20,12 +20,6 @@ void sanity_lose() { insane = true; } -bool sanity_check() { - if (!insane) reader_sanity_check(); - if (!insane) proc_sanity_check(); - return insane; -} - void validate_pointer(const void *ptr, const wchar_t *err, int null_ok) { // Test if the pointer data crosses a segment boundary. if ((0x00000003l & (intptr_t)ptr) != 0) { diff --git a/src/sanity.h b/src/sanity.h index 4c8c27b4e..202f0d9e2 100644 --- a/src/sanity.h +++ b/src/sanity.h @@ -5,9 +5,6 @@ /// Call this function to tell the program it is not in a sane state. void sanity_lose(); -/// Perform sanity checks, return 1 if program is in a sane state 0 otherwise. -bool sanity_check(); - /// Try and determine if ptr is a valid pointer. If not, loose sanity. /// /// \param ptr The pointer to validate