mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-13 05:28:49 +00:00
Fix infinite prompt loop if status message is printed in prompt
fish will print messages for some jobs when they exit abnormally, such as with SIGABRT. If a job exits abnormally inside the prompt, then (prior to this commit) fish would print the message and re-trigger the prompt, which could result in an infinite loop. This has existed for a very long time. Fix it by reaping jobs after running the prompt, and NOT triggering a redraw based on that reaping. We still print the message but the prompt is not executed. Add a test. Fixes #9796
This commit is contained in:
parent
c97b1a992c
commit
5c8b6adc2c
2 changed files with 35 additions and 0 deletions
|
@ -4204,6 +4204,11 @@ impl<'a> Reader<'a> {
|
||||||
// hack to work.
|
// hack to work.
|
||||||
reader_write_title(L!(""), zelf.parser, false);
|
reader_write_title(L!(""), zelf.parser, false);
|
||||||
|
|
||||||
|
// Reap jobs but do NOT trigger a repaint.
|
||||||
|
// This is to prevent infinite loops in case a job from the prompt triggers a repaint.
|
||||||
|
// See #9796.
|
||||||
|
job_reap(zelf.parser, true);
|
||||||
|
|
||||||
// Some prompt may have requested an exit (#8033).
|
// Some prompt may have requested an exit (#8033).
|
||||||
let exit_current_script = zelf.parser.libdata().exit_current_script;
|
let exit_current_script = zelf.parser.libdata().exit_current_script;
|
||||||
zelf.exit_loop_requested |= exit_current_script;
|
zelf.exit_loop_requested |= exit_current_script;
|
||||||
|
|
30
tests/pexpects/prompt_redraw_loop.py
Normal file
30
tests/pexpects/prompt_redraw_loop.py
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
from pexpect_helper import SpawnedProc
|
||||||
|
import re
|
||||||
|
|
||||||
|
sp = SpawnedProc()
|
||||||
|
send, sendline, sleep, expect_prompt, expect_re, expect_str = (
|
||||||
|
sp.send,
|
||||||
|
sp.sendline,
|
||||||
|
sp.sleep,
|
||||||
|
sp.expect_prompt,
|
||||||
|
sp.expect_re,
|
||||||
|
sp.expect_str,
|
||||||
|
)
|
||||||
|
expect_prompt()
|
||||||
|
|
||||||
|
# Regression test for 9796
|
||||||
|
# If a process in the prompt exits with a status that would cause a message to be printed,
|
||||||
|
# don't trigger another prompt execution which would result in an infinite loop.
|
||||||
|
sendline("sh -c 'kill -ABRT $$'")
|
||||||
|
expect_prompt(re.escape("fish: Job 1, 'sh -c 'kill -ABRT $$'' terminated by signal SIGABRT (Abort)"))
|
||||||
|
|
||||||
|
# Copy current prompt so we can reuse it.
|
||||||
|
sendline("functions --copy fish_prompt fish_prompt_orig")
|
||||||
|
expect_prompt()
|
||||||
|
|
||||||
|
sendline("function fish_prompt; sh -c 'kill -ABRT $$'; fish_prompt_orig; end")
|
||||||
|
expect_prompt(re.escape("fish: Job 1, 'sh -c 'kill -ABRT $$'' terminated by signal SIGABRT (Abort)"))
|
||||||
|
|
||||||
|
sendline("echo still alive!")
|
||||||
|
expect_prompt("still alive!")
|
Loading…
Reference in a new issue