📄 posixmodule.c
字号:
/* execv has two arguments: (path, argv), where
argv is a list or tuple of strings. */
if (!PyArg_ParseTuple(args, "sO:execv", &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 {
PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
return NULL;
}
if (argc == 0) {
PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
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);
PyErr_SetString(PyExc_TypeError,
"execv() arg 2 must contain only strings");
return NULL;
}
}
argvlist[argc] = NULL;
#ifdef BAD_EXEC_PROTOTYPES
execv(path, (const char **) argvlist);
#else /* BAD_EXEC_PROTOTYPES */
execv(path, argvlist);
#endif /* BAD_EXEC_PROTOTYPES */
/* If we get here it's definitely an error */
PyMem_DEL(argvlist);
return posix_error();
}
static const char posix_execve__doc__[] =
"execve(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: dictionary of strings mapping to strings";
static PyObject *
posix_execve(PyObject *self, PyObject *args)
{
char *path;
PyObject *argv, *env;
char **argvlist;
char **envlist;
PyObject *key, *val, *keys=NULL, *vals=NULL;
int i, pos, argc, envc;
PyObject *(*getitem)(PyObject *, int);
/* execve has three arguments: (path, argv, env), where
argv is a list or tuple of strings and env is a dictionary
like posix.environ. */
if (!PyArg_ParseTuple(args, "sOO:execve", &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, "execve() arg 2 must be a tuple or list");
return NULL;
}
if (!PyMapping_Check(env)) {
PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
return NULL;
}
if (argc == 0) {
PyErr_SetString(PyExc_ValueError,
"execve() arg 2 must not be empty");
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;execve() arg 2 must contain only strings",
&argvlist[i]))
{
goto fail_1;
}
}
argvlist[argc] = NULL;
i = PyMapping_Size(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;
size_t len;
key = PyList_GetItem(keys, pos);
val = PyList_GetItem(vals, pos);
if (!key || !val)
goto fail_2;
if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
!PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
{
goto fail_2;
}
#if defined(PYOS_OS2)
/* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
#endif
len = PyString_Size(key) + PyString_Size(val) + 2;
p = PyMem_NEW(char, len);
if (p == NULL) {
PyErr_NoMemory();
goto fail_2;
}
PyOS_snprintf(p, len, "%s=%s", k, v);
envlist[envc++] = p;
#if defined(PYOS_OS2)
}
#endif
}
envlist[envc] = 0;
#ifdef BAD_EXEC_PROTOTYPES
execve(path, (const char **)argvlist, envlist);
#else /* BAD_EXEC_PROTOTYPES */
execve(path, argvlist, envlist);
#endif /* BAD_EXEC_PROTOTYPES */
/* If we get here it's definitely an error */
(void) posix_error();
fail_2:
while (--envc >= 0)
PyMem_DEL(envlist[envc]);
PyMem_DEL(envlist);
fail_1:
PyMem_DEL(argvlist);
Py_XDECREF(vals);
Py_XDECREF(keys);
return NULL;
}
#endif /* HAVE_EXECV */
#ifdef HAVE_SPAWNV
static const char posix_spawnv__doc__[] =
"spawnv(mode, path, args)\n\
Execute the program 'path' in a new process.\n\
\n\
mode: mode of process creation\n\
path: path of executable file\n\
args: tuple or list of strings";
static PyObject *
posix_spawnv(PyObject *self, PyObject *args)
{
char *path;
PyObject *argv;
char **argvlist;
int mode, i, argc;
Py_intptr_t spawnval;
PyObject *(*getitem)(PyObject *, int);
/* spawnv has three arguments: (mode, path, argv), where
argv is a list or tuple of strings. */
if (!PyArg_ParseTuple(args, "isO:spawnv", &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 {
PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
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);
PyErr_SetString(PyExc_TypeError,
"spawnv() arg 2 must contain only strings");
return NULL;
}
}
argvlist[argc] = NULL;
if (mode == _OLD_P_OVERLAY)
mode = _P_OVERLAY;
Py_BEGIN_ALLOW_THREADS
spawnval = _spawnv(mode, path, argvlist);
Py_END_ALLOW_THREADS
PyMem_DEL(argvlist);
if (spawnval == -1)
return posix_error();
else
#if SIZEOF_LONG == SIZEOF_VOID_P
return Py_BuildValue("l", (long) spawnval);
#else
return Py_BuildValue("L", (LONG_LONG) spawnval);
#endif
}
static const char posix_spawnve__doc__[] =
"spawnve(mode, path, args, env)\n\
Execute the program 'path' in a new process.\n\
\n\
mode: mode of process creation\n\
path: path of executable file\n\
args: tuple or list of arguments\n\
env: dictionary of strings mapping to strings";
static PyObject *
posix_spawnve(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;
Py_intptr_t spawnval;
PyObject *(*getitem)(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_ParseTuple(args, "isOO:spawnve", &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, "spawnve() arg 2 must be a tuple or list");
return NULL;
}
if (!PyMapping_Check(env)) {
PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a 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;spawnve() arg 2 must contain only strings",
&argvlist[i]))
{
goto fail_1;
}
}
argvlist[argc] = NULL;
i = PyMapping_Size(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;
size_t len;
key = PyList_GetItem(keys, pos);
val = PyList_GetItem(vals, pos);
if (!key || !val)
goto fail_2;
if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
!PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
{
goto fail_2;
}
len = PyString_Size(key) + PyString_Size(val) + 2;
p = PyMem_NEW(char, len);
if (p == NULL) {
PyErr_NoMemory();
goto fail_2;
}
PyOS_snprintf(p, len, "%s=%s", k, v);
envlist[envc++] = p;
}
envlist[envc] = 0;
if (mode == _OLD_P_OVERLAY)
mode = _P_OVERLAY;
Py_BEGIN_ALLOW_THREADS
spawnval = _spawnve(mode, path, argvlist, envlist);
Py_END_ALLOW_THREADS
if (spawnval == -1)
(void) posix_error();
else
#if SIZEOF_LONG == SIZEOF_VOID_P
res = Py_BuildValue("l", (long) spawnval);
#else
res = Py_BuildValue("L", (LONG_LONG) spawnval);
#endif
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_FORK1
static const char posix_fork1__doc__[] =
"fork1() -> pid\n\
Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
\n\
Return 0 to child process and PID of child to parent process.";
static PyObject *
posix_fork1(self, args)
PyObject *self;
PyObject *args;
{
int pid;
if (!PyArg_ParseTuple(args, ":fork1"))
return NULL;
pid = fork1();
if (pid == -1)
return posix_error();
PyOS_AfterFork();
return PyInt_FromLong((long)pid);
}
#endif
#ifdef HAVE_FORK
static const char posix_fork__doc__[] =
"fork() -> pid\n\
Fork a child process.\n\
\n\
Return 0 to child process and PID of child to parent process.";
static PyObject *
posix_fork(PyObject *self, PyObject *args)
{
int pid;
if (!PyArg_ParseTuple(args, ":fork"))
return NULL;
pid = fork();
if (pid == -1)
return posix_error();
if (pid == 0)
PyOS_AfterFork();
return PyInt_FromLong((long)pid);
}
#endif
#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
#ifdef HAVE_PTY_H
#include <pty.h>
#else
#ifdef HAVE_LIBUTIL_H
#include <libutil.h>
#endif /* HAVE_LIBUTIL_H */
#endif /* HAVE_PTY_H */
#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
static const char posix_openpty__doc__[] =
"openpty() -> (master_fd, slave_fd)\n\
Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
static PyObject *
posix_openpty(PyObject *self, PyObject *args)
{
int master_fd, slave_fd;
#ifndef HAVE_OPENPTY
char * slave_name;
#endif
if (!PyArg_ParseTuple(args, ":openpty"))
return NULL;
#ifdef HAVE_OPENPTY
if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
return posix_error();
#else
slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
if (slave_name == NULL)
return posix_error();
slave_fd = open(slave_name, O_RDWR);
if (slave_fd < 0)
return posix_error();
#endif /* HAVE_OPENPTY */
return Py_BuildValue("(ii)", master_fd, slave_fd);
}
#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
#ifdef HAVE_FORKPTY
static const char posix_forkpty__doc__[] =
"forkpty() -> (pid, master_fd)\n\
Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
To both, return fd of newly opened pseudo-terminal.\n";
static PyObject *
posix_forkpty(PyObject *self, PyObject *args)
{
int master_fd, pid;
if (!PyArg_ParseTuple(args, ":forkpty"))
return NULL;
pid = forkpty(&master_fd, NULL, NULL, NULL);
if (pid == -1)
return posix_error();
if (pid == 0)
PyOS_AfterFork();
return Py_BuildValue("(ii)", pid, master_fd);
}
#endif
#ifdef HAVE_GETEGID
static const char posix_getegid__doc__[] =
"getegid() -> egid\n\
Return the current process's effective group id.";
static PyObject *
posix_getegid(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ":getegid"))
return NULL;
return PyInt_FromLong((long)getegid());
}
#endif
#ifdef HAVE_GETEUID
static const char posix_geteuid__doc__[] =
"geteuid() -> euid\n\
Return the current process's effective user id.";
static PyObject *
posix_geteuid(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ":geteuid"))
return NULL;
return PyInt_FromLong((long)geteuid());
}
#endif
#ifdef HAVE_GETGID
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -