mirror of
https://github.com/python/cpython.git
synced 2025-07-24 11:44:31 +00:00
bpo-20104: Add flag capabilities to posix_spawn (GH-6693)
Implement the "attributes objects" parameter of `os.posix_spawn` to complete the implementation and fully cover the underlying API.
This commit is contained in:
parent
5e922658fb
commit
254a4663d8
5 changed files with 344 additions and 14 deletions
|
@ -5177,6 +5177,114 @@ enum posix_spawn_file_actions_identifier {
|
|||
POSIX_SPAWN_DUP2
|
||||
};
|
||||
|
||||
static int
|
||||
convert_sched_param(PyObject *param, struct sched_param *res);
|
||||
|
||||
static int
|
||||
parse_posix_spawn_flags(PyObject *setpgroup, int resetids, PyObject *setsigmask,
|
||||
PyObject *setsigdef, PyObject *scheduler,
|
||||
posix_spawnattr_t *attrp)
|
||||
{
|
||||
long all_flags = 0;
|
||||
|
||||
errno = posix_spawnattr_init(attrp);
|
||||
if (errno) {
|
||||
posix_error();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setpgroup) {
|
||||
pid_t pgid = PyLong_AsPid(setpgroup);
|
||||
if (pgid == (pid_t)-1 && PyErr_Occurred()) {
|
||||
goto fail;
|
||||
}
|
||||
errno = posix_spawnattr_setpgroup(attrp, pgid);
|
||||
if (errno) {
|
||||
posix_error();
|
||||
goto fail;
|
||||
}
|
||||
all_flags |= POSIX_SPAWN_SETPGROUP;
|
||||
}
|
||||
|
||||
if (resetids) {
|
||||
all_flags |= POSIX_SPAWN_RESETIDS;
|
||||
}
|
||||
|
||||
if (setsigmask) {
|
||||
sigset_t set;
|
||||
if (!_Py_Sigset_Converter(setsigmask, &set)) {
|
||||
goto fail;
|
||||
}
|
||||
errno = posix_spawnattr_setsigmask(attrp, &set);
|
||||
if (errno) {
|
||||
posix_error();
|
||||
goto fail;
|
||||
}
|
||||
all_flags |= POSIX_SPAWN_SETSIGMASK;
|
||||
}
|
||||
|
||||
if (setsigdef) {
|
||||
sigset_t set;
|
||||
if (!_Py_Sigset_Converter(setsigdef, &set)) {
|
||||
goto fail;
|
||||
}
|
||||
errno = posix_spawnattr_setsigdefault(attrp, &set);
|
||||
if (errno) {
|
||||
posix_error();
|
||||
goto fail;
|
||||
}
|
||||
all_flags |= POSIX_SPAWN_SETSIGDEF;
|
||||
}
|
||||
|
||||
if (scheduler) {
|
||||
#ifdef POSIX_SPAWN_SETSCHEDULER
|
||||
PyObject *py_schedpolicy;
|
||||
struct sched_param schedparam;
|
||||
|
||||
if (!PyArg_ParseTuple(scheduler, "OO&"
|
||||
";A scheduler tuple must have two elements",
|
||||
&py_schedpolicy, convert_sched_param, &schedparam)) {
|
||||
goto fail;
|
||||
}
|
||||
if (py_schedpolicy != Py_None) {
|
||||
int schedpolicy = _PyLong_AsInt(py_schedpolicy);
|
||||
|
||||
if (schedpolicy == -1 && PyErr_Occurred()) {
|
||||
goto fail;
|
||||
}
|
||||
errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
|
||||
if (errno) {
|
||||
posix_error();
|
||||
goto fail;
|
||||
}
|
||||
all_flags |= POSIX_SPAWN_SETSCHEDULER;
|
||||
}
|
||||
errno = posix_spawnattr_setschedparam(attrp, &schedparam);
|
||||
if (errno) {
|
||||
posix_error();
|
||||
goto fail;
|
||||
}
|
||||
all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
|
||||
#else
|
||||
PyErr_SetString(PyExc_NotImplementedError,
|
||||
"The scheduler option is not supported in this system.");
|
||||
goto fail;
|
||||
#endif
|
||||
}
|
||||
|
||||
errno = posix_spawnattr_setflags(attrp, all_flags);
|
||||
if (errno) {
|
||||
posix_error();
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
(void)posix_spawnattr_destroy(attrp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_file_actions(PyObject *file_actions,
|
||||
posix_spawn_file_actions_t *file_actionsp,
|
||||
|
@ -5277,6 +5385,7 @@ parse_file_actions(PyObject *file_actions,
|
|||
}
|
||||
Py_DECREF(file_action);
|
||||
}
|
||||
|
||||
Py_DECREF(seq);
|
||||
return 0;
|
||||
|
||||
|
@ -5299,19 +5408,33 @@ os.posix_spawn
|
|||
file_actions: object = None
|
||||
A sequence of file action tuples.
|
||||
/
|
||||
|
||||
*
|
||||
setpgroup: object = NULL
|
||||
The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
|
||||
resetids: bool(accept={int}) = False
|
||||
If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
|
||||
setsigmask: object(c_default='NULL') = ()
|
||||
The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
|
||||
setsigdef: object(c_default='NULL') = ()
|
||||
The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
|
||||
scheduler: object = NULL
|
||||
A tuple with the scheduler policy (optional) and parameters.
|
||||
Execute the program specified by path in a new process.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
|
||||
PyObject *env, PyObject *file_actions)
|
||||
/*[clinic end generated code: output=d023521f541c709c input=a3db1021d33230dc]*/
|
||||
PyObject *env, PyObject *file_actions,
|
||||
PyObject *setpgroup, int resetids, PyObject *setsigmask,
|
||||
PyObject *setsigdef, PyObject *scheduler)
|
||||
/*[clinic end generated code: output=45dfa4c515d09f2c input=2d7a7578430a90f0]*/
|
||||
{
|
||||
EXECV_CHAR **argvlist = NULL;
|
||||
EXECV_CHAR **envlist = NULL;
|
||||
posix_spawn_file_actions_t file_actions_buf;
|
||||
posix_spawn_file_actions_t *file_actionsp = NULL;
|
||||
posix_spawnattr_t attr;
|
||||
posix_spawnattr_t *attrp = NULL;
|
||||
Py_ssize_t argc, envc;
|
||||
PyObject *result = NULL;
|
||||
PyObject *temp_buffer = NULL;
|
||||
|
@ -5373,9 +5496,15 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
|
|||
file_actionsp = &file_actions_buf;
|
||||
}
|
||||
|
||||
if (parse_posix_spawn_flags(setpgroup, resetids, setsigmask,
|
||||
setsigdef, scheduler, &attr)) {
|
||||
goto exit;
|
||||
}
|
||||
attrp = &attr;
|
||||
|
||||
_Py_BEGIN_SUPPRESS_IPH
|
||||
err_code = posix_spawn(&pid, path->narrow,
|
||||
file_actionsp, NULL, argvlist, envlist);
|
||||
file_actionsp, attrp, argvlist, envlist);
|
||||
_Py_END_SUPPRESS_IPH
|
||||
if (err_code) {
|
||||
errno = err_code;
|
||||
|
@ -5388,6 +5517,9 @@ exit:
|
|||
if (file_actionsp) {
|
||||
(void)posix_spawn_file_actions_destroy(file_actionsp);
|
||||
}
|
||||
if (attrp) {
|
||||
(void)posix_spawnattr_destroy(attrp);
|
||||
}
|
||||
if (envlist) {
|
||||
free_string_array(envlist, envc);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue