fix: reliably answer delayed DOS batch termination prompts
This commit is contained in:
+13
-12
@@ -235,11 +235,10 @@ class Host:
|
|||||||
reported = started
|
reported = started
|
||||||
interrupt_at: float | None = None
|
interrupt_at: float | None = None
|
||||||
interrupted = ""
|
interrupted = ""
|
||||||
answered = False
|
|
||||||
|
|
||||||
def supervise() -> None:
|
def supervise() -> None:
|
||||||
"""Called every EXEC_POLL_SECONDS while the agent stays silent."""
|
"""Called every EXEC_POLL_SECONDS while the agent stays silent."""
|
||||||
nonlocal reported, interrupt_at, interrupted, answered
|
nonlocal reported, interrupt_at, interrupted
|
||||||
now = time.monotonic()
|
now = time.monotonic()
|
||||||
idle = self.guest_idle_seconds()
|
idle = self.guest_idle_seconds()
|
||||||
if now - reported >= 15:
|
if now - reported >= 15:
|
||||||
@@ -259,16 +258,18 @@ class Host:
|
|||||||
self.monitor("sendkey ctrl-c")
|
self.monitor("sendkey ctrl-c")
|
||||||
return
|
return
|
||||||
waited = now - interrupt_at
|
waited = now - interrupt_at
|
||||||
if not answered and waited > 4:
|
# DOS answers Ctrl+C with "Terminate batch file (Y/N/A)?" and
|
||||||
# COMMAND.COM asks "Terminate batch file (Y/N/A)?" for .BAT
|
# waits there. The prompt only appears once COMMAND.COM reaches
|
||||||
# targets and sits at that prompt until it is answered.
|
# the next batch line, which can be many seconds into a slow
|
||||||
answered = True
|
# command, so answer on every poll rather than once: a single
|
||||||
self.monitor("sendkey y")
|
# early 'y' is swallowed by whatever is still running. Send only
|
||||||
self.monitor("sendkey ret")
|
# 'y' -- the prompt takes one keystroke, and a trailing Enter
|
||||||
# Ctrl+C only lands at a DOS break check. With BREAK=OFF (the
|
# gets read as "keep going".
|
||||||
# FreeDOS default) a compute-bound child whose output we
|
self.monitor("sendkey y")
|
||||||
# redirected to a file may never reach one, so the command runs
|
# Even answered, Ctrl+C is a request. It lands only at a DOS
|
||||||
# to completion regardless. Keep collecting its result rather
|
# break check, and a DOS/4GW child (wcc386, wmake) runs in
|
||||||
|
# protected mode where it may never reach one, so the command
|
||||||
|
# can still run to completion. Keep collecting its result rather
|
||||||
# than abandoning a stream that still owes us one -- give up
|
# than abandoning a stream that still owes us one -- give up
|
||||||
# only once the guest has gone quiet too.
|
# only once the guest has gone quiet too.
|
||||||
if waited > INTERRUPT_GRACE_SECONDS and (idle is None or idle > 5):
|
if waited > INTERRUPT_GRACE_SECONDS and (idle is None or idle > 5):
|
||||||
|
|||||||
Reference in New Issue
Block a user