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