Python pty.fork() Examples

The following are 30 code examples of pty.fork(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module pty , or try the search function .
Example #1
Source File: stack_symbolizer.py    From clusterfuzz with Apache License 2.0 6 votes vote down vote up
def __init__(self, args, close_stderr=False):
    pid, fd = pty.fork()
    if pid == 0:
      # We're the child. Transfer control to command.
      if close_stderr:
        dev_null = os.open('/dev/null', 0)
        os.dup2(dev_null, 2)
      os.execvp(args[0], args)
    else:
      # Disable echoing.
      attr = termios.tcgetattr(fd)
      attr[3] = attr[3] & ~termios.ECHO
      termios.tcsetattr(fd, termios.TCSANOW, attr)
      # Set up a file()-like interface to the child process
      self.r = os.fdopen(fd, 'r', 1)
      self.w = os.fdopen(os.dup(fd), 'w', 1) 
Example #2
Source File: tty_test.py    From dumb-init with MIT License 6 votes vote down vote up
def test_child_gets_controlling_tty_if_we_had_one():
    """If dumb-init has a controlling TTY, it should give it to the child.

    To test this, we make a new TTY then exec "dumb-init bash" and ensure that
    the shell has working job control.
    """
    pid, sfd = pty.fork()
    if pid == 0:
        os.execvp('dumb-init', ('dumb-init', 'bash', '-m'))
    else:
        ttyflags(sfd)

        # We might get lots of extra output from the shell, so print something
        # we can match on easily.
        assert os.write(sfd, b'echo "flags are: [[$-]]"\n') == 25
        assert os.write(sfd, b'exit 0\n') == 7
        output = readall(sfd)
        assert os.waitpid(pid, 0) == (pid, 0), output

        m = re.search(b'flags are: \\[\\[([a-zA-Z]+)\\]\\]\n', output)
        assert m, output

        # "m" is job control
        flags = m.group(1)
        assert b'm' in flags 
Example #3
Source File: epdb_server.py    From epdb with MIT License 6 votes vote down vote up
def handle(self):
        masterFd, slaveFd = pty.openpty()
        try:
            # if we're not in the main thread, this will not work.
            signal.signal(signal.SIGTTOU, signal.SIG_IGN)
        except:  # noqa
            pass
        pid = os.fork()
        if pid:
            os.close(masterFd)
            raise SocketConnected(slaveFd, pid)
            # make parent process the pty slave - the opposite of
            # pty.fork().  In this setup, the parent process continues
            # to act normally, while the child process performs the
            # logging.  This makes it simple to kill the logging process
            # when we are done with it and restore the parent process to
            # normal, unlogged operation.
        else:
            os.close(slaveFd)
            try:
                protocol = TelnetServerProtocolHandler(self.request, masterFd)
                protocol.handle()
            finally:
                os.close(masterFd)
                os._exit(1) 
Example #4
Source File: terminal.py    From ashier with Apache License 2.0 6 votes vote down vote up
def SpawnPTY(argv):
  """Spawn a process and connect its controlling terminal to a PTY.

  Create a new PTY device and spawn a process with the controlling
  terminal of the child process set to the slave end of the new PTY.

  Args:
    argv: arguments (including executable name) for the child process.

  Returns:
    A pair containing the PID of the child process and the file
    descriptor for the master end of the new PTY device.
  """

  assert argv, 'SpawnPTY: argv is an empty list'

  (pid, fd) = pty.fork()
  if pid == 0:
    try:
      os.execvp(argv[0], argv)
    except OSError as err:
      print "# Error: cannot execute program '%s'" % argv[0]
      print '# %s\n%s' % (str(err), chr(4))
      sys.exit(1)
  return (pid, fd) 
Example #5
Source File: vterm.py    From anyMesh-Python with MIT License 6 votes vote down vote up
def spawn(self):
        env = self.env
        env['TERM'] = 'linux'

        self.pid, self.master = pty.fork()

        if self.pid == 0:
            if callable(self.command):
                try:
                    try:
                        self.command()
                    except:
                        sys.stderr.write(traceback.format_exc())
                        sys.stderr.flush()
                finally:
                    os._exit(0)
            else:
                os.execvpe(self.command[0], self.command, env)

        if self.main_loop is None:
            fcntl.fcntl(self.master, fcntl.F_SETFL, os.O_NONBLOCK)

        atexit.register(self.terminate) 
Example #6
Source File: epdb_server.py    From conary with Apache License 2.0 5 votes vote down vote up
def handle(self):
        masterFd, slaveFd = pty.openpty()

        try:
            # if we're not in the main thread, this will not work.
            signal.signal(signal.SIGTTOU, signal.SIG_IGN)
        except:
            pass
        pid = os.fork()
        if pid:
            os.close(masterFd)
            raise SocketConnected(slaveFd, pid)
            # make parent process the pty slave - the opposite of
            # pty.fork().  In this setup, the parent process continues
            # to act normally, while the child process performs the
            # logging.  This makes it simple to kill the logging process
            # when we are done with it and restore the parent process to
            # normal, unlogged operation.
        else:
            os.close(slaveFd)
            try:
                protocol = TelnetServerProtocolHandler(self.request, masterFd)
                protocol.handle()
            finally:
                os.close(masterFd)
                os._exit(1) 
Example #7
Source File: test_keyboard.py    From MARA_Framework with GNU Lesser General Public License v3.0 5 votes vote down vote up
def test_inkey_0s_raw_ctrl_c():
    "0-second inkey with raw allows receiving ^C."
    pid, master_fd = pty.fork()
    if pid is 0:  # child
        try:
            cov = __import__('cov_core_init').init()
        except ImportError:
            cov = None
        term = TestTerminal()
        read_until_semaphore(sys.__stdin__.fileno(), semaphore=SEMAPHORE)
        with term.raw():
            os.write(sys.__stdout__.fileno(), RECV_SEMAPHORE)
            inp = term.inkey(timeout=0)
            os.write(sys.__stdout__.fileno(), inp.encode('latin1'))
        if cov is not None:
            cov.stop()
            cov.save()
        os._exit(0)

    with echo_off(master_fd):
        os.write(master_fd, SEND_SEMAPHORE)
        # ensure child is in raw mode before sending ^C,
        read_until_semaphore(master_fd)
        os.write(master_fd, u'\x03'.encode('latin1'))
        stime = time.time()
        output = read_until_eof(master_fd)
    pid, status = os.waitpid(pid, 0)
    if os.environ.get('TRAVIS', None) is not None:
        # For some reason, setraw has no effect travis-ci,
        # is still accepts ^C, causing system exit on py26,
        # but exit 0 on py27, and either way on py33
        # .. strange, huh?
        assert output in (u'', u'\x03')
        assert os.WEXITSTATUS(status) in (0, 2)
    else:
        assert (output == u'\x03' or
                output == u'' and not os.isatty(0))
        assert os.WEXITSTATUS(status) == 0
    assert math.floor(time.time() - stime) == 0.0 
Example #8
Source File: test_keyboard.py    From MARA_Framework with GNU Lesser General Public License v3.0 5 votes vote down vote up
def test_inkey_0s_cbreak_sequence():
    "0-second inkey with multibyte sequence; should decode immediately."
    pid, master_fd = pty.fork()
    if pid is 0:  # child
        try:
            cov = __import__('cov_core_init').init()
        except ImportError:
            cov = None
        term = TestTerminal()
        os.write(sys.__stdout__.fileno(), SEMAPHORE)
        with term.cbreak():
            inp = term.inkey(timeout=0)
            os.write(sys.__stdout__.fileno(), inp.name.encode('ascii'))
            sys.stdout.flush()
        if cov is not None:
            cov.stop()
            cov.save()
        os._exit(0)

    with echo_off(master_fd):
        os.write(master_fd, u'\x1b[D'.encode('ascii'))
        read_until_semaphore(master_fd)
        stime = time.time()
        output = read_until_eof(master_fd)
    pid, status = os.waitpid(pid, 0)
    assert output == u'KEY_LEFT'
    assert os.WEXITSTATUS(status) == 0
    assert math.floor(time.time() - stime) == 0.0 
Example #9
Source File: test_keyboard.py    From MARA_Framework with GNU Lesser General Public License v3.0 5 votes vote down vote up
def test_inkey_1s_cbreak_input():
    "1-second inkey w/multibyte sequence; should return after ~1 second."
    pid, master_fd = pty.fork()
    if pid is 0:  # child
        try:
            cov = __import__('cov_core_init').init()
        except ImportError:
            cov = None
        term = TestTerminal()
        os.write(sys.__stdout__.fileno(), SEMAPHORE)
        with term.cbreak():
            inp = term.inkey(timeout=3)
            os.write(sys.__stdout__.fileno(), inp.name.encode('utf-8'))
            sys.stdout.flush()
        if cov is not None:
            cov.stop()
            cov.save()
        os._exit(0)

    with echo_off(master_fd):
        read_until_semaphore(master_fd)
        stime = time.time()
        time.sleep(1)
        os.write(master_fd, u'\x1b[C'.encode('ascii'))
        output = read_until_eof(master_fd)

    pid, status = os.waitpid(pid, 0)
    assert output == u'KEY_RIGHT'
    assert os.WEXITSTATUS(status) == 0
    assert math.floor(time.time() - stime) == 1.0 
Example #10
Source File: linux_pty.py    From TerminalView with MIT License 5 votes vote down vote up
def __init__(self, cmd, cwd):
        self._cmd_return_code = 0
        self._cmd_kill_signal = 0
        self._shell_pid, self._master_fd = pty.fork()
        if self._shell_pid == pty.CHILD:
            os.environ["TERM"] = "linux"
            os.chdir(cwd)
            os.execv(cmd[0], cmd) 
Example #11
Source File: test_keyboard.py    From MARA_Framework with GNU Lesser General Public License v3.0 5 votes vote down vote up
def test_esc_delay_cbreak_timout_0():
    """esc_delay still in effect with timeout of 0 ("nonblocking")."""
    pid, master_fd = pty.fork()
    if pid is 0:  # child
        try:
            cov = __import__('cov_core_init').init()
        except ImportError:
            cov = None
        term = TestTerminal()
        os.write(sys.__stdout__.fileno(), SEMAPHORE)
        with term.cbreak():
            stime = time.time()
            inp = term.inkey(timeout=0)
            measured_time = (time.time() - stime) * 100
            os.write(sys.__stdout__.fileno(), (
                '%s %i' % (inp.name, measured_time,)).encode('ascii'))
            sys.stdout.flush()
        if cov is not None:
            cov.stop()
            cov.save()
        os._exit(0)

    with echo_off(master_fd):
        os.write(master_fd, u'\x1b'.encode('ascii'))
        read_until_semaphore(master_fd)
        stime = time.time()
        key_name, duration_ms = read_until_eof(master_fd).split()

    pid, status = os.waitpid(pid, 0)
    assert key_name == u'KEY_ESCAPE'
    assert os.WEXITSTATUS(status) == 0
    assert math.floor(time.time() - stime) == 0.0
    assert 35 <= int(duration_ms) <= 45, int(duration_ms) 
Example #12
Source File: utils.py    From libvirt-test-API with GNU General Public License v2.0 5 votes vote down vote up
def remote_exec(hostname, username, password, cmd):
    """Remote execution on specified host"""
    global subproc_flag
    pid, fd = pty.fork()
    if pid == 0:
        try:
            os.execv("/usr/bin/ssh", ["/usr/bin/ssh", "-l",
                                      username, hostname, cmd])
        except OSError as err:
            print("OSError: " + str(err))
            return -1
    else:
        signal.signal(signal.SIGCHLD, subproc)
        try:
            timeout = 50
            i = 0
            while i <= timeout:
                time.sleep(1)
                output = os.read(fd, 10240)
                if re.search(r'(yes\/no)', output):
                    os.write(fd, "yes\r")
                elif re.search('password:', output):
                    os.write(fd, password + "\r")
                elif subproc_flag == 1:
                    ret = output.decode().strip()
                    break
                elif i == timeout:
                    print("TIMEOUT!!!!")
                    return -1

                i = i+1

            subproc_flag = 0
            return ret
        except Exception as err:
            print(err)
            subproc_flag = 0
            return -1 
Example #13
Source File: TerminalProcess.py    From deprecated-binaryninja-python with GNU General Public License v2.0 5 votes vote down vote up
def restart(self, cmd):
		if not self.completed:
			self.process_input("\n\033[01;31mProcess killed.\033[00m\r\n")
			os.kill(self.pid, signal.SIGHUP)
			thread = self.thread
			thread.stop()
			while thread.alive:
				QCoreApplication.processEvents()

		self.exit_pipe, child_pipe = os.pipe()
		pid, fd = pty.fork()
		if pid == 0:
			try:
				os.environ["TERM"] = "xterm-256color"
				retval = subprocess.call(cmd, close_fds=True)
				os.write(2, "\033[01;34mProcess has completed.\033[00m\n")
				os.write(child_pipe, "t")
				os._exit(retval)
			except:
				pass
			os.write(2, "\033[01;31mCommand '" + cmd[0] + "' failed to execute.\033[00m\n")
			os.write(child_pipe, "f")
			os._exit(1)

		os.close(child_pipe)
		self.process_input("\033[01;34mStarted process with PID %d.\033[00m\r\n" % pid)

		self.pid = pid
		self.data_pipe = fd
		self.completed = False

		# Initialize terminal settings
		fcntl.ioctl(self.data_pipe, termios.TIOCSWINSZ, struct.pack("hhhh", self.rows, self.cols, 0, 0))
		attribute = termios.tcgetattr(self.data_pipe)
		termios.tcsetattr(self.data_pipe, termios.TCSAFLUSH, attribute)

		self.thread = TerminalUpdateThread(self, self.data_pipe, self.exit_pipe)
		self.thread.start() 
Example #14
Source File: utils.py    From dusty with MIT License 5 votes vote down vote up
def pty_fork(*args):
    """Runs a subprocess with a PTY attached via fork and exec.
    The output from the PTY is streamed through log_to_client.
    This should not be necessary for most subprocesses, we
    built this to handle Compose up which only streams pull
    progress if it is attached to a TTY."""

    updated_env = copy(os.environ)
    updated_env.update(get_docker_env())
    args += (updated_env,)
    executable = args[0]
    demote_fn = demote_to_user(get_config_value(constants.CONFIG_MAC_USERNAME_KEY))

    child_pid, pty_fd = pty.fork()
    if child_pid == 0:
        demote_fn()
        os.execle(_executable_path(executable), *args)
    else:
        child_process = psutil.Process(child_pid)
        terminal = os.fdopen(pty_fd, 'r', 0)
        with streaming_to_client():
            while child_process.status() == 'running':
                output = terminal.read(1)
                log_to_client(output)
        _, exit_code = os.waitpid(child_pid, 0)
        if exit_code != 0:
            raise subprocess.CalledProcessError(exit_code, ' '.join(args[:-1])) 
Example #15
Source File: epdb_server.py    From conary with Apache License 2.0 5 votes vote down vote up
def handle(self):
        """
            Creates a child process that is fully controlled by this
            request handler, and serves data to and from it via the 
            protocol handler.
        """
        pid, fd = pty.fork()
        if pid:
            protocol = TelnetServerProtocolHandler(self.request, fd)
            protocol.handle()
        else:
            self.execute() 
Example #16
Source File: test_keyboard.py    From MARA_Framework with GNU Lesser General Public License v3.0 5 votes vote down vote up
def test_esc_delay_cbreak_135():
    "esc_delay=1.35 will cause a single ESC (\\x1b) to delay for 1.35."
    pid, master_fd = pty.fork()
    if pid is 0:  # child
        try:
            cov = __import__('cov_core_init').init()
        except ImportError:
            cov = None
        term = TestTerminal()
        os.write(sys.__stdout__.fileno(), SEMAPHORE)
        with term.cbreak():
            stime = time.time()
            inp = term.inkey(timeout=5, esc_delay=1.35)
            measured_time = (time.time() - stime) * 100
            os.write(sys.__stdout__.fileno(), (
                '%s %i' % (inp.name, measured_time,)).encode('ascii'))
            sys.stdout.flush()
        if cov is not None:
            cov.stop()
            cov.save()
        os._exit(0)

    with echo_off(master_fd):
        read_until_semaphore(master_fd)
        stime = time.time()
        os.write(master_fd, u'\x1b'.encode('ascii'))
        key_name, duration_ms = read_until_eof(master_fd).split()

    pid, status = os.waitpid(pid, 0)
    assert key_name == u'KEY_ESCAPE'
    assert os.WEXITSTATUS(status) == 0
    assert math.floor(time.time() - stime) == 1.0
    assert 135 <= int(duration_ms) <= 145, int(duration_ms) 
Example #17
Source File: epdb_server.py    From epdb with MIT License 5 votes vote down vote up
def handle(self):
        """
            Creates a child process that is fully controlled by this
            request handler, and serves data to and from it via the
            protocol handler.
        """
        pid, fd = pty.fork()
        if pid:
            protocol = TelnetServerProtocolHandler(self.request, fd)
            protocol.handle()
        else:
            self.execute() 
Example #18
Source File: app.py    From pyxterm.js with MIT License 5 votes vote down vote up
def connect():
    """new client connected"""

    if app.config["child_pid"]:
        # already started child process, don't start another
        return

    # create child process attached to a pty we can read from and write to
    (child_pid, fd) = pty.fork()
    if child_pid == 0:
        # this is the child process fork.
        # anything printed here will show up in the pty, including the output
        # of this subprocess
        subprocess.run(app.config["cmd"])
    else:
        # this is the parent process fork.
        # store child fd and pid
        app.config["fd"] = fd
        app.config["child_pid"] = child_pid
        set_winsize(fd, 50, 50)
        cmd = " ".join(shlex.quote(c) for c in app.config["cmd"])
        print("child pid is", child_pid)
        print(
            f"starting background task with command `{cmd}` to continously read "
            "and forward pty output to client"
        )
        socketio.start_background_task(target=read_and_forward_pty_output)
        print("task started") 
Example #19
Source File: remote_dispatcher.py    From polysh with GNU General Public License v2.0 5 votes vote down vote up
def __init__(self, hostname: str, port: str) -> None:
        if port != "22":
            port = "-p " + port
        else:
            port = ''

        self.pid, fd = pty.fork()
        if self.pid == 0:
            # Child
            self.launch_ssh(hostname, port)
            sys.exit(1)

        # Parent
        super().__init__(fd)
        self.temporary = False
        self.hostname = hostname
        self.port = port
        self.debug = options.debug
        self.enabled = True  # shells can be enabled and disabled
        self.state = STATE_NOT_STARTED
        self.term_size = (-1, -1)
        self.display_name = None  # type: Optional[str]
        self.change_name(self.hostname.encode())
        self.init_string = self.configure_tty() + self.set_prompt()
        self.init_string_sent = False
        self.read_in_state_not_started = b''
        self.command = options.command
        self.last_printed_line = b''
        self.color_code = None
        if sys.stdout.isatty() and not options.disable_color:
            COLORS.insert(0, COLORS.pop())  # Rotate the colors
            self.color_code = COLORS[0] 
Example #20
Source File: step_definitions.py    From dockerpty with Apache License 2.0 5 votes vote down vote up
def alloc_pty(ctx, f, *args, **kwargs):
    pid, fd = pty.fork()

    if pid == pty.CHILD:
        tty = os.ttyname(0)

        sys.stdin = open(tty, 'r')
        sys.stdout = open(tty, 'w')
        sys.stderr = open(tty, 'w')

        # alternative way of doing ^ is to do:
        # kwargs["stdout"] = open(tty, 'w')
        # kwargs["stderr"] = open(tty, 'w')
        # kwargs["stdin"] = open(tty, 'r')

        # Create a new client for the child process to avoid concurrency issues
        client = get_client()
        f(client, *args, **kwargs)
        sys.exit(0)
    else:
        ctx.pty = fd
        util.set_pty_size(
            ctx.pty,
            (ctx.rows, ctx.cols)
        )
        ctx.pid = pid
        util.wait(ctx.pty, timeout=5)
    time.sleep(1)  # give the terminal some time to print prompt

    # util.exit_code can be called only once
    ctx.exit_code = util.exit_code(ctx.pid, timeout=5)
    if ctx.exit_code != 0:
        raise Exception("child process did not finish correctly") 
Example #21
Source File: pexpect.py    From lpts with GNU General Public License v2.0 5 votes vote down vote up
def __fork_pty(self):

        """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 ExceptionPexpect, "Error! Could not open pty with os.openpty()."

        pid = os.fork()
        if pid < 0:
            raise ExceptionPexpect, "Error! Failed os.fork()."
        elif pid == 0:
            # Child.
            os.close(parent_fd)
            self.__pty_make_controlling_tty(child_fd)

            os.dup2(child_fd, 0)
            os.dup2(child_fd, 1)
            os.dup2(child_fd, 2)

            if child_fd > 2:
                os.close(child_fd)
        else:
            # Parent.
            os.close(child_fd)

        return pid, parent_fd 
Example #22
Source File: tty_test.py    From dumb-init with MIT License 5 votes vote down vote up
def test_tty():
    """Ensure processes under dumb-init can write successfully, given a tty."""
    pid, fd = pty.fork()
    if pid == 0:
        os.execvp('dumb-init', ('dumb-init', 'tac'))
    else:
        # write to tac via the pty and verify its output
        ttyflags(fd)
        assert os.write(fd, b'1\n2\n3\n') == 6
        assert os.write(fd, EOF * 2) == 2
        output = readall(fd)
        assert os.waitpid(pid, 0) == (pid, 0)

        assert output == b'3\n2\n1\n', repr(output) 
Example #23
Source File: tty_test.py    From dumb-init with MIT License 5 votes vote down vote up
def test_sighup_sigcont_ignored_if_was_session_leader():
    """The first SIGHUP/SIGCONT should be ignored if dumb-init is the session leader.

    Due to TTY quirks (#136), when dumb-init is the session leader and forks,
    it needs to avoid forwarding the first SIGHUP and SIGCONT to the child.
    Otherwise, the child might receive the SIGHUP post-exec and terminate
    itself.

    You can "force" this race by adding a `sleep(1)` before the signal handling
    loop in dumb-init's code, but it's hard to reproduce the race reliably in a
    test otherwise. Because of this, we're stuck just asserting debug messages.
    """
    pid, fd = pty.fork()
    if pid == 0:
        # child
        os.execvp('dumb-init', ('dumb-init', '-v', 'sleep', '20'))
    else:
        # parent
        ttyflags(fd)

        # send another SIGCONT to make sure only the first is ignored
        time.sleep(0.5)
        os.kill(pid, signal.SIGHUP)

        output = readall(fd).decode('UTF-8')

        assert 'Ignoring tty hand-off signal {}.'.format(signal.SIGHUP) in output
        assert 'Ignoring tty hand-off signal {}.'.format(signal.SIGCONT) in output

        assert '[dumb-init] Forwarded signal {} to children.'.format(signal.SIGHUP) in output
        assert '[dumb-init] Forwarded signal {} to children.'.format(signal.SIGCONT) not in output 
Example #24
Source File: test_keyboard.py    From MARA_Framework with GNU Lesser General Public License v3.0 5 votes vote down vote up
def test_inkey_cbreak_input_slowly():
    "0-second inkey with input; Keypress should be immediately returned."
    pid, master_fd = pty.fork()
    if pid is 0:
        try:
            cov = __import__('cov_core_init').init()
        except ImportError:
            cov = None
        # child pauses, writes semaphore and begins awaiting input
        term = TestTerminal()
        read_until_semaphore(sys.__stdin__.fileno(), semaphore=SEMAPHORE)
        os.write(sys.__stdout__.fileno(), SEMAPHORE)
        with term.cbreak():
            while True:
                inp = term.inkey(timeout=0.5)
                os.write(sys.__stdout__.fileno(), inp.encode('utf-8'))
                if inp == 'X':
                    break
        if cov is not None:
            cov.stop()
            cov.save()
        os._exit(0)

    with echo_off(master_fd):
        os.write(master_fd, SEND_SEMAPHORE)
        os.write(master_fd, u'a'.encode('ascii'))
        time.sleep(0.1)
        os.write(master_fd, u'b'.encode('ascii'))
        time.sleep(0.1)
        os.write(master_fd, u'cdefgh'.encode('ascii'))
        time.sleep(0.1)
        os.write(master_fd, u'X'.encode('ascii'))
        read_until_semaphore(master_fd)
        stime = time.time()
        output = read_until_eof(master_fd)

    pid, status = os.waitpid(pid, 0)
    assert output == u'abcdefghX'
    assert os.WEXITSTATUS(status) == 0
    assert math.floor(time.time() - stime) == 0.0 
Example #25
Source File: pexpect.py    From smod-1 with GNU General Public License v2.0 5 votes vote down vote up
def __fork_pty(self):

        """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 ExceptionPexpect, "Error! Could not open pty with os.openpty()."

        pid = os.fork()
        if pid < 0:
            raise ExceptionPexpect, "Error! Failed os.fork()."
        elif pid == 0:
            # Child.
            os.close(parent_fd)
            self.__pty_make_controlling_tty(child_fd)

            os.dup2(child_fd, 0)
            os.dup2(child_fd, 1)
            os.dup2(child_fd, 2)

            if child_fd > 2:
                os.close(child_fd)
        else:
            # Parent.
            os.close(child_fd)

        return pid, parent_fd 
Example #26
Source File: __init__.py    From camr with GNU General Public License v2.0 5 votes vote down vote up
def __fork_pty(self):
        '''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 ExceptionPexpect("Could not open with os.openpty().")

        pid = os.fork()
        if pid == pty.CHILD:
            # Child.
            os.close(parent_fd)
            self.__pty_make_controlling_tty(child_fd)

            os.dup2(child_fd, self.STDIN_FILENO)
            os.dup2(child_fd, self.STDOUT_FILENO)
            os.dup2(child_fd, self.STDERR_FILENO)

        else:
            # Parent.
            os.close(child_fd)

        return pid, parent_fd 
Example #27
Source File: __init__.py    From camr with GNU General Public License v2.0 5 votes vote down vote up
def __pty_make_controlling_tty(self, tty_fd):
        '''This makes the pseudo-terminal the controlling tty. This should be
        more portable than the pty.fork() function. Specifically, this should
        work on Solaris. '''

        child_name = os.ttyname(tty_fd)

        # Disconnect from controlling tty, if any.  Raises OSError of ENXIO
        # if there was no controlling tty to begin with, such as when
        # executed by a cron(1) job.
        try:
            fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY)
            os.close(fd)
        except OSError as err:
            if err.errno != errno.ENXIO:
                raise

        os.setsid()

        # Verify we are disconnected from controlling tty by attempting to open
        # it again.  We expect that OSError of ENXIO should always be raised.
        try:
            fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY)
            os.close(fd)
            raise ExceptionPexpect("OSError of errno.ENXIO should be raised.")
        except OSError as err:
            if err.errno != errno.ENXIO:
                raise

        # Verify we can open child pty.
        fd = os.open(child_name, os.O_RDWR)
        os.close(fd)

        # Verify we now have a controlling tty.
        fd = os.open("/dev/tty", os.O_WRONLY)
        os.close(fd) 
Example #28
Source File: accessories.py    From deepWordBug with Apache License 2.0 5 votes vote down vote up
def read_until_semaphore(fd, semaphore=RECV_SEMAPHORE,
                         encoding='utf8', timeout=10):
    """Read file descriptor ``fd`` until ``semaphore`` is found.

    Used to ensure the child process is awake and ready. For timing
    tests; without a semaphore, the time to fork() would be (incorrectly)
    included in the duration of the test, which can be very length on
    continuous integration servers (such as Travis-CI).
    """
    # note that when a child process writes xyz\\n, the parent
    # process will read xyz\\r\\n -- this is how pseudo terminals
    # behave; a virtual terminal requires both carriage return and
    # line feed, it is only for convenience that \\n does both.
    outp = six.text_type()
    decoder = codecs.getincrementaldecoder(encoding)()
    semaphore = semaphore.decode('ascii')
    while not outp.startswith(semaphore):
        try:
            _exc = os.read(fd, 1)
        except OSError:  # Linux EOF
            break
        if not _exc:     # BSD EOF
            break
        outp += decoder.decode(_exc, final=False)
    assert outp.startswith(semaphore), (
        'Semaphore not recv before EOF '
        '(expected: %r, got: %r)' % (semaphore, outp,))
    return outp[len(semaphore):] 
Example #29
Source File: shell_logger.py    From thefuck with MIT License 5 votes vote down vote up
def _spawn(shell, master_read):
    """Create a spawned process.

    Modified version of pty.spawn with terminal size support.

    """
    pid, master_fd = pty.fork()

    if pid == pty.CHILD:
        os.execlp(shell, shell)

    try:
        mode = tty.tcgetattr(pty.STDIN_FILENO)
        tty.setraw(pty.STDIN_FILENO)
        restore = True
    except tty.error:    # This is the same as termios.error
        restore = False

    _set_pty_size(master_fd)
    signal.signal(signal.SIGWINCH, lambda *_: _set_pty_size(master_fd))

    try:
        pty._copy(master_fd, master_read, pty._read)
    except OSError:
        if restore:
            tty.tcsetattr(pty.STDIN_FILENO, tty.TCSAFLUSH, mode)

    os.close(master_fd)
    return os.waitpid(pid, 0)[1] 
Example #30
Source File: accessories.py    From MARA_Framework with GNU Lesser General Public License v3.0 5 votes vote down vote up
def read_until_semaphore(fd, semaphore=RECV_SEMAPHORE,
                         encoding='utf8', timeout=10):
    """Read file descriptor ``fd`` until ``semaphore`` is found.

    Used to ensure the child process is awake and ready. For timing
    tests; without a semaphore, the time to fork() would be (incorrectly)
    included in the duration of the test, which can be very length on
    continuous integration servers (such as Travis-CI).
    """
    # note that when a child process writes xyz\\n, the parent
    # process will read xyz\\r\\n -- this is how pseudo terminals
    # behave; a virtual terminal requires both carriage return and
    # line feed, it is only for convenience that \\n does both.
    outp = unicode()
    decoder = codecs.getincrementaldecoder(encoding)()
    semaphore = semaphore.decode('ascii')
    while not outp.startswith(semaphore):
        try:
            _exc = os.read(fd, 1)
        except OSError:  # Linux EOF
            break
        if not _exc:     # BSD EOF
            break
        outp += decoder.decode(_exc, final=False)
    assert outp.startswith(semaphore), (
        'Semaphore not recv before EOF '
        '(expected: %r, got: %r)' % (semaphore, outp,))
    return outp[len(semaphore):]