diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index b76bb2c7778..50ab645fc74 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -68,6 +68,7 @@ extern void _PyFloat_Fini(void); extern void _PySlice_Fini(void); extern void _PyAsyncGen_Fini(void); +extern int _PySignal_Init(int install_signal_handlers); extern void PyOS_FiniInterrupts(void); extern void _PyExc_Fini(void); diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-11-17-16-25-50.bpo-41686.hX77kL.rst b/Misc/NEWS.d/next/Core and Builtins/2020-11-17-16-25-50.bpo-41686.hX77kL.rst new file mode 100644 index 00000000000..0265d48660a --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-11-17-16-25-50.bpo-41686.hX77kL.rst @@ -0,0 +1,4 @@ +On Windows, the ``SIGINT`` event, ``_PyOS_SigintEvent()``, is now created +even if Python is configured to not install signal handlers (if +:c:member:`PyConfig.install_signal_handlers` equals to 0, or +``Py_InitializeEx(0)``). diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 9041848cadf..540e2d90448 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -1632,11 +1632,6 @@ PyInit__signal(void) goto finally; #endif -#ifdef MS_WINDOWS - /* Create manual-reset event, initially unset */ - sigint_event = CreateEvent(NULL, TRUE, FALSE, FALSE); -#endif - if (PyErr_Occurred()) { Py_DECREF(m); m = NULL; @@ -1773,6 +1768,53 @@ PyOS_InitInterrupts(void) } } + +static int +signal_install_handlers(void) +{ +#ifdef SIGPIPE + PyOS_setsig(SIGPIPE, SIG_IGN); +#endif +#ifdef SIGXFZ + PyOS_setsig(SIGXFZ, SIG_IGN); +#endif +#ifdef SIGXFSZ + PyOS_setsig(SIGXFSZ, SIG_IGN); +#endif + + // Import _signal to install the Python SIGINT handler + PyObject *module = PyImport_ImportModule("_signal"); + if (!module) { + return -1; + } + Py_DECREF(module); + + return 0; +} + + +int +_PySignal_Init(int install_signal_handlers) +{ +#ifdef MS_WINDOWS + /* Create manual-reset event, initially unset */ + sigint_event = CreateEvent(NULL, TRUE, FALSE, FALSE); + if (sigint_event == NULL) { + PyErr_SetFromWindowsErr(0); + return -1; + } +#endif + + if (install_signal_handlers) { + if (signal_install_handlers() < 0) { + return -1; + } + } + + return 0; +} + + void PyOS_FiniInterrupts(void) { diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index cfb3a7d9417..5c50d4d290f 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -57,7 +57,6 @@ static PyStatus add_main_module(PyInterpreterState *interp); static PyStatus init_import_site(void); static PyStatus init_set_builtins_open(void); static PyStatus init_sys_streams(PyThreadState *tstate); -static PyStatus init_signals(PyThreadState *tstate); static void call_py_exitfuncs(PyThreadState *tstate); static void wait_for_thread_shutdown(PyThreadState *tstate); static void call_ll_exitfuncs(_PyRuntimeState *runtime); @@ -1013,11 +1012,8 @@ init_interp_main(PyThreadState *tstate) } if (is_main_interp) { - if (config->install_signal_handlers) { - status = init_signals(tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } + if (_PySignal_Init(config->install_signal_handlers) < 0) { + return _PyStatus_ERR("can't initialize signals"); } if (_PyTraceMalloc_Init(config->tracemalloc) < 0) { @@ -2442,25 +2438,6 @@ Py_Exit(int sts) exit(sts); } -static PyStatus -init_signals(PyThreadState *tstate) -{ -#ifdef SIGPIPE - PyOS_setsig(SIGPIPE, SIG_IGN); -#endif -#ifdef SIGXFZ - PyOS_setsig(SIGXFZ, SIG_IGN); -#endif -#ifdef SIGXFSZ - PyOS_setsig(SIGXFSZ, SIG_IGN); -#endif - PyOS_InitInterrupts(); /* May imply init_signals() */ - if (_PyErr_Occurred(tstate)) { - return _PyStatus_ERR("can't import signal"); - } - return _PyStatus_OK(); -} - /* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. *