diff options
Diffstat (limited to 'Modules/_posixsubprocess.c')
-rw-r--r-- | Modules/_posixsubprocess.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index 18a81c6..b852ad7 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -936,8 +936,31 @@ subprocess_fork_exec(PyObject *module, PyObject *args) #ifdef VFORK_USABLE /* Use vfork() only if it's safe. See the comment above child_exec(). */ sigset_t old_sigs; - if (preexec_fn == Py_None && - !call_setuid && !call_setgid && !call_setgroups) { + int allow_vfork; + if (preexec_fn == Py_None) { + allow_vfork = 1; /* 3.10.0 behavior */ + PyObject *subprocess_module = PyImport_ImportModule("subprocess"); + if (subprocess_module != NULL) { + PyObject *allow_vfork_obj = PyObject_GetAttrString( + subprocess_module, "_USE_VFORK"); + Py_DECREF(subprocess_module); + if (allow_vfork_obj != NULL) { + allow_vfork = PyObject_IsTrue(allow_vfork_obj); + Py_DECREF(allow_vfork_obj); + if (allow_vfork < 0) { + PyErr_Clear(); /* Bad _USE_VFORK attribute. */ + allow_vfork = 1; /* 3.10.0 behavior */ + } + } else { + PyErr_Clear(); /* No _USE_VFORK attribute. */ + } + } else { + PyErr_Clear(); /* no subprocess module? suspicious; don't care. */ + } + } else { + allow_vfork = 0; + } + if (allow_vfork && !call_setuid && !call_setgid && !call_setgroups) { /* Block all signals to ensure that no signal handlers are run in the * child process while it shares memory with us. Note that signals * used internally by C libraries won't be blocked by |