diff --git a/src/fish.cpp b/src/fish.cpp index 68d81b60b..3db9d58f2 100644 --- a/src/fish.cpp +++ b/src/fish.cpp @@ -520,8 +520,6 @@ int main(int argc, char **argv) { int exit_status = res ? STATUS_CMD_UNKNOWN : parser.get_last_status(); - // TODO: The generic process-exit event is useless and unused. - // Remove this in future. event_fire(parser, proc_create_event(L"PROCESS_EXIT", event_type_t::exit, getpid(), exit_status)); diff --git a/src/parse_execution.cpp b/src/parse_execution.cpp index 94d3becc4..ce7e8bad5 100644 --- a/src/parse_execution.cpp +++ b/src/parse_execution.cpp @@ -1243,6 +1243,7 @@ parse_execution_result_t parse_execution_context_t::run_1_job(tnode_t jo props.wants_terminal = wants_job_control && !ld.is_event; props.skip_notification = ld.is_subshell || ld.is_block || ld.is_event || !shell_is_interactive(); + props.from_event_handler = ld.is_event; shared_ptr job = std::make_shared(acquire_job_id(), props, block_io, parent_job); job->tmodes = tmodes; diff --git a/src/proc.cpp b/src/proc.cpp index c28f357b4..87eb0bf72 100644 --- a/src/proc.cpp +++ b/src/proc.cpp @@ -472,9 +472,11 @@ static bool try_clean_process_in_job(process_t *p, job_t *j, std::vectorstatus; - // Add an exit event. - exit_events->push_back(proc_create_event(L"PROCESS_EXIT", event_type_t::exit, p->pid, - s.normal_exited() ? s.exit_code() : -1)); + // Add an exit event if the process did not come from a job handler. + if (!j->from_event_handler()) { + exit_events->push_back(proc_create_event(L"PROCESS_EXIT", event_type_t::exit, p->pid, + s.normal_exited() ? s.exit_code() : -1)); + } // Ignore SIGPIPE. We issue it ourselves to the pipe writer when the pipe reader dies. if (!s.signal_exited() || s.signal_code() == SIGPIPE) { @@ -600,8 +602,9 @@ static bool process_clean_after_marking(parser_t &parser, bool allow_interactive printed = true; } - // Prepare events for completed jobs. - if (j->is_completed()) { + // Prepare events for completed jobs, except for jobs that themselves came from event + // handlers. + if (!j->from_event_handler() && j->is_completed()) { if (j->pgid != INVALID_PID) { exit_events.push_back( proc_create_event(L"JOB_EXIT", event_type_t::exit, -j->pgid, 0)); diff --git a/src/proc.h b/src/proc.h index ad1290491..4b59440e2 100644 --- a/src/proc.h +++ b/src/proc.h @@ -296,6 +296,9 @@ class job_t { /// Whether the job wants to own the terminal when in the foreground. bool wants_terminal{}; + + /// Whether this job was created as part of an event handler. + bool from_event_handler{}; }; private: @@ -421,6 +424,7 @@ class job_t { return !is_completed() && is_constructed() && !get_flag(job_flag_t::DISOWN_REQUESTED); }; bool skip_notification() const { return properties.skip_notification; } + bool from_event_handler() const { return properties.from_event_handler; } /// \return the parent job, or nullptr. const std::shared_ptr get_parent() const { return parent_job; }