From aa37e4e3dabfe013a70316d49e723edb619b349e Mon Sep 17 00:00:00 2001 From: Aaron Heise Date: Thu, 16 Feb 2023 18:02:44 -0600 Subject: [PATCH] Added a polling tty function --- rnsh/process.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/rnsh/process.py b/rnsh/process.py index 0fe7d0d..7802501 100644 --- a/rnsh/process.py +++ b/rnsh/process.py @@ -108,6 +108,35 @@ def tty_read(fd: int) -> bytes: module_logger.error("tty_read error: {ex}") +def tty_read_poll(fd: int) -> bytes: + """ + Read available bytes from a tty file descriptor. When used in a callback added to a file descriptor using + tty_add_reader_callback(...), this function creates a solution for non-blocking reads from ttys. + :param fd: tty file descriptor + :return: bytes read + """ + if fd_is_closed(fd): + raise EOFError + + result = bytearray() + try: + flags = fcntl.fcntl(fd, fcntl.F_GETFL) + fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK) + try: + data = os.read(fd, 4096) + result.extend(data or []) + except OSError as e: + if e.errno != errno.EIO and e.errno != errno.EWOULDBLOCK: + raise + elif e.errno == errno.EIO: + raise EOFError + except EOFError: + raise + except Exception as ex: + module_logger.error("tty_read error: {ex}") + return result + + def fd_is_closed(fd: int) -> bool: """ Check if file descriptor is closed