14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"""Spawn a command with pipes to its stdin, stdout, and optionally stderr.
24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmThe normal os.popen(cmd, mode) call spawns a shell command and provides a
44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfile interface to just the input or output of the process depending on
54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmwhether mode is 'r' or 'w'.  This module provides the functions popen2(cmd)
64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmand popen3(cmd) which return two or three pipes to the spawned command.
74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"""
84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport os
104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport sys
114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport warnings
124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmwarnings.warn("The popen2 module is deprecated.  Use the subprocess module.",
134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm              DeprecationWarning, stacklevel=2)
144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm__all__ = ["popen2", "popen3", "popen4"]
164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtry:
184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    MAXFD = os.sysconf('SC_OPEN_MAX')
194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmexcept (AttributeError, ValueError):
204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    MAXFD = 256
214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_active = []
234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _cleanup():
254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    for inst in _active[:]:
264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if inst.poll(_deadstate=sys.maxint) >= 0:
274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try:
284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                _active.remove(inst)
294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            except ValueError:
304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                # This can happen if two threads create a new Popen instance.
314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                # It's harmless that it was already removed, so ignore.
324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                pass
334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass Popen3:
354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    """Class representing a child process.  Normally, instances are created
364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    internally by the functions popen2() and popen3()."""
374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    sts = -1                    # Child not completed yet
394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __init__(self, cmd, capturestderr=False, bufsize=-1):
414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        """The parameter 'cmd' is the shell command to execute in a
424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        sub-process.  On UNIX, 'cmd' may be a sequence, in which case arguments
434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        will be passed directly to the program without shell intervention (as
444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        with os.spawnv()).  If 'cmd' is a string it will be passed to the shell
454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        (as with os.system()).   The 'capturestderr' flag, if true, specifies
464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        that the object should capture standard error output of the child
474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        process.  The default is false.  If the 'bufsize' parameter is
484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        specified, it specifies the size of the I/O buffers to/from the child
494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        process."""
504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        _cleanup()
514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.cmd = cmd
524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        p2cread, p2cwrite = os.pipe()
534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        c2pread, c2pwrite = os.pipe()
544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if capturestderr:
554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            errout, errin = os.pipe()
564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.pid = os.fork()
574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if self.pid == 0:
584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # Child
594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            os.dup2(p2cread, 0)
604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            os.dup2(c2pwrite, 1)
614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if capturestderr:
624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                os.dup2(errin, 2)
634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self._run_child(cmd)
644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        os.close(p2cread)
654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.tochild = os.fdopen(p2cwrite, 'w', bufsize)
664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        os.close(c2pwrite)
674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.fromchild = os.fdopen(c2pread, 'r', bufsize)
684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if capturestderr:
694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            os.close(errin)
704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.childerr = os.fdopen(errout, 'r', bufsize)
714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else:
724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.childerr = None
734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __del__(self):
754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # In case the child hasn't been waited on, check if it's done.
764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.poll(_deadstate=sys.maxint)
774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if self.sts < 0:
784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if _active is not None:
794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                # Child is still running, keep us alive until we can wait on it.
804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                _active.append(self)
814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def _run_child(self, cmd):
834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if isinstance(cmd, basestring):
844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            cmd = ['/bin/sh', '-c', cmd]
854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        os.closerange(3, MAXFD)
864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        try:
874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            os.execvp(cmd[0], cmd)
884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        finally:
894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            os._exit(1)
904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def poll(self, _deadstate=None):
924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        """Return the exit status of the child process if it has finished,
934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        or -1 if it hasn't finished yet."""
944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if self.sts < 0:
954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            try:
964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                pid, sts = os.waitpid(self.pid, os.WNOHANG)
974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                # pid will be 0 if self.pid hasn't terminated
984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if pid == self.pid:
994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    self.sts = sts
1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            except os.error:
1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if _deadstate is not None:
1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    self.sts = _deadstate
1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.sts
1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def wait(self):
1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        """Wait for and return the exit status of the child process."""
1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if self.sts < 0:
1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pid, sts = os.waitpid(self.pid, 0)
1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # This used to be a test, but it is believed to be
1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # always true, so I changed it to an assertion - mvl
1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            assert pid == self.pid
1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.sts = sts
1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.sts
1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass Popen4(Popen3):
1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    childerr = None
1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __init__(self, cmd, bufsize=-1):
1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        _cleanup()
1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.cmd = cmd
1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        p2cread, p2cwrite = os.pipe()
1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        c2pread, c2pwrite = os.pipe()
1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.pid = os.fork()
1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if self.pid == 0:
1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # Child
1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            os.dup2(p2cread, 0)
1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            os.dup2(c2pwrite, 1)
1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            os.dup2(c2pwrite, 2)
1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self._run_child(cmd)
1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        os.close(p2cread)
1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.tochild = os.fdopen(p2cwrite, 'w', bufsize)
1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        os.close(c2pwrite)
1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.fromchild = os.fdopen(c2pread, 'r', bufsize)
1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmif sys.platform[:3] == "win" or sys.platform == "os2emx":
1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    # Some things don't make sense on non-Unix platforms.
1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    del Popen3, Popen4
1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def popen2(cmd, bufsize=-1, mode='t'):
1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        be a sequence, in which case arguments will be passed directly to the
1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        program without shell intervention (as with os.spawnv()). If 'cmd' is a
1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        string it will be passed to the shell (as with os.system()). If
1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        'bufsize' is specified, it sets the buffer size for the I/O pipes. The
1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        file objects (child_stdout, child_stdin) are returned."""
1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        w, r = os.popen2(cmd, mode, bufsize)
1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return r, w
1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def popen3(cmd, bufsize=-1, mode='t'):
1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        be a sequence, in which case arguments will be passed directly to the
1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        program without shell intervention (as with os.spawnv()). If 'cmd' is a
1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        string it will be passed to the shell (as with os.system()). If
1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        'bufsize' is specified, it sets the buffer size for the I/O pipes. The
1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        file objects (child_stdout, child_stdin, child_stderr) are returned."""
1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        w, r, e = os.popen3(cmd, mode, bufsize)
1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return r, w, e
1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def popen4(cmd, bufsize=-1, mode='t'):
1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        be a sequence, in which case arguments will be passed directly to the
1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        program without shell intervention (as with os.spawnv()). If 'cmd' is a
1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        string it will be passed to the shell (as with os.system()). If
1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        'bufsize' is specified, it sets the buffer size for the I/O pipes. The
1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        file objects (child_stdout_stderr, child_stdin) are returned."""
1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        w, r = os.popen4(cmd, mode, bufsize)
1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return r, w
1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmelse:
1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def popen2(cmd, bufsize=-1, mode='t'):
1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        be a sequence, in which case arguments will be passed directly to the
1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        program without shell intervention (as with os.spawnv()). If 'cmd' is a
1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        string it will be passed to the shell (as with os.system()). If
1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        'bufsize' is specified, it sets the buffer size for the I/O pipes. The
1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        file objects (child_stdout, child_stdin) are returned."""
1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        inst = Popen3(cmd, False, bufsize)
1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return inst.fromchild, inst.tochild
1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def popen3(cmd, bufsize=-1, mode='t'):
1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        be a sequence, in which case arguments will be passed directly to the
1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        program without shell intervention (as with os.spawnv()). If 'cmd' is a
1854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        string it will be passed to the shell (as with os.system()). If
1864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        'bufsize' is specified, it sets the buffer size for the I/O pipes. The
1874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        file objects (child_stdout, child_stdin, child_stderr) are returned."""
1884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        inst = Popen3(cmd, True, bufsize)
1894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return inst.fromchild, inst.tochild, inst.childerr
1904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def popen4(cmd, bufsize=-1, mode='t'):
1924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
1934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        be a sequence, in which case arguments will be passed directly to the
1944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        program without shell intervention (as with os.spawnv()). If 'cmd' is a
1954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        string it will be passed to the shell (as with os.system()). If
1964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        'bufsize' is specified, it sets the buffer size for the I/O pipes. The
1974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        file objects (child_stdout_stderr, child_stdin) are returned."""
1984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        inst = Popen4(cmd, bufsize)
1994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return inst.fromchild, inst.tochild
2004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    __all__.extend(["Popen3", "Popen4"])
202