PyXR

c:\python24\lib \ subprocess.py



0001 # subprocess - Subprocesses with accessible I/O streams
0002 #
0003 # For more information about this module, see PEP 324.
0004 #
0005 # Copyright (c) 2003-2004 by Peter Astrand <astrand@lysator.liu.se>
0006 #
0007 # By obtaining, using, and/or copying this software and/or its
0008 # associated documentation, you agree that you have read, understood,
0009 # and will comply with the following terms and conditions:
0010 #
0011 # Permission to use, copy, modify, and distribute this software and
0012 # its associated documentation for any purpose and without fee is
0013 # hereby granted, provided that the above copyright notice appears in
0014 # all copies, and that both that copyright notice and this permission
0015 # notice appear in supporting documentation, and that the name of the
0016 # author not be used in advertising or publicity pertaining to
0017 # distribution of the software without specific, written prior
0018 # permission.
0019 #
0020 # THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
0021 # INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
0022 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
0023 # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
0024 # OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
0025 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
0026 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0027 
0028 r"""subprocess - Subprocesses with accessible I/O streams
0029 
0030 This module allows you to spawn processes, connect to their
0031 input/output/error pipes, and obtain their return codes.  This module
0032 intends to replace several other, older modules and functions, like:
0033 
0034 os.system
0035 os.spawn*
0036 os.popen*
0037 popen2.*
0038 commands.*
0039 
0040 Information about how the subprocess module can be used to replace these
0041 modules and functions can be found below.
0042 
0043 
0044 
0045 Using the subprocess module
0046 ===========================
0047 This module defines one class called Popen:
0048 
0049 class Popen(args, bufsize=0, executable=None,
0050             stdin=None, stdout=None, stderr=None,
0051             preexec_fn=None, close_fds=False, shell=False,
0052             cwd=None, env=None, universal_newlines=False,
0053             startupinfo=None, creationflags=0):
0054 
0055 
0056 Arguments are:
0057 
0058 args should be a string, or a sequence of program arguments.  The
0059 program to execute is normally the first item in the args sequence or
0060 string, but can be explicitly set by using the executable argument.
0061 
0062 On UNIX, with shell=False (default): In this case, the Popen class
0063 uses os.execvp() to execute the child program.  args should normally
0064 be a sequence.  A string will be treated as a sequence with the string
0065 as the only item (the program to execute).
0066 
0067 On UNIX, with shell=True: If args is a string, it specifies the
0068 command string to execute through the shell.  If args is a sequence,
0069 the first item specifies the command string, and any additional items
0070 will be treated as additional shell arguments.
0071 
0072 On Windows: the Popen class uses CreateProcess() to execute the child
0073 program, which operates on strings.  If args is a sequence, it will be
0074 converted to a string using the list2cmdline method.  Please note that
0075 not all MS Windows applications interpret the command line the same
0076 way: The list2cmdline is designed for applications using the same
0077 rules as the MS C runtime.
0078 
0079 bufsize, if given, has the same meaning as the corresponding argument
0080 to the built-in open() function: 0 means unbuffered, 1 means line
0081 buffered, any other positive value means use a buffer of
0082 (approximately) that size.  A negative bufsize means to use the system
0083 default, which usually means fully buffered.  The default value for
0084 bufsize is 0 (unbuffered).
0085 
0086 stdin, stdout and stderr specify the executed programs' standard
0087 input, standard output and standard error file handles, respectively.
0088 Valid values are PIPE, an existing file descriptor (a positive
0089 integer), an existing file object, and None.  PIPE indicates that a
0090 new pipe to the child should be created.  With None, no redirection
0091 will occur; the child's file handles will be inherited from the
0092 parent.  Additionally, stderr can be STDOUT, which indicates that the
0093 stderr data from the applications should be captured into the same
0094 file handle as for stdout.
0095 
0096 If preexec_fn is set to a callable object, this object will be called
0097 in the child process just before the child is executed.
0098 
0099 If close_fds is true, all file descriptors except 0, 1 and 2 will be
0100 closed before the child process is executed.
0101 
0102 if shell is true, the specified command will be executed through the
0103 shell.
0104 
0105 If cwd is not None, the current directory will be changed to cwd
0106 before the child is executed.
0107 
0108 If env is not None, it defines the environment variables for the new
0109 process.
0110 
0111 If universal_newlines is true, the file objects stdout and stderr are
0112 opened as a text files, but lines may be terminated by any of '\n',
0113 the Unix end-of-line convention, '\r', the Macintosh convention or
0114 '\r\n', the Windows convention.  All of these external representations
0115 are seen as '\n' by the Python program.  Note: This feature is only
0116 available if Python is built with universal newline support (the
0117 default).  Also, the newlines attribute of the file objects stdout,
0118 stdin and stderr are not updated by the communicate() method.
0119 
0120 The startupinfo and creationflags, if given, will be passed to the
0121 underlying CreateProcess() function.  They can specify things such as
0122 appearance of the main window and priority for the new process.
0123 (Windows only)
0124 
0125 
0126 This module also defines two shortcut functions:
0127 
0128 call(*args, **kwargs):
0129     Run command with arguments.  Wait for command to complete, then
0130     return the returncode attribute.
0131 
0132     The arguments are the same as for the Popen constructor.  Example:
0133 
0134     retcode = call(["ls", "-l"])
0135 
0136 
0137 Exceptions
0138 ----------
0139 Exceptions raised in the child process, before the new program has
0140 started to execute, will be re-raised in the parent.  Additionally,
0141 the exception object will have one extra attribute called
0142 'child_traceback', which is a string containing traceback information
0143 from the childs point of view.
0144 
0145 The most common exception raised is OSError.  This occurs, for
0146 example, when trying to execute a non-existent file.  Applications
0147 should prepare for OSErrors.
0148 
0149 A ValueError will be raised if Popen is called with invalid arguments.
0150 
0151 
0152 Security
0153 --------
0154 Unlike some other popen functions, this implementation will never call
0155 /bin/sh implicitly.  This means that all characters, including shell
0156 metacharacters, can safely be passed to child processes.
0157 
0158 
0159 Popen objects
0160 =============
0161 Instances of the Popen class have the following methods:
0162 
0163 poll()
0164     Check if child process has terminated.  Returns returncode
0165     attribute.
0166 
0167 wait()
0168     Wait for child process to terminate.  Returns returncode attribute.
0169 
0170 communicate(input=None)
0171     Interact with process: Send data to stdin.  Read data from stdout
0172     and stderr, until end-of-file is reached.  Wait for process to
0173     terminate.  The optional stdin argument should be a string to be
0174     sent to the child process, or None, if no data should be sent to
0175     the child.
0176 
0177     communicate() returns a tuple (stdout, stderr).
0178 
0179     Note: The data read is buffered in memory, so do not use this
0180     method if the data size is large or unlimited.
0181 
0182 The following attributes are also available:
0183 
0184 stdin
0185     If the stdin argument is PIPE, this attribute is a file object
0186     that provides input to the child process.  Otherwise, it is None.
0187 
0188 stdout
0189     If the stdout argument is PIPE, this attribute is a file object
0190     that provides output from the child process.  Otherwise, it is
0191     None.
0192 
0193 stderr
0194     If the stderr argument is PIPE, this attribute is file object that
0195     provides error output from the child process.  Otherwise, it is
0196     None.
0197 
0198 pid
0199     The process ID of the child process.
0200 
0201 returncode
0202     The child return code.  A None value indicates that the process
0203     hasn't terminated yet.  A negative value -N indicates that the
0204     child was terminated by signal N (UNIX only).
0205 
0206 
0207 Replacing older functions with the subprocess module
0208 ====================================================
0209 In this section, "a ==> b" means that b can be used as a replacement
0210 for a.
0211 
0212 Note: All functions in this section fail (more or less) silently if
0213 the executed program cannot be found; this module raises an OSError
0214 exception.
0215 
0216 In the following examples, we assume that the subprocess module is
0217 imported with "from subprocess import *".
0218 
0219 
0220 Replacing /bin/sh shell backquote
0221 ---------------------------------
0222 output=`mycmd myarg`
0223 ==>
0224 output = Popen(["mycmd", "myarg"], stdout=PIPE).communicate()[0]
0225 
0226 
0227 Replacing shell pipe line
0228 -------------------------
0229 output=`dmesg | grep hda`
0230 ==>
0231 p1 = Popen(["dmesg"], stdout=PIPE)
0232 p2 = Popen(["grep", "hda"], stdin=p1.stdout)
0233 output = p2.communicate()[0]
0234 
0235 
0236 Replacing os.system()
0237 ---------------------
0238 sts = os.system("mycmd" + " myarg")
0239 ==>
0240 p = Popen("mycmd" + " myarg", shell=True)
0241 sts = os.waitpid(p.pid, 0)
0242 
0243 Note:
0244 
0245 * Calling the program through the shell is usually not required.
0246 
0247 * It's easier to look at the returncode attribute than the
0248   exitstatus.
0249 
0250 A more real-world example would look like this:
0251 
0252 try:
0253     retcode = call("mycmd" + " myarg", shell=True)
0254     if retcode < 0:
0255         print >>sys.stderr, "Child was terminated by signal", -retcode
0256     else:
0257         print >>sys.stderr, "Child returned", retcode
0258 except OSError, e:
0259     print >>sys.stderr, "Execution failed:", e
0260 
0261 
0262 Replacing os.spawn*
0263 -------------------
0264 P_NOWAIT example:
0265 
0266 pid = os.spawnlp(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg")
0267 ==>
0268 pid = Popen(["/bin/mycmd", "myarg"]).pid
0269 
0270 
0271 P_WAIT example:
0272 
0273 retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd", "mycmd", "myarg")
0274 ==>
0275 retcode = call(["/bin/mycmd", "myarg"])
0276 
0277 
0278 Vector example:
0279 
0280 os.spawnvp(os.P_NOWAIT, path, args)
0281 ==>
0282 Popen([path] + args[1:])
0283 
0284 
0285 Environment example:
0286 
0287 os.spawnlpe(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg", env)
0288 ==>
0289 Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"})
0290 
0291 
0292 Replacing os.popen*
0293 -------------------
0294 pipe = os.popen(cmd, mode='r', bufsize)
0295 ==>
0296 pipe = Popen(cmd, shell=True, bufsize=bufsize, stdout=PIPE).stdout
0297 
0298 pipe = os.popen(cmd, mode='w', bufsize)
0299 ==>
0300 pipe = Popen(cmd, shell=True, bufsize=bufsize, stdin=PIPE).stdin
0301 
0302 
0303 (child_stdin, child_stdout) = os.popen2(cmd, mode, bufsize)
0304 ==>
0305 p = Popen(cmd, shell=True, bufsize=bufsize,
0306           stdin=PIPE, stdout=PIPE, close_fds=True)
0307 (child_stdin, child_stdout) = (p.stdin, p.stdout)
0308 
0309 
0310 (child_stdin,
0311  child_stdout,
0312  child_stderr) = os.popen3(cmd, mode, bufsize)
0313 ==>
0314 p = Popen(cmd, shell=True, bufsize=bufsize,
0315           stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
0316 (child_stdin,
0317  child_stdout,
0318  child_stderr) = (p.stdin, p.stdout, p.stderr)
0319 
0320 
0321 (child_stdin, child_stdout_and_stderr) = os.popen4(cmd, mode, bufsize)
0322 ==>
0323 p = Popen(cmd, shell=True, bufsize=bufsize,
0324           stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
0325 (child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)
0326 
0327 
0328 Replacing popen2.*
0329 ------------------
0330 Note: If the cmd argument to popen2 functions is a string, the command
0331 is executed through /bin/sh.  If it is a list, the command is directly
0332 executed.
0333 
0334 (child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode)
0335 ==>
0336 p = Popen(["somestring"], shell=True, bufsize=bufsize
0337           stdin=PIPE, stdout=PIPE, close_fds=True)
0338 (child_stdout, child_stdin) = (p.stdout, p.stdin)
0339 
0340 
0341 (child_stdout, child_stdin) = popen2.popen2(["mycmd", "myarg"], bufsize, mode)
0342 ==>
0343 p = Popen(["mycmd", "myarg"], bufsize=bufsize,
0344           stdin=PIPE, stdout=PIPE, close_fds=True)
0345 (child_stdout, child_stdin) = (p.stdout, p.stdin)
0346 
0347 The popen2.Popen3 and popen3.Popen4 basically works as subprocess.Popen,
0348 except that:
0349 
0350 * subprocess.Popen raises an exception if the execution fails
0351 * the capturestderr argument is replaced with the stderr argument.
0352 * stdin=PIPE and stdout=PIPE must be specified.
0353 * popen2 closes all filedescriptors by default, but you have to specify
0354   close_fds=True with subprocess.Popen.
0355 
0356 
0357 """
0358 
0359 import sys
0360 mswindows = (sys.platform == "win32")
0361 
0362 import os
0363 import types
0364 import traceback
0365 
0366 if mswindows:
0367     import threading
0368     import msvcrt
0369     if 0: # <-- change this to use pywin32 instead of the _subprocess driver
0370         import pywintypes
0371         from win32api import GetStdHandle, STD_INPUT_HANDLE, \
0372                              STD_OUTPUT_HANDLE, STD_ERROR_HANDLE
0373         from win32api import GetCurrentProcess, DuplicateHandle, \
0374                              GetModuleFileName, GetVersion
0375         from win32con import DUPLICATE_SAME_ACCESS
0376         from win32pipe import CreatePipe
0377         from win32process import CreateProcess, STARTUPINFO, \
0378                                  GetExitCodeProcess, STARTF_USESTDHANDLES, \
0379                                  CREATE_NEW_CONSOLE
0380         from win32event import WaitForSingleObject, INFINITE, WAIT_OBJECT_0
0381     else:
0382         from _subprocess import *
0383         class STARTUPINFO:
0384             dwFlags = 0
0385             hStdInput = None
0386             hStdOutput = None
0387             hStdError = None
0388         class pywintypes:
0389             error = IOError
0390 else:
0391     import select
0392     import errno
0393     import fcntl
0394     import pickle
0395 
0396 __all__ = ["Popen", "PIPE", "STDOUT", "call"]
0397 
0398 try:
0399     MAXFD = os.sysconf("SC_OPEN_MAX")
0400 except:
0401     MAXFD = 256
0402 
0403 # True/False does not exist on 2.2.0
0404 try:
0405     False
0406 except NameError:
0407     False = 0
0408     True = 1
0409 
0410 _active = []
0411 
0412 def _cleanup():
0413     for inst in _active[:]:
0414         inst.poll()
0415 
0416 PIPE = -1
0417 STDOUT = -2
0418 
0419 
0420 def call(*args, **kwargs):
0421     """Run command with arguments.  Wait for command to complete, then
0422     return the returncode attribute.
0423 
0424     The arguments are the same as for the Popen constructor.  Example:
0425 
0426     retcode = call(["ls", "-l"])
0427     """
0428     return Popen(*args, **kwargs).wait()
0429 
0430 
0431 def list2cmdline(seq):
0432     """
0433     Translate a sequence of arguments into a command line
0434     string, using the same rules as the MS C runtime:
0435 
0436     1) Arguments are delimited by white space, which is either a
0437        space or a tab.
0438 
0439     2) A string surrounded by double quotation marks is
0440        interpreted as a single argument, regardless of white space
0441        contained within.  A quoted string can be embedded in an
0442        argument.
0443 
0444     3) A double quotation mark preceded by a backslash is
0445        interpreted as a literal double quotation mark.
0446 
0447     4) Backslashes are interpreted literally, unless they
0448        immediately precede a double quotation mark.
0449 
0450     5) If backslashes immediately precede a double quotation mark,
0451        every pair of backslashes is interpreted as a literal
0452        backslash.  If the number of backslashes is odd, the last
0453        backslash escapes the next double quotation mark as
0454        described in rule 3.
0455     """
0456 
0457     # See
0458     # http://msdn.microsoft.com/library/en-us/vccelng/htm/progs_12.asp
0459     result = []
0460     needquote = False
0461     for arg in seq:
0462         bs_buf = []
0463 
0464         # Add a space to separate this argument from the others
0465         if result:
0466             result.append(' ')
0467 
0468         needquote = (" " in arg) or ("\t" in arg)
0469         if needquote:
0470             result.append('"')
0471 
0472         for c in arg:
0473             if c == '\\':
0474                 # Don't know if we need to double yet.
0475                 bs_buf.append(c)
0476             elif c == '"':
0477                 # Double backspaces.
0478                 result.append('\\' * len(bs_buf)*2)
0479                 bs_buf = []
0480                 result.append('\\"')
0481             else:
0482                 # Normal char
0483                 if bs_buf:
0484                     result.extend(bs_buf)
0485                     bs_buf = []
0486                 result.append(c)
0487 
0488         # Add remaining backspaces, if any.
0489         if bs_buf:
0490             result.extend(bs_buf)
0491 
0492         if needquote:
0493             result.append('"')
0494 
0495     return ''.join(result)
0496 
0497 
0498 class Popen(object):
0499     def __init__(self, args, bufsize=0, executable=None,
0500                  stdin=None, stdout=None, stderr=None,
0501                  preexec_fn=None, close_fds=False, shell=False,
0502                  cwd=None, env=None, universal_newlines=False,
0503                  startupinfo=None, creationflags=0):
0504         """Create new Popen instance."""
0505         _cleanup()
0506 
0507         if mswindows:
0508             if preexec_fn is not None:
0509                 raise ValueError("preexec_fn is not supported on Windows "
0510                                  "platforms")
0511             if close_fds:
0512                 raise ValueError("close_fds is not supported on Windows "
0513                                  "platforms")
0514         else:
0515             # POSIX
0516             if startupinfo is not None:
0517                 raise ValueError("startupinfo is only supported on Windows "
0518                                  "platforms")
0519             if creationflags != 0:
0520                 raise ValueError("creationflags is only supported on Windows "
0521                                  "platforms")
0522 
0523         self.stdin = None
0524         self.stdout = None
0525         self.stderr = None
0526         self.pid = None
0527         self.returncode = None
0528         self.universal_newlines = universal_newlines
0529 
0530         # Input and output objects. The general principle is like
0531         # this:
0532         #
0533         # Parent                   Child
0534         # ------                   -----
0535         # p2cwrite   ---stdin--->  p2cread
0536         # c2pread    <--stdout---  c2pwrite
0537         # errread    <--stderr---  errwrite
0538         #
0539         # On POSIX, the child objects are file descriptors.  On
0540         # Windows, these are Windows file handles.  The parent objects
0541         # are file descriptors on both platforms.  The parent objects
0542         # are None when not using PIPEs. The child objects are None
0543         # when not redirecting.
0544 
0545         (p2cread, p2cwrite,
0546          c2pread, c2pwrite,
0547          errread, errwrite) = self._get_handles(stdin, stdout, stderr)
0548 
0549         self._execute_child(args, executable, preexec_fn, close_fds,
0550                             cwd, env, universal_newlines,
0551                             startupinfo, creationflags, shell,
0552                             p2cread, p2cwrite,
0553                             c2pread, c2pwrite,
0554                             errread, errwrite)
0555 
0556         if p2cwrite:
0557             self.stdin = os.fdopen(p2cwrite, 'wb', bufsize)
0558         if c2pread:
0559             if universal_newlines:
0560                 self.stdout = os.fdopen(c2pread, 'rU', bufsize)
0561             else:
0562                 self.stdout = os.fdopen(c2pread, 'rb', bufsize)
0563         if errread:
0564             if universal_newlines:
0565                 self.stderr = os.fdopen(errread, 'rU', bufsize)
0566             else:
0567                 self.stderr = os.fdopen(errread, 'rb', bufsize)
0568 
0569         _active.append(self)
0570 
0571 
0572     def _translate_newlines(self, data):
0573         data = data.replace("\r\n", "\n")
0574         data = data.replace("\r", "\n")
0575         return data
0576 
0577 
0578     if mswindows:
0579         #
0580         # Windows methods
0581         #
0582         def _get_handles(self, stdin, stdout, stderr):
0583             """Construct and return tupel with IO objects:
0584             p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite
0585             """
0586             if stdin == None and stdout == None and stderr == None:
0587                 return (None, None, None, None, None, None)
0588 
0589             p2cread, p2cwrite = None, None
0590             c2pread, c2pwrite = None, None
0591             errread, errwrite = None, None
0592 
0593             if stdin == None:
0594                 p2cread = GetStdHandle(STD_INPUT_HANDLE)
0595             elif stdin == PIPE:
0596                 p2cread, p2cwrite = CreatePipe(None, 0)
0597                 # Detach and turn into fd
0598                 p2cwrite = p2cwrite.Detach()
0599                 p2cwrite = msvcrt.open_osfhandle(p2cwrite, 0)
0600             elif type(stdin) == types.IntType:
0601                 p2cread = msvcrt.get_osfhandle(stdin)
0602             else:
0603                 # Assuming file-like object
0604                 p2cread = msvcrt.get_osfhandle(stdin.fileno())
0605             p2cread = self._make_inheritable(p2cread)
0606 
0607             if stdout == None:
0608                 c2pwrite = GetStdHandle(STD_OUTPUT_HANDLE)
0609             elif stdout == PIPE:
0610                 c2pread, c2pwrite = CreatePipe(None, 0)
0611                 # Detach and turn into fd
0612                 c2pread = c2pread.Detach()
0613                 c2pread = msvcrt.open_osfhandle(c2pread, 0)
0614             elif type(stdout) == types.IntType:
0615                 c2pwrite = msvcrt.get_osfhandle(stdout)
0616             else:
0617                 # Assuming file-like object
0618                 c2pwrite = msvcrt.get_osfhandle(stdout.fileno())
0619             c2pwrite = self._make_inheritable(c2pwrite)
0620 
0621             if stderr == None:
0622                 errwrite = GetStdHandle(STD_ERROR_HANDLE)
0623             elif stderr == PIPE:
0624                 errread, errwrite = CreatePipe(None, 0)
0625                 # Detach and turn into fd
0626                 errread = errread.Detach()
0627                 errread = msvcrt.open_osfhandle(errread, 0)
0628             elif stderr == STDOUT:
0629                 errwrite = c2pwrite
0630             elif type(stderr) == types.IntType:
0631                 errwrite = msvcrt.get_osfhandle(stderr)
0632             else:
0633                 # Assuming file-like object
0634                 errwrite = msvcrt.get_osfhandle(stderr.fileno())
0635             errwrite = self._make_inheritable(errwrite)
0636 
0637             return (p2cread, p2cwrite,
0638                     c2pread, c2pwrite,
0639                     errread, errwrite)
0640 
0641 
0642         def _make_inheritable(self, handle):
0643             """Return a duplicate of handle, which is inheritable"""
0644             return DuplicateHandle(GetCurrentProcess(), handle,
0645                                    GetCurrentProcess(), 0, 1,
0646                                    DUPLICATE_SAME_ACCESS)
0647 
0648 
0649         def _find_w9xpopen(self):
0650             """Find and return absolut path to w9xpopen.exe"""
0651             w9xpopen = os.path.join(os.path.dirname(GetModuleFileName(0)),
0652                                     "w9xpopen.exe")
0653             if not os.path.exists(w9xpopen):
0654                 # Eeek - file-not-found - possibly an embedding
0655                 # situation - see if we can locate it in sys.exec_prefix
0656                 w9xpopen = os.path.join(os.path.dirname(sys.exec_prefix),
0657                                         "w9xpopen.exe")
0658                 if not os.path.exists(w9xpopen):
0659                     raise RuntimeError("Cannot locate w9xpopen.exe, which is "
0660                                        "needed for Popen to work with your "
0661                                        "shell or platform.")
0662             return w9xpopen
0663 
0664 
0665         def _execute_child(self, args, executable, preexec_fn, close_fds,
0666                            cwd, env, universal_newlines,
0667                            startupinfo, creationflags, shell,
0668                            p2cread, p2cwrite,
0669                            c2pread, c2pwrite,
0670                            errread, errwrite):
0671             """Execute program (MS Windows version)"""
0672 
0673             if not isinstance(args, types.StringTypes):
0674                 args = list2cmdline(args)
0675 
0676             if shell:
0677                 comspec = os.environ.get("COMSPEC", "cmd.exe")
0678                 args = comspec + " /c " + args
0679                 if (GetVersion() >= 0x80000000L or
0680                         os.path.basename(comspec).lower() == "command.com"):
0681                     # Win9x, or using command.com on NT. We need to
0682                     # use the w9xpopen intermediate program. For more
0683                     # information, see KB Q150956
0684                     # (http://web.archive.org/web/20011105084002/http://support.microsoft.com/support/kb/articles/Q150/9/56.asp)
0685                     w9xpopen = self._find_w9xpopen()
0686                     args = '"%s" %s' % (w9xpopen, args)
0687                     # Not passing CREATE_NEW_CONSOLE has been known to
0688                     # cause random failures on win9x.  Specifically a
0689                     # dialog: "Your program accessed mem currently in
0690                     # use at xxx" and a hopeful warning about the
0691                     # stability of your system.  Cost is Ctrl+C wont
0692                     # kill children.
0693                     creationflags |= CREATE_NEW_CONSOLE
0694 
0695             # Process startup details
0696             if startupinfo == None:
0697                 startupinfo = STARTUPINFO()
0698             if not None in (p2cread, c2pwrite, errwrite):
0699                 startupinfo.dwFlags |= STARTF_USESTDHANDLES
0700                 startupinfo.hStdInput = p2cread
0701                 startupinfo.hStdOutput = c2pwrite
0702                 startupinfo.hStdError = errwrite
0703 
0704             # Start the process
0705             try:
0706                 hp, ht, pid, tid = CreateProcess(executable, args,
0707                                          # no special security
0708                                          None, None,
0709                                          # must inherit handles to pass std
0710                                          # handles
0711                                          1,
0712                                          creationflags,
0713                                          env,
0714                                          cwd,
0715                                          startupinfo)
0716             except pywintypes.error, e:
0717                 # Translate pywintypes.error to WindowsError, which is
0718                 # a subclass of OSError.  FIXME: We should really
0719                 # translate errno using _sys_errlist (or simliar), but
0720                 # how can this be done from Python?
0721                 raise WindowsError(*e.args)
0722 
0723             # Retain the process handle, but close the thread handle
0724             self._handle = hp
0725             self.pid = pid
0726             ht.Close()
0727 
0728             # Child is launched. Close the parent's copy of those pipe
0729             # handles that only the child should have open.  You need
0730             # to make sure that no handles to the write end of the
0731             # output pipe are maintained in this process or else the
0732             # pipe will not close when the child process exits and the
0733             # ReadFile will hang.
0734             if p2cread != None:
0735                 p2cread.Close()
0736             if c2pwrite != None:
0737                 c2pwrite.Close()
0738             if errwrite != None:
0739                 errwrite.Close()
0740 
0741 
0742         def poll(self):
0743             """Check if child process has terminated.  Returns returncode
0744             attribute."""
0745             if self.returncode == None:
0746                 if WaitForSingleObject(self._handle, 0) == WAIT_OBJECT_0:
0747                     self.returncode = GetExitCodeProcess(self._handle)
0748                     _active.remove(self)
0749             return self.returncode
0750 
0751 
0752         def wait(self):
0753             """Wait for child process to terminate.  Returns returncode
0754             attribute."""
0755             if self.returncode == None:
0756                 obj = WaitForSingleObject(self._handle, INFINITE)
0757                 self.returncode = GetExitCodeProcess(self._handle)
0758                 _active.remove(self)
0759             return self.returncode
0760 
0761 
0762         def _readerthread(self, fh, buffer):
0763             buffer.append(fh.read())
0764 
0765 
0766         def communicate(self, input=None):
0767             """Interact with process: Send data to stdin.  Read data from
0768             stdout and stderr, until end-of-file is reached.  Wait for
0769             process to terminate.  The optional input argument should be a
0770             string to be sent to the child process, or None, if no data
0771             should be sent to the child.
0772 
0773             communicate() returns a tuple (stdout, stderr)."""
0774             stdout = None # Return
0775             stderr = None # Return
0776 
0777             if self.stdout:
0778                 stdout = []
0779                 stdout_thread = threading.Thread(target=self._readerthread,
0780                                                  args=(self.stdout, stdout))
0781                 stdout_thread.setDaemon(True)
0782                 stdout_thread.start()
0783             if self.stderr:
0784                 stderr = []
0785                 stderr_thread = threading.Thread(target=self._readerthread,
0786                                                  args=(self.stderr, stderr))
0787                 stderr_thread.setDaemon(True)
0788                 stderr_thread.start()
0789 
0790             if self.stdin:
0791                 if input != None:
0792                     self.stdin.write(input)
0793                 self.stdin.close()
0794 
0795             if self.stdout:
0796                 stdout_thread.join()
0797             if self.stderr:
0798                 stderr_thread.join()
0799 
0800             # All data exchanged.  Translate lists into strings.
0801             if stdout != None:
0802                 stdout = stdout[0]
0803             if stderr != None:
0804                 stderr = stderr[0]
0805 
0806             # Translate newlines, if requested.  We cannot let the file
0807             # object do the translation: It is based on stdio, which is
0808             # impossible to combine with select (unless forcing no
0809             # buffering).
0810             if self.universal_newlines and hasattr(open, 'newlines'):
0811                 if stdout:
0812                     stdout = self._translate_newlines(stdout)
0813                 if stderr:
0814                     stderr = self._translate_newlines(stderr)
0815 
0816             self.wait()
0817             return (stdout, stderr)
0818 
0819     else:
0820         #
0821         # POSIX methods
0822         #
0823         def _get_handles(self, stdin, stdout, stderr):
0824             """Construct and return tupel with IO objects:
0825             p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite
0826             """
0827             p2cread, p2cwrite = None, None
0828             c2pread, c2pwrite = None, None
0829             errread, errwrite = None, None
0830 
0831             if stdin == None:
0832                 pass
0833             elif stdin == PIPE:
0834                 p2cread, p2cwrite = os.pipe()
0835             elif type(stdin) == types.IntType:
0836                 p2cread = stdin
0837             else:
0838                 # Assuming file-like object
0839                 p2cread = stdin.fileno()
0840 
0841             if stdout == None:
0842                 pass
0843             elif stdout == PIPE:
0844                 c2pread, c2pwrite = os.pipe()
0845             elif type(stdout) == types.IntType:
0846                 c2pwrite = stdout
0847             else:
0848                 # Assuming file-like object
0849                 c2pwrite = stdout.fileno()
0850 
0851             if stderr == None:
0852                 pass
0853             elif stderr == PIPE:
0854                 errread, errwrite = os.pipe()
0855             elif stderr == STDOUT:
0856                 errwrite = c2pwrite
0857             elif type(stderr) == types.IntType:
0858                 errwrite = stderr
0859             else:
0860                 # Assuming file-like object
0861                 errwrite = stderr.fileno()
0862 
0863             return (p2cread, p2cwrite,
0864                     c2pread, c2pwrite,
0865                     errread, errwrite)
0866 
0867 
0868         def _set_cloexec_flag(self, fd):
0869             try:
0870                 cloexec_flag = fcntl.FD_CLOEXEC
0871             except AttributeError:
0872                 cloexec_flag = 1
0873 
0874             old = fcntl.fcntl(fd, fcntl.F_GETFD)
0875             fcntl.fcntl(fd, fcntl.F_SETFD, old | cloexec_flag)
0876 
0877 
0878         def _close_fds(self, but):
0879             for i in range(3, MAXFD):
0880                 if i == but:
0881                     continue
0882                 try:
0883                     os.close(i)
0884                 except:
0885                     pass
0886 
0887 
0888         def _execute_child(self, args, executable, preexec_fn, close_fds,
0889                            cwd, env, universal_newlines,
0890                            startupinfo, creationflags, shell,
0891                            p2cread, p2cwrite,
0892                            c2pread, c2pwrite,
0893                            errread, errwrite):
0894             """Execute program (POSIX version)"""
0895 
0896             if isinstance(args, types.StringTypes):
0897                 args = [args]
0898 
0899             if shell:
0900                 args = ["/bin/sh", "-c"] + args
0901 
0902             if executable == None:
0903                 executable = args[0]
0904 
0905             # For transferring possible exec failure from child to parent
0906             # The first char specifies the exception type: 0 means
0907             # OSError, 1 means some other error.
0908             errpipe_read, errpipe_write = os.pipe()
0909             self._set_cloexec_flag(errpipe_write)
0910 
0911             self.pid = os.fork()
0912             if self.pid == 0:
0913                 # Child
0914                 try:
0915                     # Close parent's pipe ends
0916                     if p2cwrite:
0917                         os.close(p2cwrite)
0918                     if c2pread:
0919                         os.close(c2pread)
0920                     if errread:
0921                         os.close(errread)
0922                     os.close(errpipe_read)
0923 
0924                     # Dup fds for child
0925                     if p2cread:
0926                         os.dup2(p2cread, 0)
0927                     if c2pwrite:
0928                         os.dup2(c2pwrite, 1)
0929                     if errwrite:
0930                         os.dup2(errwrite, 2)
0931 
0932                     # Close pipe fds.  Make sure we doesn't close the same
0933                     # fd more than once.
0934                     if p2cread:
0935                         os.close(p2cread)
0936                     if c2pwrite and c2pwrite not in (p2cread,):
0937                         os.close(c2pwrite)
0938                     if errwrite and errwrite not in (p2cread, c2pwrite):
0939                         os.close(errwrite)
0940 
0941                     # Close all other fds, if asked for
0942                     if close_fds:
0943                         self._close_fds(but=errpipe_write)
0944 
0945                     if cwd != None:
0946                         os.chdir(cwd)
0947 
0948                     if preexec_fn:
0949                         apply(preexec_fn)
0950 
0951                     if env == None:
0952                         os.execvp(executable, args)
0953                     else:
0954                         os.execvpe(executable, args, env)
0955 
0956                 except:
0957                     exc_type, exc_value, tb = sys.exc_info()
0958                     # Save the traceback and attach it to the exception object
0959                     exc_lines = traceback.format_exception(exc_type,
0960                                                            exc_value,
0961                                                            tb)
0962                     exc_value.child_traceback = ''.join(exc_lines)
0963                     os.write(errpipe_write, pickle.dumps(exc_value))
0964 
0965                 # This exitcode won't be reported to applications, so it
0966                 # really doesn't matter what we return.
0967                 os._exit(255)
0968 
0969             # Parent
0970             os.close(errpipe_write)
0971             if p2cread and p2cwrite:
0972                 os.close(p2cread)
0973             if c2pwrite and c2pread:
0974                 os.close(c2pwrite)
0975             if errwrite and errread:
0976                 os.close(errwrite)
0977 
0978             # Wait for exec to fail or succeed; possibly raising exception
0979             data = os.read(errpipe_read, 1048576) # Exceptions limited to 1 MB
0980             os.close(errpipe_read)
0981             if data != "":
0982                 child_exception = pickle.loads(data)
0983                 raise child_exception
0984 
0985 
0986         def _handle_exitstatus(self, sts):
0987             if os.WIFSIGNALED(sts):
0988                 self.returncode = -os.WTERMSIG(sts)
0989             elif os.WIFEXITED(sts):
0990                 self.returncode = os.WEXITSTATUS(sts)
0991             else:
0992                 # Should never happen
0993                 raise RuntimeError("Unknown child exit status!")
0994 
0995             _active.remove(self)
0996 
0997 
0998         def poll(self):
0999             """Check if child process has terminated.  Returns returncode
1000             attribute."""
1001             if self.returncode == None:
1002                 try:
1003                     pid, sts = os.waitpid(self.pid, os.WNOHANG)
1004                     if pid == self.pid:
1005                         self._handle_exitstatus(sts)
1006                 except os.error:
1007                     pass
1008             return self.returncode
1009 
1010 
1011         def wait(self):
1012             """Wait for child process to terminate.  Returns returncode
1013             attribute."""
1014             if self.returncode == None:
1015                 pid, sts = os.waitpid(self.pid, 0)
1016                 self._handle_exitstatus(sts)
1017             return self.returncode
1018 
1019 
1020         def communicate(self, input=None):
1021             """Interact with process: Send data to stdin.  Read data from
1022             stdout and stderr, until end-of-file is reached.  Wait for
1023             process to terminate.  The optional input argument should be a
1024             string to be sent to the child process, or None, if no data
1025             should be sent to the child.
1026 
1027             communicate() returns a tuple (stdout, stderr)."""
1028             read_set = []
1029             write_set = []
1030             stdout = None # Return
1031             stderr = None # Return
1032 
1033             if self.stdin:
1034                 # Flush stdio buffer.  This might block, if the user has
1035                 # been writing to .stdin in an uncontrolled fashion.
1036                 self.stdin.flush()
1037                 if input:
1038                     write_set.append(self.stdin)
1039                 else:
1040                     self.stdin.close()
1041             if self.stdout:
1042                 read_set.append(self.stdout)
1043                 stdout = []
1044             if self.stderr:
1045                 read_set.append(self.stderr)
1046                 stderr = []
1047 
1048             while read_set or write_set:
1049                 rlist, wlist, xlist = select.select(read_set, write_set, [])
1050 
1051                 if self.stdin in wlist:
1052                     # When select has indicated that the file is writable,
1053                     # we can write up to PIPE_BUF bytes without risk
1054                     # blocking.  POSIX defines PIPE_BUF >= 512
1055                     bytes_written = os.write(self.stdin.fileno(), input[:512])
1056                     input = input[bytes_written:]
1057                     if not input:
1058                         self.stdin.close()
1059                         write_set.remove(self.stdin)
1060 
1061                 if self.stdout in rlist:
1062                     data = os.read(self.stdout.fileno(), 1024)
1063                     if data == "":
1064                         self.stdout.close()
1065                         read_set.remove(self.stdout)
1066                     stdout.append(data)
1067 
1068                 if self.stderr in rlist:
1069                     data = os.read(self.stderr.fileno(), 1024)
1070                     if data == "":
1071                         self.stderr.close()
1072                         read_set.remove(self.stderr)
1073                     stderr.append(data)
1074 
1075             # All data exchanged.  Translate lists into strings.
1076             if stdout != None:
1077                 stdout = ''.join(stdout)
1078             if stderr != None:
1079                 stderr = ''.join(stderr)
1080 
1081             # Translate newlines, if requested.  We cannot let the file
1082             # object do the translation: It is based on stdio, which is
1083             # impossible to combine with select (unless forcing no
1084             # buffering).
1085             if self.universal_newlines and hasattr(open, 'newlines'):
1086                 if stdout:
1087                     stdout = self._translate_newlines(stdout)
1088                 if stderr:
1089                     stderr = self._translate_newlines(stderr)
1090 
1091             self.wait()
1092             return (stdout, stderr)
1093 
1094 
1095 def _demo_posix():
1096     #
1097     # Example 1: Simple redirection: Get process list
1098     #
1099     plist = Popen(["ps"], stdout=PIPE).communicate()[0]
1100     print "Process list:"
1101     print plist
1102 
1103     #
1104     # Example 2: Change uid before executing child
1105     #
1106     if os.getuid() == 0:
1107         p = Popen(["id"], preexec_fn=lambda: os.setuid(100))
1108         p.wait()
1109 
1110     #
1111     # Example 3: Connecting several subprocesses
1112     #
1113     print "Looking for 'hda'..."
1114     p1 = Popen(["dmesg"], stdout=PIPE)
1115     p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
1116     print repr(p2.communicate()[0])
1117 
1118     #
1119     # Example 4: Catch execution error
1120     #
1121     print
1122     print "Trying a weird file..."
1123     try:
1124         print Popen(["/this/path/does/not/exist"]).communicate()
1125     except OSError, e:
1126         if e.errno == errno.ENOENT:
1127             print "The file didn't exist.  I thought so..."
1128             print "Child traceback:"
1129             print e.child_traceback
1130         else:
1131             print "Error", e.errno
1132     else:
1133         print >>sys.stderr, "Gosh.  No error."
1134 
1135 
1136 def _demo_windows():
1137     #
1138     # Example 1: Connecting several subprocesses
1139     #
1140     print "Looking for 'PROMPT' in set output..."
1141     p1 = Popen("set", stdout=PIPE, shell=True)
1142     p2 = Popen('find "PROMPT"', stdin=p1.stdout, stdout=PIPE)
1143     print repr(p2.communicate()[0])
1144 
1145     #
1146     # Example 2: Simple execution of program
1147     #
1148     print "Executing calc..."
1149     p = Popen("calc")
1150     p.wait()
1151 
1152 
1153 if __name__ == "__main__":
1154     if mswindows:
1155         _demo_windows()
1156     else:
1157         _demo_posix()
1158 

Generated by PyXR 0.9.4
SourceForge.net Logo