mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-29 14:23:09 +00:00
bdd478bbd0
We sometimes leak ^[[I and ^[[O focus reporting events when run from VSCode's "Run python file" button in the top right corner. To reproduce I installed the ms-python extension set the VSCode default shell to fish and repeatedly ran a script that does "time.sleep(1)". I believe VSCode synthesizes keys and triggers a race condition. We can probably fix this but I'm not sure when I'll get to it (given how relatively unimportant this feature is). So let's go back to the old behavior of only enabling focus reporting in tmux. I believe that tmux is affected by the same VSCode issue (also on 3.7.1 I think) but I haven't been able to get tmux to emit focus reporting sequences yet. Still, keep it to not regress cursor shape (#4788). So far this is the only motivation for focus reporting and I believe it is only relevant for terminals that can split windows (though there are a bunch that do). Closes #10448
129 lines
3.6 KiB
Python
129 lines
3.6 KiB
Python
#!/usr/bin/env python3
|
|
from pexpect_helper import SpawnedProc
|
|
|
|
sp = SpawnedProc(timeout=10)
|
|
send, sendline, sleep, expect_prompt, expect_re, expect_str = (
|
|
sp.send,
|
|
sp.sendline,
|
|
sp.sleep,
|
|
sp.expect_prompt,
|
|
sp.expect_re,
|
|
sp.expect_str,
|
|
)
|
|
|
|
from time import sleep
|
|
import os
|
|
import platform
|
|
import signal
|
|
import subprocess
|
|
import sys
|
|
|
|
if "CI" in os.environ and platform.system() == "Darwin":
|
|
sys.exit(127)
|
|
|
|
if platform.system() == "FreeBSD": # Spurious failure. TODO Only disable this in CI.
|
|
sys.exit(127)
|
|
|
|
expect_prompt()
|
|
|
|
# Verify that SIGINT inside a command sub cancels it.
|
|
# Negate the pid to send to the pgroup (which should include sleep).
|
|
sendline("while true; echo (sleep 1000); end")
|
|
sleep(0.5)
|
|
os.kill(-sp.spawn.pid, signal.SIGINT)
|
|
expect_prompt()
|
|
|
|
sendline("sleep 10 &")
|
|
expect_prompt()
|
|
|
|
send("\x03")
|
|
sleep(0.010)
|
|
sendline("jobs")
|
|
expect_prompt("sleep.10")
|
|
sendline("kill %1")
|
|
expect_prompt()
|
|
|
|
# Verify that the fish_postexec handler is called after SIGINT.
|
|
sendline("function postexec --on-event fish_postexec; echo fish_postexec spotted; end")
|
|
expect_prompt()
|
|
sendline("read")
|
|
expect_re(r"\r\n?read> (\x1b\[\?1004h)?$")
|
|
sleep(0.200)
|
|
os.kill(sp.spawn.pid, signal.SIGINT)
|
|
expect_str("fish_postexec spotted")
|
|
expect_prompt()
|
|
|
|
# Verify that the fish_kill_signal is set.
|
|
sendline(
|
|
"functions -e postexec; function postexec --on-event fish_postexec; echo fish_kill_signal $fish_kill_signal; end"
|
|
)
|
|
expect_prompt()
|
|
sendline("sleep 5")
|
|
sleep(0.200)
|
|
subprocess.call(["pkill", "-INT", "-P", str(sp.spawn.pid), "sleep"])
|
|
expect_str("fish_kill_signal 2")
|
|
expect_prompt()
|
|
|
|
sendline("sleep 5")
|
|
sleep(0.200)
|
|
subprocess.call(["pkill", "-TERM", "-P", str(sp.spawn.pid), "sleep"])
|
|
expect_str("fish_kill_signal 15")
|
|
expect_prompt()
|
|
|
|
# See that open() is only interruptible by SIGINT.
|
|
sendline("mkfifo fifoo")
|
|
expect_prompt()
|
|
sendline("cat >fifoo")
|
|
subprocess.call(["kill", "-WINCH", str(sp.spawn.pid)])
|
|
expect_re("open: ", shouldfail=True, timeout=10)
|
|
subprocess.call(["kill", "-INT", str(sp.spawn.pid)])
|
|
expect_prompt()
|
|
|
|
# Verify that sending SIGHUP to the shell, such as will happen when the tty is
|
|
# closed by the terminal, terminates the shell and the foreground command and
|
|
# any background commands run from that shell.
|
|
#
|
|
# Save the pids for later to check if they are still running.
|
|
pids = []
|
|
send("sleep 130 & echo $last_pid\r")
|
|
pids += [expect_re("\\d+\r\n").group().strip()]
|
|
expect_prompt()
|
|
send("sleep 131 & echo $last_pid\r")
|
|
pids += [expect_re("\\d+\r\n").group().strip()]
|
|
expect_prompt()
|
|
send("sleep 9999999\r")
|
|
sleep(0.500) # ensure fish kicks off the above sleep before it gets HUP - see #7288
|
|
os.kill(sp.spawn.pid, signal.SIGHUP)
|
|
|
|
# Verify the spawned fish shell has exited.
|
|
sp.spawn.wait()
|
|
|
|
# Verify all child processes have been killed. We don't use `-p $pid` because
|
|
# if the shell has a bug the child processes might have been reparented to pid
|
|
# 1 rather than killed.
|
|
proc = subprocess.run(
|
|
["pgrep", "-l", "-f", "sleep 13"], stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
|
)
|
|
|
|
remaining = []
|
|
if proc.returncode == 0:
|
|
# If any sleeps exist, we check them against our pids,
|
|
# to avoid false-positives (any other `sleep 13xyz` running on the system)
|
|
print(proc.stdout)
|
|
for line in proc.stdout.split(b"\n"):
|
|
pid = line.split(b" ", maxsplit=1)[0].decode("utf-8")
|
|
if pid in pids:
|
|
remaining += [pid]
|
|
|
|
# Kill any remaining sleeps ourselves, otherwise rerunning this is pointless.
|
|
for pid in remaining:
|
|
try:
|
|
os.kill(int(pid), signal.SIGTERM)
|
|
except ProcessLookupError:
|
|
continue
|
|
|
|
if remaining:
|
|
# We still have processes left over!
|
|
print("Commands were still running!")
|
|
print(remaining)
|
|
sys.exit(1)
|