summaryrefslogtreecommitdiffstats
path: root/Modules/posixmodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/posixmodule.c')
-rw-r--r--Modules/posixmodule.c140
1 files changed, 136 insertions, 4 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 7f13735..4a8a8d7 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -5178,6 +5178,114 @@ enum posix_spawn_file_actions_identifier {
};
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,
PyObject *temp_buffer)
@@ -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);
}