diff --git a/scrapli/transport/plugins/system/ptyprocess.py b/scrapli/transport/plugins/system/ptyprocess.py index 2b244174..d06e39ed 100644 --- a/scrapli/transport/plugins/system/ptyprocess.py +++ b/scrapli/transport/plugins/system/ptyprocess.py @@ -34,6 +34,7 @@ from typing import List, Optional, Type, TypeVar from scrapli.exceptions import ScrapliValueError +from scrapli.helper import user_warning class PtyProcessError(Exception): @@ -176,6 +177,35 @@ def _setecho(fd: int, state: bool) -> None: raise +def _setonlcr(fd: int, state: bool) -> None: + import termios + + try: + attr = termios.tcgetattr(fd) + except termios.error as err: + if err.args[0] == errno.EINVAL: + raise OSError(err.args[0], "{}: {}.".format(err.args[1], errmsg)) + raise + + if state: + attr[1] = attr[1] | termios.ONLCR + else: + attr[1] = attr[1] & ~termios.ONLCR + + try: + termios.tcsetattr(fd, termios.TCSANOW, attr) + except OSError as err: + if err.args[0] == errno.EINVAL: + title = "Set ONLCR!" + message = ( + "_setonlcr() failed -- if you encounter this error please open an issue! unless you " + "are seeing this when using scrapli_netconf you can *probably* ignore this though!" + ) + + user_warning(title=title, message=message) + raise + + class PtyProcess: def __init__(self, pid: int, fd: int) -> None: """ @@ -355,6 +385,12 @@ def spawn( if err.args[0] not in (errno.EINVAL, errno.ENOTTY, errno.ENXIO): raise + # attrs = termios.tcgetattr(fd) + # attrs[1] &= ~termios.ONLCR + # termios.tcsetattr(fd, termios.TCSANOW, attrs) + + _setonlcr(fd, True) + return inst def __repr__(self) -> str: diff --git a/tests/unit/test_helper.py b/tests/unit/test_helper.py index bdc6b2c9..13759e83 100644 --- a/tests/unit/test_helper.py +++ b/tests/unit/test_helper.py @@ -267,8 +267,13 @@ def test_format_user_warning(): def test_format_user_warning_really_long_title(): terminal_width = get_terminal_size().columns - warning_string = format_user_warning(title=("blah" * 30), message="something") - assert warning_string.lstrip().startswith("*" * terminal_width) + title = "z" * (terminal_width - 5) + + warning_string = format_user_warning(title=title, message="something") + + assert warning_string.strip().startswith("*") + assert warning_string.strip().endswith("*") + assert title in warning_string def test_user_warning():