Commit ad8127a8 authored by Sébastien Luttringer's avatar Sébastien Luttringer
Browse files

Move FakeTtySocket into printer module

parent d07fca36
Loading
Loading
Loading
Loading
+1 −55
Original line number Diff line number Diff line
@@ -7,66 +7,12 @@ CloudControl Console related commands

from cccli.command import TqlCommand
from cccli.exception import *
from cccli.printer import FakeTtySocket
from sjrpc.core.exceptions import *
import fcntl
import os
import signal
import struct
import sys
import termios
import tty

class FakeTtySocket(object):
    '''
    Give a tty a socket interface

    This object cannot handle sigwinch directly because close
    can be called by remote RPC and by the way, called outside the main
    thread and fail.
    '''

    def __init__(self):
        if not os.isatty(0):
            raise cmdError("stdin is not tty")
        # flush stdin
        sys.stdin.flush()
        # save termios settings
        self._tc_attr = termios.tcgetattr(0)
        # set tty in raw mode
        tty.setraw(0)

    @staticmethod
    def recv(size):
        '''Emulate socket recv'''
        data =  os.read(0, size)
        if "\x1d" in data:
            # return empty sting to simulate an EOF instead of raise
            # and execption
            return ""
        return data

    @staticmethod
    def send(data):
        '''Emulate socket send'''
        return os.write(0, data)

    @staticmethod
    def fileno():
        '''Emulate socket fileno'''
        return 0

    @staticmethod
    def setblocking(*args):
        '''Emulate socket send'''
        # Do NOT be in non-blocking mode : non-blocking mode
        # causes rshell to get EAGAIN errors when having to
        # output loads of data, causing the TTY to break.
        return

    def close(self):
        '''Emulate socket close'''
        # reset tty original state
        termios.tcsetattr(0, termios.TCSADRAIN, self._tc_attr)


class Command_shell(TqlCommand):
+54 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ import struct
import subprocess
import sys
import termios
import tty

color = {
    # regular
@@ -299,3 +300,56 @@ class Completion(object):
        self.readline.set_completer(self._completer)
        self.readline.parse_and_bind("tab: complete")
        self.readline.set_completer_delims(" \t")


class FakeTtySocket(object):
    '''
    Give a tty a socket interface

    This object cannot handle sigwinch directly because close
    can be called by remote RPC and by the way, called outside the main
    thread and fail.
    '''

    def __init__(self):
        if not os.isatty(0):
            raise cmdError("stdin is not tty")
        # flush stdin
        sys.stdin.flush()
        # save termios settings
        self._tc_attr = termios.tcgetattr(0)
        # set tty in raw mode
        tty.setraw(0)

    @staticmethod
    def recv(size):
        '''Emulate socket recv'''
        data =  os.read(0, size)
        if "\x1d" in data:
            # return empty sting to simulate an EOF instead of raise
            # and execption
            return ""
        return data

    @staticmethod
    def send(data):
        '''Emulate socket send'''
        return os.write(0, data)

    @staticmethod
    def fileno():
        '''Emulate socket fileno'''
        return 0

    @staticmethod
    def setblocking(*args):
        '''Emulate socket send'''
        # Do NOT be in non-blocking mode : non-blocking mode
        # causes rshell to get EAGAIN errors when having to
        # output loads of data, causing the TTY to break.
        return

    def close(self):
        '''Emulate socket close'''
        # reset tty original state
        termios.tcsetattr(0, termios.TCSADRAIN, self._tc_attr)