Add spawnv and spawnve functions for Win32 platforms.

This commit is contained in:
Guido van Rossum 1999-01-25 23:20:23 +00:00
parent 54ec2884b8
commit a106568eed
1 changed files with 178 additions and 0 deletions

View File

@ -105,6 +105,7 @@ corresponding Unix manual entries for more information on calls.";
#ifdef _MSC_VER /* Microsoft compiler */
#define HAVE_GETCWD 1
#ifdef MS_WIN32
#define HAVE_SPAWNV 1
#define HAVE_EXECV 1
#define HAVE_PIPE 1
#define HAVE_POPEN 1
@ -1392,6 +1393,179 @@ posix_execve(self, args)
#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
static char posix_fork__doc__[] =
"fork() -> pid\n\
@ -2922,6 +3096,10 @@ static PyMethodDef posix_methods[] = {
{"execv", posix_execv, 0, posix_execv__doc__},
{"execve", posix_execve, 0, posix_execve__doc__},
#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
{"fork", posix_fork, 0, posix_fork__doc__},
#endif /* HAVE_FORK */