mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
Ensure that on-process-exit events fire for reaped jobs
This ensures that if a job exits before we have set up the on-process-exit handler, the handler will still fire. Fixes #7210
This commit is contained in:
parent
60d75e9aa0
commit
6d00ad1045
5 changed files with 37 additions and 3 deletions
|
@ -45,7 +45,7 @@ Interactive improvements
|
|||
- Variable ``fish_killring`` containing entries from killring is now available (:issue:`7445`).
|
||||
- ``fish --private`` prints a note on private mode on startup even if ``$fish_greeting`` is an empty list (:issue:`7974`).
|
||||
- fish no longer attempts to lock history or universal variable files on remote filesystems, including NFS and SMB. In rare cases, updates to these files may be dropped if separate fish instances modify them simultaneously. (:issue:`7968`).
|
||||
- ``wait`` works correctly with jobs that have already exited (:issue:`7210`).
|
||||
- ``wait`` and ``on-process-exit`` work correctly with jobs that have already exited (:issue:`7210`).
|
||||
|
||||
New or improved bindings
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -264,12 +264,30 @@ maybe_t<int> builtin_function(parser_t &parser, io_streams_t &streams,
|
|||
// Add the function itself.
|
||||
function_add(function_name, opts.description, props, parser.libdata().current_filename);
|
||||
|
||||
// Handle wrap targets by creating the appropriate completions.
|
||||
for (const wcstring &wt : opts.wrap_targets) {
|
||||
complete_add_wrapper(function_name, wt);
|
||||
}
|
||||
|
||||
// Add any event handlers.
|
||||
for (const event_description_t &ed : opts.events) {
|
||||
event_add_handler(std::make_shared<event_handler_t>(ed, function_name));
|
||||
}
|
||||
|
||||
// Handle wrap targets by creating the appropriate completions.
|
||||
for (const wcstring &wt : opts.wrap_targets) complete_add_wrapper(function_name, wt);
|
||||
// If there is an --on-process-exit or --on-job-exit event handler for some pid, and that
|
||||
// process has already exited, run it immediately (#7210).
|
||||
for (const event_description_t &ed : opts.events) {
|
||||
if (ed.type == event_type_t::exit && ed.param1.pid != EVENT_ANY_PID) {
|
||||
wait_handle_ref_t wh = parser.get_wait_handles().get_by_pid(abs(ed.param1.pid));
|
||||
if (wh && wh->completed) {
|
||||
if (ed.param1.pid > 0) {
|
||||
event_fire(parser, event_t::process_exit(ed.param1.pid, wh->status));
|
||||
} else {
|
||||
event_fire(parser, event_t::job_exit(ed.param1.pid));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_CMD_OK;
|
||||
}
|
||||
|
|
|
@ -609,6 +609,7 @@ static void save_wait_handle_for_completed_job(const shared_ptr<job_t> &job,
|
|||
// Mark all wait handles as complete (but don't create just for this).
|
||||
for (auto &proc : job->processes) {
|
||||
if (wait_handle_ref_t wh = proc->get_wait_handle(false /* create */)) {
|
||||
wh->status = proc->status.status_value();
|
||||
wh->completed = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,9 @@ struct wait_handle_t {
|
|||
/// For example if the process is "/bin/sleep" then this will be 'sleep'.
|
||||
wcstring base_name{};
|
||||
|
||||
/// The value appropriate for populating $status, if completed.
|
||||
int status{0};
|
||||
|
||||
/// Set to true when the process is completed.
|
||||
bool completed{false};
|
||||
};
|
||||
|
|
|
@ -24,3 +24,15 @@ end
|
|||
wait true false
|
||||
jobs
|
||||
# CHECK: jobs: There are no jobs
|
||||
|
||||
# Ensure on-process-exit works for exited jobs.
|
||||
command false &
|
||||
set pid $last_pid
|
||||
|
||||
# Ensure it gets reaped
|
||||
sleep .1
|
||||
|
||||
function waiter --on-process-exit $pid
|
||||
echo exited $argv
|
||||
end
|
||||
# CHECK: exited PROCESS_EXIT {{\d+}} 1
|
||||
|
|
Loading…
Reference in a new issue