Commit 92b8322e authored by Joannah Nanjekye's avatar Joannah Nanjekye Committed by Victor Stinner

bpo-35674: Add os.posix_spawnp() (GH-11554)

Add a new os.posix_spawnp() function.
parent 9daecf37
...@@ -3396,6 +3396,10 @@ written in Python, such as a mail server's external command delivery program. ...@@ -3396,6 +3396,10 @@ written in Python, such as a mail server's external command delivery program.
The positional-only arguments *path*, *args*, and *env* are similar to The positional-only arguments *path*, *args*, and *env* are similar to
:func:`execve`. :func:`execve`.
The *path* parameter is the path to the executable file.The *path* should
contain a directory.Use :func:`posix_spawnp` to pass an executable file
without directory.
The *file_actions* argument may be a sequence of tuples describing actions The *file_actions* argument may be a sequence of tuples describing actions
to take on specific file descriptors in the child process between the C to take on specific file descriptors in the child process between the C
library implementation's :c:func:`fork` and :c:func:`exec` steps. library implementation's :c:func:`fork` and :c:func:`exec` steps.
...@@ -3459,6 +3463,19 @@ written in Python, such as a mail server's external command delivery program. ...@@ -3459,6 +3463,19 @@ written in Python, such as a mail server's external command delivery program.
.. versionadded:: 3.7 .. versionadded:: 3.7
.. function:: posix_spawnp(path, argv, env, *, file_actions=None, \
setpgroup=None, resetids=False, setsigmask=(), \
setsigdef=(), scheduler=None)
Wraps the :c:func:`posix_spawnp` C library API for use from Python.
Similar to :func:`posix_spawn` except that the system searches
for the *executable* file in the list of directories specified by the
:envvar:`PATH` environment variable (in the same way as for ``execvp(3)``).
.. versionadded:: 3.8
.. function:: register_at_fork(*, before=None, after_in_parent=None, \ .. function:: register_at_fork(*, before=None, after_in_parent=None, \
after_in_child=None) after_in_child=None)
......
This diff is collapsed.
Add a new :func:`os.posix_spawnp` function.
Patch by Joannah Nanjekye.
\ No newline at end of file
...@@ -1791,6 +1791,75 @@ exit: ...@@ -1791,6 +1791,75 @@ exit:
#endif /* defined(HAVE_POSIX_SPAWN) */ #endif /* defined(HAVE_POSIX_SPAWN) */
#if defined(HAVE_POSIX_SPAWNP)
PyDoc_STRVAR(os_posix_spawnp__doc__,
"posix_spawnp($module, path, argv, env, /, *, file_actions=(),\n"
" setpgroup=None, resetids=False, setsigmask=(),\n"
" setsigdef=(), scheduler=None)\n"
"--\n"
"\n"
"Execute the program specified by path in a new process.\n"
"\n"
" path\n"
" Path of executable file.\n"
" argv\n"
" Tuple or list of strings.\n"
" env\n"
" Dictionary of strings mapping to strings.\n"
" file_actions\n"
" A sequence of file action tuples.\n"
" setpgroup\n"
" The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.\n"
" resetids\n"
" If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.\n"
" setsigmask\n"
" The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.\n"
" setsigdef\n"
" The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.\n"
" scheduler\n"
" A tuple with the scheduler policy (optional) and parameters.");
#define OS_POSIX_SPAWNP_METHODDEF \
{"posix_spawnp", (PyCFunction)(void(*)(void))os_posix_spawnp, METH_FASTCALL|METH_KEYWORDS, os_posix_spawnp__doc__},
static PyObject *
os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
PyObject *env, PyObject *file_actions,
PyObject *setpgroup, int resetids, PyObject *setsigmask,
PyObject *setsigdef, PyObject *scheduler);
static PyObject *
os_posix_spawnp(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_spawnp", _keywords, 0};
path_t path = PATH_T_INITIALIZE("posix_spawnp", "path", 0, 0);
PyObject *argv;
PyObject *env;
PyObject *file_actions = NULL;
PyObject *setpgroup = NULL;
int resetids = 0;
PyObject *setsigmask = NULL;
PyObject *setsigdef = NULL;
PyObject *scheduler = NULL;
if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
path_converter, &path, &argv, &env, &file_actions, &setpgroup, &resetids, &setsigmask, &setsigdef, &scheduler)) {
goto exit;
}
return_value = os_posix_spawnp_impl(module, &path, argv, env, file_actions, setpgroup, resetids, setsigmask, setsigdef, scheduler);
exit:
/* Cleanup for path */
path_cleanup(&path);
return return_value;
}
#endif /* defined(HAVE_POSIX_SPAWNP) */
#if (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)) #if (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV))
PyDoc_STRVAR(os_spawnv__doc__, PyDoc_STRVAR(os_spawnv__doc__,
...@@ -6851,6 +6920,10 @@ exit: ...@@ -6851,6 +6920,10 @@ exit:
#define OS_POSIX_SPAWN_METHODDEF #define OS_POSIX_SPAWN_METHODDEF
#endif /* !defined(OS_POSIX_SPAWN_METHODDEF) */ #endif /* !defined(OS_POSIX_SPAWN_METHODDEF) */
#ifndef OS_POSIX_SPAWNP_METHODDEF
#define OS_POSIX_SPAWNP_METHODDEF
#endif /* !defined(OS_POSIX_SPAWNP_METHODDEF) */
#ifndef OS_SPAWNV_METHODDEF #ifndef OS_SPAWNV_METHODDEF
#define OS_SPAWNV_METHODDEF #define OS_SPAWNV_METHODDEF
#endif /* !defined(OS_SPAWNV_METHODDEF) */ #endif /* !defined(OS_SPAWNV_METHODDEF) */
...@@ -7258,4 +7331,4 @@ exit: ...@@ -7258,4 +7331,4 @@ exit:
#ifndef OS_GETRANDOM_METHODDEF #ifndef OS_GETRANDOM_METHODDEF
#define OS_GETRANDOM_METHODDEF #define OS_GETRANDOM_METHODDEF
#endif /* !defined(OS_GETRANDOM_METHODDEF) */ #endif /* !defined(OS_GETRANDOM_METHODDEF) */
/*[clinic end generated code: output=febc1e16c9024e40 input=a9049054013a1b77]*/ /*[clinic end generated code: output=dabd0fa27bf87044 input=a9049054013a1b77]*/
...@@ -5381,39 +5381,12 @@ fail: ...@@ -5381,39 +5381,12 @@ fail:
return -1; return -1;
} }
/*[clinic input]
os.posix_spawn
path: path_t
Path of executable file.
argv: object
Tuple or list of strings.
env: object
Dictionary of strings mapping to strings.
/
*
file_actions: object(c_default='NULL') = ()
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 * static PyObject *
os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv,
PyObject *env, PyObject *file_actions, PyObject *env, PyObject *file_actions,
PyObject *setpgroup, int resetids, PyObject *setsigmask, PyObject *setpgroup, int resetids, PyObject *setsigmask,
PyObject *setsigdef, PyObject *scheduler) PyObject *setsigdef, PyObject *scheduler)
/*[clinic end generated code: output=45dfa4c515d09f2c input=2891c2f1d457e39b]*/
{ {
EXECV_CHAR **argvlist = NULL; EXECV_CHAR **argvlist = NULL;
EXECV_CHAR **envlist = NULL; EXECV_CHAR **envlist = NULL;
...@@ -5489,9 +5462,19 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, ...@@ -5489,9 +5462,19 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
attrp = &attr; attrp = &attr;
_Py_BEGIN_SUPPRESS_IPH _Py_BEGIN_SUPPRESS_IPH
err_code = posix_spawn(&pid, path->narrow, #ifdef HAVE_POSIX_SPAWNP
file_actionsp, attrp, argvlist, envlist); if (use_posix_spawnp) {
err_code = posix_spawnp(&pid, path->narrow,
file_actionsp, attrp, argvlist, envlist);
}
else
#endif /* HAVE_POSIX_SPAWNP */
{
err_code = posix_spawn(&pid, path->narrow,
file_actionsp, attrp, argvlist, envlist);
}
_Py_END_SUPPRESS_IPH _Py_END_SUPPRESS_IPH
if (err_code) { if (err_code) {
errno = err_code; errno = err_code;
PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object); PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
...@@ -5518,7 +5501,90 @@ exit: ...@@ -5518,7 +5501,90 @@ exit:
Py_XDECREF(temp_buffer); Py_XDECREF(temp_buffer);
return result; return result;
} }
#endif /* HAVE_POSIX_SPAWN */
/*[clinic input]
os.posix_spawn
path: path_t
Path of executable file.
argv: object
Tuple or list of strings.
env: object
Dictionary of strings mapping to strings.
/
*
file_actions: object(c_default='NULL') = ()
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,
PyObject *setpgroup, int resetids, PyObject *setsigmask,
PyObject *setsigdef, PyObject *scheduler)
/*[clinic end generated code: output=45dfa4c515d09f2c input=2891c2f1d457e39b]*/
{
return py_posix_spawn(0, module, path, argv, env, file_actions,
setpgroup, resetids, setsigmask, setsigdef,
scheduler);
}
#endif /* HAVE_POSIX_SPAWN */
#ifdef HAVE_POSIX_SPAWNP
/*[clinic input]
os.posix_spawnp
path: path_t
Path of executable file.
argv: object
Tuple or list of strings.
env: object
Dictionary of strings mapping to strings.
/
*
file_actions: object(c_default='NULL') = ()
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_spawnp_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=7955dc0edc82b8c3 input=b7576eb25b1ed9eb]*/
{
return py_posix_spawn(1, module, path, argv, env, file_actions,
setpgroup, resetids, setsigmask, setsigdef,
scheduler);
}
#endif /* HAVE_POSIX_SPAWNP */
#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) #if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
...@@ -13084,6 +13150,7 @@ static PyMethodDef posix_methods[] = { ...@@ -13084,6 +13150,7 @@ static PyMethodDef posix_methods[] = {
OS_GETPRIORITY_METHODDEF OS_GETPRIORITY_METHODDEF
OS_SETPRIORITY_METHODDEF OS_SETPRIORITY_METHODDEF
OS_POSIX_SPAWN_METHODDEF OS_POSIX_SPAWN_METHODDEF
OS_POSIX_SPAWNP_METHODDEF
OS_READLINK_METHODDEF OS_READLINK_METHODDEF
OS_RENAME_METHODDEF OS_RENAME_METHODDEF
OS_REPLACE_METHODDEF OS_REPLACE_METHODDEF
......
# generated automatically by aclocal 1.15.1 -*- Autoconf -*- # generated automatically by aclocal 1.15 -*- Autoconf -*-
# Copyright (C) 1996-2017 Free Software Foundation, Inc. # Copyright (C) 1996-2014 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
dnl serial 11 (pkg-config-0.29) dnl serial 11 (pkg-config-0.29.1)
dnl dnl
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>. dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com> dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
...@@ -55,7 +55,7 @@ dnl ...@@ -55,7 +55,7 @@ dnl
dnl See the "Since" comment for each macro you use to see what version dnl See the "Since" comment for each macro you use to see what version
dnl of the macros you require. dnl of the macros you require.
m4_defun([PKG_PREREQ], m4_defun([PKG_PREREQ],
[m4_define([PKG_MACROS_VERSION], [0.29]) [m4_define([PKG_MACROS_VERSION], [0.29.1])
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
])dnl PKG_PREREQ ])dnl PKG_PREREQ
......
...@@ -11447,7 +11447,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ ...@@ -11447,7 +11447,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \ initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \ memrchr mbrtowc mkdirat mkfifo \
mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \ mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
posix_fallocate posix_fadvise posix_spawn pread preadv preadv2 \ posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_init pthread_kill putenv pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \ pthread_init pthread_kill putenv pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \ sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \
setgid sethostname \ setgid sethostname \
......
...@@ -3505,7 +3505,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ ...@@ -3505,7 +3505,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \ initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \ memrchr mbrtowc mkdirat mkfifo \
mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \ mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
posix_fallocate posix_fadvise posix_spawn pread preadv preadv2 \ posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_init pthread_kill putenv pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \ pthread_init pthread_kill putenv pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \ sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \
setgid sethostname \ setgid sethostname \
......
...@@ -732,6 +732,9 @@ ...@@ -732,6 +732,9 @@
/* Define to 1 if you have the `posix_spawn' function. */ /* Define to 1 if you have the `posix_spawn' function. */
#undef HAVE_POSIX_SPAWN #undef HAVE_POSIX_SPAWN
/* Define to 1 if you have the `posix_spawnp' function. */
#undef HAVE_POSIX_SPAWNP
/* Define to 1 if you have the `pread' function. */ /* Define to 1 if you have the `pread' function. */
#undef HAVE_PREAD #undef HAVE_PREAD
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment