*** Python-2.3-orig/Lib/popen2.py Mon Jul 7 16:36:19 2003 --- Python-2.3/Lib/popen2.py Wed Oct 1 13:40:25 2003 *************** *** 2,9 **** The normal os.popen(cmd, mode) call spawns a shell command and provides a file interface to just the input or output of the process depending on ! whether mode is 'r' or 'w'. This module provides the functions popen2(cmd) ! and popen3(cmd) which return two or three pipes to the spawned command. """ import os --- 2,10 ---- The normal os.popen(cmd, mode) call spawns a shell command and provides a file interface to just the input or output of the process depending on ! whether mode is 'r' or 'w'. This module provides the functions popen2(cmd), ! popen3(cmd), and popen4(cmd) which return two or three pipes to the spawned ! command. """ import os *************** *** 11,19 **** __all__ = ["popen2", "popen3", "popen4"] ! MAXFD = 256 # Max number of file descriptors (os.getdtablesize()???) ! _active = [] def _cleanup(): for inst in _active[:]: --- 12,20 ---- __all__ = ["popen2", "popen3", "popen4"] ! MAXFD = 256 # XXX should be dynamic; need an os.max_fd() wrapper around getdtablesize on POSIX and _getmaxstdio on Windows (although only POSIX systems would use it in this module) ! _active = [] # Popen[34] objects are leaked when popen2._cleanup() or Popen[34].{poll,wait} are not called before the thread that created the objects dies. popen2.popen[234] remove their references manually. def _cleanup(): for inst in _active[:]: *************** *** 21,29 **** class Popen3: """Class representing a child process. Normally instances are created ! by the factory functions popen2() and popen3().""" ! ! sts = -1 # Child not completed yet def __init__(self, cmd, capturestderr=False, bufsize=-1): """The parameter 'cmd' is the shell command to execute in a --- 22,31 ---- class Popen3: """Class representing a child process. Normally instances are created ! by the factory functions popen2(), popen3() and popen4(). Popen3 objects ! are used directly when one is interested in the child's exit status. If ! Popen3 objects are created by multiple threads, popen2._cleanup or ! Popen3.{poll,wait} must be called before the thread exits.""" def __init__(self, cmd, capturestderr=False, bufsize=-1): """The parameter 'cmd' is the shell command to execute in a *************** *** 32,58 **** The default is false. If the 'bufsize' parameter is specified, it specifies the size of the I/O buffers to/from the child process.""" _cleanup() ! p2cread, p2cwrite = os.pipe() ! c2pread, c2pwrite = os.pipe() ! if capturestderr: ! errout, errin = os.pipe() ! self.pid = os.fork() ! if self.pid == 0: ! # Child ! os.dup2(p2cread, 0) ! os.dup2(c2pwrite, 1) if capturestderr: ! os.dup2(errin, 2) ! self._run_child(cmd) ! os.close(p2cread) ! self.tochild = os.fdopen(p2cwrite, 'w', bufsize) ! os.close(c2pwrite) ! self.fromchild = os.fdopen(c2pread, 'r', bufsize) ! if capturestderr: ! os.close(errin) ! self.childerr = os.fdopen(errout, 'r', bufsize) ! else: ! self.childerr = None _active.append(self) def _run_child(self, cmd): --- 34,68 ---- The default is false. If the 'bufsize' parameter is specified, it specifies the size of the I/O buffers to/from the child process.""" _cleanup() ! self.sts = -1 # Child not completed yet ! p2cread = p2cwrite = c2pread = c2pwrite = errout = errin = None ! try: ! p2cread, p2cwrite = os.pipe() ! c2pread, c2pwrite = os.pipe() if capturestderr: ! errout, errin = os.pipe() ! self.pid = os.fork() ! if self.pid == 0: ! # Child ! os.dup2(p2cread, 0) ! os.dup2(c2pwrite, 1) ! if capturestderr: ! os.dup2(errin, 2) ! self._run_child(cmd) ! os.close(p2cread) ! self.tochild = os.fdopen(p2cwrite, 'w', bufsize) ! os.close(c2pwrite) ! self.fromchild = os.fdopen(c2pread, 'r', bufsize) ! if capturestderr: ! os.close(errin) ! self.childerr = os.fdopen(errout, 'r', bufsize) ! else: ! self.childerr = None ! except OSError: ! for fd in p2cread, p2cwrite, c2pread, c2pwrite, errout, errin: ! if fd is not None: ! os.close(fd) ! raise _active.append(self) def _run_child(self, cmd): *************** *** 92,114 **** class Popen4(Popen3): - childerr = None - def __init__(self, cmd, bufsize=-1): _cleanup() ! p2cread, p2cwrite = os.pipe() ! c2pread, c2pwrite = os.pipe() ! self.pid = os.fork() ! if self.pid == 0: ! # Child ! os.dup2(p2cread, 0) ! os.dup2(c2pwrite, 1) ! os.dup2(c2pwrite, 2) ! self._run_child(cmd) ! os.close(p2cread) ! self.tochild = os.fdopen(p2cwrite, 'w', bufsize) ! os.close(c2pwrite) ! self.fromchild = os.fdopen(c2pread, 'r', bufsize) _active.append(self) --- 102,131 ---- class Popen4(Popen3): def __init__(self, cmd, bufsize=-1): _cleanup() ! self.sts = -1 # Child not completed yet ! p2cread = p2cwrite = c2pread = c2pwrite = None ! try: ! p2cread, p2cwrite = os.pipe() ! c2pread, c2pwrite = os.pipe() ! self.pid = os.fork() ! if self.pid == 0: ! # Child ! os.dup2(p2cread, 0) ! os.dup2(c2pwrite, 1) ! os.dup2(c2pwrite, 2) ! self._run_child(cmd) ! os.close(p2cread) ! self.tochild = os.fdopen(p2cwrite, 'w', bufsize) ! os.close(c2pwrite) ! self.fromchild = os.fdopen(c2pread, 'r', bufsize) ! self.childerr = None ! except OSError: ! for fd in p2cread, p2cwrite, c2pread, c2pwrite: ! if fd is not None: ! os.close(fd) ! raise _active.append(self) *************** *** 142,147 **** --- 159,165 ---- specified, it sets the buffer size for the I/O pipes. The file objects (child_stdout, child_stdin) are returned.""" inst = Popen3(cmd, False, bufsize) + _active.remove(inst) return inst.fromchild, inst.tochild def popen3(cmd, bufsize=-1, mode='t'): *************** *** 149,154 **** --- 167,173 ---- specified, it sets the buffer size for the I/O pipes. The file objects (child_stdout, child_stdin, child_stderr) are returned.""" inst = Popen3(cmd, True, bufsize) + _active.remove(inst) return inst.fromchild, inst.tochild, inst.childerr def popen4(cmd, bufsize=-1, mode='t'): *************** *** 156,161 **** --- 175,181 ---- specified, it sets the buffer size for the I/O pipes. The file objects (child_stdout_stderr, child_stdin) are returned.""" inst = Popen4(cmd, bufsize) + _active.remove(inst) return inst.fromchild, inst.tochild __all__.extend(["Popen3", "Popen4"])