add logging capability

This commit is contained in:
xenia 2021-05-20 00:14:53 -04:00
parent c760bf2fb3
commit fb64863bbe
2 changed files with 39 additions and 15 deletions

View File

@ -49,6 +49,12 @@ CTRL-A is the escape character. CTRL-A + Q quits megacom. CTRL-A + CTRL-A sends
there will be more keyboard shortcuts later, hopefully
### non-tty mode
megacom can be run even if stdin is not a tty. in this mode, keyboard shortcuts (CTRL-A) are
disabled and input is passed through verbatim. this can be useful to pipe input and output out of a
UART device with programs that are not tty-aware
### baud
any standard baud rate (as an integer) which is supported by pyserial can be used. usually you want

View File

@ -2,6 +2,8 @@ import argparse
import asyncio
import contextlib
import errno
import fcntl
import os
import re
import signal
import sys
@ -31,29 +33,39 @@ MODE_LOOKUP = {
class TtyRaw:
__slots__ = ["isatty", "fd", "settings"]
__slots__ = ["isatty", "infd", "outfd", "settings"]
isatty: bool
fd: int
infd: int
outfd: int
settings: List[Any]
def __init__(self) -> None:
self.isatty = False
self.fd = 0
self.infd = 0
self.outfd = 0
self.settings = []
def __enter__(self) -> None:
def __enter__(self) -> 'TtyRaw':
if sys.stdin.isatty():
self.isatty = True
self.fd = sys.stdin.fileno()
self.settings = termios.tcgetattr(self.fd)
tty.setraw(self.fd)
return None
self.infd = sys.stdin.fileno()
self.outfd = sys.stdout.fileno()
self.settings = termios.tcgetattr(self.infd)
tty.setraw(self.infd)
return self
def __exit__(self, exc_type: Optional[Type[BaseException]],
exc_value: Optional[BaseException],
exc_traceback: Optional[TracebackType]) -> Literal[False]:
if self.isatty:
termios.tcsetattr(self.fd, termios.TCSADRAIN, self.settings)
termios.tcsetattr(self.infd, termios.TCSADRAIN, self.settings)
# unset nonblocking modes
flags = fcntl.fcntl(self.infd, fcntl.F_GETFL)
flags = flags & (~os.O_NONBLOCK)
fcntl.fcntl(self.infd, fcntl.F_SETFL, flags)
flags = fcntl.fcntl(self.outfd, fcntl.F_GETFL)
flags = flags & (~os.O_NONBLOCK)
fcntl.fcntl(self.outfd, fcntl.F_SETFL, flags)
return False
@ -74,15 +86,21 @@ ESC_CHAR = b"\x01"
class KeycodeHandler:
__slots__ = ["exit_flag", "esc"]
__slots__ = ["exit_flag", "esc", "isatty"]
exit_flag: asyncio.Event
esc: bool
isatty: bool
def __init__(self) -> None:
def __init__(self, isatty: bool) -> None:
self.exit_flag = asyncio.Event()
self.esc = False
self.isatty = isatty
def process(self, byte: bytes) -> bytes:
# only translate or eat input if stdin is actually a tty
if not self.isatty:
return byte
if self.esc:
self.esc = False
if byte == b"q":
@ -104,7 +122,7 @@ class KeycodeHandler:
return byte
async def megacom(tty: str, baud: int, mode: str, logfile: Optional[str]) -> None:
async def megacom(ttyraw: TtyRaw, tty: str, baud: int, mode: str, logfile: Optional[str]) -> None:
(stdin, stdout) = await setup_async()
m = MODE_RE.match(mode)
@ -124,7 +142,7 @@ async def megacom(tty: str, baud: int, mode: str, logfile: Optional[str]) -> Non
sys.exit(1)
loop = asyncio.get_event_loop()
keycodes = KeycodeHandler()
keycodes = KeycodeHandler(ttyraw.isatty)
loop.add_signal_handler(signal.SIGINT, lambda: keycodes.exit_flag.set())
@ -268,6 +286,6 @@ def main() -> None:
parser.add_argument("-l", "--logfile", type=str, default="", help="file to log to")
args = parser.parse_args()
with TtyRaw():
asyncio.run(megacom(args.tty, args.baud, args.mode,
with TtyRaw() as ttyraw:
asyncio.run(megacom(ttyraw, args.tty, args.baud, args.mode,
args.logfile if args.logfile != "" else None))