mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-29 06:13:20 +00:00
Don't generate exit events for jobs created from within event handlers
Add a new job property from_event_handler, and do not create exit events for such jobs. This prevents easy accidental infinite recursion.
This commit is contained in:
parent
d7a9bdf5c3
commit
f7e2e7d26b
4 changed files with 13 additions and 7 deletions
|
@ -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));
|
||||
|
||||
|
|
|
@ -1243,6 +1243,7 @@ parse_execution_result_t parse_execution_context_t::run_1_job(tnode_t<g::job> 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_t> job = std::make_shared<job_t>(acquire_job_id(), props, block_io, parent_job);
|
||||
job->tmodes = tmodes;
|
||||
|
|
13
src/proc.cpp
13
src/proc.cpp
|
@ -472,9 +472,11 @@ static bool try_clean_process_in_job(process_t *p, job_t *j, std::vector<event_t
|
|||
|
||||
auto s = p->status;
|
||||
|
||||
// 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));
|
||||
|
|
|
@ -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<job_t> get_parent() const { return parent_job; }
|
||||
|
|
Loading…
Reference in a new issue