mirror of https://github.com/python/cpython.git
Add spawnv and spawnve functions for Win32 platforms.
This commit is contained in:
parent
54ec2884b8
commit
a106568eed
|
@ -105,6 +105,7 @@ corresponding Unix manual entries for more information on calls.";
|
||||||
#ifdef _MSC_VER /* Microsoft compiler */
|
#ifdef _MSC_VER /* Microsoft compiler */
|
||||||
#define HAVE_GETCWD 1
|
#define HAVE_GETCWD 1
|
||||||
#ifdef MS_WIN32
|
#ifdef MS_WIN32
|
||||||
|
#define HAVE_SPAWNV 1
|
||||||
#define HAVE_EXECV 1
|
#define HAVE_EXECV 1
|
||||||
#define HAVE_PIPE 1
|
#define HAVE_PIPE 1
|
||||||
#define HAVE_POPEN 1
|
#define HAVE_POPEN 1
|
||||||
|
@ -1392,6 +1393,179 @@ posix_execve(self, args)
|
||||||
#endif /* HAVE_EXECV */
|
#endif /* HAVE_EXECV */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_SPAWNV
|
||||||
|
static char posix_spawnv__doc__[] =
|
||||||
|
"spawnv(path, args)\n\
|
||||||
|
Execute an executable path with arguments, replacing current process.\n\
|
||||||
|
\n\
|
||||||
|
path: path of executable file\n\
|
||||||
|
args: tuple or list of strings";
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
posix_spawnv(self, args)
|
||||||
|
PyObject *self;
|
||||||
|
PyObject *args;
|
||||||
|
{
|
||||||
|
char *path;
|
||||||
|
PyObject *argv;
|
||||||
|
char **argvlist;
|
||||||
|
int mode, i, argc;
|
||||||
|
PyObject *(*getitem) Py_PROTO((PyObject *, int));
|
||||||
|
|
||||||
|
/* spawnv has three arguments: (mode, path, argv), where
|
||||||
|
argv is a list or tuple of strings. */
|
||||||
|
|
||||||
|
if (!PyArg_Parse(args, "(isO)", &mode, &path, &argv))
|
||||||
|
return NULL;
|
||||||
|
if (PyList_Check(argv)) {
|
||||||
|
argc = PyList_Size(argv);
|
||||||
|
getitem = PyList_GetItem;
|
||||||
|
}
|
||||||
|
else if (PyTuple_Check(argv)) {
|
||||||
|
argc = PyTuple_Size(argv);
|
||||||
|
getitem = PyTuple_GetItem;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
badarg:
|
||||||
|
PyErr_BadArgument();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
argvlist = PyMem_NEW(char *, argc+1);
|
||||||
|
if (argvlist == NULL)
|
||||||
|
return NULL;
|
||||||
|
for (i = 0; i < argc; i++) {
|
||||||
|
if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
|
||||||
|
PyMem_DEL(argvlist);
|
||||||
|
goto badarg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
argvlist[argc] = NULL;
|
||||||
|
|
||||||
|
i = _spawnv(mode, path, argvlist);
|
||||||
|
|
||||||
|
PyMem_DEL(argvlist);
|
||||||
|
|
||||||
|
if (i == -1)
|
||||||
|
return posix_error();
|
||||||
|
else
|
||||||
|
return Py_BuildValue("i", i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char posix_spawnve__doc__[] =
|
||||||
|
"spawnve(path, args, env)\n\
|
||||||
|
Execute a path with arguments and environment, replacing current process.\n\
|
||||||
|
\n\
|
||||||
|
path: path of executable file\n\
|
||||||
|
args: tuple or list of arguments\n\
|
||||||
|
env: dictonary of strings mapping to strings";
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
posix_spawnve(self, args)
|
||||||
|
PyObject *self;
|
||||||
|
PyObject *args;
|
||||||
|
{
|
||||||
|
char *path;
|
||||||
|
PyObject *argv, *env;
|
||||||
|
char **argvlist;
|
||||||
|
char **envlist;
|
||||||
|
PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
|
||||||
|
int mode, i, pos, argc, envc;
|
||||||
|
PyObject *(*getitem) Py_PROTO((PyObject *, int));
|
||||||
|
|
||||||
|
/* spawnve has four arguments: (mode, path, argv, env), where
|
||||||
|
argv is a list or tuple of strings and env is a dictionary
|
||||||
|
like posix.environ. */
|
||||||
|
|
||||||
|
if (!PyArg_Parse(args, "(isOO)", &mode, &path, &argv, &env))
|
||||||
|
return NULL;
|
||||||
|
if (PyList_Check(argv)) {
|
||||||
|
argc = PyList_Size(argv);
|
||||||
|
getitem = PyList_GetItem;
|
||||||
|
}
|
||||||
|
else if (PyTuple_Check(argv)) {
|
||||||
|
argc = PyTuple_Size(argv);
|
||||||
|
getitem = PyTuple_GetItem;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!PyMapping_Check(env)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "env must be mapping object");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
argvlist = PyMem_NEW(char *, argc+1);
|
||||||
|
if (argvlist == NULL) {
|
||||||
|
PyErr_NoMemory();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for (i = 0; i < argc; i++) {
|
||||||
|
if (!PyArg_Parse((*getitem)(argv, i),
|
||||||
|
"s;argv must be list of strings",
|
||||||
|
&argvlist[i]))
|
||||||
|
{
|
||||||
|
goto fail_1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
argvlist[argc] = NULL;
|
||||||
|
|
||||||
|
i = PyMapping_Length(env);
|
||||||
|
envlist = PyMem_NEW(char *, i + 1);
|
||||||
|
if (envlist == NULL) {
|
||||||
|
PyErr_NoMemory();
|
||||||
|
goto fail_1;
|
||||||
|
}
|
||||||
|
envc = 0;
|
||||||
|
keys = PyMapping_Keys(env);
|
||||||
|
vals = PyMapping_Values(env);
|
||||||
|
if (!keys || !vals)
|
||||||
|
goto fail_2;
|
||||||
|
|
||||||
|
for (pos = 0; pos < i; pos++) {
|
||||||
|
char *p, *k, *v;
|
||||||
|
|
||||||
|
key = PyList_GetItem(keys, pos);
|
||||||
|
val = PyList_GetItem(vals, pos);
|
||||||
|
if (!key || !val)
|
||||||
|
goto fail_2;
|
||||||
|
|
||||||
|
if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
|
||||||
|
!PyArg_Parse(val, "s;non-string value in env", &v))
|
||||||
|
{
|
||||||
|
goto fail_2;
|
||||||
|
}
|
||||||
|
p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
|
||||||
|
if (p == NULL) {
|
||||||
|
PyErr_NoMemory();
|
||||||
|
goto fail_2;
|
||||||
|
}
|
||||||
|
sprintf(p, "%s=%s", k, v);
|
||||||
|
envlist[envc++] = p;
|
||||||
|
}
|
||||||
|
envlist[envc] = 0;
|
||||||
|
|
||||||
|
i = _spawnve(mode, path, argvlist, envlist);
|
||||||
|
if (i == -1)
|
||||||
|
(void) posix_error();
|
||||||
|
else
|
||||||
|
res = Py_BuildValue("i", i);
|
||||||
|
|
||||||
|
fail_2:
|
||||||
|
while (--envc >= 0)
|
||||||
|
PyMem_DEL(envlist[envc]);
|
||||||
|
PyMem_DEL(envlist);
|
||||||
|
fail_1:
|
||||||
|
PyMem_DEL(argvlist);
|
||||||
|
Py_XDECREF(vals);
|
||||||
|
Py_XDECREF(keys);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_SPAWNV */
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_FORK
|
#ifdef HAVE_FORK
|
||||||
static char posix_fork__doc__[] =
|
static char posix_fork__doc__[] =
|
||||||
"fork() -> pid\n\
|
"fork() -> pid\n\
|
||||||
|
@ -2922,6 +3096,10 @@ static PyMethodDef posix_methods[] = {
|
||||||
{"execv", posix_execv, 0, posix_execv__doc__},
|
{"execv", posix_execv, 0, posix_execv__doc__},
|
||||||
{"execve", posix_execve, 0, posix_execve__doc__},
|
{"execve", posix_execve, 0, posix_execve__doc__},
|
||||||
#endif /* HAVE_EXECV */
|
#endif /* HAVE_EXECV */
|
||||||
|
#ifdef HAVE_SPAWNV
|
||||||
|
{"spawnv", posix_spawnv, 0, posix_spawnv__doc__},
|
||||||
|
{"spawnve", posix_spawnve, 0, posix_spawnve__doc__},
|
||||||
|
#endif /* HAVE_SPAWNV */
|
||||||
#ifdef HAVE_FORK
|
#ifdef HAVE_FORK
|
||||||
{"fork", posix_fork, 0, posix_fork__doc__},
|
{"fork", posix_fork, 0, posix_fork__doc__},
|
||||||
#endif /* HAVE_FORK */
|
#endif /* HAVE_FORK */
|
||||||
|
|
Loading…
Reference in New Issue