PyXR

c:\python24\lib \ distutils \ spawn.py



0001 """distutils.spawn
0002 
0003 Provides the 'spawn()' function, a front-end to various platform-
0004 specific functions for launching another program in a sub-process.
0005 Also provides the 'find_executable()' to search the path for a given
0006 executable name.
0007 """
0008 
0009 # This module should be kept compatible with Python 1.5.2.
0010 
0011 __revision__ = "$Id: spawn.py,v 1.18 2004/07/18 06:14:42 tim_one Exp $"
0012 
0013 import sys, os, string
0014 from distutils.errors import *
0015 from distutils import log
0016 
0017 def spawn (cmd,
0018            search_path=1,
0019            verbose=0,
0020            dry_run=0):
0021 
0022     """Run another program, specified as a command list 'cmd', in a new
0023     process.  'cmd' is just the argument list for the new process, ie.
0024     cmd[0] is the program to run and cmd[1:] are the rest of its arguments.
0025     There is no way to run a program with a name different from that of its
0026     executable.
0027 
0028     If 'search_path' is true (the default), the system's executable
0029     search path will be used to find the program; otherwise, cmd[0]
0030     must be the exact path to the executable.  If 'dry_run' is true,
0031     the command will not actually be run.
0032 
0033     Raise DistutilsExecError if running the program fails in any way; just
0034     return on success.
0035     """
0036     if os.name == 'posix':
0037         _spawn_posix(cmd, search_path, dry_run=dry_run)
0038     elif os.name == 'nt':
0039         _spawn_nt(cmd, search_path, dry_run=dry_run)
0040     elif os.name == 'os2':
0041         _spawn_os2(cmd, search_path, dry_run=dry_run)
0042     else:
0043         raise DistutilsPlatformError, \
0044               "don't know how to spawn programs on platform '%s'" % os.name
0045 
0046 # spawn ()
0047 
0048 
0049 def _nt_quote_args (args):
0050     """Quote command-line arguments for DOS/Windows conventions: just
0051     wraps every argument which contains blanks in double quotes, and
0052     returns a new argument list.
0053     """
0054 
0055     # XXX this doesn't seem very robust to me -- but if the Windows guys
0056     # say it'll work, I guess I'll have to accept it.  (What if an arg
0057     # contains quotes?  What other magic characters, other than spaces,
0058     # have to be escaped?  Is there an escaping mechanism other than
0059     # quoting?)
0060 
0061     for i in range(len(args)):
0062         if string.find(args[i], ' ') != -1:
0063             args[i] = '"%s"' % args[i]
0064     return args
0065 
0066 def _spawn_nt (cmd,
0067                search_path=1,
0068                verbose=0,
0069                dry_run=0):
0070 
0071     executable = cmd[0]
0072     cmd = _nt_quote_args(cmd)
0073     if search_path:
0074         # either we find one or it stays the same
0075         executable = find_executable(executable) or executable
0076     log.info(string.join([executable] + cmd[1:], ' '))
0077     if not dry_run:
0078         # spawn for NT requires a full path to the .exe
0079         try:
0080             rc = os.spawnv(os.P_WAIT, executable, cmd)
0081         except OSError, exc:
0082             # this seems to happen when the command isn't found
0083             raise DistutilsExecError, \
0084                   "command '%s' failed: %s" % (cmd[0], exc[-1])
0085         if rc != 0:
0086             # and this reflects the command running but failing
0087             raise DistutilsExecError, \
0088                   "command '%s' failed with exit status %d" % (cmd[0], rc)
0089 
0090 
0091 def _spawn_os2 (cmd,
0092                 search_path=1,
0093                 verbose=0,
0094                 dry_run=0):
0095 
0096     executable = cmd[0]
0097     #cmd = _nt_quote_args(cmd)
0098     if search_path:
0099         # either we find one or it stays the same
0100         executable = find_executable(executable) or executable
0101     log.info(string.join([executable] + cmd[1:], ' '))
0102     if not dry_run:
0103         # spawnv for OS/2 EMX requires a full path to the .exe
0104         try:
0105             rc = os.spawnv(os.P_WAIT, executable, cmd)
0106         except OSError, exc:
0107             # this seems to happen when the command isn't found
0108             raise DistutilsExecError, \
0109                   "command '%s' failed: %s" % (cmd[0], exc[-1])
0110         if rc != 0:
0111             # and this reflects the command running but failing
0112             print "command '%s' failed with exit status %d" % (cmd[0], rc)
0113             raise DistutilsExecError, \
0114                   "command '%s' failed with exit status %d" % (cmd[0], rc)
0115 
0116 
0117 def _spawn_posix (cmd,
0118                   search_path=1,
0119                   verbose=0,
0120                   dry_run=0):
0121 
0122     log.info(string.join(cmd, ' '))
0123     if dry_run:
0124         return
0125     exec_fn = search_path and os.execvp or os.execv
0126 
0127     pid = os.fork()
0128 
0129     if pid == 0:                        # in the child
0130         try:
0131             #print "cmd[0] =", cmd[0]
0132             #print "cmd =", cmd
0133             exec_fn(cmd[0], cmd)
0134         except OSError, e:
0135             sys.stderr.write("unable to execute %s: %s\n" %
0136                              (cmd[0], e.strerror))
0137             os._exit(1)
0138 
0139         sys.stderr.write("unable to execute %s for unknown reasons" % cmd[0])
0140         os._exit(1)
0141 
0142 
0143     else:                               # in the parent
0144         # Loop until the child either exits or is terminated by a signal
0145         # (ie. keep waiting if it's merely stopped)
0146         while 1:
0147             try:
0148                 (pid, status) = os.waitpid(pid, 0)
0149             except OSError, exc:
0150                 import errno
0151                 if exc.errno == errno.EINTR:
0152                     continue
0153                 raise DistutilsExecError, \
0154                       "command '%s' failed: %s" % (cmd[0], exc[-1])
0155             if os.WIFSIGNALED(status):
0156                 raise DistutilsExecError, \
0157                       "command '%s' terminated by signal %d" % \
0158                       (cmd[0], os.WTERMSIG(status))
0159 
0160             elif os.WIFEXITED(status):
0161                 exit_status = os.WEXITSTATUS(status)
0162                 if exit_status == 0:
0163                     return              # hey, it succeeded!
0164                 else:
0165                     raise DistutilsExecError, \
0166                           "command '%s' failed with exit status %d" % \
0167                           (cmd[0], exit_status)
0168 
0169             elif os.WIFSTOPPED(status):
0170                 continue
0171 
0172             else:
0173                 raise DistutilsExecError, \
0174                       "unknown error executing '%s': termination status %d" % \
0175                       (cmd[0], status)
0176 # _spawn_posix ()
0177 
0178 
0179 def find_executable(executable, path=None):
0180     """Try to find 'executable' in the directories listed in 'path' (a
0181     string listing directories separated by 'os.pathsep'; defaults to
0182     os.environ['PATH']).  Returns the complete filename or None if not
0183     found.
0184     """
0185     if path is None:
0186         path = os.environ['PATH']
0187     paths = string.split(path, os.pathsep)
0188     (base, ext) = os.path.splitext(executable)
0189     if (sys.platform == 'win32' or os.name == 'os2') and (ext != '.exe'):
0190         executable = executable + '.exe'
0191     if not os.path.isfile(executable):
0192         for p in paths:
0193             f = os.path.join(p, executable)
0194             if os.path.isfile(f):
0195                 # the file exists, we have a shot at spawn working
0196                 return f
0197         return None
0198     else:
0199         return executable
0200 
0201 # find_executable()
0202 

Generated by PyXR 0.9.4
SourceForge.net Logo