]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Python-2.7.2/Lib/distutils/spawn.py
AppPkg/Applications/Python: Add Python 2.7.2 sources since the release of Python...
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / Lib / distutils / spawn.py
CommitLineData
4710c53d 1"""distutils.spawn\r
2\r
3Provides the 'spawn()' function, a front-end to various platform-\r
4specific functions for launching another program in a sub-process.\r
5Also provides the 'find_executable()' to search the path for a given\r
6executable name.\r
7"""\r
8\r
9__revision__ = "$Id$"\r
10\r
11import sys\r
12import os\r
13\r
14from distutils.errors import DistutilsPlatformError, DistutilsExecError\r
15from distutils import log\r
16\r
17def spawn(cmd, search_path=1, verbose=0, dry_run=0):\r
18 """Run another program, specified as a command list 'cmd', in a new process.\r
19\r
20 'cmd' is just the argument list for the new process, ie.\r
21 cmd[0] is the program to run and cmd[1:] are the rest of its arguments.\r
22 There is no way to run a program with a name different from that of its\r
23 executable.\r
24\r
25 If 'search_path' is true (the default), the system's executable\r
26 search path will be used to find the program; otherwise, cmd[0]\r
27 must be the exact path to the executable. If 'dry_run' is true,\r
28 the command will not actually be run.\r
29\r
30 Raise DistutilsExecError if running the program fails in any way; just\r
31 return on success.\r
32 """\r
33 if os.name == 'posix':\r
34 _spawn_posix(cmd, search_path, dry_run=dry_run)\r
35 elif os.name == 'nt':\r
36 _spawn_nt(cmd, search_path, dry_run=dry_run)\r
37 elif os.name == 'os2':\r
38 _spawn_os2(cmd, search_path, dry_run=dry_run)\r
39 else:\r
40 raise DistutilsPlatformError, \\r
41 "don't know how to spawn programs on platform '%s'" % os.name\r
42\r
43def _nt_quote_args(args):\r
44 """Quote command-line arguments for DOS/Windows conventions.\r
45\r
46 Just wraps every argument which contains blanks in double quotes, and\r
47 returns a new argument list.\r
48 """\r
49 # XXX this doesn't seem very robust to me -- but if the Windows guys\r
50 # say it'll work, I guess I'll have to accept it. (What if an arg\r
51 # contains quotes? What other magic characters, other than spaces,\r
52 # have to be escaped? Is there an escaping mechanism other than\r
53 # quoting?)\r
54 for i, arg in enumerate(args):\r
55 if ' ' in arg:\r
56 args[i] = '"%s"' % arg\r
57 return args\r
58\r
59def _spawn_nt(cmd, search_path=1, verbose=0, dry_run=0):\r
60 executable = cmd[0]\r
61 cmd = _nt_quote_args(cmd)\r
62 if search_path:\r
63 # either we find one or it stays the same\r
64 executable = find_executable(executable) or executable\r
65 log.info(' '.join([executable] + cmd[1:]))\r
66 if not dry_run:\r
67 # spawn for NT requires a full path to the .exe\r
68 try:\r
69 rc = os.spawnv(os.P_WAIT, executable, cmd)\r
70 except OSError, exc:\r
71 # this seems to happen when the command isn't found\r
72 raise DistutilsExecError, \\r
73 "command '%s' failed: %s" % (cmd[0], exc[-1])\r
74 if rc != 0:\r
75 # and this reflects the command running but failing\r
76 raise DistutilsExecError, \\r
77 "command '%s' failed with exit status %d" % (cmd[0], rc)\r
78\r
79def _spawn_os2(cmd, search_path=1, verbose=0, dry_run=0):\r
80 executable = cmd[0]\r
81 if search_path:\r
82 # either we find one or it stays the same\r
83 executable = find_executable(executable) or executable\r
84 log.info(' '.join([executable] + cmd[1:]))\r
85 if not dry_run:\r
86 # spawnv for OS/2 EMX requires a full path to the .exe\r
87 try:\r
88 rc = os.spawnv(os.P_WAIT, executable, cmd)\r
89 except OSError, exc:\r
90 # this seems to happen when the command isn't found\r
91 raise DistutilsExecError, \\r
92 "command '%s' failed: %s" % (cmd[0], exc[-1])\r
93 if rc != 0:\r
94 # and this reflects the command running but failing\r
95 log.debug("command '%s' failed with exit status %d" % (cmd[0], rc))\r
96 raise DistutilsExecError, \\r
97 "command '%s' failed with exit status %d" % (cmd[0], rc)\r
98\r
99\r
100def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0):\r
101 log.info(' '.join(cmd))\r
102 if dry_run:\r
103 return\r
104 exec_fn = search_path and os.execvp or os.execv\r
105 pid = os.fork()\r
106\r
107 if pid == 0: # in the child\r
108 try:\r
109 exec_fn(cmd[0], cmd)\r
110 except OSError, e:\r
111 sys.stderr.write("unable to execute %s: %s\n" %\r
112 (cmd[0], e.strerror))\r
113 os._exit(1)\r
114\r
115 sys.stderr.write("unable to execute %s for unknown reasons" % cmd[0])\r
116 os._exit(1)\r
117 else: # in the parent\r
118 # Loop until the child either exits or is terminated by a signal\r
119 # (ie. keep waiting if it's merely stopped)\r
120 while 1:\r
121 try:\r
122 pid, status = os.waitpid(pid, 0)\r
123 except OSError, exc:\r
124 import errno\r
125 if exc.errno == errno.EINTR:\r
126 continue\r
127 raise DistutilsExecError, \\r
128 "command '%s' failed: %s" % (cmd[0], exc[-1])\r
129 if os.WIFSIGNALED(status):\r
130 raise DistutilsExecError, \\r
131 "command '%s' terminated by signal %d" % \\r
132 (cmd[0], os.WTERMSIG(status))\r
133\r
134 elif os.WIFEXITED(status):\r
135 exit_status = os.WEXITSTATUS(status)\r
136 if exit_status == 0:\r
137 return # hey, it succeeded!\r
138 else:\r
139 raise DistutilsExecError, \\r
140 "command '%s' failed with exit status %d" % \\r
141 (cmd[0], exit_status)\r
142\r
143 elif os.WIFSTOPPED(status):\r
144 continue\r
145\r
146 else:\r
147 raise DistutilsExecError, \\r
148 "unknown error executing '%s': termination status %d" % \\r
149 (cmd[0], status)\r
150\r
151def find_executable(executable, path=None):\r
152 """Tries to find 'executable' in the directories listed in 'path'.\r
153\r
154 A string listing directories separated by 'os.pathsep'; defaults to\r
155 os.environ['PATH']. Returns the complete filename or None if not found.\r
156 """\r
157 if path is None:\r
158 path = os.environ['PATH']\r
159 paths = path.split(os.pathsep)\r
160 base, ext = os.path.splitext(executable)\r
161\r
162 if (sys.platform == 'win32' or os.name == 'os2') and (ext != '.exe'):\r
163 executable = executable + '.exe'\r
164\r
165 if not os.path.isfile(executable):\r
166 for p in paths:\r
167 f = os.path.join(p, executable)\r
168 if os.path.isfile(f):\r
169 # the file exists, we have a shot at spawn working\r
170 return f\r
171 return None\r
172 else:\r
173 return executable\r