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();
|
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,
|
event_fire(parser,
|
||||||
proc_create_event(L"PROCESS_EXIT", event_type_t::exit, getpid(), exit_status));
|
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.wants_terminal = wants_job_control && !ld.is_event;
|
||||||
props.skip_notification =
|
props.skip_notification =
|
||||||
ld.is_subshell || ld.is_block || ld.is_event || !shell_is_interactive();
|
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);
|
shared_ptr<job_t> job = std::make_shared<job_t>(acquire_job_id(), props, block_io, parent_job);
|
||||||
job->tmodes = tmodes;
|
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;
|
auto s = p->status;
|
||||||
|
|
||||||
// Add an exit event.
|
// Add an exit event if the process did not come from a job handler.
|
||||||
exit_events->push_back(proc_create_event(L"PROCESS_EXIT", event_type_t::exit, p->pid,
|
if (!j->from_event_handler()) {
|
||||||
s.normal_exited() ? s.exit_code() : -1));
|
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.
|
// Ignore SIGPIPE. We issue it ourselves to the pipe writer when the pipe reader dies.
|
||||||
if (!s.signal_exited() || s.signal_code() == SIGPIPE) {
|
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;
|
printed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare events for completed jobs.
|
// Prepare events for completed jobs, except for jobs that themselves came from event
|
||||||
if (j->is_completed()) {
|
// handlers.
|
||||||
|
if (!j->from_event_handler() && j->is_completed()) {
|
||||||
if (j->pgid != INVALID_PID) {
|
if (j->pgid != INVALID_PID) {
|
||||||
exit_events.push_back(
|
exit_events.push_back(
|
||||||
proc_create_event(L"JOB_EXIT", event_type_t::exit, -j->pgid, 0));
|
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.
|
/// Whether the job wants to own the terminal when in the foreground.
|
||||||
bool wants_terminal{};
|
bool wants_terminal{};
|
||||||
|
|
||||||
|
/// Whether this job was created as part of an event handler.
|
||||||
|
bool from_event_handler{};
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -421,6 +424,7 @@ class job_t {
|
||||||
return !is_completed() && is_constructed() && !get_flag(job_flag_t::DISOWN_REQUESTED);
|
return !is_completed() && is_constructed() && !get_flag(job_flag_t::DISOWN_REQUESTED);
|
||||||
};
|
};
|
||||||
bool skip_notification() const { return properties.skip_notification; }
|
bool skip_notification() const { return properties.skip_notification; }
|
||||||
|
bool from_event_handler() const { return properties.from_event_handler; }
|
||||||
|
|
||||||
/// \return the parent job, or nullptr.
|
/// \return the parent job, or nullptr.
|
||||||
const std::shared_ptr<job_t> get_parent() const { return parent_job; }
|
const std::shared_ptr<job_t> get_parent() const { return parent_job; }
|
||||||
|
|
Loading…
Reference in a new issue