From 2fe108953ef6927a3e9835b5877096d9fd907f51 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Thu, 13 Sep 2018 11:15:02 -0700 Subject: [PATCH 1/6] Add support for POSIX_SPAWN_USEVFORK in posix_spawn when available --- Lib/test/test_posix.py | 13 ++++++++++++ .../2018-09-13-11-14-38.bpo-34663.BtJz-5.rst | 2 ++ Modules/clinic/posixmodule.c.h | 19 ++++++++++-------- Modules/posixmodule.c | 20 +++++++++++++++---- 4 files changed, 42 insertions(+), 12 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2018-09-13-11-14-38.bpo-34663.BtJz-5.rst diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index d402d4fb088ca2..808281d0f750a6 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -1790,6 +1790,19 @@ def test_dup2(self): with open(dupfile) as f: self.assertEqual(f.read(), 'hello') + def test_usevfork(self): + try: + pid = posix.posix_spawn( + sys.executable, + [sys.executable, '-c', 'pass'], + os.environ, + usevfork=True + ) + except NotImplementedError: + unittest.SkipTest("POSIX_SPAWN_USEVFORK not available on this system") + else: + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + def test_main(): try: diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-09-13-11-14-38.bpo-34663.BtJz-5.rst b/Misc/NEWS.d/next/Core and Builtins/2018-09-13-11-14-38.bpo-34663.BtJz-5.rst new file mode 100644 index 00000000000000..48dd639d27166c --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-09-13-11-14-38.bpo-34663.BtJz-5.rst @@ -0,0 +1,2 @@ +Added support for `usevfork` parameters of `posix_spawn`, which allows to +use ``POSIX_SPAWN_USEVFORK`` when the flag is available in the system. diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index c3849a93c0c240..ca371c0fc0d917 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -1732,7 +1732,7 @@ os_execve(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k PyDoc_STRVAR(os_posix_spawn__doc__, "posix_spawn($module, path, argv, env, /, *, file_actions=(),\n" " setpgroup=None, resetids=False, setsigmask=(),\n" -" setsigdef=(), scheduler=None)\n" +" setsigdef=(), scheduler=None, usevfork=False)\n" "--\n" "\n" "Execute the program specified by path in a new process.\n" @@ -1754,7 +1754,9 @@ PyDoc_STRVAR(os_posix_spawn__doc__, " setsigdef\n" " The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.\n" " scheduler\n" -" A tuple with the scheduler policy (optional) and parameters."); +" A tuple with the scheduler policy (optional) and parameters.\n" +" usevfork\n" +" If the value is `True` the POSIX_SPAWN_USEVFORK will be activated."); #define OS_POSIX_SPAWN_METHODDEF \ {"posix_spawn", (PyCFunction)os_posix_spawn, METH_FASTCALL|METH_KEYWORDS, os_posix_spawn__doc__}, @@ -1763,14 +1765,14 @@ static PyObject * os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env, PyObject *file_actions, PyObject *setpgroup, int resetids, PyObject *setsigmask, - PyObject *setsigdef, PyObject *scheduler); + PyObject *setsigdef, PyObject *scheduler, int usevfork); static PyObject * os_posix_spawn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"", "", "", "file_actions", "setpgroup", "resetids", "setsigmask", "setsigdef", "scheduler", NULL}; - static _PyArg_Parser _parser = {"O&OO|$OOiOOO:posix_spawn", _keywords, 0}; + static const char * const _keywords[] = {"", "", "", "file_actions", "setpgroup", "resetids", "setsigmask", "setsigdef", "scheduler", "usevfork", NULL}; + static _PyArg_Parser _parser = {"O&OO|$OOiOOOi:posix_spawn", _keywords, 0}; path_t path = PATH_T_INITIALIZE("posix_spawn", "path", 0, 0); PyObject *argv; PyObject *env; @@ -1780,12 +1782,13 @@ os_posix_spawn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje PyObject *setsigmask = NULL; PyObject *setsigdef = NULL; PyObject *scheduler = NULL; + int usevfork = 0; if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - path_converter, &path, &argv, &env, &file_actions, &setpgroup, &resetids, &setsigmask, &setsigdef, &scheduler)) { + path_converter, &path, &argv, &env, &file_actions, &setpgroup, &resetids, &setsigmask, &setsigdef, &scheduler, &usevfork)) { goto exit; } - return_value = os_posix_spawn_impl(module, &path, argv, env, file_actions, setpgroup, resetids, setsigmask, setsigdef, scheduler); + return_value = os_posix_spawn_impl(module, &path, argv, env, file_actions, setpgroup, resetids, setsigmask, setsigdef, scheduler, usevfork); exit: /* Cleanup for path */ @@ -6648,4 +6651,4 @@ os_getrandom(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #ifndef OS_GETRANDOM_METHODDEF #define OS_GETRANDOM_METHODDEF #endif /* !defined(OS_GETRANDOM_METHODDEF) */ -/*[clinic end generated code: output=758ee0434fb03d90 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=adeb97aed906eb1b input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 7c02351a466130..7cddcea149eda4 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -5188,7 +5188,7 @@ 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, + PyObject *setsigdef, PyObject *scheduler, int usevfork, posix_spawnattr_t *attrp) { long all_flags = 0; @@ -5278,6 +5278,16 @@ parse_posix_spawn_flags(PyObject *setpgroup, int resetids, PyObject *setsigmask, #endif } + if (usevfork) { +#ifdef POSIX_SPAWN_USEVFORK + all_flags |= POSIX_SPAWN_SETSCHEDULER; +#else + PyErr_SetString(PyExc_NotImplementedError, + "The UseVFork option is not supported in this system."); + goto fail; +#endif + } + errno = posix_spawnattr_setflags(attrp, all_flags); if (errno) { posix_error(); @@ -5425,6 +5435,8 @@ os.posix_spawn The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag. scheduler: object = NULL A tuple with the scheduler policy (optional) and parameters. + usevfork: bool(accept={int}) = False + If the value is `True` the POSIX_SPAWN_USEVFORK will be activated. Execute the program specified by path in a new process. [clinic start generated code]*/ @@ -5433,8 +5445,8 @@ static PyObject * os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env, PyObject *file_actions, PyObject *setpgroup, int resetids, PyObject *setsigmask, - PyObject *setsigdef, PyObject *scheduler) -/*[clinic end generated code: output=45dfa4c515d09f2c input=2891c2f1d457e39b]*/ + PyObject *setsigdef, PyObject *scheduler, int usevfork) +/*[clinic end generated code: output=7e7b403caa228664 input=1fc98a9706886420]*/ { EXECV_CHAR **argvlist = NULL; EXECV_CHAR **envlist = NULL; @@ -5504,7 +5516,7 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, } if (parse_posix_spawn_flags(setpgroup, resetids, setsigmask, - setsigdef, scheduler, &attr)) { + setsigdef, scheduler, usevfork, &attr)) { goto exit; } attrp = &attr; From e72c246d9c06d509f2e9e8a586780126f335f4a5 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Thu, 13 Sep 2018 12:18:06 -0700 Subject: [PATCH 2/6] Rename parameter to and correct error --- Lib/test/test_posix.py | 4 ++-- Modules/clinic/posixmodule.c.h | 16 ++++++++-------- Modules/posixmodule.c | 14 +++++++------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 808281d0f750a6..08cfa85e4c1ca2 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -1790,13 +1790,13 @@ def test_dup2(self): with open(dupfile) as f: self.assertEqual(f.read(), 'hello') - def test_usevfork(self): + def test_vfork(self): try: pid = posix.posix_spawn( sys.executable, [sys.executable, '-c', 'pass'], os.environ, - usevfork=True + use_vfork=True ) except NotImplementedError: unittest.SkipTest("POSIX_SPAWN_USEVFORK not available on this system") diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index ca371c0fc0d917..f0af09269ed52a 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -1732,7 +1732,7 @@ os_execve(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k PyDoc_STRVAR(os_posix_spawn__doc__, "posix_spawn($module, path, argv, env, /, *, file_actions=(),\n" " setpgroup=None, resetids=False, setsigmask=(),\n" -" setsigdef=(), scheduler=None, usevfork=False)\n" +" setsigdef=(), scheduler=None, use_vfork=False)\n" "--\n" "\n" "Execute the program specified by path in a new process.\n" @@ -1755,7 +1755,7 @@ PyDoc_STRVAR(os_posix_spawn__doc__, " The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.\n" " scheduler\n" " A tuple with the scheduler policy (optional) and parameters.\n" -" usevfork\n" +" use_vfork\n" " If the value is `True` the POSIX_SPAWN_USEVFORK will be activated."); #define OS_POSIX_SPAWN_METHODDEF \ @@ -1765,13 +1765,13 @@ static PyObject * os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env, PyObject *file_actions, PyObject *setpgroup, int resetids, PyObject *setsigmask, - PyObject *setsigdef, PyObject *scheduler, int usevfork); + PyObject *setsigdef, PyObject *scheduler, int use_vfork); static PyObject * os_posix_spawn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"", "", "", "file_actions", "setpgroup", "resetids", "setsigmask", "setsigdef", "scheduler", "usevfork", NULL}; + static const char * const _keywords[] = {"", "", "", "file_actions", "setpgroup", "resetids", "setsigmask", "setsigdef", "scheduler", "use_vfork", NULL}; static _PyArg_Parser _parser = {"O&OO|$OOiOOOi:posix_spawn", _keywords, 0}; path_t path = PATH_T_INITIALIZE("posix_spawn", "path", 0, 0); PyObject *argv; @@ -1782,13 +1782,13 @@ os_posix_spawn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje PyObject *setsigmask = NULL; PyObject *setsigdef = NULL; PyObject *scheduler = NULL; - int usevfork = 0; + int use_vfork = 0; if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - path_converter, &path, &argv, &env, &file_actions, &setpgroup, &resetids, &setsigmask, &setsigdef, &scheduler, &usevfork)) { + path_converter, &path, &argv, &env, &file_actions, &setpgroup, &resetids, &setsigmask, &setsigdef, &scheduler, &use_vfork)) { goto exit; } - return_value = os_posix_spawn_impl(module, &path, argv, env, file_actions, setpgroup, resetids, setsigmask, setsigdef, scheduler, usevfork); + return_value = os_posix_spawn_impl(module, &path, argv, env, file_actions, setpgroup, resetids, setsigmask, setsigdef, scheduler, use_vfork); exit: /* Cleanup for path */ @@ -6651,4 +6651,4 @@ os_getrandom(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #ifndef OS_GETRANDOM_METHODDEF #define OS_GETRANDOM_METHODDEF #endif /* !defined(OS_GETRANDOM_METHODDEF) */ -/*[clinic end generated code: output=adeb97aed906eb1b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=74cf88c3208b5088 input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 7cddcea149eda4..8b555585a5f786 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -5188,7 +5188,7 @@ 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, int usevfork, + PyObject *setsigdef, PyObject *scheduler, int use_vfork, posix_spawnattr_t *attrp) { long all_flags = 0; @@ -5278,12 +5278,12 @@ parse_posix_spawn_flags(PyObject *setpgroup, int resetids, PyObject *setsigmask, #endif } - if (usevfork) { + if (use_vfork) { #ifdef POSIX_SPAWN_USEVFORK all_flags |= POSIX_SPAWN_SETSCHEDULER; #else PyErr_SetString(PyExc_NotImplementedError, - "The UseVFork option is not supported in this system."); + "The use_vfork option is not supported in this system."); goto fail; #endif } @@ -5435,7 +5435,7 @@ os.posix_spawn The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag. scheduler: object = NULL A tuple with the scheduler policy (optional) and parameters. - usevfork: bool(accept={int}) = False + use_vfork: bool(accept={int}) = False If the value is `True` the POSIX_SPAWN_USEVFORK will be activated. Execute the program specified by path in a new process. @@ -5445,8 +5445,8 @@ static PyObject * os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env, PyObject *file_actions, PyObject *setpgroup, int resetids, PyObject *setsigmask, - PyObject *setsigdef, PyObject *scheduler, int usevfork) -/*[clinic end generated code: output=7e7b403caa228664 input=1fc98a9706886420]*/ + PyObject *setsigdef, PyObject *scheduler, int use_vfork) +/*[clinic end generated code: output=ed9323af139a50f7 input=d033288962226596]*/ { EXECV_CHAR **argvlist = NULL; EXECV_CHAR **envlist = NULL; @@ -5516,7 +5516,7 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, } if (parse_posix_spawn_flags(setpgroup, resetids, setsigmask, - setsigdef, scheduler, usevfork, &attr)) { + setsigdef, scheduler, use_vfork, &attr)) { goto exit; } attrp = &attr; From 2fe9bf1b5ac19b6f91ea0bcfb75dff5085970a0c Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Thu, 13 Sep 2018 13:55:54 -0700 Subject: [PATCH 3/6] Add docs and improve implementation and naming --- Doc/library/os.rst | 6 +++++- Lib/test/test_posix.py | 5 +++-- Modules/clinic/posixmodule.c.h | 4 ++-- Modules/posixmodule.c | 7 +++---- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Doc/library/os.rst b/Doc/library/os.rst index bc8d5a8abbf31a..94677d48ab2e3f 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -3396,7 +3396,7 @@ written in Python, such as a mail server's external command delivery program. .. function:: posix_spawn(path, argv, env, *, file_actions=None, \ setpgroup=None, resetids=False, setsigmask=(), \ - setsigdef=(), scheduler=None) + setsigdef=(), scheduler=None, use_vfork=False) Wraps the :c:func:`posix_spawn` C library API for use from Python. @@ -3465,6 +3465,10 @@ written in Python, such as a mail server's external command delivery program. :c:data:`POSIX_SPAWN_SETSCHEDPARAM` and :c:data:`POSIX_SPAWN_SETSCHEDULER` flags. + If the value of *use_vfork* is true, the child will be created using + :c:func:`vfork` instead of :c:func:`fork`. This corresponds to the + GNU specific flag :c:data:`POSIX_SPAWN_USEVFORK`. + .. versionadded:: 3.7 diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 08cfa85e4c1ca2..e5048d5fc4d298 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -1791,10 +1791,11 @@ def test_dup2(self): self.assertEqual(f.read(), 'hello') def test_vfork(self): + args = self.python_args() try: pid = posix.posix_spawn( - sys.executable, - [sys.executable, '-c', 'pass'], + args[0], + args, os.environ, use_vfork=True ) diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index f0af09269ed52a..e35ef159632a51 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -1756,7 +1756,7 @@ PyDoc_STRVAR(os_posix_spawn__doc__, " scheduler\n" " A tuple with the scheduler policy (optional) and parameters.\n" " use_vfork\n" -" If the value is `True` the POSIX_SPAWN_USEVFORK will be activated."); +" If the value is true the POSIX_SPAWN_USEVFORK will be activated."); #define OS_POSIX_SPAWN_METHODDEF \ {"posix_spawn", (PyCFunction)os_posix_spawn, METH_FASTCALL|METH_KEYWORDS, os_posix_spawn__doc__}, @@ -6651,4 +6651,4 @@ os_getrandom(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #ifndef OS_GETRANDOM_METHODDEF #define OS_GETRANDOM_METHODDEF #endif /* !defined(OS_GETRANDOM_METHODDEF) */ -/*[clinic end generated code: output=74cf88c3208b5088 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d4d3d9754ff072e7 input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 8b555585a5f786..8820f516bced13 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -5282,8 +5282,7 @@ parse_posix_spawn_flags(PyObject *setpgroup, int resetids, PyObject *setsigmask, #ifdef POSIX_SPAWN_USEVFORK all_flags |= POSIX_SPAWN_SETSCHEDULER; #else - PyErr_SetString(PyExc_NotImplementedError, - "The use_vfork option is not supported in this system."); + argument_unavailable_error("posix_spawn", "use_vfork"); goto fail; #endif } @@ -5436,7 +5435,7 @@ os.posix_spawn scheduler: object = NULL A tuple with the scheduler policy (optional) and parameters. use_vfork: bool(accept={int}) = False - If the value is `True` the POSIX_SPAWN_USEVFORK will be activated. + If the value is true the POSIX_SPAWN_USEVFORK will be activated. Execute the program specified by path in a new process. [clinic start generated code]*/ @@ -5446,7 +5445,7 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env, PyObject *file_actions, PyObject *setpgroup, int resetids, PyObject *setsigmask, PyObject *setsigdef, PyObject *scheduler, int use_vfork) -/*[clinic end generated code: output=ed9323af139a50f7 input=d033288962226596]*/ +/*[clinic end generated code: output=ed9323af139a50f7 input=9ca9c905ec19bf04]*/ { EXECV_CHAR **argvlist = NULL; EXECV_CHAR **envlist = NULL; From 70db5e975cbebbd783d01bd56bfc3ec01d6de786 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Thu, 13 Sep 2018 14:32:39 -0700 Subject: [PATCH 4/6] Improve documentation and error messages --- Doc/library/os.rst | 5 ++++- Lib/test/test_posix.py | 6 +++--- .../2018-09-13-11-14-38.bpo-34663.BtJz-5.rst | 5 +++-- Modules/posixmodule.c | 3 ++- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 94677d48ab2e3f..d94e10fca0099c 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -3467,7 +3467,10 @@ written in Python, such as a mail server's external command delivery program. If the value of *use_vfork* is true, the child will be created using :c:func:`vfork` instead of :c:func:`fork`. This corresponds to the - GNU specific flag :c:data:`POSIX_SPAWN_USEVFORK`. + GNU specific flag :c:data:`POSIX_SPAWN_USEVFORK`. If the flag is not + available on the platform, :exc:`NotImplementedError` will be raised. + + Availability: Using *use_vfork* is only available on Linux. .. versionadded:: 3.7 diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index e5048d5fc4d298..4defcd74ff31c7 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -1791,7 +1791,7 @@ def test_dup2(self): self.assertEqual(f.read(), 'hello') def test_vfork(self): - args = self.python_args() + args = self.python_args('-c', 'pass') try: pid = posix.posix_spawn( args[0], @@ -1799,8 +1799,8 @@ def test_vfork(self): os.environ, use_vfork=True ) - except NotImplementedError: - unittest.SkipTest("POSIX_SPAWN_USEVFORK not available on this system") + except NotImplementedError as e: + raise unittest.SkipTest(e) else: self.assertEqual(os.waitpid(pid, 0), (pid, 0)) diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-09-13-11-14-38.bpo-34663.BtJz-5.rst b/Misc/NEWS.d/next/Core and Builtins/2018-09-13-11-14-38.bpo-34663.BtJz-5.rst index 48dd639d27166c..b6ba2b45c56327 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2018-09-13-11-14-38.bpo-34663.BtJz-5.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2018-09-13-11-14-38.bpo-34663.BtJz-5.rst @@ -1,2 +1,3 @@ -Added support for `usevfork` parameters of `posix_spawn`, which allows to -use ``POSIX_SPAWN_USEVFORK`` when the flag is available in the system. +Added support for `use_vfork` parameters of :func:`os.posix_spawn`, which +allows to use ``POSIX_SPAWN_USEVFORK`` when the flag is available in the +system. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 8820f516bced13..587279cbe23937 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -5282,7 +5282,8 @@ parse_posix_spawn_flags(PyObject *setpgroup, int resetids, PyObject *setsigmask, #ifdef POSIX_SPAWN_USEVFORK all_flags |= POSIX_SPAWN_SETSCHEDULER; #else - argument_unavailable_error("posix_spawn", "use_vfork"); + PyErr_SetString(PyExc_NotImplementedError, + "The POSIX_SPAWN_USEVFORK flag is unavailable on this platform"); goto fail; #endif } From 6f03dc597bf4a9e8061741ce02037b65c7010952 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Fri, 14 Sep 2018 14:20:47 -0700 Subject: [PATCH 5/6] Add availability and clean tests --- Doc/library/os.rst | 2 +- Lib/test/test_posix.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/os.rst b/Doc/library/os.rst index d94e10fca0099c..7d552557e412ca 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -3470,7 +3470,7 @@ written in Python, such as a mail server's external command delivery program. GNU specific flag :c:data:`POSIX_SPAWN_USEVFORK`. If the flag is not available on the platform, :exc:`NotImplementedError` will be raised. - Availability: Using *use_vfork* is only available on Linux. + Availability: Unix. Using *use_vfork* is only available on Linux. .. versionadded:: 3.7 diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 4defcd74ff31c7..bea2d5884594fe 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -1799,8 +1799,8 @@ def test_vfork(self): os.environ, use_vfork=True ) - except NotImplementedError as e: - raise unittest.SkipTest(e) + except NotImplementedError as exc: + raise self.skipTest(str(exc)) else: self.assertEqual(os.waitpid(pid, 0), (pid, 0)) From c8b46c6d71665edbc5be012706804175dbe2dbd8 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Fri, 14 Sep 2018 14:39:46 -0700 Subject: [PATCH 6/6] fixup! Add availability and clean tests --- Doc/library/os.rst | 32 +++++++++---------- Lib/test/test_posix.py | 2 +- .../2018-09-13-11-14-38.bpo-34663.BtJz-5.rst | 6 ++-- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 7d552557e412ca..46d42d394016c8 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -3435,22 +3435,22 @@ written in Python, such as a mail server's external command delivery program. :c:func:`posix_spawn_file_actions_adddup2` API calls used to prepare for the :c:func:`posix_spawn` call itself. - The *setpgroup* argument will set the process group of the child to the value - specified. If the value specified is 0, the child's process group ID will be - made the same as its process ID. If the value of *setpgroup* is not set, the - child will inherit the parent's process group ID. This argument corresponds - to the C library :c:data:`POSIX_SPAWN_SETPGROUP` flag. + The *setpgroup* argument will set the process group of the child process to + the value specified. If the value specified is 0, the child's process group + ID will be made the same as its process ID. If the value of *setpgroup* is + not set, the child process will inherit the parent's process group ID. This + argument corresponds to the C library :c:data:`POSIX_SPAWN_SETPGROUP` flag. If the *resetids* argument is ``True`` it will reset the effective UID and - GID of the child to the real UID and GID of the parent process. If the - argument is ``False``, then the child retains the effective UID and GID of - the parent. In either case, if the set-user-ID and set-group-ID permission - bits are enabled on the executable file, their effect will override the - setting of the effective UID and GID. This argument corresponds to the C - library :c:data:`POSIX_SPAWN_RESETIDS` flag. + GID of the child process to the real UID and GID of the parent process. If + the argument is ``False``, then the child process retains the effective UID + and GID of the parent. In either case, if the set-user-ID and set-group-ID + permission bits are enabled on the executable file, their effect will + override the setting of the effective UID and GID. This argument corresponds + to the C library :c:data:`POSIX_SPAWN_RESETIDS` flag. The *setsigmask* argument will set the signal mask to the signal set - specified. If the parameter is not used, then the child inherits the + specified. If the parameter is not used, then the child process inherits the parent's signal mask. This argument corresponds to the C library :c:data:`POSIX_SPAWN_SETSIGMASK` flag. @@ -3465,10 +3465,10 @@ written in Python, such as a mail server's external command delivery program. :c:data:`POSIX_SPAWN_SETSCHEDPARAM` and :c:data:`POSIX_SPAWN_SETSCHEDULER` flags. - If the value of *use_vfork* is true, the child will be created using - :c:func:`vfork` instead of :c:func:`fork`. This corresponds to the - GNU specific flag :c:data:`POSIX_SPAWN_USEVFORK`. If the flag is not - available on the platform, :exc:`NotImplementedError` will be raised. + If the value of *use_vfork* is true, the child process will be created using + :c:func:`vfork` instead of :c:func:`fork`. This corresponds to the GNU + specific flag :c:data:`POSIX_SPAWN_USEVFORK`. If the flag is not available on + the platform, :exc:`NotImplementedError` will be raised. Availability: Unix. Using *use_vfork* is only available on Linux. diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index bea2d5884594fe..6e9c2b7667a13c 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -1790,7 +1790,7 @@ def test_dup2(self): with open(dupfile) as f: self.assertEqual(f.read(), 'hello') - def test_vfork(self): + def test_use_vfork(self): args = self.python_args('-c', 'pass') try: pid = posix.posix_spawn( diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-09-13-11-14-38.bpo-34663.BtJz-5.rst b/Misc/NEWS.d/next/Core and Builtins/2018-09-13-11-14-38.bpo-34663.BtJz-5.rst index b6ba2b45c56327..d5ccb0b881c208 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2018-09-13-11-14-38.bpo-34663.BtJz-5.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2018-09-13-11-14-38.bpo-34663.BtJz-5.rst @@ -1,3 +1,3 @@ -Added support for `use_vfork` parameters of :func:`os.posix_spawn`, which -allows to use ``POSIX_SPAWN_USEVFORK`` when the flag is available in the -system. +Added support for `use_vfork` parameter of :func:`os.posix_spawn`, which +allows to use ``POSIX_SPAWN_USEVFORK`` constant when the flag is available +in the system.