Skip to content
Snippets Groups Projects
Commit 4b30c691 authored by Per Cederqvist's avatar Per Cederqvist
Browse files

(_spawn): New helper function, extracted from Spawn.__init__. New

	argument: use_stderr_pipe.
(Spawn.__init__): New optional argument: use_stderr_pipe.  Set the
	stderr attribute to an Expectable object that represents the
	stderr output from the subprocess it it is true.  Get rid of
	the __pty attribute, and renamed __child to __child_pid.
(Spawn.send): Use self.fileno() instead of self.__pty.
(Spawn.close): Ditto.  Close the stderr pipe if present.
(spawn2): New function.  A possibly easier API if you want to
	have the stderr output in a separate Expectable.
parent f2722e60
No related branches found
No related tags found
No related merge requests found
......@@ -7,7 +7,8 @@ import pcl_expect
__all__ = [
"inherit_stty",
"stty_init",
"spawn",
"Spawn",
"spawn2",
]
# When a new pty is created by spawn(), the terminal settings will be
......@@ -22,8 +23,7 @@ def set_cloexec_flag(fd):
old = fcntl.fcntl(fd, fcntl.F_GETFD)
fcntl.fcntl(fd, fcntl.F_SETFD, old | fcntl.FD_CLOEXEC)
class Spawn(pcl_expect.Expectable):
def __init__(self, cmd):
def _spawn(cmd, use_stderr_pipe):
if inherit_stty:
f = os.popen("stty -g")
settings = f.read()
......@@ -32,37 +32,62 @@ class Spawn(pcl_expect.Expectable):
if isinstance(cmd, basestring):
cmd = cmd.split(" ")
(r, w) = os.pipe()
if use_stderr_pipe:
(stderr_r, stderr_w) = os.pipe()
else:
stderr_r = None
set_cloexec_flag(w)
self.__child, self.__pty = pty.fork()
if self.__child == 0:
pid, fd = pty.fork()
if pid == 0:
try:
os.close(r)
if inherit_stty:
os.system("stty %s" % settings)
if stty_init is not None:
os.system("stty %s" % stty_init)
if use_stderr_pipe:
os.close(stderr_r)
os.dup2(stderr_w, 2)
os.close(stderr_w)
try:
os.execvp(cmd[0], cmd)
except OSError:
# FIXME: transfer failure reason.
os.write(w, "exec failed\n")
finally:
os._exit(1)
else:
# In parent.
os.close(w)
if use_stderr_pipe:
os.close(stderr_w)
res = os.read(r, 100)
os.close(r)
if res != "":
os.close(self.__pty)
os.waitpid(self.__child, 0)
os.close(fd)
os.waitpid(pid, 0)
raise OSError("exec failed")
pcl_expect.Expectable.__init__(self, self.__pty)
return pid, fd, stderr_r
class Spawn(pcl_expect.Expectable):
def __init__(self, cmd, use_stderr_pipe = False):
self.__child_pid, fd, stderr = _spawn(cmd, use_stderr_pipe)
pcl_expect.Expectable.__init__(self, fd)
if use_stderr_pipe:
self.stderr = pcl_expect.Expectable(stderr)
def send(self, s):
pcl_expect.debug("sending \"%s\" to fd %d" % (s, self.fileno()))
os.write(self.__pty, s)
os.write(self.fileno(), s)
def close(self):
os.close(self.fileno())
pcl_expect.Expectable.close(self)
os.close(self.__pty)
return os.waitpid(self.__child, 0)
if hasattr(self, "stderr"):
os.close(self.stderr.fileno())
self.stderr.close()
return os.waitpid(self.__child_pid, 0)
def spawn2(cmd):
proc = Spawn(cmd, True)
return proc, proc.stderr
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment