mirror of https://github.com/python/cpython
Checking in a bunch of spawn functions. These are only defined if we
have fork and execv (and friends) but not spawnv. They operate exactly like the spawn functions on Windows. A limited set of needed constants is also defined (P_WAIT, P_NOWAIT etc.). Also add getenv() as a familiar alias for environ.get().
This commit is contained in:
parent
66e53854d6
commit
5a2ca9328d
82
Lib/os.py
82
Lib/os.py
|
@ -201,8 +201,8 @@ def execvpe(file, args, env):
|
||||||
_execvpe(file, args, env)
|
_execvpe(file, args, env)
|
||||||
|
|
||||||
_notfound = None
|
_notfound = None
|
||||||
def _execvpe(file, args, env = None):
|
def _execvpe(file, args, env=None):
|
||||||
if env:
|
if env is not None:
|
||||||
func = execve
|
func = execve
|
||||||
argrest = (args, env)
|
argrest = (args, env)
|
||||||
else:
|
else:
|
||||||
|
@ -273,3 +273,81 @@ else:
|
||||||
self.data[key] = item
|
self.data[key] = item
|
||||||
|
|
||||||
environ = _Environ(environ)
|
environ = _Environ(environ)
|
||||||
|
|
||||||
|
def getenv(key, default=None):
|
||||||
|
"""Get an environment variable, return None if it doesn't exist.
|
||||||
|
|
||||||
|
The optional second argument can specify an alternative default."""
|
||||||
|
return environ.get(key, default)
|
||||||
|
|
||||||
|
def _exists(name):
|
||||||
|
try:
|
||||||
|
eval(name)
|
||||||
|
return 1
|
||||||
|
except NameError:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# Supply spawn*() (probably only for Unix)
|
||||||
|
if _exists("fork") and not _exists("spawnv") and _exists("execv"):
|
||||||
|
|
||||||
|
P_WAIT = 0
|
||||||
|
P_NOWAIT = P_NOWAITO = 1
|
||||||
|
|
||||||
|
# XXX Should we support P_DETACH? I suppose it could fork()**2
|
||||||
|
# and close the std I/O streams. Also, P_OVERLAY is the same
|
||||||
|
# as execv*()?
|
||||||
|
|
||||||
|
def _spawnvef(mode, file, args, env, func):
|
||||||
|
# Internal helper; func is the exec*() function to use
|
||||||
|
pid = fork()
|
||||||
|
if not pid:
|
||||||
|
# Child
|
||||||
|
try:
|
||||||
|
if env is None:
|
||||||
|
func(file, args)
|
||||||
|
else:
|
||||||
|
func(file, args, env)
|
||||||
|
except:
|
||||||
|
_exit(127)
|
||||||
|
else:
|
||||||
|
# Parent
|
||||||
|
if mode == P_NOWAIT:
|
||||||
|
return pid # Caller is responsible for waiting!
|
||||||
|
while 1:
|
||||||
|
wpid, sts = waitpid(pid, 0)
|
||||||
|
if WIFSTOPPED(sts):
|
||||||
|
continue
|
||||||
|
elif WIFSIGNALED(sts):
|
||||||
|
return -WTERMSIG(sts)
|
||||||
|
elif WIFEXITED(sts):
|
||||||
|
return WEXITSTATUS(sts)
|
||||||
|
else:
|
||||||
|
raise error, "Not stopped, signaled or exited???"
|
||||||
|
|
||||||
|
def spawnv(mode, file, args):
|
||||||
|
return _spawnvef(mode, file, args, None, execv)
|
||||||
|
|
||||||
|
def spawnve(mode, file, args, env):
|
||||||
|
return _spawnvef(mode, file, args, env, execve)
|
||||||
|
|
||||||
|
# Supply the various other variants
|
||||||
|
|
||||||
|
def spawnl(mode, file, *args):
|
||||||
|
return spawnv(mode, file, args)
|
||||||
|
|
||||||
|
def spawnle(mode, file, *args):
|
||||||
|
env = args[-1]
|
||||||
|
return spawnve(mode, file, args[:-1], env)
|
||||||
|
|
||||||
|
def spawnlp(mode, file, *args):
|
||||||
|
return spawnvp(mode, file, args)
|
||||||
|
|
||||||
|
def spawnlpe(mode, file, *args):
|
||||||
|
env = args[-1]
|
||||||
|
return spawnvpe(mode, file, args[:-1], env)
|
||||||
|
|
||||||
|
def spawnvp(mode, file, args):
|
||||||
|
return _spawnvef(mode, file, args, None, execvp)
|
||||||
|
|
||||||
|
def spawnvpe(mode, file, args, env):
|
||||||
|
return _spawnvef(mode, file, args, env, execvpe)
|
||||||
|
|
Loading…
Reference in New Issue