mirror of
https://github.com/python/cpython.git
synced 2026-04-13 23:31:02 +00:00
[3.14] gh-143698: correctly check scheduler and setpgroup values for os.posix_spawn[p] (GH-143699) (#145073)
Fix an issue where passing invalid arguments to `os.posix_spawn[p]` functions
raised a SystemError instead of a TypeError, and allow to explicitly use `None`
for `scheduler` and `setpgroup` as specified in the docs.
(cherry picked from commit 347fc438cf)
This commit is contained in:
parent
8e482eb1ec
commit
dcf96d0ed6
6 changed files with 46 additions and 15 deletions
|
|
@ -6203,8 +6203,7 @@ def test_operator_module_has_signatures(self):
|
|||
def test_os_module_has_signatures(self):
|
||||
unsupported_signature = {'chmod', 'utime'}
|
||||
unsupported_signature |= {name for name in
|
||||
['get_terminal_size', 'link', 'posix_spawn', 'posix_spawnp',
|
||||
'register_at_fork', 'startfile']
|
||||
['get_terminal_size', 'link', 'register_at_fork', 'startfile']
|
||||
if hasattr(os, name)}
|
||||
self._test_module_has_signatures(os, unsupported_signature=unsupported_signature)
|
||||
|
||||
|
|
|
|||
|
|
@ -1933,6 +1933,11 @@ def test_setpgroup(self):
|
|||
)
|
||||
support.wait_process(pid, exitcode=0)
|
||||
|
||||
def test_setpgroup_allow_none(self):
|
||||
path, args = self.NOOP_PROGRAM[0], self.NOOP_PROGRAM
|
||||
pid = self.spawn_func(path, args, os.environ, setpgroup=None)
|
||||
support.wait_process(pid, exitcode=0)
|
||||
|
||||
def test_setpgroup_wrong_type(self):
|
||||
with self.assertRaises(TypeError):
|
||||
self.spawn_func(sys.executable,
|
||||
|
|
@ -2033,6 +2038,20 @@ def test_setsigdef_wrong_type(self):
|
|||
[sys.executable, "-c", "pass"],
|
||||
os.environ, setsigdef=[signal.NSIG, signal.NSIG+1])
|
||||
|
||||
def test_scheduler_allow_none(self):
|
||||
path, args = self.NOOP_PROGRAM[0], self.NOOP_PROGRAM
|
||||
pid = self.spawn_func(path, args, os.environ, scheduler=None)
|
||||
support.wait_process(pid, exitcode=0)
|
||||
|
||||
@support.subTests("scheduler", [object(), 1, [1, 2]])
|
||||
def test_scheduler_wrong_type(self, scheduler):
|
||||
path, args = self.NOOP_PROGRAM[0], self.NOOP_PROGRAM
|
||||
with self.assertRaisesRegex(
|
||||
TypeError,
|
||||
"scheduler must be a tuple or None",
|
||||
):
|
||||
self.spawn_func(path, args, os.environ, scheduler=scheduler)
|
||||
|
||||
@requires_sched
|
||||
@unittest.skipIf(sys.platform.startswith(('freebsd', 'netbsd')),
|
||||
"bpo-34685: test can fail on BSD")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
Raise :exc:`TypeError` instead of :exc:`SystemError` when the *scheduler*
|
||||
in :func:`os.posix_spawn` or :func:`os.posix_spawnp` is not a tuple.
|
||||
Patch by Bénédikt Tran.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
Allow *scheduler* and *setpgroup* arguments to be explicitly :const:`None`
|
||||
when calling :func:`os.posix_spawn` or :func:`os.posix_spawnp`. Patch by
|
||||
Bénédikt Tran.
|
||||
10
Modules/clinic/posixmodule.c.h
generated
10
Modules/clinic/posixmodule.c.h
generated
|
|
@ -3845,8 +3845,8 @@ exit:
|
|||
|
||||
PyDoc_STRVAR(os_posix_spawn__doc__,
|
||||
"posix_spawn($module, path, argv, env, /, *, file_actions=(),\n"
|
||||
" setpgroup=<unrepresentable>, resetids=False, setsid=False,\n"
|
||||
" setsigmask=(), setsigdef=(), scheduler=<unrepresentable>)\n"
|
||||
" setpgroup=None, resetids=False, setsid=False,\n"
|
||||
" setsigmask=(), setsigdef=(), scheduler=None)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Execute the program specified by path in a new process.\n"
|
||||
|
|
@ -3998,8 +3998,8 @@ exit:
|
|||
|
||||
PyDoc_STRVAR(os_posix_spawnp__doc__,
|
||||
"posix_spawnp($module, path, argv, env, /, *, file_actions=(),\n"
|
||||
" setpgroup=<unrepresentable>, resetids=False, setsid=False,\n"
|
||||
" setsigmask=(), setsigdef=(), scheduler=<unrepresentable>)\n"
|
||||
" setpgroup=None, resetids=False, setsid=False,\n"
|
||||
" setsigmask=(), setsigdef=(), scheduler=None)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Execute the program specified by path in a new process.\n"
|
||||
|
|
@ -13476,4 +13476,4 @@ exit:
|
|||
#ifndef OS__EMSCRIPTEN_LOG_METHODDEF
|
||||
#define OS__EMSCRIPTEN_LOG_METHODDEF
|
||||
#endif /* !defined(OS__EMSCRIPTEN_LOG_METHODDEF) */
|
||||
/*[clinic end generated code: output=9e5f9b9ce732a534 input=a9049054013a1b77]*/
|
||||
/*[clinic end generated code: output=291f607b7a26ca5e input=a9049054013a1b77]*/
|
||||
|
|
|
|||
|
|
@ -7155,6 +7155,7 @@ parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpg
|
|||
PyObject *setsigdef, PyObject *scheduler,
|
||||
posix_spawnattr_t *attrp)
|
||||
{
|
||||
assert(scheduler == NULL || scheduler == Py_None || PyTuple_Check(scheduler));
|
||||
long all_flags = 0;
|
||||
|
||||
errno = posix_spawnattr_init(attrp);
|
||||
|
|
@ -7163,7 +7164,7 @@ parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpg
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (setpgroup) {
|
||||
if (setpgroup && setpgroup != Py_None) {
|
||||
pid_t pgid = PyLong_AsPid(setpgroup);
|
||||
if (pgid == (pid_t)-1 && PyErr_Occurred()) {
|
||||
goto fail;
|
||||
|
|
@ -7236,7 +7237,7 @@ parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpg
|
|||
}
|
||||
#endif
|
||||
|
||||
if (scheduler) {
|
||||
if (scheduler && scheduler != Py_None) {
|
||||
#ifdef POSIX_SPAWN_SETSCHEDULER
|
||||
PyObject *py_schedpolicy;
|
||||
PyObject *schedparam_obj;
|
||||
|
|
@ -7461,6 +7462,12 @@ py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *a
|
|||
goto exit;
|
||||
}
|
||||
|
||||
if (scheduler && !PyTuple_Check(scheduler) && scheduler != Py_None) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"%s: scheduler must be a tuple or None", func_name);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
argvlist = parse_arglist(argv, &argc);
|
||||
if (argvlist == NULL) {
|
||||
goto exit;
|
||||
|
|
@ -7572,7 +7579,7 @@ os.posix_spawn
|
|||
*
|
||||
file_actions: object(c_default='NULL') = ()
|
||||
A sequence of file action tuples.
|
||||
setpgroup: object = NULL
|
||||
setpgroup: object(c_default='NULL') = None
|
||||
The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
|
||||
resetids: bool = False
|
||||
If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
|
||||
|
|
@ -7582,7 +7589,7 @@ os.posix_spawn
|
|||
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
|
||||
scheduler: object(c_default='NULL') = None
|
||||
A tuple with the scheduler policy (optional) and parameters.
|
||||
|
||||
Execute the program specified by path in a new process.
|
||||
|
|
@ -7594,7 +7601,7 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
|
|||
PyObject *setpgroup, int resetids, int setsid,
|
||||
PyObject *setsigmask, PyObject *setsigdef,
|
||||
PyObject *scheduler)
|
||||
/*[clinic end generated code: output=14a1098c566bc675 input=808aed1090d84e33]*/
|
||||
/*[clinic end generated code: output=14a1098c566bc675 input=69e7c9ebbdcf94a5]*/
|
||||
{
|
||||
return py_posix_spawn(0, module, path, argv, env, file_actions,
|
||||
setpgroup, resetids, setsid, setsigmask, setsigdef,
|
||||
|
|
@ -7618,7 +7625,7 @@ os.posix_spawnp
|
|||
*
|
||||
file_actions: object(c_default='NULL') = ()
|
||||
A sequence of file action tuples.
|
||||
setpgroup: object = NULL
|
||||
setpgroup: object(c_default='NULL') = None
|
||||
The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
|
||||
resetids: bool = False
|
||||
If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
|
||||
|
|
@ -7628,7 +7635,7 @@ os.posix_spawnp
|
|||
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
|
||||
scheduler: object(c_default='NULL') = None
|
||||
A tuple with the scheduler policy (optional) and parameters.
|
||||
|
||||
Execute the program specified by path in a new process.
|
||||
|
|
@ -7640,7 +7647,7 @@ os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
|
|||
PyObject *setpgroup, int resetids, int setsid,
|
||||
PyObject *setsigmask, PyObject *setsigdef,
|
||||
PyObject *scheduler)
|
||||
/*[clinic end generated code: output=7b9aaefe3031238d input=9e89e616116752a1]*/
|
||||
/*[clinic end generated code: output=7b9aaefe3031238d input=a5c057527c6881a5]*/
|
||||
{
|
||||
return py_posix_spawn(1, module, path, argv, env, file_actions,
|
||||
setpgroup, resetids, setsid, setsigmask, setsigdef,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue