Skip to content
This repository was archived by the owner on Jan 23, 2026. It is now read-only.

Commit b7284f2

Browse files
authored
Merge branch 'main' into doc-fixup
2 parents f34c657 + 563fac2 commit b7284f2

2 files changed

Lines changed: 604 additions & 528 deletions

File tree

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,64 @@
1-
import os
21
import sys
32
import termios
4-
import threading
53
import tty
4+
from contextlib import contextmanager
5+
6+
from anyio import create_task_group
7+
from anyio.streams.file import FileReadStream, FileWriteStream
68

79
from jumpstarter.client import DriverClient
810

911

12+
class ConsoleExit(Exception):
13+
pass
14+
15+
1016
class Console:
1117
def __init__(self, serial_client: DriverClient):
1218
self.serial_client = serial_client
1319

1420
def run(self):
15-
with self.serial_client.stream() as stream:
16-
self._run(stream)
21+
with self.setraw():
22+
self.serial_client.portal.call(self.__run)
1723

18-
def _run(self, stream):
19-
self._stream = stream
20-
self._old_settings = termios.tcgetattr(0)
24+
@contextmanager
25+
def setraw(self):
26+
original = termios.tcgetattr(sys.stdin.fileno())
2127
try:
2228
tty.setraw(sys.stdin.fileno())
23-
thread_serial_to_stdout = threading.Thread(target=self._copy_serial_to_stdout, daemon=True)
24-
thread_serial_to_stdout.start()
25-
ctrl_b_count = 0
26-
while True:
27-
data = sys.stdin.buffer.read(1)
28-
if not data:
29-
continue
30-
if data == b"\x02": # Ctrl-B
31-
ctrl_b_count += 1
32-
if ctrl_b_count == 3:
33-
return
34-
else:
35-
ctrl_b_count = 0
36-
stream.send(data)
29+
yield
3730
finally:
38-
self._reset_terminal()
31+
termios.tcsetattr(sys.stdin.fileno(), termios.TCSADRAIN, original)
32+
# Clear screen and move cursor to top-left (like \033c\033[2J\033[H).
33+
print("\033c\033[2J\033[H", end="")
3934

40-
def _reset_terminal(self):
41-
termios.tcsetattr(sys.stdin.fileno(), termios.TCSADRAIN, self._old_settings)
42-
# Clear screen and move cursor to top-left (like \033c\033[2J\033[H).
43-
print("\033c\033[2J\033[H", end="")
35+
async def __run(self):
36+
async with self.serial_client.stream_async(method="connect") as stream:
37+
try:
38+
async with create_task_group() as tg:
39+
tg.start_soon(self.__serial_to_stdout, stream)
40+
tg.start_soon(self.__stdin_to_serial, stream)
41+
except* ConsoleExit:
42+
pass
4443

45-
def _copy_serial_to_stdout(self):
46-
try:
47-
while True:
48-
data = self._stream.receive()
49-
os.write(sys.stdout.fileno(), data)
50-
sys.stdout.flush()
51-
finally:
52-
self._reset_terminal()
44+
async def __serial_to_stdout(self, stream):
45+
stdout = FileWriteStream(sys.stdout.buffer)
46+
while True:
47+
data = await stream.receive()
48+
await stdout.send(data)
49+
sys.stdout.flush()
50+
51+
async def __stdin_to_serial(self, stream):
52+
stdin = FileReadStream(sys.stdin.buffer)
53+
ctrl_b_count = 0
54+
while True:
55+
data = await stdin.receive(max_bytes=1)
56+
if not data:
57+
continue
58+
if data == b"\x02": # Ctrl-B
59+
ctrl_b_count += 1
60+
if ctrl_b_count == 3:
61+
raise ConsoleExit
62+
else:
63+
ctrl_b_count = 0
64+
await stream.send(data)

0 commit comments

Comments
 (0)