Switch wait command to use topics

Prior to this fix, the wait command used waitpid() directly. Switch it to
calling process_mark_finished_children() along with the rest of the job
machinery. This centralizes the waitpid call to a single location.
This commit is contained in:
ridiculousfish
2019-03-02 16:45:15 -08:00
parent dc27de8190
commit dac5d79059
5 changed files with 15 additions and 12 deletions

View File

@@ -6,6 +6,7 @@
#include "builtin_wait.h" #include "builtin_wait.h"
#include "common.h" #include "common.h"
#include "proc.h" #include "proc.h"
#include "reader.h"
#include "wgetopt.h" #include "wgetopt.h"
#include "wutil.h" #include "wutil.h"
@@ -73,10 +74,10 @@ static int wait_for_backgrounds(bool any_flag) {
size_t jobs_len = jobs.count(); size_t jobs_len = jobs.count();
while ((!any_flag && !all_jobs_finished()) || (any_flag && !any_jobs_finished(jobs_len))) { while ((!any_flag && !all_jobs_finished()) || (any_flag && !any_jobs_finished(jobs_len))) {
pid_t pid = proc_wait_any(); if (reader_test_interrupted()) {
if (pid == -1 && errno == EINTR) {
return 128 + SIGINT; return 128 + SIGINT;
} }
proc_wait_any();
} }
return 0; return 0;
} }
@@ -112,10 +113,10 @@ static bool any_specified_jobs_finished(const std::vector<job_id_t> &ids) {
static int wait_for_backgrounds_specified(const std::vector<job_id_t> &ids, bool any_flag) { static int wait_for_backgrounds_specified(const std::vector<job_id_t> &ids, bool any_flag) {
while ((!any_flag && !all_specified_jobs_finished(ids)) || while ((!any_flag && !all_specified_jobs_finished(ids)) ||
(any_flag && !any_specified_jobs_finished(ids))) { (any_flag && !any_specified_jobs_finished(ids))) {
pid_t pid = proc_wait_any(); if (reader_test_interrupted()) {
if (pid == -1 && errno == EINTR) {
return 128 + SIGINT; return 128 + SIGINT;
} }
proc_wait_any();
} }
return 0; return 0;
} }

View File

@@ -983,13 +983,10 @@ void proc_pop_interactive() {
if (is_interactive != old) signal_set_handlers(); if (is_interactive != old) signal_set_handlers();
} }
pid_t proc_wait_any() { void proc_wait_any() {
int pid_status; ASSERT_IS_MAIN_THREAD();
pid_t pid = waitpid(-1, &pid_status, WUNTRACED); process_mark_finished_children(true /* block_ok */);
if (pid == -1) return -1;
handle_child_status(pid, proc_status_t::from_waitpid(pid_status));
process_clean_after_marking(is_interactive); process_clean_after_marking(is_interactive);
return pid;
} }
void hup_background_jobs() { void hup_background_jobs() {

View File

@@ -542,8 +542,8 @@ void proc_push_interactive(int value);
/// Set is_interactive flag to the previous value. If needed, update signal handlers. /// Set is_interactive flag to the previous value. If needed, update signal handlers.
void proc_pop_interactive(); void proc_pop_interactive();
/// Wait for any process finishing. /// Wait for any process finishing, or receipt of a signal.
pid_t proc_wait_any(); void proc_wait_any();
/// Set and get whether we are in initialization. /// Set and get whether we are in initialization.
// Hackish. In order to correctly report the origin of code with no associated file, we need to // Hackish. In order to correctly report the origin of code with no associated file, we need to

View File

@@ -797,6 +797,8 @@ bool reader_data_t::expand_abbreviation_as_necessary(size_t cursor_backtrack) {
void reader_reset_interrupted() { interrupted = 0; } void reader_reset_interrupted() { interrupted = 0; }
bool reader_test_interrupted() { return interrupted != 0; }
bool reader_test_and_clear_interrupted() { bool reader_test_and_clear_interrupted() {
int res = interrupted; int res = interrupted;
if (res) { if (res) {

View File

@@ -121,6 +121,9 @@ size_t reader_get_cursor_pos();
/// selection, true otherwise. /// selection, true otherwise.
bool reader_get_selection(size_t *start, size_t *len); bool reader_get_selection(size_t *start, size_t *len);
/// Return the value of the interrupted flag, which is set by the sigint handler.
bool reader_test_interrupted();
/// Return the value of the interrupted flag, which is set by the sigint handler, and clear it if it /// Return the value of the interrupted flag, which is set by the sigint handler, and clear it if it
/// was set. /// was set.
bool reader_test_and_clear_interrupted(); bool reader_test_and_clear_interrupted();