]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-41686: Always create the SIGINT event on Windows (GH-23344) (GH-23347)
authorVictor Stinner <vstinner@python.org>
Tue, 17 Nov 2020 17:58:12 +0000 (18:58 +0100)
committerGitHub <noreply@github.com>
Tue, 17 Nov 2020 17:58:12 +0000 (18:58 +0100)
bpo-41686, bpo-41713: On Windows, the SIGINT event,
_PyOS_SigintEvent(), is now created even if Python is configured to
not install signal handlers (PyConfig.install_signal_handlers=0 or
Py_InitializeEx(0)).

Include/internal/pycore_pylifecycle.h
Misc/NEWS.d/next/Core and Builtins/2020-11-17-16-25-50.bpo-41686.hX77kL.rst [new file with mode: 0644]
Modules/signalmodule.c
Python/pylifecycle.c

index b76bb2c7778aec139f200c7a94b7ffcf7f285a70..50ab645fc7485973e41201d764de3653227ae50d 100644 (file)
@@ -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 (file)
index 0000000..0265d48
--- /dev/null
@@ -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)``).
index 9041848cadf07da05cb6b5b56919b8cff3ee1b2c..540e2d90448044c992065ca7a6e46626db0a7136 100644 (file)
@@ -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)
 {
index cfb3a7d941710f9fa9f0bf6c5371e0278b793aff..5c50d4d290f4dbf3fb2beaaae73385a3c259d1e2 100644 (file)
@@ -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.
  *