]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/distutils/spawn.py
   3 Provides the 'spawn()' function, a front-end to various platform- 
   4 specific functions for launching another program in a sub-process. 
   5 Also provides the 'find_executable()' to search the path for a given 
   9 # This module should be kept compatible with Python 1.5.2. 
  13 import sys
, os
, string
 
  14 from distutils
.errors 
import * 
  15 from distutils 
import log
 
  22     """Run another program, specified as a command list 'cmd', in a new 
  23     process.  'cmd' is just the argument list for the new process, ie. 
  24     cmd[0] is the program to run and cmd[1:] are the rest of its arguments. 
  25     There is no way to run a program with a name different from that of its 
  28     If 'search_path' is true (the default), the system's executable 
  29     search path will be used to find the program; otherwise, cmd[0] 
  30     must be the exact path to the executable.  If 'dry_run' is true, 
  31     the command will not actually be run. 
  33     Raise DistutilsExecError if running the program fails in any way; just 
  36     if os
.name 
== 'posix': 
  37         _spawn_posix(cmd
, search_path
, dry_run
=dry_run
) 
  39         _spawn_nt(cmd
, search_path
, dry_run
=dry_run
) 
  40     elif os
.name 
== 'os2': 
  41         _spawn_os2(cmd
, search_path
, dry_run
=dry_run
) 
  43         raise DistutilsPlatformError
, \
 
  44               "don't know how to spawn programs on platform '%s'" % os
.name
 
  49 def _nt_quote_args (args
): 
  50     """Quote command-line arguments for DOS/Windows conventions: just 
  51     wraps every argument which contains blanks in double quotes, and 
  52     returns a new argument list. 
  55     # XXX this doesn't seem very robust to me -- but if the Windows guys 
  56     # say it'll work, I guess I'll have to accept it.  (What if an arg 
  57     # contains quotes?  What other magic characters, other than spaces, 
  58     # have to be escaped?  Is there an escaping mechanism other than 
  61     for i 
in range(len(args
)): 
  62         if string
.find(args
[i
], ' ') != -1: 
  63             args
[i
] = '"%s"' % args
[i
] 
  72     cmd 
= _nt_quote_args(cmd
) 
  74         # either we find one or it stays the same 
  75         executable 
= find_executable(executable
) or executable
 
  76     log
.info(string
.join([executable
] + cmd
[1:], ' ')) 
  78         # spawn for NT requires a full path to the .exe 
  80             rc 
= os
.spawnv(os
.P_WAIT
, executable
, cmd
) 
  82             # this seems to happen when the command isn't found 
  83             raise DistutilsExecError
, \
 
  84                   "command '%s' failed: %s" % (cmd
[0], exc
[-1]) 
  86             # and this reflects the command running but failing 
  87             raise DistutilsExecError
, \
 
  88                   "command '%s' failed with exit status %d" % (cmd
[0], rc
) 
  97     #cmd = _nt_quote_args(cmd) 
  99         # either we find one or it stays the same 
 100         executable 
= find_executable(executable
) or executable 
 
 101     log
.info(string
.join([executable
] + cmd
[1:], ' ')) 
 103         # spawnv for OS/2 EMX requires a full path to the .exe 
 105             rc 
= os
.spawnv(os
.P_WAIT
, executable
, cmd
) 
 107             # this seems to happen when the command isn't found 
 108             raise DistutilsExecError
, \
 
 109                   "command '%s' failed: %s" % (cmd
[0], exc
[-1]) 
 111             # and this reflects the command running but failing 
 112             print "command '%s' failed with exit status %d" % (cmd
[0], rc
) 
 113             raise DistutilsExecError
, \
 
 114                   "command '%s' failed with exit status %d" % (cmd
[0], rc
) 
 117 def _spawn_posix (cmd
, 
 122     log
.info(string
.join(cmd
, ' ')) 
 125     exec_fn 
= search_path 
and os
.execvp 
or os
.execv
 
 129     if pid 
== 0:                        # in the child 
 131             #print "cmd[0] =", cmd[0] 
 135             sys
.stderr
.write("unable to execute %s: %s\n" % 
 136                              (cmd
[0], e
.strerror
)) 
 139         sys
.stderr
.write("unable to execute %s for unknown reasons" % cmd
[0]) 
 143     else:                               # in the parent 
 144         # Loop until the child either exits or is terminated by a signal 
 145         # (ie. keep waiting if it's merely stopped) 
 147             (pid
, status
) = os
.waitpid(pid
, 0) 
 148             if os
.WIFSIGNALED(status
): 
 149                 raise DistutilsExecError
, \
 
 150                       "command '%s' terminated by signal %d" % \
 
 151                       (cmd
[0], os
.WTERMSIG(status
)) 
 153             elif os
.WIFEXITED(status
): 
 154                 exit_status 
= os
.WEXITSTATUS(status
) 
 156                     return              # hey, it succeeded! 
 158                     raise DistutilsExecError
, \
 
 159                           "command '%s' failed with exit status %d" % \
 
 160                           (cmd
[0], exit_status
) 
 162             elif os
.WIFSTOPPED(status
): 
 166                 raise DistutilsExecError
, \
 
 167                       "unknown error executing '%s': termination status %d" % \
 
 172 def find_executable(executable
, path
=None): 
 173     """Try to find 'executable' in the directories listed in 'path' (a 
 174     string listing directories separated by 'os.pathsep'; defaults to 
 175     os.environ['PATH']).  Returns the complete filename or None if not 
 179         path 
= os
.environ
['PATH'] 
 180     paths 
= string
.split(path
, os
.pathsep
) 
 181     (base
, ext
) = os
.path
.splitext(executable
) 
 182     if (sys
.platform 
== 'win32' or os
.name 
== 'os2') and (ext 
!= '.exe'): 
 183         executable 
= executable 
+ '.exe' 
 184     if not os
.path
.isfile(executable
): 
 186             f 
= os
.path
.join(p
, executable
) 
 187             if os
.path
.isfile(f
): 
 188                 # the file exists, we have a shot at spawn working