From 31cea814977c32b02bf9166cf4490f70e9861d1c Mon Sep 17 00:00:00 2001 From: Thomas Ballinger Date: Thu, 16 Oct 2014 21:36:20 -0400 Subject: Add Python 2 compatibility --- termcast_client/__init__.py | 6 +++++- termcast_client/pity.py | 9 ++++++--- termcast_client/py2compat.py | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 termcast_client/py2compat.py diff --git a/termcast_client/__init__.py b/termcast_client/__init__.py index 0bab15b..70d1798 100644 --- a/termcast_client/__init__.py +++ b/termcast_client/__init__.py @@ -9,6 +9,7 @@ import ssl import sys from . import pity +from . import py2compat class Client(object): def __init__(self, host, port, username, password, tls, fingerprint): @@ -76,7 +77,10 @@ class Client(object): return self._build_winsize_metadata_string() def _build_winsize_metadata_string(self): - size = shutil.get_terminal_size() + if py2compat.py2: + size = py2compat.get_terminal_size() + else: + size = shutil.get_terminal_size() return self._build_metadata_string({ "geometry": [ size.columns, size.lines ], }) diff --git a/termcast_client/pity.py b/termcast_client/pity.py index 26a9e49..966c793 100644 --- a/termcast_client/pity.py +++ b/termcast_client/pity.py @@ -1,3 +1,4 @@ +import errno import fcntl import os import pty @@ -5,6 +6,8 @@ import signal import termios import tty +from . import py2compat + CHILD = pty.CHILD STDIN_FILENO = pty.STDIN_FILENO STDOUT_FILENO = pty.STDOUT_FILENO @@ -68,9 +71,9 @@ def spawn(argv, master_read=pty._read, stdin_read=pty._read, handle_window_size= while True: try: pty._copy(master_fd, master_read, stdin_read) - except InterruptedError: - continue - except OSError: + except OSError as e: + if e.errno == errno.EINTR: + continue if restore: tty.tcsetattr(STDIN_FILENO, tty.TCSAFLUSH, mode) break diff --git a/termcast_client/py2compat.py b/termcast_client/py2compat.py new file mode 100644 index 0000000..16f2b34 --- /dev/null +++ b/termcast_client/py2compat.py @@ -0,0 +1,40 @@ +import fcntl +import os +import struct +import sys +import termios + +from collections import namedtuple + +terminal_size = namedtuple('terminal_size', ['columns', 'lines']) + +py2 = sys.version_info[0] == 2 + +def get_terminal_size(fallback=(80, 24)): + """Based on Python 3 os.get_terminal_size()""" + # columns, lines are the working values + try: + columns = int(os.environ['COLUMNS']) + except (KeyError, ValueError): + columns = 0 + + try: + lines = int(os.environ['LINES']) + except (KeyError, ValueError): + lines = 0 + + # only query if necessary + if columns <= 0 or lines <= 0: + try: + winsize = fcntl.ioctl(sys.__stdout__.fileno(), + termios.TIOCGWINSZ, '\000' * 8) + size = terminal_size(*struct.unpack('hhhh', winsize)[1::-1]) + + except (NameError, OSError): + size = terminal_size(*fallback) + if columns <= 0: + columns = size.columns + if lines <= 0: + lines = size.lines + + return terminal_size(*size) -- cgit v1.2.3