symbian-qemu-0.9.1-12/python-win32-2.6.1/lib/popen2.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 """Spawn a command with pipes to its stdin, stdout, and optionally stderr.
       
     2 
       
     3 The normal os.popen(cmd, mode) call spawns a shell command and provides a
       
     4 file interface to just the input or output of the process depending on
       
     5 whether mode is 'r' or 'w'.  This module provides the functions popen2(cmd)
       
     6 and popen3(cmd) which return two or three pipes to the spawned command.
       
     7 """
       
     8 
       
     9 import os
       
    10 import sys
       
    11 import warnings
       
    12 warnings.warn("The popen2 module is deprecated.  Use the subprocess module.",
       
    13               DeprecationWarning, stacklevel=2)
       
    14 
       
    15 __all__ = ["popen2", "popen3", "popen4"]
       
    16 
       
    17 try:
       
    18     MAXFD = os.sysconf('SC_OPEN_MAX')
       
    19 except (AttributeError, ValueError):
       
    20     MAXFD = 256
       
    21 
       
    22 _active = []
       
    23 
       
    24 def _cleanup():
       
    25     for inst in _active[:]:
       
    26         if inst.poll(_deadstate=sys.maxint) >= 0:
       
    27             try:
       
    28                 _active.remove(inst)
       
    29             except ValueError:
       
    30                 # This can happen if two threads create a new Popen instance.
       
    31                 # It's harmless that it was already removed, so ignore.
       
    32                 pass
       
    33 
       
    34 class Popen3:
       
    35     """Class representing a child process.  Normally, instances are created
       
    36     internally by the functions popen2() and popen3()."""
       
    37 
       
    38     sts = -1                    # Child not completed yet
       
    39 
       
    40     def __init__(self, cmd, capturestderr=False, bufsize=-1):
       
    41         """The parameter 'cmd' is the shell command to execute in a
       
    42         sub-process.  On UNIX, 'cmd' may be a sequence, in which case arguments
       
    43         will be passed directly to the program without shell intervention (as
       
    44         with os.spawnv()).  If 'cmd' is a string it will be passed to the shell
       
    45         (as with os.system()).   The 'capturestderr' flag, if true, specifies
       
    46         that the object should capture standard error output of the child
       
    47         process.  The default is false.  If the 'bufsize' parameter is
       
    48         specified, it specifies the size of the I/O buffers to/from the child
       
    49         process."""
       
    50         _cleanup()
       
    51         self.cmd = cmd
       
    52         p2cread, p2cwrite = os.pipe()
       
    53         c2pread, c2pwrite = os.pipe()
       
    54         if capturestderr:
       
    55             errout, errin = os.pipe()
       
    56         self.pid = os.fork()
       
    57         if self.pid == 0:
       
    58             # Child
       
    59             os.dup2(p2cread, 0)
       
    60             os.dup2(c2pwrite, 1)
       
    61             if capturestderr:
       
    62                 os.dup2(errin, 2)
       
    63             self._run_child(cmd)
       
    64         os.close(p2cread)
       
    65         self.tochild = os.fdopen(p2cwrite, 'w', bufsize)
       
    66         os.close(c2pwrite)
       
    67         self.fromchild = os.fdopen(c2pread, 'r', bufsize)
       
    68         if capturestderr:
       
    69             os.close(errin)
       
    70             self.childerr = os.fdopen(errout, 'r', bufsize)
       
    71         else:
       
    72             self.childerr = None
       
    73 
       
    74     def __del__(self):
       
    75         # In case the child hasn't been waited on, check if it's done.
       
    76         self.poll(_deadstate=sys.maxint)
       
    77         if self.sts < 0:
       
    78             if _active is not None:
       
    79                 # Child is still running, keep us alive until we can wait on it.
       
    80                 _active.append(self)
       
    81 
       
    82     def _run_child(self, cmd):
       
    83         if isinstance(cmd, basestring):
       
    84             cmd = ['/bin/sh', '-c', cmd]
       
    85         os.closerange(3, MAXFD)
       
    86         try:
       
    87             os.execvp(cmd[0], cmd)
       
    88         finally:
       
    89             os._exit(1)
       
    90 
       
    91     def poll(self, _deadstate=None):
       
    92         """Return the exit status of the child process if it has finished,
       
    93         or -1 if it hasn't finished yet."""
       
    94         if self.sts < 0:
       
    95             try:
       
    96                 pid, sts = os.waitpid(self.pid, os.WNOHANG)
       
    97                 # pid will be 0 if self.pid hasn't terminated
       
    98                 if pid == self.pid:
       
    99                     self.sts = sts
       
   100             except os.error:
       
   101                 if _deadstate is not None:
       
   102                     self.sts = _deadstate
       
   103         return self.sts
       
   104 
       
   105     def wait(self):
       
   106         """Wait for and return the exit status of the child process."""
       
   107         if self.sts < 0:
       
   108             pid, sts = os.waitpid(self.pid, 0)
       
   109             # This used to be a test, but it is believed to be
       
   110             # always true, so I changed it to an assertion - mvl
       
   111             assert pid == self.pid
       
   112             self.sts = sts
       
   113         return self.sts
       
   114 
       
   115 
       
   116 class Popen4(Popen3):
       
   117     childerr = None
       
   118 
       
   119     def __init__(self, cmd, bufsize=-1):
       
   120         _cleanup()
       
   121         self.cmd = cmd
       
   122         p2cread, p2cwrite = os.pipe()
       
   123         c2pread, c2pwrite = os.pipe()
       
   124         self.pid = os.fork()
       
   125         if self.pid == 0:
       
   126             # Child
       
   127             os.dup2(p2cread, 0)
       
   128             os.dup2(c2pwrite, 1)
       
   129             os.dup2(c2pwrite, 2)
       
   130             self._run_child(cmd)
       
   131         os.close(p2cread)
       
   132         self.tochild = os.fdopen(p2cwrite, 'w', bufsize)
       
   133         os.close(c2pwrite)
       
   134         self.fromchild = os.fdopen(c2pread, 'r', bufsize)
       
   135 
       
   136 
       
   137 if sys.platform[:3] == "win" or sys.platform == "os2emx":
       
   138     # Some things don't make sense on non-Unix platforms.
       
   139     del Popen3, Popen4
       
   140 
       
   141     def popen2(cmd, bufsize=-1, mode='t'):
       
   142         """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
       
   143         be a sequence, in which case arguments will be passed directly to the
       
   144         program without shell intervention (as with os.spawnv()). If 'cmd' is a
       
   145         string it will be passed to the shell (as with os.system()). If
       
   146         'bufsize' is specified, it sets the buffer size for the I/O pipes. The
       
   147         file objects (child_stdout, child_stdin) are returned."""
       
   148         w, r = os.popen2(cmd, mode, bufsize)
       
   149         return r, w
       
   150 
       
   151     def popen3(cmd, bufsize=-1, mode='t'):
       
   152         """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
       
   153         be a sequence, in which case arguments will be passed directly to the
       
   154         program without shell intervention (as with os.spawnv()). If 'cmd' is a
       
   155         string it will be passed to the shell (as with os.system()). If
       
   156         'bufsize' is specified, it sets the buffer size for the I/O pipes. The
       
   157         file objects (child_stdout, child_stdin, child_stderr) are returned."""
       
   158         w, r, e = os.popen3(cmd, mode, bufsize)
       
   159         return r, w, e
       
   160 
       
   161     def popen4(cmd, bufsize=-1, mode='t'):
       
   162         """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
       
   163         be a sequence, in which case arguments will be passed directly to the
       
   164         program without shell intervention (as with os.spawnv()). If 'cmd' is a
       
   165         string it will be passed to the shell (as with os.system()). If
       
   166         'bufsize' is specified, it sets the buffer size for the I/O pipes. The
       
   167         file objects (child_stdout_stderr, child_stdin) are returned."""
       
   168         w, r = os.popen4(cmd, mode, bufsize)
       
   169         return r, w
       
   170 else:
       
   171     def popen2(cmd, bufsize=-1, mode='t'):
       
   172         """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
       
   173         be a sequence, in which case arguments will be passed directly to the
       
   174         program without shell intervention (as with os.spawnv()). If 'cmd' is a
       
   175         string it will be passed to the shell (as with os.system()). If
       
   176         'bufsize' is specified, it sets the buffer size for the I/O pipes. The
       
   177         file objects (child_stdout, child_stdin) are returned."""
       
   178         inst = Popen3(cmd, False, bufsize)
       
   179         return inst.fromchild, inst.tochild
       
   180 
       
   181     def popen3(cmd, bufsize=-1, mode='t'):
       
   182         """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
       
   183         be a sequence, in which case arguments will be passed directly to the
       
   184         program without shell intervention (as with os.spawnv()). If 'cmd' is a
       
   185         string it will be passed to the shell (as with os.system()). If
       
   186         'bufsize' is specified, it sets the buffer size for the I/O pipes. The
       
   187         file objects (child_stdout, child_stdin, child_stderr) are returned."""
       
   188         inst = Popen3(cmd, True, bufsize)
       
   189         return inst.fromchild, inst.tochild, inst.childerr
       
   190 
       
   191     def popen4(cmd, bufsize=-1, mode='t'):
       
   192         """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
       
   193         be a sequence, in which case arguments will be passed directly to the
       
   194         program without shell intervention (as with os.spawnv()). If 'cmd' is a
       
   195         string it will be passed to the shell (as with os.system()). If
       
   196         'bufsize' is specified, it sets the buffer size for the I/O pipes. The
       
   197         file objects (child_stdout_stderr, child_stdin) are returned."""
       
   198         inst = Popen4(cmd, bufsize)
       
   199         return inst.fromchild, inst.tochild
       
   200 
       
   201     __all__.extend(["Popen3", "Popen4"])