def popen_game(): rfd, stdout = os.openpty() wfd, stdin = os.openpty() proc = subprocess.Popen(CMD, bufsize=0, stdout=stdout, stdin=stdin) os.close(stdout) os.close(stdin) return proc, os.fdopen(rfd, 'rb'), os.fdopen(wfd, 'wb')
def prepare_fds (self): if '_in' in self.options: i= self.options['_in'] if ( not isinstance (i, io.IOBase) and type (i)!=int and i is not None and not isinstance (i, Command) ): if self.options['_in_tty']: # TODO: no support yet for input from file when _in_tty # NOTE: os.openpty() returns (master, slave) # but when writing master=w, slave=r (master, slave)= os.openpty () self.stdin_pipe= (slave, master) else: # logging.debug ("prepare_fds: _in::%s creates a pipe()", type (i)) self.stdin_pipe= os.pipe () elif isinstance (i, Command): if i.options.get ('_out', None)==Capture: # if it's a captured command, create a pipe to feed the data # logging.debug ("prepare_fds: _in::Command, _in._out==Capture creates a pipe()") self.stdin_pipe= os.pipe () elif i.options.get ('_out', None)==Pipe: # if it's a piped command, use its pipe and hope it runs in the bg # logging.debug ("prepare_fds: _in::Command uses the stdout_pipe") self.stdin_pipe= i.stdout_pipe if '_out' in self.options: if self.options['_out']==Capture: if self.options['_out_tty']: if self.options['_in_tty']: # we use a copy of the pty created for the stdin self.stdout_pipe= (os.dup (self.stdin_pipe[1]), os.dup (self.stdin_pipe[0])) else: # this time the order is right (master, slave)= os.openpty () self.stdout_pipe= (master, slave) else: # logging.debug ("prepare_fds: _out==Capture creates a pipe()") self.stdout_pipe= os.pipe () elif self.options['_out']==Pipe: # this pipe should be picked up by the outer Command # logging.debug ("prepare_fds: _out==Pipe creates a pipe()") self.stdout_pipe= os.pipe () if '_err' in self.options: if self.options['_err']==Capture: # if stdout is also Capture'd, then use the same pipe if not '_out' in self.options or self.options['_out']!=Capture: # if stdout is a tty, hook to that one if self.options['_out_tty']: self.stderr_pipe= (os.dup (self.stdout_pipe[0]), os.dup (self.stdout_pipe[1])) else: # logging.debug ("prepare_fds: _err==Capture creates a pipe()") self.stderr_pipe= os.pipe () elif self.options['_err']==Pipe: # this pipe should be picked up by the outer Command # logging.debug ("prepare_fds: _err==Pipe creates a pipe()") self.stderr_pipe= os.pipe ()
def test_colored_tty(): from os import openpty read, write = openpty() out = pipe_output(read, write) assert unprintable(out), out
def __init__(self, protocol): self.root_node = protocol.factory.root_node self.extra_loggers = protocol.factory.extra_loggers self.runtime_options = protocol.factory.runtime_options self.transportHandle = protocol._handle self.doneCallback = protocol.transport.loseConnection self.connectionPool = protocol.factory.connectionPool self.connection_shell = None self.exit_status = 0 self.process_done = False # Done, but waiting for the user to close the pane. # Create PTY master, self.slave = os.openpty() # File descriptors for the shell self.shell_in = os.fdopen(master, "w", 0) self.shell_out = os.fdopen(master, "r", 0) # File descriptors for slave pty. stdin = os.fdopen(self.slave, "r", 0) stdout = os.fdopen(self.slave, "w", 0) # Create pty object, for passing to deployment enviroment. self.pty = SocketPty(stdin, stdout, self.runInNewPtys, interactive=protocol.factory.interactive) # Start read loop self._startReading()
def test_read_pty_output(self): proto = MyReadPipeProto(loop=self.loop) master, slave = os.openpty() master_read_obj = io.open(master, "rb", 0) @asyncio.coroutine def connect(): t, p = yield from self.loop.connect_read_pipe(lambda: proto, master_read_obj) self.assertIs(p, proto) self.assertIs(t, proto.transport) self.assertEqual(["INITIAL", "CONNECTED"], proto.state) self.assertEqual(0, proto.nbytes) self.loop.run_until_complete(connect()) os.write(slave, b"1") test_utils.run_until(self.loop, lambda: proto.nbytes) self.assertEqual(1, proto.nbytes) os.write(slave, b"2345") test_utils.run_until(self.loop, lambda: proto.nbytes >= 5) self.assertEqual(["INITIAL", "CONNECTED"], proto.state) self.assertEqual(5, proto.nbytes) # On Linux, transport raises EIO when slave is closed -- # ignore it. self.loop.set_exception_handler(lambda loop, ctx: None) os.close(slave) self.loop.run_until_complete(proto.done) self.assertEqual(["INITIAL", "CONNECTED", "EOF", "CLOSED"], proto.state) # extra info is available self.assertIsNotNone(proto.transport.get_extra_info("pipe"))
def _start(self): (self._status, self._runtime, self._pid) = (None, None, None) # Setup of file descriptors - stdin / stdout via pty, stderr via pipe LocalProcess.fd_creation_lock.acquire() try: # terminal is used for stdin / stdout fd_parent_terminal, fd_child_terminal = os.openpty() fd_parent_stdin, fd_child_stdin = (fd_parent_terminal, fd_child_terminal) fd_parent_stdout, fd_child_stdout = (fd_parent_terminal, fd_child_terminal) fd_parent_stderr, fd_child_stderr = os.pipe() # Returns (r, w) FDs finally: LocalProcess.fd_creation_lock.release() self._setup_terminal(fd_parent_terminal) for fd_setup in [fd_parent_stdout, fd_parent_stderr]: # non-blocking operation on stdout/stderr fcntl.fcntl(fd_setup, fcntl.F_SETFL, os.O_NONBLOCK | fcntl.fcntl(fd_setup, fcntl.F_GETFL)) pid = os.fork() self._time_started = time.time() self._time_finished = None fd_map = {0: fd_child_stdin, 1: fd_child_stdout, 2: fd_child_stderr} if pid == 0: # We are in the child process - redirect streams and exec external program from grid_control.utils.process_child import run_command run_command(self._cmd, [self._cmd] + self._args, fd_map, self._env_dict) else: # Still in the parent process - setup threads to communicate with external program os.close(fd_child_terminal) os.close(fd_child_stderr) self._pid = pid self._start_watcher('interact', True, pid, self._interact_with_child, pid, fd_parent_stdin, fd_parent_stdout, fd_parent_stderr)
def forkpty(attrs=[], winsz=[]): (master, slave) = os.openpty() if attrs: termios.tcsetattr(slave, termios.TCSADRAIN, attrs) if winsz: if len(winsz) not in (2,4): raise TypeError("winsz must be a 2-element array") winsz[2],winsz[3] = 0,0 fcntl.ioctl(slave, termios.TIOCSWINSZ, winsz) pid = os.fork() if pid: os.close(slave) return (pid, master) else: os.close(master) os.setsid() if fcntl.ioctl(slave, termios.TIOCSCTTY): raise Error("failed to ioctl TIOCSCTTY") os.dup2(slave, 0) os.dup2(slave, 1) #os.dup2(slave, 2) if slave > 2: os.close(slave) return (0, 0)
def __init__(self, eventloop, invalidate, exec_func, bell_func=None, done_callback=None, has_priority=None): assert isinstance(eventloop, EventLoop) assert callable(invalidate) assert callable(exec_func) assert bell_func is None or callable(bell_func) assert done_callback is None or callable(done_callback) assert has_priority is None or callable(has_priority) self.eventloop = eventloop self.invalidate = invalidate self.exec_func = exec_func self.done_callback = done_callback self.has_priority = has_priority or (lambda: True) self.pid = None self.is_terminated = False self.suspended = False # Create pseudo terminal for this pane. self.master, self.slave = os.openpty() # Master side -> attached to terminal emulator. self._reader = PosixStdinReader(self.master) # Create output stream and attach to screen self.sx = 0 self.sy = 0 self.screen = BetterScreen(self.sx, self.sy, write_process_input=self.write_input, bell_func=bell_func) self.stream = BetterStream(self.screen) self.stream.attach(self.screen)
def _pipe(isatty): r_fd, w_fd = os.openpty() if isatty else os.pipe() try: yield (r_fd, w_fd) finally: os.close(r_fd) os.close(w_fd)
def openpty(space): "Open a pseudo-terminal, returning open fd's for both master and slave end." try: master_fd, slave_fd = os.openpty() except OSError as e: raise wrap_oserror(space, e) return space.newtuple([space.wrap(master_fd), space.wrap(slave_fd)])
def __init__(self, speed=4800, databits=8, parity='N', stopbits=1): # Allow Serial: header to be overridden by explicit spped. self.speed = speed baudrates = { 0: termios.B0, 50: termios.B50, 75: termios.B75, 110: termios.B110, 134: termios.B134, 150: termios.B150, 200: termios.B200, 300: termios.B300, 600: termios.B600, 1200: termios.B1200, 1800: termios.B1800, 2400: termios.B2400, 4800: termios.B4800, 9600: termios.B9600, 19200: termios.B19200, 38400: termios.B38400, 57600: termios.B57600, 115200: termios.B115200, 230400: termios.B230400, } speed = baudrates[speed] # Throw an error if the speed isn't legal (self.fd, self.slave_fd) = os.openpty() self.byname = os.ttyname(self.slave_fd) print os.ttyname(self.slave_fd), os.ttyname(self.fd) opencpn_conf = ConfigParser.RawConfigParser() opencpn_conf.read(os.getenv('HOME') + "/.opencpn/opencpn.conf") opencpn_conf.set("Settings/NMEADataSource", "Source", "Serial:AIS Port (Shared)") opencpn_conf.set("Settings/AISPort", "Port", "Serial:" + os.ttyname(self.slave_fd)) opencpn_conf_file = open(os.getenv('HOME') + "/.opencpn/opencpn.conf", "w") opencpn_conf.write(opencpn_conf_file) opencpn_conf_file.close() (iflag, oflag, cflag, lflag, ispeed, ospeed, cc) = termios.tcgetattr(self.slave_fd) cc[termios.VMIN] = 1 cflag &= ~(termios.PARENB | termios.PARODD | termios.CRTSCTS) cflag |= termios.CREAD | termios.CLOCAL iflag = oflag = lflag = 0 iflag &=~ (termios.PARMRK | termios.INPCK) cflag &=~ (termios.CSIZE | termios.CSTOPB | termios.PARENB | termios.PARODD) if databits == 7: cflag |= termios.CS7 else: cflag |= termios.CS8 if stopbits == 2: cflag |= termios.CSTOPB if parity == 'E': iflag |= termios.INPCK cflag |= termios.PARENB elif parity == 'O': iflag |= termios.INPCK cflag |= termios.PARENB | termios.PARODD ispeed = ospeed = speed termios.tcsetattr(self.slave_fd, termios.TCSANOW, [iflag, oflag, cflag, lflag, ispeed, ospeed, cc])
def run_cmd(self): def child_setup(): os.setsid() tty_slave_fd = os.open(self.tty_slave_name, os.O_RDWR) os.close(tty_slave_fd) os.close(self.tty_master_fd) self.set_state(STATE_RUNNING) self.cmd = self.cmd_widget.get_text() self.tty_master_fd, self.tty_slave_fd = os.openpty() self.tty_slave_name = os.ttyname(self.tty_slave_fd) self.tty_view.set_fd(self.tty_master_fd) set_raw_input(self.tty_master_fd) try: import shlex self.pid, self.stdin_fd, self.stdout_fd, self.stderr_fd = \ gobject.spawn_async(shlex.split(self.cmd), standard_output=True, standard_error=True, flags=gobject.SPAWN_DO_NOT_REAP_CHILD | gobject.SPAWN_SEARCH_PATH, child_setup=child_setup) except Exception, e: self.insert_text('stderr', str(e)) self.exit_status = -1 self.set_state(STATE_DONE) return
def test(self): master, slave = os.openpty() if not os.isatty(slave): self.fail("Slave-end of pty is not a terminal.") os.write(slave, b'Ping!') self.assertEqual(os.read(master, 1024), b'Ping!')
def fork_pty(): '''This implements a substitute for the forkpty system call. This should be more portable than the pty.fork() function. Specifically, this should work on Solaris. Modified 10.06.05 by Geoff Marshall: Implemented __fork_pty() method to resolve the issue with Python's pty.fork() not supporting Solaris, particularly ssh. Based on patch to posixmodule.c authored by Noah Spurrier:: http://mail.python.org/pipermail/python-dev/2003-May/035281.html ''' parent_fd, child_fd = os.openpty() if parent_fd < 0 or child_fd < 0: raise OSError("os.openpty() failed") pid = os.fork() if pid == CHILD: # Child. os.close(parent_fd) pty_make_controlling_tty(child_fd) os.dup2(child_fd, STDIN_FILENO) os.dup2(child_fd, STDOUT_FILENO) os.dup2(child_fd, STDERR_FILENO) else: # Parent. os.close(child_fd) return pid, parent_fd
def __init__(self,command,readyprompt=None): userargs = command.split(' ') log.msg(userargs) command = userargs[0] self.ptycommand = command self.args = userargs #self.pid, self.parent = pty.fork() self.parent,self.child = os.openpty() self.pid = os.fork() if self.pid == 0: os.close(self.parent) os.dup2(self.child, 0) #sys.stdin = rc os.dup2(self.child, 1) #sys.stdout = wc os.dup2(self.child, 2) #sys.stderr = ec log.msg(self.args) os.execv(self.ptycommand,self.args) else: os.close(self.child) self.makeNonBlocking(self.parent) log.msg('bacha pid :'+str(self.pid)) new = termios.tcgetattr(self.parent) new[3] = new[3] & ~termios.ECHO termios.tcsetattr(self.parent, termios.TCSANOW, new) #self.parent = fdopen(self.parent,'rw') if (readyprompt): self.expect(None,readyprompt)
def __init__(self, on_update = None): ''' Constructor @param on_update:()→void Called when a new line is available ''' def noop(): pass self.on_update = noop if on_update is None else on_update (self.master, self.slave) = os.openpty() self.__reader = LineReader(self.master) self.__condition = threading.Condition() self.__queue = [] def background(): try: while True: got = self.__reader.next() if got is None: return self.__condition.acquire() try: self.__queue.append(got) finally: self.__condition.release() self.on_update() except: return self.__thread = threading.Thread(target = background) self.__thread.setDaemon(True) self.__thread.start()
def __init__(self): super().__init__() self.window = None # Weakref set by window.add # Pane position. self.px = 0 self.py = 0 # Pane size self.sx = 120 self.sy = 24 self.location = Location(self.py, self.py, self.sx, self.sy) # Create output stream and attach to screen self.screen = BetterScreen(self.sx, self.sy) self.stream = pyte.Stream() self.stream.attach(self.screen) # Create pseudo terminal for this pane. self.master, self.slave = os.openpty() # Slave side -> attached to process. set_size(self.slave, self.sy, self.sx) self.id = self._next_id()
def test_openpty(self): os = self.posix master_fd, slave_fd = os.openpty() assert isinstance(master_fd, int) assert isinstance(slave_fd, int) os.write(slave_fd, 'x\n') data = os.read(master_fd, 100) assert data.startswith('x')
def _python_fork_parse(self, commandargs, env, cwd, parser_func): self._term.connect('commit', self.on_commit_python) env = dict(os.environ) env['TERM'] = 'xterm' master, self.slave = os.openpty() self._term.set_pty(master) self.master, slave = os.openpty() p = subprocess.Popen(commandargs, stdout=slave, stderr=subprocess.STDOUT, stdin=slave, close_fds=True) self._pid = p.pid self._last_cwd = cwd gobject.timeout_add(200, self._save_cwd) gobject.io_add_watch(self.master, gobject.IO_IN, self._on_python_fork_parse_stdout, parser_func) self._term.connect('key-press-event', self._on_python_fork_parse_key_press_event, self.master)
def openpty(): try: return os.openpty() except (AttributeError, OSError): pass (master_fd, slave_name) = _open_terminal() slave_fd = slave_open(slave_name) return (master_fd, slave_fd)
def __init__(self): self.master, self.slave = os.openpty() self._old_winch = signal.signal(signal.SIGWINCH, self._size_changed) self._size_changed() try: os.set_inheritable(self.slave, True) except AttributeError: pass
def master_open(): try: (master_fd, slave_fd) = os.openpty() except (AttributeError, OSError): pass slave_name = os.ttyname(slave_fd) os.close(slave_fd) return (master_fd, slave_name) return _open_terminal()
def it_logs_continuously_when_run_interactively(self, in_example_dir): check_call(('pgctl', 'start')) # this pty simulates running in a terminal read, write = os.openpty() pty.normalize_newlines(read) p = Popen(('pgctl', 'log'), stdout=write, stderr=write) os.close(write) import fcntl fl = fcntl.fcntl(read, fcntl.F_GETFL) fcntl.fcntl(read, fcntl.F_SETFL, fl | os.O_NONBLOCK) assert p.poll() is None # it's still running # needs to loop for several seconds because the default event loop # in tail-f is one second. # TODO: buf is a list, use wait_for() to append to it limit = 3.0 wait = .1 buf = b'' while True: try: block = os.read(read, 1024) print('BLOCK:', block) except OSError as error: print('ERROR:', error) if error.errno == 11: # other end didn't write yet if limit > 0: import time time.sleep(wait) limit -= wait continue else: break else: raise buf += block from testfixtures import StringComparison as S buf = norm.pgctl(buf.decode('UTF-8')) print('NORMED:') print(buf) assert buf == S('''(?s)\ ==> playground/ohhi/logs/current <== {TIMESTAMP} [oe].* ==> playground/sweet/logs/current <== {TIMESTAMP} sweet {TIMESTAMP} sweet_error ==> playground/ohhi/logs/current <== .*{TIMESTAMP} .*$''') assert p.poll() is None # it's still running p.terminate() assert p.wait() == -15
def __init__(self, text_widget): super(PtyView, self).__init__() self.text_widget = text_widget self.master, self.slave = os.openpty() self.slave_name = os.ttyname(self.slave) self.file_obj = os.fdopen(self.master, 'r') QtCore.QThread.__init__(self) self.start() self.data_ready.connect(self.handle_data)
def test_pty(): from os import openpty read, write = openpty() out = pipe_output(read, write) assert out == "hi there!\n", repr(out) return "pty works"
def _set_proc(self, cmd): '''Set the command, should produce 'SYNC0\n' when ready''' mfd, sfd = os.openpty() self._pty = FdIo(mfd) self._pty_slave = FdIo(sfd) slavetty = os.ttyname(sfd) self._proc = subprocess.Popen(cmd, preexec_fn=lambda:self._set_controlling_tty(slavetty), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
def spawn_test_process(self, home_dir, test, executable, args): env_dir = test.env_dir(home_dir) print('-- cd', env_dir) os.chdir(env_dir) cmd = [executable] + args print('--', ' '.join(cmd), '&') (stdout_master, stdout_slave) = os.openpty() (stderr_master, stderr_slave) = os.openpty() self.set_fd_nonblocking(stdout_master) self.set_fd_nonblocking(stderr_master) stdout_master = os.fdopen(stdout_master, 'r') stderr_master = os.fdopen(stderr_master, 'r') process = subprocess.Popen(cmd, stdin=stdout_slave, stdout=stdout_slave, stderr=stderr_slave, close_fds=True, preexec_fn=os.setsid) os.close(stdout_slave) os.close(stderr_slave) print('-- pid', process.pid) return TestPairProcess(process, stdout_master, stderr_master)
def __init__(self, *args, **kwargs): if 'stdin' in kwargs or 'stdout' in kwargs or 'stderr' in kwargs: raise AttributeError(u'Neither stdin, stdout nor stderr keyword args are allowed') master, slave = os.openpty() self.pipe = _FdFile(master) self.proc = Popen(*args, stdin=slave, stdout=slave, stderr=slave, **kwargs) self.poll = self.proc.poll self.terminate = self.proc.terminate self.kill = self.proc.kill self.wait = self.proc.wait
def run_cmd(cmd, *, use_pty=False, silent=False): logger.debug('running %r, %susing pty,%s showing output', cmd, '' if use_pty else 'not ', ' not' if silent else '') if use_pty: rfd, stdout = os.openpty() stdin = stdout # for fd leakage logger.debug('pty master fd=%d, slave fd=%d.', rfd, stdout) else: stdin = subprocess.DEVNULL stdout = subprocess.PIPE exited = False def child_exited(signum, sigframe): nonlocal exited exited = True old_hdl = signal.signal(signal.SIGCHLD, child_exited) p = subprocess.Popen(cmd, stdin = stdin, stdout = stdout, stderr = subprocess.STDOUT) if use_pty: os.close(stdout) else: rfd = p.stdout.fileno() out = [] while not exited: try: r = os.read(rfd, 4096) if not r: # EOF break except InterruptedError: continue except OSError as e: if e.errno == 5: # Input/output error: no clients run break else: raise r = r.replace(b'\x0f', b'') # ^O if not silent: sys.stderr.buffer.write(r) out.append(r) code = p.wait() if use_pty: os.close(rfd) if old_hdl is not None: signal.signal(signal.SIGCHLD, old_hdl) out = b''.join(out) out = out.decode('utf-8', errors='replace') if code != 0: raise CalledProcessError(code, cmd, out) return out
def _open_pty(self): """Create a PTY """ # get our terminal params self.tcattr = termios.tcgetattr(STDIN) winsize = fcntl.ioctl(STDIN, termios.TIOCGWINSZ, "0123") # open a pty self.master, self.slave = os.openpty() # set the slave's terminal params termios.tcsetattr(self.slave, termios.TCSANOW, self.tcattr) fcntl.ioctl(self.slave, termios.TIOCSWINSZ, winsize)
def openpty(): """openpty() -> (master_fd, slave_fd) Open a pty master/slave pair, using os.openpty() if possible.""" try: return os.openpty() except (AttributeError, OSError): pass master_fd, slave_name = _open_terminal() slave_fd = slave_open(slave_name) return master_fd, slave_fd
def begin(self): if self.__in_descriptor is None: self.clean() try: self.__parser.reset() self.__out_descriptor, self.__in_descriptor = os.openpty() self.__out = self.__prepare_descriptor(self.__out_descriptor) except: self.clean() raise return self.__out_descriptor, self.__in_descriptor
def __init__(self, az, el): logging.debug("SerialEmulator - init") self.mfd, self.sfd = os.openpty() # create pseudo terminal self.s_slave = str(os.ttyname(self.sfd)) logging.info("SerialEmulator - Slave device: " + self.s_slave) # subprocess.run('putty -serial ' + self.s_slave, shell=True) self.az = az self.el = el loop = threading.Thread(target=self.loop, name='Emulator') # prepare a new thread loop.daemon = True loop.start() # and start it
def master_open(): try: master_fd, slave_fd = os.openpty() except (AttributeError, OSError): pass else: slave_name = os.ttyname(slave_fd) os.close(slave_fd) return ( master_fd, slave_name) return _open_terminal()
def it_logs_continuously_when_run_interactively(self, in_example_dir): check_call(('pgctl-2015', 'start')) # this pty simulates running in a terminal read, write = os.openpty() pty_normalize_newlines(read) p = Popen(('pgctl-2015', 'log'), stdout=write, stderr=write) os.close(write) import fcntl fl = fcntl.fcntl(read, fcntl.F_GETFL) fcntl.fcntl(read, fcntl.F_SETFL, fl | os.O_NONBLOCK) assert p.poll() is None # it's still running # needs to loop for at least two seconds because the default event loop # in tail-f is one second. retries = 20 buf = '' while True: try: block = os.read(read, 1024) print('BLOCK:', block) except OSError as error: print('ERROR:', error) if error.errno == 11: # other end didn't write yet if retries > 0: retries -= 1 import time time.sleep(.1) continue else: break else: raise buf += block assert buf == S('''(?s)\ ==> playground/ohhi/stdout\\.log <== o.* ==> playground/ohhi/stderr\\.log <== e.* ==> playground/sweet/stdout\\.log <== sweet ==> playground/sweet/stderr\\.log <== sweet_error .*$''') assert p.poll() is None # it's still running p.terminate() assert p.wait() == -15
def __init__(self, printer, prot, iomanager): self.printer = printer self.prot = prot self.iomanager = iomanager (master_fd, slave_fd) = os.openpty() slave = os.ttyname(slave_fd) master_flags = fcntl.fcntl(master_fd, fcntl.F_GETFL, 0) fcntl.fcntl(master_fd, fcntl.F_SETFL, master_flags | os.O_NONBLOCK) # switch to "raw" mode - these constants come from the manpage for termios under cfmakeraw() master_attr = termios.tcgetattr(master_fd) master_attr[0] &= ~( termios.IGNBRK | termios.BRKINT | termios.PARMRK | termios.ISTRIP | termios.INLCR | termios.IGNCR | termios.ICRNL | termios.IXON) master_attr[1] &= ~termios.OPOST master_attr[2] &= ~(termios.CSIZE | termios.PARENB) master_attr[3] &= ~(termios.ECHO | termios.ECHONL | termios.ICANON | termios.ISIG | termios.IEXTEN) master_attr[3] |= termios.CS8 termios.tcsetattr(master_fd, termios.TCSADRAIN, master_attr) # Fun detail: master will always show as /dev/ptmx, but the kernel knows from # the fd which PTY we're using. This means we have to use master_fd instead # of opening master by name. logging.info("Opened PTY for {} and got {}".format( prot, os.ttyname(slave_fd))) self.pipe_link = "/dev/" + prot + "_1" try: os.unlink(self.pipe_link) except OSError as e: # file not found is fine to ignore - anythine else and we should log it if e.errno != errno.ENOENT: logging.error("Failed to unlink '{}': {}".format( self.pipe_link, e.strerror)) logging.info("linking {}".format(self.pipe_link)) os.symlink(slave, self.pipe_link) os.chmod(self.pipe_link, 0o666) logging.info("{} Pipe open. Use '{}' to communicate with it".format( self.prot, self.pipe_link)) self.rd = os.fdopen(master_fd, "r") self.wr = os.fdopen(master_fd, "w") self.send_response = True self.iomanager.add_file(self.rd, self.get_message)
def test_colored_tty(tmpdir): tmpdir.chdir() from os import openpty read, write = openpty() from testing.capture_subprocess import pty_normalize_newlines pty_normalize_newlines(read) out, uncolored = pipe_output(read, write) assert out != uncolored
def execute(self): """Run the process""" #(self.childStdin, self.toChild) = os.pipe() if 1: # Do it with a pseudo-tty (self.fromChild,self.childStdout) = os.openpty() # os.pipe() # (self.errChild,self.childStderr) = ( os.dup(self.fromChild),os.dup(self.childStdout)) #os.openpty() # os.pipe() (self.errChild,self.childStderr) = os.openpty() #(self.childStdin, self.toChild) = (self.childStdout, self.fromChild) self.toChild = os.dup(self.fromChild) self.childStdin = os.dup(self.childStdout) else: # Do it with pipes (does NOT work if the process is interactive), but "cleaner" if it is not interactive (self.fromChild,self.childStdout) = os.pipe() (self.errChild,self.childStderr) = os.pipe() (self.childStdin, self.toChild) = os.pipe() # Let's set all these fds to be non blocking if 0: fl = fcntl.fcntl(self.childStdout, fcntl.F_GETFL) fcntl.fcntl(self.childStdout, fcntl.F_SETFL, fl | os.O_NONBLOCK) if self.childStdout != self.childStderr: fl = fcntl.fcntl(self.childStderr, fcntl.F_GETFL) fcntl.fcntl(self.childStderr, fcntl.F_SETFL, fl | os.O_NONBLOCK) if 0: # Actually we don't want it to be nonblocking because we are using a xmldoc feed... fl = fcntl.fcntl(self.fromChild, fcntl.F_GETFL) fcntl.fcntl(self.fromChild, fcntl.F_SETFL, fl | os.O_NONBLOCK) if self.errChild != self.fromChild: fl = fcntl.fcntl(self.errChild, fcntl.F_GETFL) fcntl.fcntl(self.errChild, fcntl.F_SETFL, fl | os.O_NONBLOCK) try: print "executing ", self.cmdLine self.process = subprocess.Popen(args=self.cmdLine,stdin=self.childStdin,stdout=self.childStdout,stderr=self.childStderr,close_fds=True) # TODO, shouldn't we now be able to close the fds that we are not using (the child side FDs)? self.doc.startFeed(self.fromChild) except OSError, e: self.doc.append('<text fore="#FF0000">' + str(e) + "</text>") self.doc.layout() self.finish() self.render()
def start_server(self): print "loading the model" print self.cmd cmd = self.cmd.split() master, slave = os.openpty() backend = sp.Popen(cmd, bufsize=0, stdout=slave, stdin=sp.PIPE) poem_stdout = os.fdopen(master) while True: line = poem_stdout.readline() print line, if line.startswith("Please input"): break print "model is loaded" s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print 'Socket created' try: s.bind((self.host, self.port)) except socket.error as msg: print 'Bind failed. Error Code : ' + str( msg[0]) + ' Message ' + msg[1] sys.exit() print 'Socket bind complete' s.listen(0) print 'Socket now listening on {}:{}'.format(self.host, self.port) while True: conn, addr = s.accept() conn.sendall("Accept") print 'Connected with ' + addr[0] + ':' + str(addr[1]) data = conn.recv(1024) print data result = "" backend.stdin.write(data) while True: line = poem_stdout.readline() print line, if line.startswith('[END]'): break result += line while True: line = poem_stdout.readline() print line, if line.startswith("Please input"): break conn.sendall(result) conn.close() s.close()
def __init__(self, buffered=None, handlers=None): try: self.r, self.w = os.openpty() except OSError: self.r, self.w = os.pipe() self.od_stdout = sys.__stdout__.fileno() self.od_stderr = sys.__stderr__.fileno() self.buffered = buffered if handlers is None: handlers = [] self.handlers = handlers
def master_open(): """master_open() -> (master_fd, slave_name) Open a pty master and return the fd, and the filename of the slave end. Deprecated, use openpty() instead.""" try: master_fd, slave_fd = os.openpty() except (AttributeError, OSError): pass else: slave_name = os.ttyname(slave_fd) os.close(slave_fd) return master_fd, slave_name return _open_terminal()
def __init__(self): master, slave = os.openpty() #create queues self.tx = Queue() self.rx = Queue() #start rx/tx threads TxManager(master, self.tx).start() RxManager(master, self.rx).start() #print out the port we should connect to self.port_name = os.ttyname(slave)
def _play(self, filepath, allocate_pty): cmd = [self.exe] + self.default_args + [filepath.resolve()] logging.debug("PlayerInterface._play: %s", cmd) if allocate_pty: master, slave = os.openpty() self.child = subprocess.Popen(cmd, stdin=master, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) self.child_stdin = slave else: self.child = subprocess.Popen(cmd) self.child_stdin = None
def f_inotify(): _configure_logging() i = inotify.adapters.Inotify() folder_to_watch = b'/dev/shm/_tmp/' i.add_watch(folder_to_watch) m = [] s = [] d = [] for j in range(57): m.append(0) s.append(0) d.append(0) try: for event in i.event_gen(): if event is not None: os.kill(asd_PID, signal.SIGSTOP) (header, type_names, watch_path, filename) = event _LOGGER.info( "WD=(%d) MASK=(%d) COOKIE=(%d) LEN=(%d) MASK->NAMES=%s " "WATCH-PATH=[%s] FILENAME=[%s]", header.wd, header.mask, header.cookie, header.len, type_names, watch_path.decode('utf-8'), filename.decode('utf-8')) if re.search("IN_OPEN", str(type_names)) and not filename.decode('utf-8'): os.kill(asd_PID, signal.SIGSTOP) for j in range(57): m[j], s[j] = os.openpty() os.kill(asd_PID, signal.SIGCONT) if re.search("IN_CLOSE_NOWRITE", str(type_names)) and not filename.decode('utf-8'): os.kill(asd_PID, signal.SIGSTOP) subprocess.Popen("unlink /dev/shm/_tmp/_tty", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() subprocess.Popen("ln -s {} /dev/shm/_tmp/_tty".format( args.file), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() #time.sleep(10) os.kill(asd_PID, signal.SIGCONT) # I don't yet understand why this sleep is needed time.sleep(1) finally: i.remove_watch(folder_to_watch)
def run(device=_default_device, baudrate=_default_baudrate, width=_default_width, parity=_default_parity, stopbits=_default_stopbits, xon=_default_xon, rtc=_default_rtc): ##### Serial port setup ttyS = serial.Serial(device, baudrate, width, parity, stopbits, 1, xon, rtc) ttyS.timeout = 0 # Non-blocking ttyS.write("AT\r\n") data = "" while data != "OK\r\n": data = ttyS.readline() #logging.debug(data) number_of_slave_terminals = 1 ##### PTYs setup pts = [] for n in range(number_of_slave_terminals): master, slave = os.openpty() # Print slave names so others know where to connect print >> sys.stderr, 'MUX > fd: %d pty: %s' % (slave, os.ttyname(slave)) pts.append(master) ##### Poller setup poller = select.poll() poller.register(ttyS.fd, select.POLLIN | select.POLLPRI) for pt in pts: poller.register(pt, select.POLLIN | select.POLLPRI) ##### MAIN while True: events = poller.poll(500) for fd, flag in events: # fd has input if flag & (select.POLLIN | select.POLLPRI): # Data on serial if fd == ttyS.fd: data = ttyS.read(80) for pt in pts: os.write(pt, data) # Data on other pty else: ttyS.write(os.read(fd, 80))
def fork(self): if self.forked: return self.forked = True master, slave = os.openpty( ) # Note that master and slave are in blocking mode remove_cloexec(slave) stdin, self.stdin = self.stdin, None if stdin is not None: stdin_read_fd, stdin_write_fd = os.pipe() remove_cloexec(stdin_read_fd) stdin_file = os.fdopen(stdin_write_fd, 'wb') pid = os.fork() if pid == 0: # child try: os.chdir(self.cwd) except EnvironmentError: os.chdir('/') os.setsid() for i in range(3): if stdin is not None and i == 0: os.dup2(stdin_read_fd, i) os.close(stdin_read_fd), os.close(stdin_write_fd) else: os.dup2(slave, i) os.close(slave), os.close(master) os.closerange(3, 200) # Establish the controlling terminal (see man 7 credentials) os.close(os.open(os.ttyname(1), os.O_RDWR)) os.environ['TERM'] = self.opts.term os.environ['COLORTERM'] = 'truecolor' if os.path.isdir(terminfo_dir): os.environ['TERMINFO'] = terminfo_dir try: os.execvp(self.argv[0], self.argv) except Exception as err: print('Could not launch:', self.argv[0]) print('\t', err) input('\nPress Enter to exit:') else: # master os.close(slave) self.pid = pid self.child_fd = master if stdin is not None: t = Thread(name='WriteStdin', target=stdin_file.write, args=(stdin, )) t.daemon = True t.start() return pid
def fork(self): if self.forked: return self.forked = True master, slave = os.openpty() # Note that master and slave are in blocking mode remove_cloexec(slave) fast_data_types.set_iutf8(master, True) stdin, self.stdin = self.stdin, None if stdin is not None: stdin_read_fd, stdin_write_fd = os.pipe() remove_cloexec(stdin_read_fd) pid = os.fork() if pid == 0: # child try: os.chdir(self.cwd) except EnvironmentError: os.chdir('/') os.setsid() for i in range(3): if stdin is not None and i == 0: os.dup2(stdin_read_fd, i) os.close(stdin_read_fd), os.close(stdin_write_fd) else: os.dup2(slave, i) os.close(slave), os.close(master) os.closerange(3, 200) # Establish the controlling terminal (see man 7 credentials) os.close(os.open(os.ttyname(1), os.O_RDWR)) os.environ['TERM'] = self.opts.term os.environ['COLORTERM'] = 'truecolor' if os.path.isdir(terminfo_dir): os.environ['TERMINFO'] = terminfo_dir try: os.execvp(self.argv[0], self.argv) except Exception as err: # Report he failure and exec a shell instead so that # we are not left with a forked but not execed process print('Could not launch:', self.argv[0]) print('\t', err) print('\nPress Enter to exit:', end=' ') sys.stdout.flush() os.execvp('/bin/sh', ['/bin/sh', '-c', 'read w']) else: # master os.close(slave) self.pid = pid self.child_fd = master if stdin is not None: os.close(stdin_read_fd) fast_data_types.thread_write(stdin_write_fd, stdin) return pid
def __init__(self): signal_path = os.path.join(os.path.dirname(__file__), "signal.json") with open(signal_path) as f: values = json.loads(f.read()) random.shuffle(values) self._signal = itertools.cycle(values) serial_number = "-".join(re.findall(r".{2}", secrets.token_hex(4))).upper() _, slave = os.openpty() device = os.ttyname(slave) super().__init__(serial_number, device)
def __init__(self, cmd, cwd): self._cmd = cmd self._env = os.environ.copy() self._env["TERM"] = "linux" (self._pty, self._pts) = os.openpty() self._process = subprocess.Popen(self._cmd, stdin=self._pts, stdout=self._pts, stderr=self._pts, shell=False, env=self._env, close_fds=True, start_new_session=True, cwd=cwd)
def __init__(self): self.is_playing = False self.master, self.slave = openpty() if self.playlist_get(): with open(str(APP_DIR) + '/music/status', 'w+') as file: self.p = Popen( ['mpg123', '--list', str(APP_DIR) + '/music/playlist'], stdin=self.master, stdout=file, stderr=file) write(self.slave, b's') self.playlist_length = len(self.playlist_get()) self.current_song_number = 0
def __init__(self, exec_func): self.exec_func = exec_func # Create pseudo terminal for this pane. self.master, self.slave = os.openpty() # Master side -> attached to terminal emulator. self._reader = PosixStdinReader(self.master, errors='replace') self._reader_connected = False self._input_ready_callbacks = [] self.ready_f = Future() self.loop = get_event_loop() self.pid = None
def demul_client(fname, fname2=None): """ run as a client """ print "client" demultiplexer = Demultiplexer() if not fname2: fdes = os.open(fname, os.O_RDWR) fdes2 = fdes else: fdes = os.open(fname, os.O_RDONLY) fdes2 = os.open(fname2, os.O_WRONLY) pty_master_fd, pty_slave_fd = os.openpty() conf_binary_pty(pty_master_fd) conf_binary_pty(pty_slave_fd) print "first(bash) pty is " + os.ttyname(pty_slave_fd) pty2_master_fd, pty2_slave_fd = os.openpty() conf_binary_pty(pty2_master_fd) conf_binary_pty(pty2_slave_fd) print "second pty is " + os.ttyname(pty2_slave_fd) common_chan = create_channel(fdes, fdes2, '0') bash_chan = create_channel(pty_master_fd, pty_master_fd, '1') second_chan = create_channel(pty2_master_fd, pty2_master_fd, '2') demultiplexer.add_channel(common_chan) demultiplexer.add_channel(second_chan) demultiplexer.add_channel(bash_chan) demultiplexer.run_loop()
def assert_works_interactively(): read, write = os.openpty() pty.normalize_newlines(read) # setsid: this simulates the shell's job-control behavior proc = Popen(('setsid', 'pgctl', 'debug', 'greeter'), stdin=PIPE, stdout=write) os.close(write) try: assert read_line(read) == 'What is your name?\n' proc.stdin.write(b'Buck\n') proc.stdin.flush() assert read_line(read) == 'Hello, Buck.\n' finally: ctrl_c(proc) proc.wait()
def _run(self): while True: self.event.wait() self.event.clear() print('Playing {}'.format(self.audio)) master, slave = os.openpty() self.process = subprocess.Popen(['mpv', '--no-video', self.audio], stdin=master) self.tty = slave self.process.wait() print('Finished {}'.format(self.audio)) if not self.event.is_set(): self.on_eos()
def openpty(mode=None, winsz=None, name=False): """openpty() -> (master_fd, slave_fd) Open a pty master/slave pair, using os.openpty() if possible.""" master_fd, slave_fd = os.openpty() if mode: tty.tcsetattr(slave_fd, tty.TCSAFLUSH, mode) if tty.HAVE_WINSZ and winsz: tty.tcsetwinsize(slave_fd, winsz) if name: return master_fd, slave_fd, os.ttyname(slave_fd) else: return master_fd, slave_fd
def DEBUG(*obj): """Open a terminal emulator and write messages to it for debugging.""" global _debugfile if _debugfile is None: import atexit masterfd, slavefd = os.openpty() pid = os.fork() if pid: os.close(masterfd) _debugfile = os.fdopen(slavefd, "w+", 0) atexit.register(_close_debug, _debugfile) else: os.close(slavefd) os.execlp("urxvt", "urxvt", "-pty-fd", str(masterfd)) print(datetime.now(), ":", ", ".join(map(repr, obj)), file=_debugfile)
def fork(self): if self.forked: return self.forked = True master, slave = os.openpty( ) # Note that master and slave are in blocking mode remove_cloexec(slave) fast_data_types.set_iutf8(master, True) stdin, self.stdin = self.stdin, None ready_read_fd, ready_write_fd = os.pipe() remove_cloexec(ready_read_fd) if stdin is not None: stdin_read_fd, stdin_write_fd = os.pipe() remove_cloexec(stdin_read_fd) else: stdin_read_fd = stdin_write_fd = -1 env = default_env().copy() env.update(self.env) env['TERM'] = self.opts.term env['COLORTERM'] = 'truecolor' if self.cwd: # needed incase cwd is a symlink, in which case shells # can use it to display the current directory name rather # than the resolved path env['PWD'] = self.cwd if os.path.isdir(terminfo_dir): env['TERMINFO'] = terminfo_dir env = tuple('{}={}'.format(k, v) for k, v in env.items()) argv = list(self.argv) exe = argv[0] if is_macos and exe == shell_path: # Some macOS machines need the shell to have argv[0] prefixed by # hyphen, see https://github.com/kovidgoyal/kitty/issues/247 argv[0] = ('-' + exe.split('/')[-1]) pid = fast_data_types.spawn(exe, self.cwd, tuple(argv), env, master, slave, stdin_read_fd, stdin_write_fd, ready_read_fd, ready_write_fd) os.close(slave) self.pid = pid self.child_fd = master if stdin is not None: os.close(stdin_read_fd) fast_data_types.thread_write(stdin_write_fd, stdin) os.close(ready_read_fd) self.terminal_ready_fd = ready_write_fd fcntl.fcntl(self.child_fd, fcntl.F_SETFL, fcntl.fcntl(self.child_fd, fcntl.F_GETFL) | os.O_NONBLOCK) return pid
def start(self): # Setup of file descriptors - stdin / stdout via pty, stderr via pipe LocalProcess.fdCreationLock.acquire() try: self._fd_parent_terminal, fd_child_terminal = os.openpty( ) # terminal is used for stdin / stdout fd_parent_stdin, fd_child_stdin = (self._fd_parent_terminal, fd_child_terminal) fd_parent_stdout, fd_child_stdout = (self._fd_parent_terminal, fd_child_terminal) fd_parent_stderr, fd_child_stderr = os.pipe() # Returns (r, w) FDs finally: LocalProcess.fdCreationLock.release() self._setup_terminal() for fd in [fd_parent_stdout, fd_parent_stderr ]: # enable non-blocking operation on stdout/stderr fcntl.fcntl(fd, fcntl.F_SETFL, os.O_NONBLOCK | fcntl.fcntl(fd, fcntl.F_GETFL)) self._pid = os.fork() if self._pid == 0: # We are in the child process - redirect streams and exec external program os.environ['TERM'] = 'vt100' for fd_target, fd_source in enumerate( [fd_child_stdin, fd_child_stdout, fd_child_stderr]): os.dup2(fd_source, fd_target) # set stdin/stdout/stderr for fd in irange(3, FD_MAX): safeClose(fd) try: os.execv(self._cmd, [self._cmd] + self._args) except Exception: invoked = 'os.execv(%s, [%s] + %s)' % (repr( self._cmd), repr(self._cmd), repr(self._args)) sys.stderr.write('Error while calling %s: ' % invoked + repr(sys.exc_info()[1])) for fd in [0, 1, 2]: safeClose(fd) exit_without_cleanup(os.EX_OSERR) exit_without_cleanup(os.EX_OK) else: # Still in the parent process - setup threads to communicate with external program safeClose(fd_child_terminal) safeClose(fd_child_stderr) thread = threading.Thread(target=self._interact_with_child, args=(fd_parent_stdin, fd_parent_stdout, fd_parent_stderr)) thread.daemon = True thread.start()
def test_ignore_ioerror_in_readall_if_nonempty_result(self): # this is the behavior of regular files in CPython 2.7, as # well as of _io.FileIO at least in CPython 3.3. This is # *not* the behavior of _io.FileIO in CPython 3.4 or 3.5; # see CPython's issue #21090. try: from os import openpty except ImportError: pytest.skip('no openpty on this platform') read_fd, write_fd = openpty() os.write(write_fd, 'Abc\n') os.close(write_fd) x = streamio.DiskFile(read_fd) s = x.readall() assert s == 'Abc\r\n' pytest.raises(OSError, x.readall) x.close()