aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--termcast_client/__init__.py6
-rw-r--r--termcast_client/pity.py9
-rw-r--r--termcast_client/py2compat.py40
3 files changed, 51 insertions, 4 deletions
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)