[F] Fix OSC timeout too short for ssh

This commit is contained in:
Azalea (on HyDEV-Daisy) 2022-10-23 02:51:34 -04:00
parent c00848fd79
commit 7171494e95
No known key found for this signature in database
GPG key ID: E289FAC0DA92DD2B

View file

@ -6,6 +6,7 @@ import signal
import sys import sys
import termios import termios
import tty import tty
from select import select
from .color_util import RGB, AnsiMode from .color_util import RGB, AnsiMode
@ -110,17 +111,27 @@ def unix_read_osc(seq: int) -> str:
t.write(f"\x1b]{seq};?\x1b\\") t.write(f"\x1b]{seq};?\x1b\\")
t.flush() t.flush()
# Since python's select.select is behaving differently than Unix.select, we can't use it to # stdin response timeout should be higher for ssh sessions
# monitor if input is available (https://stackoverflow.com/q/74160774/7346633). timeout = 0.05 if (os.environ.get('SSH_TTY') or os.environ.get('SSH_SESSION')) is None else 0.5
# My temporary solution is to set a timeout of 0.01s and read as much as possible until the timeout.
# Wait for input to appear
if not select([sys.stdin], [], [], timeout)[0]:
raise OSCException("No response received")
# Read until termination, or if it doesn't terminate, read until 1 second passes
def handler(signum, frame): def handler(signum, frame):
raise IOError() raise IOError()
signal.signal(signal.SIGALRM, handler) signal.signal(signal.SIGALRM, handler)
signal.setitimer(signal.ITIMER_REAL, 0.01, 0.0) signal.setitimer(signal.ITIMER_REAL, timeout, 1)
code = "" code = ""
try: try:
while 1: for _ in range(28):
code += sys.stdin.read(1) code += sys.stdin.read(1)
# Terminate with sequence terminator [\ or bell ^G
if code.endswith('\x1b\\') or code.endswith('\a'):
break
signal.alarm(0)
except IOError: except IOError:
pass pass
@ -134,7 +145,9 @@ def unix_read_osc(seq: int) -> str:
start = f"\x1b]{seq};" start = f"\x1b]{seq};"
if not code.startswith(start): if not code.startswith(start):
raise OSCException("Received response is not an OSC response") raise OSCException("Received response is not an OSC response")
code = code.lstrip(start).rstrip("\x1b\\")
# Strip starting code and termination code
code = code.lstrip(start).rstrip("\x1b\\").rstrip('\a')
return code return code