def setup_tty_for_pty(func): """ Sets up tty for raw mode while retaining original tty settings and then starts the reactor to connect to the pty. Upon exiting pty, restores original tty settings. :param func: The callable to run after the tty is ready, such as ``reactor.run`` """ # Preserve original tty settings stdin_fileno = sys.stdin.fileno() old_ttyattr = tty.tcgetattr(stdin_fileno) try: # Enter raw mode on the local tty. tty.setraw(stdin_fileno) raw_ta = tty.tcgetattr(stdin_fileno) raw_ta[tty.LFLAG] |= tty.ISIG raw_ta[tty.OFLAG] |= tty.OPOST | tty.ONLCR # Pass ^C through so we can abort traceroute, etc. raw_ta[tty.CC][tty.VINTR] = '\x18' # ^X is the new ^C # Ctrl-Z is used by a lot of vendors to exit config mode raw_ta[tty.CC][tty.VSUSP] = 0 # disable ^Z tty.tcsetattr(stdin_fileno, tty.TCSANOW, raw_ta) # Execute our callable here func() finally: # Restore original tty settings tty.tcsetattr(stdin_fileno, tty.TCSANOW, old_ttyattr)
def setup(self): if tty: self.tcattr = tty.tcgetattr(sys.stdin.fileno()) tcattr = tty.tcgetattr(sys.stdin.fileno()) tcattr[0] = tcattr[0] & ~(tty.IXON) tty.tcsetattr(sys.stdin.fileno(), tty.TCSANOW, tcattr) self.w = curses.initscr() curses.cbreak() curses.noecho() try: curses.meta(1) except: pass self.cursor(0) signal.signal(signal.SIGCHLD, signal.SIG_IGN) signal.signal(signal.SIGHUP, self.handler_quit) signal.signal(signal.SIGINT, self.handler_quit) signal.signal(signal.SIGTERM, self.handler_quit) signal.signal(signal.SIGWINCH, self.handler_resize) self.win_root = RootWindow(None) self.win_root.update() self.win_status = self.win_root.win_status self.status = self.win_status.status self.win_podlist = self.win_root.win_tab.win_podlist self.timeout = Timeout()
def join_term(self): out('Successfully joined %s' % (self.room_url())) self.orig_stdout_atts = tty.tcgetattr(sys.stdout) stdout = sys.stdout.fileno() tty.setraw(stdout) fl = fcntl.fcntl(stdout, fcntl.F_GETFL) fcntl.fcntl(stdout, fcntl.F_SETFL, fl | os.O_NONBLOCK) self.orig_stdin_atts = tty.tcgetattr(sys.stdin) stdin = sys.stdin.fileno() tty.setraw(stdin) fl = fcntl.fcntl(stdin, fcntl.F_GETFL) fcntl.fcntl(stdin, fcntl.F_SETFL, fl | os.O_NONBLOCK) def ship_stdin(fd): data = read(fd) if data: self.transport("term_stdin", {'data': data, 'id': self.term_id}) if 'term_stdin' in self.ri['perms']: out('You have permission to write to this terminal. Remember: With great power comes great responsibility.') self.add_fd(stdin, reader=ship_stdin, name='join_term_stdin') else: out('You do not have permission to write to this terminal.') def stdout_write(buf): write(stdout, buf.encode('utf-8')) self.handle_stdio = stdout_write self._set_pty_size(self.ri['terms'][str(self.term_id)]['size'])
def pty(exeargv, ignoreeof=False, noecho=False, interactive=True, driver=None): if driver: debug("do_driver") do_driver(driver) interactive = sys.stdin.isatty() and interactive if interactive: ttyattr = tty.tcgetattr(0) # struct winsize 4 unsigned short. see ioctl_tty(2) winsize = fcntl.ioctl(0, tty.TIOCGWINSZ, 8 * b' ') debug("tty set to raw") tty.setraw(0) pid, fdm = os.forkpty() if pid == 0: # python's forkpty can't pass termios and winsize. do manually # see forkpty(3) if interactive: tty.tcsetattr(0, tty.TCSANOW, ttyattr) fcntl.ioctl(0, tty.TIOCSWINSZ, winsize) else: ttyattr = tty.tcgetattr(0) if noecho: ttyattr[3] = ttyattr[3] & ~tty.ECHO # lflags tty.tcsetattr(0, tty.TCSANOW, ttyattr) os.execvp(exeargv[0], exeargv) debug("do_loop") loop(fdm, ignoreeof) # only parent get here. restore tty if interactive: debug("tty set raw back") tty.tcsetattr(0, tty.TCSAFLUSH, ttyattr)
def _pty_setup(slave_echo): """Opens a pty pair. If current stdin is a tty, then applies current stdin's termios and winsize to the slave, sets current stdin to raw mode. Returns (master, slave, original stdin mode/None, stdin winsize/None).""" mode = None winsz = None try: mode = tty.tcgetattr(STDIN_FILENO) except tty.error: master_fd, slave_fd = openpty() _mode = tty.tcgetattr(slave_fd) tty.mode_echo(_mode, slave_echo) tty.tcsetattr(slave_fd, tty.TCSAFLUSH, _mode) else: if tty.HAVE_WINSZ: winsz = tty.getwinsize(STDIN_FILENO) _mode = list(mode) tty.mode_echo(_mode, slave_echo) master_fd, slave_fd = openpty(_mode, winsz) tty.mode_raw(_mode) tty.tcsetattr(STDIN_FILENO, tty.TCSAFLUSH, _mode) return master_fd, slave_fd, mode, winsz
def reset(): old = (tty.tcgetattr(sys.stdin.fileno()), tty.tcgetattr(sys.stdout.fileno()), tty.tcgetattr(sys.stderr.fileno())) import subprocess subprocess.call('reset') return old
def join_term(self): out('Successfully joined %s' % (self.workspace_url())) self.orig_stdout_atts = tty.tcgetattr(sys.stdout) stdout = sys.stdout.fileno() tty.setraw(stdout) fl = fcntl.fcntl(stdout, fcntl.F_GETFL) fcntl.fcntl(stdout, fcntl.F_SETFL, fl | os.O_NONBLOCK) self.orig_stdin_atts = tty.tcgetattr(sys.stdin) stdin = sys.stdin.fileno() tty.setraw(stdin) fl = fcntl.fcntl(stdin, fcntl.F_GETFL) fcntl.fcntl(stdin, fcntl.F_SETFL, fl | os.O_NONBLOCK) def ship_stdin(fd): data = read(fd) if data: self.transport( "term_stdin", { 'data': base64.b64encode(data).decode('utf8'), 'id': self.term_id }) if 'term_stdin' in self.ri['perms']: out('You have permission to write to this terminal. Remember: With great power comes great responsibility.' ) self.add_fd(stdin, reader=ship_stdin, name='join_term_stdin') else: out('You do not have permission to write to this terminal.') def stdout_write(buf): write(stdout, base64.b64decode(buf)) self.handle_stdio = stdout_write self._set_pty_size(self.ri['terms'][str(self.term_id)]['size'])
def expectedFailureIfStdinIsTTY(fun): # avoid isatty() try: tty.tcgetattr(pty.STDIN_FILENO) return unittest.expectedFailure(fun) except tty.error: pass return fun
def menu(self, title, names, top_info=(), cmds=None): attr = tty.tcgetattr(sys.stdin) try: self.cprint(TITLE, "==>", title) items = {} for i in top_info: self.cprint(b"34", " ", i) for c, (n, t) in letterify(names): print(" ", c, t) items[c] = n if cmds: mlen = max(len(mv) + len(k) for k, mv, name in cmds) + 1 for k, mv, name in cmds: print(" :{0:{1}} {2}".format(k + " " + mv, mlen, name)) tty.setcbreak(sys.stdin) ch = sys.stdin.read(1) if ch == ":": tty.tcsetattr(sys.stdin, tty.TCSADRAIN, attr) cmd = input(":") parts = cmd.strip().split(None, 1) if not parts: return None raise CommandExecute(*parts) elif ch in items: return items[ch] finally: tty.tcsetattr(sys.stdin, tty.TCSADRAIN, attr)
def spawn(argv, master_read=_read, stdin_read=_read, timeout=None, env=None): """Create a spawned process.""" if env is None: env = os.environ if isinstance(argv, str): argv = (argv, ) pid, master_fd = fork() if pid == CHILD: os.execvpe(argv[0], argv, env) if timeout is not None: timer = threading.Timer(timeout, _kill, args=(pid, signal.SIGKILL, master_fd)) timer.start() try: mode = tty.tcgetattr(STDIN_FILENO) tty.setraw(STDIN_FILENO) restore = 1 except tty.error: # This is the same as termios.error restore = 0 try: _copy(pid, master_fd, master_read, stdin_read) # print('copied!') except OSError: if restore: tty.tcsetattr(STDIN_FILENO, tty.TCSAFLUSH, mode) os.close(master_fd) if timeout is not None: timer.cancel() return os.waitpid(pid, 0)[1]
def _copy(master_fd, master_read=_read, stdin_read=_read, stdin_fd=STDIN_FILENO, stdout_fd=STDOUT_FILENO): """Parent copy loop. Copies pty master -> stdout_fd (master_read) stdin_fd -> pty master (stdin_read)""" try: mode = tty.tcgetattr(stdin_fd) tty.setraw(stdin_fd) restore = 1 except tty.error: # This is the same as termios.error restore = 0 try: while 1: rfds, wfds, xfds = select( [master_fd, stdin_fd], [], []) if master_fd in rfds: data = master_read(master_fd) os.write(stdout_fd, data) if stdin_fd in rfds: data = stdin_read(stdin_fd) _writen(master_fd, data) except (IOError, OSError, error): # The last entry is select.error if restore: tty.tcsetattr(stdin_fd, tty.TCSAFLUSH, mode) if stdin_fd > STDERR_FILENO: os.close(stdin_fd) if stdout_fd > STDERR_FILENO: os.close(stdout_fd)
def spawn(argv, master_read=pty._read, stdin_read=pty._read, handle_window_size=False): # copied from pty.py, with modifications # note that it references a few private functions - would be nice to not # do that, but you know if type(argv) == type(''): argv = (argv,) pid, master_fd, slave_name = fork(handle_window_size) if pid == CHILD: os.execlp(argv[0], *argv) try: mode = tty.tcgetattr(STDIN_FILENO) tty.setraw(STDIN_FILENO) restore = 1 except tty.error: # This is the same as termios.error restore = 0 if handle_window_size: signal.signal( signal.SIGWINCH, lambda signum, frame: _winch(slave_name, pid) ) while True: try: pty._copy(master_fd, master_read, stdin_read) except OSError as e: if e.errno == errno.EINTR: continue if restore: tty.tcsetattr(STDIN_FILENO, tty.TCSAFLUSH, mode) break os.close(master_fd) return os.waitpid(pid, 0)[1]
def ez_spawn(argv, master_read=_read, stdin_read=_read): """ To spawn the process. """ if type(argv) == str: argv = (argv, ) pid, master_fd = pty.fork() if pid == CHILD: # Fork worked, run the program os.execlp(argv[0], *argv) try: mode = tty.tcgetattr(STDIN_FILENO) tty.setraw(STDIN_FILENO) # disable line buffering # interrupt signals are no longer interpreted restore = 1 except tty.error: # Did not work, no need to restore. restore = 0 try: ez_copy(master_fd, "toto", master_read, stdin_read) except OSError: if restore: # Discard queued data and change mode to original tty.tcsetattr(STDIN_FILENO, tty.TCSAFLUSH, mode) os.close(master_fd) # wait for completion and return exit status return os.waitpid(pid, 0)[1]
def read_chr(): old_settings = tty.tcgetattr(sys.stdin.fileno()) tty.setraw(sys.stdin, tty.TCSANOW) chr = sys.stdin.read(1) tty.tcsetattr(sys.stdin.fileno(), tty.TCSADRAIN, old_settings) return chr
def __init__(self): self.fd = sys.stdin.fileno() self.old_settings = termios.tcgetattr(self.fd) tty.setraw(self.fd) mode = tty.tcgetattr(self.fd) mode[tty.OFLAG] = mode[tty.OFLAG] | tty.OPOST tty.tcsetattr(self.fd, tty.TCSAFLUSH, mode)
def enter(self): if self.in_raw_mode: return fd = sys.stdin.fileno() try: old = tty.tcgetattr(fd) new = old[:] self.saved_mode = old except: log.msg('not a typewriter!') self.saved_mode = None return # iflage new[0] = new[0] | tty.IGNPAR new[0] = new[0] & ~(tty.ISTRIP | tty.INLCR | tty.IGNCR | tty.ICRNL | tty.IXON | tty.IXANY | tty.IXOFF) if hasattr(tty, 'IUCLC'): new[0] = new[0] & ~tty.IUCLC # lflag new[3] = new[3] & ~(tty.ISIG | tty.ICANON | tty.ECHO | tty.ECHO | tty.ECHOE | tty.ECHOK | tty.ECHONL) if hasattr(tty, 'IEXTEN'): new[3] = new[3] & ~tty.IEXTEN #oflag new[1] = new[1] & ~tty.OPOST new[6][tty.VMIN] = 1 new[6][tty.VTIME] = 0 tty.tcsetattr(fd, tty.TCSANOW, new) self.in_raw_mode = True
def enter(self): if self.in_raw_mode: return fd = sys.stdin.fileno() try: old = tty.tcgetattr(fd) new = old[:] self.saved_mode = old except: log.msg('not a typewriter!') self.saved_mode = None return # iflage new[0] = new[0] | tty.IGNPAR new[0] = new[0] & ~(tty.ISTRIP|tty.INLCR|tty.IGNCR|tty.ICRNL | tty.IXON | tty.IXANY | tty.IXOFF) if hasattr(tty, 'IUCLC'): new[0] = new[0] & ~tty.IUCLC # lflag new[3] = new[3] & ~(tty.ISIG | tty.ICANON | tty.ECHO | tty.ECHO | tty.ECHOE | tty.ECHOK | tty.ECHONL) if hasattr(tty, 'IEXTEN'): new[3] = new[3] & ~tty.IEXTEN #oflag new[1] = new[1] & ~tty.OPOST new[6][tty.VMIN] = 1 new[6][tty.VTIME] = 0 tty.tcsetattr(fd, tty.TCSANOW, new) self.in_raw_mode = True
def _copy(master_fd, master_read=_read, stdin_read=_read, stdin_fd=STDIN_FILENO, stdout_fd=STDOUT_FILENO): """Parent copy loop. Copies pty master -> stdout_fd (master_read) stdin_fd -> pty master (stdin_read)""" try: mode = tty.tcgetattr(stdin_fd) tty.setraw(stdin_fd) restore = 1 except tty.error: # This is the same as termios.error restore = 0 try: while 1: rfds, wfds, xfds = select([master_fd, stdin_fd], [], []) if master_fd in rfds: data = master_read(master_fd) os.write(stdout_fd, data) if stdin_fd in rfds: data = stdin_read(stdin_fd) _writen(master_fd, data) except (IOError, OSError, error): # The last entry is select.error if restore: tty.tcsetattr(stdin_fd, tty.TCSAFLUSH, mode) if stdin_fd > STDERR_FILENO: os.close(stdin_fd) if stdout_fd > STDERR_FILENO: os.close(stdout_fd)
def pty_attached(cmd: str = "/bin/sh") -> int: """ Run a command in a pseudo terminal, while being attached to this terminal. """ exec_bin = "/bin/sh" exec_args = [exec_bin, "-c", cmd] master_read = pty._read stdin_read = pty._read pid, master_fd = pty.fork() if pid == pty.CHILD: log.d(f"os.execv({exec_bin}, {exec_args})") os.execv(exec_bin, exec_args) tty_mode = None try: tty_mode = tty.tcgetattr(pty.STDIN_FILENO) tty.setraw(pty.STDIN_FILENO) except tty.error: pass try: pty._copy(master_fd, master_read, stdin_read) except OSError: pass finally: if tty_mode: tty.tcsetattr(pty.STDIN_FILENO, tty.TCSAFLUSH, tty_mode) os.close(master_fd) (pid, retcode) = os.waitpid(pid, 0) return retcode
def _spawn(self): '''Create a spawned process. Based on pty.spawn() from standard library. ''' assert self.master_fd is None pid, self.master_fd = pty.fork() if pid == pty.CHILD: os.execlp(self.command[0], *self.command) old_handler = signal.signal(signal.SIGWINCH, self._signal_winch) try: mode = tty.tcgetattr(pty.STDIN_FILENO) tty.setraw(pty.STDIN_FILENO) restore = 1 except tty.error: # This is the same as termios.error restore = 0 self._set_pty_size() try: self._copy() except (IOError, OSError): if restore: tty.tcsetattr(pty.STDIN_FILENO, tty.TCSAFLUSH, mode) os.close(self.master_fd) self.master_fd = None signal.signal(signal.SIGWINCH, old_handler) return True
def spawn(argv, master_read=pty_read, stdin_read=pty_read): """Create a spawned process. Based on pty.spawn code.""" # TODO(larsbutler): This type check won't work with python3 # See http://packages.python.org/six/#six.string_types # for a possible solution. if isinstance(argv, (basestring)): argv = (argv,) pid, master_fd = pty.fork() if pid == pty.CHILD: os.execlp(argv[0], *argv) try: mode = tty.tcgetattr(pty.STDIN_FILENO) tty.setraw(pty.STDIN_FILENO) restore = 1 except tty.error: # This is the same as termios.error restore = 0 # get pseudo-terminal window size buf = array.array('h', [0, 0, 0, 0]) fcntl.ioctl(pty.STDOUT_FILENO, termios.TIOCGWINSZ, buf, True) # pass window size settings to forked one fcntl.ioctl(master_fd, termios.TIOCSWINSZ, buf) try: pty_copy(master_fd, master_read, stdin_read) except (IOError, OSError): if restore: tty.tcsetattr(pty.STDIN_FILENO, tty.TCSAFLUSH, mode) os.close(master_fd)
def posix_shell(chan,logfile): import select oldtty = termios.tcgetattr(sys.stdin) f=open(logfile,'w') try: mode = tty.tcgetattr(sys.stdin.fileno()) tty.setraw(sys.stdin.fileno()) tty.setcbreak(sys.stdin.fileno()) chan.settimeout(0.0) while True: r, w, e = select.select([chan, sys.stdin], [], []) if chan in r: try: x = chan.recv(1024) if len(x) == 0: sys.stdout.write('\r\n*** EOF\r\n') break sys.stdout.write(x) sys.stdout.flush() f.write(x) f.flush() except socket.timeout: pass if sys.stdin in r: #x = sys.stdin.read(1) x=os.read(sys.stdin.fileno(),1000) if len(x) == 0: break chan.send(x) finally: termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty) f.close()
def run(self): pid, self.master_fd = pty.fork() if pid == pty.CHILD: os.execlp(self.argv[0], *self.argv) old_handler = signal.signal(signal.SIGWINCH, lambda signum, frame: self._set_pty_size()) mode = tty.tcgetattr(pty.STDIN_FILENO) tty.setraw(pty.STDIN_FILENO) self._set_pty_size() try: self._process() except Exception: pass tty.tcsetattr(pty.STDIN_FILENO, tty.TCSAFLUSH, mode) os.close(self.master_fd) self.master_fd = None signal.signal(signal.SIGWINCH, old_handler) if self.server_address: # Make sure the socket does not already exist try: os.unlink(self.server_address) except OSError: pass
def pty_spawn(argv): """Version of pty.spawn() for PY2, that returns the exit code. This works around https://bugs.python.org/issue2489. """ logger.info("Using builtin pty.spawn()") import pty import tty if isinstance(argv, bytes): argv = (argv, ) pid, master_fd = pty.fork() if pid == pty.CHILD: os.execlp(argv[0], *argv) try: mode = tty.tcgetattr(pty.STDIN_FILENO) tty.setraw(pty.STDIN_FILENO) restore = 1 except tty.error: # This is the same as termios.error restore = 0 try: pty._copy(master_fd, pty._read, pty._read) except (IOError, OSError): if restore: tty.tcsetattr(pty.STDIN_FILENO, tty.TCSAFLUSH, mode) os.close(master_fd) return os.waitpid(pid, 0)[1]
def __init__(self, filename): SerialIO.__init__(self, filename) self.fd = os.open(filename, os.O_RDWR | os.O_NOCTTY | os.O_NONBLOCK) tty.setraw(self.fd) attr = tty.tcgetattr(self.fd) attr[tty.ISPEED] = attr[tty.OSPEED] = tty.B57600 tty.tcsetattr(self.fd, tty.TCSAFLUSH, attr)
def _spawn(shell, master_read): """Create a spawned process. Modified version of pty.spawn with terminal size support. """ pid, master_fd = pty.fork() if pid == pty.CHILD: os.execlp(shell, shell) try: mode = tty.tcgetattr(pty.STDIN_FILENO) tty.setraw(pty.STDIN_FILENO) restore = True except tty.error: # This is the same as termios.error restore = False _set_pty_size(master_fd) signal.signal(signal.SIGWINCH, lambda *_: _set_pty_size(master_fd)) try: pty._copy(master_fd, master_read, pty._read) except OSError: if restore: tty.tcsetattr(pty.STDIN_FILENO, tty.TCSAFLUSH, mode) os.close(master_fd) return os.waitpid(pid, 0)[1]
def pty_spawn(argv): """Version of pty.spawn() for PY2, that returns the exit code. This works around https://bugs.python.org/issue2489. """ logger.info("Using builtin pty.spawn()") import pty import tty if isinstance(argv, bytes): argv = (argv,) pid, master_fd = pty.fork() if pid == pty.CHILD: os.execlp(argv[0], *argv) try: mode = tty.tcgetattr(pty.STDIN_FILENO) tty.setraw(pty.STDIN_FILENO) restore = 1 except tty.error: # This is the same as termios.error restore = 0 try: pty._copy(master_fd, pty._read, pty._read) except (IOError, OSError): if restore: tty.tcsetattr(pty.STDIN_FILENO, tty.TCSAFLUSH, mode) os.close(master_fd) return os.waitpid(pid, 0)[1]
def spawn(argv, master_read=_read, stdin_read=_read): """Create a spawned process.""" if type(argv) == type(''): argv = (argv,) pid, master_fd = fork() if pid == CHILD: try: os.execlp(argv[0], *argv) except: # If we wanted to be really clever, we would use # the same method as subprocess() to pass the error # back to the parent. For now just dump stack trace. traceback.print_exc() finally: os._exit(1) try: mode = tty.tcgetattr(STDIN_FILENO) tty.setraw(STDIN_FILENO) restore = 1 except tty.error: # This is the same as termios.error restore = 0 try: _copy(master_fd, master_read, stdin_read) except OSError: # Some OSes never return an EOF on pty, just raise # an error instead. pass finally: if restore: tty.tcsetattr(STDIN_FILENO, tty.TCSAFLUSH, mode) os.close(master_fd) return os.waitpid(pid, 0)[1]
def _enterRawMode(): global _inRawMode, _savedRawMode if _inRawMode: return fd = sys.stdin.fileno() try: old = tty.tcgetattr(fd) new = old[:] except: log.msg('not a typewriter!') else: # iflage new[0] = new[0] | tty.IGNPAR new[0] = new[0] & ~(tty.ISTRIP | tty.INLCR | tty.IGNCR | tty.ICRNL | tty.IXON | tty.IXANY | tty.IXOFF) if hasattr(tty, 'IUCLC'): new[0] = new[0] & ~tty.IUCLC # lflag new[3] = new[3] & ~(tty.ISIG | tty.ICANON | tty.ECHO | tty.ECHO | tty.ECHOE | tty.ECHOK | tty.ECHONL) if hasattr(tty, 'IEXTEN'): new[3] = new[3] & ~tty.IEXTEN #oflag new[1] = new[1] & ~tty.OPOST new[6][tty.VMIN] = 1 new[6][tty.VTIME] = 0 _savedRawMode = old tty.tcsetattr(fd, tty.TCSANOW, new) #tty.setraw(fd) _inRawMode = 1
def setModes(self): pty = self.pty attr = tty.tcgetattr(pty.fileno()) for mode, modeValue in self.modes: if mode not in ttymodes.TTYMODES: continue ttyMode = ttymodes.TTYMODES[mode] if len(ttyMode) == 2: # Flag. flag, ttyAttr = ttyMode if not hasattr(tty, ttyAttr): continue ttyval = getattr(tty, ttyAttr) if modeValue: attr[flag] = attr[flag] | ttyval else: attr[flag] = attr[flag] & ~ttyval elif ttyMode == "OSPEED": attr[tty.OSPEED] = getattr(tty, "B%s" % (modeValue, )) elif ttyMode == "ISPEED": attr[tty.ISPEED] = getattr(tty, "B%s" % (modeValue, )) else: if not hasattr(tty, ttyMode): continue ttyval = getattr(tty, ttyMode) attr[tty.CC][ttyval] = bytes((modeValue, )) tty.tcsetattr(pty.fileno(), tty.TCSANOW, attr)
def posix_shell(chan, logfile): import select oldtty = termios.tcgetattr(sys.stdin) f = open(logfile, 'w') try: mode = tty.tcgetattr(sys.stdin.fileno()) tty.setraw(sys.stdin.fileno()) tty.setcbreak(sys.stdin.fileno()) chan.settimeout(0.0) while True: r, w, e = select.select([chan, sys.stdin], [], []) if chan in r: try: x = chan.recv(1024) if len(x) == 0: sys.stdout.write('\r\n*** EOF\r\n') break sys.stdout.write(x) sys.stdout.flush() f.write(x) f.flush() except socket.timeout: pass if sys.stdin in r: #x = sys.stdin.read(1) x = os.read(sys.stdin.fileno(), 1000) if len(x) == 0: break chan.send(x) finally: termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty) f.close()
def setModes(self): pty = self.pty attr = tty.tcgetattr(pty.fileno()) for mode, modeValue in self.modes: if mode not in ttymodes.TTYMODES: continue ttyMode = ttymodes.TTYMODES[mode] if len(ttyMode) == 2: # Flag. flag, ttyAttr = ttyMode if not hasattr(tty, ttyAttr): continue ttyval = getattr(tty, ttyAttr) if modeValue: attr[flag] = attr[flag] | ttyval else: attr[flag] = attr[flag] & ~ttyval elif ttyMode == 'OSPEED': attr[tty.OSPEED] = getattr(tty, 'B%s' % (modeValue,)) elif ttyMode == 'ISPEED': attr[tty.ISPEED] = getattr(tty, 'B%s' % (modeValue,)) else: if not hasattr(tty, ttyMode): continue ttyval = getattr(tty, ttyMode) attr[tty.CC][ttyval] = chr(modeValue) tty.tcsetattr(pty.fileno(), tty.TCSANOW, attr)
def spawn(self, argv=None): ''' Create a spawned process. Based on the code for pty.spawn(). ''' assert self.master_fd is None if not argv: argv = [os.environ['SHELL']] pid, master_fd = pty.fork() self.master_fd = master_fd if pid == pty.CHILD: os.execlp(argv[0], *argv) old_handler = signal.signal(signal.SIGWINCH, self._signal_winch) try: mode = tty.tcgetattr(pty.STDIN_FILENO) tty.setraw(pty.STDIN_FILENO) restore = 1 except tty.error: # This is the same as termios.error restore = 0 self._init_fd() try: self._copy() except (IOError, OSError): if restore: tty.tcsetattr(pty.STDIN_FILENO, tty.TCSAFLUSH, mode) os.close(master_fd) self.master_fd = None signal.signal(signal.SIGWINCH, old_handler)
def _init_tty(self): try: self.mode = tty.tcgetattr(pty.STDIN_FILENO) tty.setraw(pty.STDIN_FILENO ) # this seems to change the behavior of the stdout except tty.error: pass
def spawn(argv, master_read=pty._read, stdin_read=pty._read, handle_window_size=False): # copied from pty.py, with modifications # note that it references a few private functions - would be nice to not # do that, but you know if type(argv) == type(''): argv = (argv, ) pid, master_fd, slave_name = fork(handle_window_size) if pid == CHILD: os.execlp(argv[0], *argv) try: mode = tty.tcgetattr(STDIN_FILENO) tty.setraw(STDIN_FILENO) restore = 1 except tty.error: # This is the same as termios.error restore = 0 if handle_window_size: signal.signal(signal.SIGWINCH, lambda signum, frame: _winch(slave_name, pid)) while True: try: pty._copy(master_fd, master_read, stdin_read) except OSError as e: if e.errno == errno.EINTR: continue if restore: tty.tcsetattr(STDIN_FILENO, tty.TCSAFLUSH, mode) break os.close(master_fd) return os.waitpid(pid, 0)[1]
def spawn(argv, master_read=_read, stdin_read=_read): """Create a spawned process.""" if type(argv) == type(''): argv = (argv, ) pid, master_fd = fork() if pid == CHILD: try: os.execlp(argv[0], *argv) except: # If we wanted to be really clever, we would use # the same method as subprocess() to pass the error # back to the parent. For now just dump stack trace. traceback.print_exc() finally: os._exit(1) try: mode = tty.tcgetattr(STDIN_FILENO) tty.setraw(STDIN_FILENO) restore = 1 except tty.error: # This is the same as termios.error restore = 0 try: _copy(master_fd, master_read, stdin_read) except OSError: # Some OSes never return an EOF on pty, just raise # an error instead. pass finally: if restore: tty.tcsetattr(STDIN_FILENO, tty.TCSAFLUSH, mode) os.close(master_fd) return os.waitpid(pid, 0)[1]
def run(self): """Run the proxy, the entry point.""" old_handler = signal.signal(signal.SIGWINCH, lambda signum, frame: self._set_pty_size()) mode = tty.tcgetattr(pty.STDIN_FILENO) tty.setraw(pty.STDIN_FILENO) self._set_pty_size() try: self._process() except OSError as os_err: self.logger.exception("Exception") # Avoid printing I/O Error that happens on every GDB quit if os_err.errno != errno.EIO: raise except Exception: self.logger.exception("Exception") raise finally: tty.tcsetattr(pty.STDIN_FILENO, tty.TCSAFLUSH, mode) os.close(self.master_fd) self.master_fd = None signal.signal(signal.SIGWINCH, old_handler) if self.server_address: # Make sure the socket does not already exist try: os.unlink(self.server_address) except OSError: pass
def spawn(argv, master_read=_read, stdin_read=_read): """Create a spawned process.""" if type(argv) == type(''): argv = (argv, ) sys.audit('pty.spawn', argv) pid, master_fd = fork() if pid == CHILD: os.execlp(argv[0], *argv) try: mode = tcgetattr(STDIN_FILENO) setraw(STDIN_FILENO) restore = True except tty.error: # This is the same as termios.error restore = False try: _copy(master_fd, master_read, stdin_read) finally: if restore: tcsetattr(STDIN_FILENO, tty.TCSAFLUSH, mode) close(master_fd) return waitpid(pid, 0)[1]
def _connectSSHLocal(self, hostname, username, passwd): sshcmd = [self.ssh_bin, '%s@%s' % (username, hostname)] if self.ssh_extraopt: sshcmd += self.ssh_extraopt.split() self.addStringToClipboard(passwd) pid, self.remote_fd = pty.fork() if pid == pty.CHILD: os.execlp(sshcmd[0], *sshcmd) try: mode = tty.tcgetattr(pty.STDIN_FILENO) tty.setraw(pty.STDIN_FILENO) restore = True except tty.error: restore = False signal.signal(signal.SIGWINCH, self._winchHandler) self._setRemoteTTYSize(self.remote_fd) self._setTerminalTitle('%s@%s' % (username, hostname)) try: self._copySSHData(self.remote_fd, passwd) except (IOError, OSError): pass except: if restore: tty.tcsetattr(pty.STDIN_FILENO, tty.TCSAFLUSH, mode) raise if restore: tty.tcsetattr(pty.STDIN_FILENO, tty.TCSAFLUSH, mode) signal.signal(signal.SIGWINCH, signal.SIG_DFL) os.close(self.remote_fd)
def spawn(self, argv=None): ''' Create a spawned process. Based on the code for pty.spawn(). ''' assert self.master_fd is None if not argv: argv = [os.environ['SHELL']] pid, master_fd = pty.fork() self.master_fd = master_fd if pid == pty.CHILD: os.execlp(argv[0], *argv) old_handler = signal.signal(signal.SIGWINCH, self._signal_winch) try: mode = tty.tcgetattr(pty.STDIN_FILENO) tty.setraw(pty.STDIN_FILENO) restore = 1 except tty.error: # This is the same as termios.error restore = 0 self._init_fd() try: self._copy() except (IOError, OSError): if restore: tty.tcsetattr(pty.STDIN_FILENO, tty.TCSAFLUSH, mode) os.close(master_fd) self.master_fd = None signal.signal(signal.SIGWINCH, old_handler) self._set_pty_size()
def __enter__(self): try: self.mode = tty.tcgetattr(self.fd) tty.setraw(self.fd) self.restore = True except tty.error: # This is the same as termios.error pass
def spawn(argv, master_read=pty_read, stdin_read=pty_read): """Create a spawned process. Based on pty.spawn code.""" # TODO(larsbutler): This type check won't work with python3 # See http://packages.python.org/six/#six.string_types # for a possible solution. if isinstance(argv, (basestring)): argv = (argv, ) pid, master_fd = pty.fork() if pid == pty.CHILD: os.execlp(argv[0], *argv) try: mode = tty.tcgetattr(pty.STDIN_FILENO) tty.setraw(pty.STDIN_FILENO) restore = 1 except tty.error: # This is the same as termios.error restore = 0 # get pseudo-terminal window size buf = array.array('h', [0, 0, 0, 0]) fcntl.ioctl(pty.STDOUT_FILENO, termios.TIOCGWINSZ, buf, True) # pass window size settings to forked one fcntl.ioctl(master_fd, termios.TIOCSWINSZ, buf) try: pty_copy(master_fd, master_read, stdin_read) except (IOError, OSError): if restore: tty.tcsetattr(pty.STDIN_FILENO, tty.TCSAFLUSH, mode) os.close(master_fd)
def set_cbreak(fp=sys.stdin): old = None try: fileno = fp.fileno() old = tty.tcgetattr(fileno) tty.setcbreak(fileno) except: pass return old
def interact(self, escape_character=chr(29), input_filter=None, output_filter=None): '''This gives control of the child process to the interactive user (the human at the keyboard). Keystrokes are sent to the child process, and the stdout and stderr output of the child process is printed. This simply echos the child stdout and child stderr to the real stdout and it echos the real stdin to the child stdin. When the user types the escape_character this method will return None. The escape_character will not be transmitted. The default for escape_character is entered as ``Ctrl - ]``, the very same as BSD telnet. To prevent escaping, escape_character may be set to None. If a logfile is specified, then the data sent and received from the child process in interact mode is duplicated to the given log. You may pass in optional input and output filter functions. These functions should take bytes array and return bytes array too. Even with ``encoding='utf-8'`` support, meth:`interact` will always pass input_filter and output_filter bytes. You may need to wrap your function to decode and encode back to UTF-8. The output_filter will be passed all the output from the child process. The input_filter will be passed all the keyboard input from the user. The input_filter is run BEFORE the check for the escape_character. Note that if you change the window size of the parent the SIGWINCH signal will not be passed through to the child. If you want the child window size to change when the parent's window size changes then do something like the following example:: import pexpect, struct, fcntl, termios, signal, sys def sigwinch_passthrough (sig, data): s = struct.pack("HHHH", 0, 0, 0, 0) a = struct.unpack('hhhh', fcntl.ioctl(sys.stdout.fileno(), termios.TIOCGWINSZ , s)) if not p.closed: p.setwinsize(a[0],a[1]) # Note this 'p' is global and used in sigwinch_passthrough. p = pexpect.spawn('/bin/bash') signal.signal(signal.SIGWINCH, sigwinch_passthrough) p.interact() ''' # Flush the buffer. self.write_to_stdout(self.buffer) self.stdout.flush() self._buffer = self.buffer_type() mode = tty.tcgetattr(self.STDIN_FILENO) tty.setraw(self.STDIN_FILENO) if escape_character is not None and PY3: escape_character = escape_character.encode('latin-1') try: self.__interact_copy(escape_character, input_filter, output_filter) finally: tty.tcsetattr(self.STDIN_FILENO, tty.TCSAFLUSH, mode)
def _writeHack(self, data): """ Hack to send ignore messages when we aren't echoing. """ if self.pty is not None: attr = tty.tcgetattr(self.pty.fileno())[3] if not attr & tty.ECHO and attr & tty.ICANON: # No echo. self.avatar.conn.transport.sendIgnore('\x00'*(8+len(data))) self.oldWrite(data)
def run(): global options, old args = sys.argv[1:] if '-l' in args: # cvs is an idiot i = args.index('-l') args = args[i:i+2]+args del args[i+2:i+4] for arg in args[:]: try: i = args.index(arg) if arg[:2] == '-o' and args[i+1][0]!='-': args[i:i+2] = [] # suck on it scp except ValueError: pass options = ClientOptions() try: options.parseOptions(args) except usage.UsageError as u: print('ERROR: %s' % u) options.opt_help() sys.exit(1) if options['log']: if options['logfile']: if options['logfile'] == '-': f = sys.stdout else: f = file(options['logfile'], 'a+') else: f = sys.stderr realout = sys.stdout log.startLogging(f) sys.stdout = realout else: log.discardLogs() doConnect() fd = sys.stdin.fileno() try: old = tty.tcgetattr(fd) except: old = None try: oldUSR1 = signal.signal(signal.SIGUSR1, lambda *a: reactor.callLater(0, reConnect)) except: oldUSR1 = None try: reactor.run() finally: if old: tty.tcsetattr(fd, tty.TCSANOW, old) if oldUSR1: signal.signal(signal.SIGUSR1, oldUSR1) if (options['command'] and options['tty']) or not options['notty']: signal.signal(signal.SIGWINCH, signal.SIG_DFL) if sys.stdout.isatty() and not options['command']: print('Connection to %s closed.' % options['host']) sys.exit(exitStatus)
def mergePipeAndInteract(self, pipe): self.stdout.write (self.buffer) self.stdout.flush() self.buffer = '' mode = tty.tcgetattr(self.STDIN_FILENO) tty.setraw(self.STDIN_FILENO) try: self.__merge_copy(pipe) finally: tty.tcsetattr(self.STDIN_FILENO, tty.TCSAFLUSH, mode)
def __call__(self): tty, sys, select = self.mods fd = sys.stdin.fileno() old = tty.tcgetattr(fd) tty.setcbreak(fd, tty.TCSANOW) try: return sys.stdin.read(1) finally: tty.tcsetattr(fd, tty.TCSAFLUSH, old)
def __init__(self,infile): if not infile.isatty(): raise NotTTYException() self.file=infile #prepare for getch self.save_attr=tty.tcgetattr(self.file) newattr=self.save_attr[:] newattr[3] &= ~tty.ECHO & ~tty.ICANON tty.tcsetattr(self.file, tty.TCSANOW, newattr)
def open(self, command, env={}): """ Create subprocess using forkpty() """ # parse command command_arr = shlex.split(command) executable = command_arr[0] args = command_arr # try to fork a new pty try: self.pid, self.fd = pty.fork() except: return False # child proc, replace with command after altering terminal attributes if self.pid == 0: # Set signals to default values in child try: signal.signal(signal.SIGCHLD, signal.SIG_DFL) except: pass try: signal.signal(signal.SIGHUP, signal.SIG_DFL) except: pass # set requested environment variables for k in env.keys(): os.environ[k] = env[k] # set tty attributes try: attrs = tty.tcgetattr(1) attrs[0] = attrs[0] ^ tty.IGNBRK attrs[0] = attrs[0] | tty.BRKINT | tty.IXANY | tty.IMAXBEL attrs[2] = attrs[2] | tty.HUPCL attrs[3] = attrs[3] | tty.ICANON | tty.ECHO | tty.ISIG | tty.ECHOKE attrs[6][tty.VMIN] = 1 attrs[6][tty.VTIME] = 0 tty.tcsetattr(1, tty.TCSANOW, attrs) except: pass # replace this process with the subprocess os.execvp(executable, args) # else master, do nothing else: pass
def __init__(self, filename, speed=tty.B57600): try: self.filename = filename logger.info('opening %r' % filename) self.fd = os.open(filename, os.O_RDWR | os.O_NOCTTY | os.O_NONBLOCK) tty.setraw(self.fd) attr = tty.tcgetattr(self.fd) attr[tty.ISPEED] = attr[tty.OSPEED] = speed tty.tcsetattr(self.fd, tty.TCSAFLUSH, attr) except termios.error: raise IOError
def spawn(argv, master_read=read, stdin_read=read): if type(argv) == type(''): argv = (argv,) pid, master_fd = fork() if pid == CHILD: apply(os.execlp, (argv[0],) + argv) mode = tty.tcgetattr(STDIN_FILENO) tty.setraw(STDIN_FILENO) try: copy(master_fd, master_read, stdin_read) except: tty.tcsetattr(STDIN_FILENO, tty.TCSAFLUSH, mode)