]> granicus.if.org Git - python/commitdiff
[3.6] bpo-30185: avoid KeyboardInterrupt tracebacks in forkserver (GH-1319) (#1454)
authorAntoine Pitrou <pitrou@free.fr>
Thu, 4 May 2017 15:12:35 +0000 (17:12 +0200)
committerGitHub <noreply@github.com>
Thu, 4 May 2017 15:12:35 +0000 (17:12 +0200)
* bpo-30185: avoid KeyboardInterrupt tracebacks in forkserver

* Tweak comment.
(cherry picked from commit 6dd4d734ed207ba16b017e38f8909de7ef187e29)

Lib/multiprocessing/forkserver.py
Misc/NEWS

index f2c179e4e0afaa68ffacc5e4e621f0fbc1b8a1ae..d5ce6257456766123080f16379eb21e249a82ff6 100644 (file)
@@ -149,8 +149,15 @@ def main(listener_fd, alive_r, preload, main_path=None, sys_path=None):
 
     util._close_stdin()
 
-    # ignoring SIGCHLD means no need to reap zombie processes
-    handler = signal.signal(signal.SIGCHLD, signal.SIG_IGN)
+    # ignoring SIGCHLD means no need to reap zombie processes;
+    # letting SIGINT through avoids KeyboardInterrupt tracebacks
+    handlers = {
+        signal.SIGCHLD: signal.SIG_IGN,
+        signal.SIGINT: signal.SIG_DFL,
+        }
+    old_handlers = {sig: signal.signal(sig, val)
+                    for (sig, val) in handlers.items()}
+
     with socket.socket(socket.AF_UNIX, fileno=listener_fd) as listener, \
          selectors.DefaultSelector() as selector:
         _forkserver._forkserver_address = listener.getsockname()
@@ -175,7 +182,7 @@ def main(listener_fd, alive_r, preload, main_path=None, sys_path=None):
                     code = 1
                     if os.fork() == 0:
                         try:
-                            _serve_one(s, listener, alive_r, handler)
+                            _serve_one(s, listener, alive_r, old_handlers)
                         except Exception:
                             sys.excepthook(*sys.exc_info())
                             sys.stderr.flush()
@@ -186,11 +193,12 @@ def main(listener_fd, alive_r, preload, main_path=None, sys_path=None):
                 if e.errno != errno.ECONNABORTED:
                     raise
 
-def _serve_one(s, listener, alive_r, handler):
-    # close unnecessary stuff and reset SIGCHLD handler
+def _serve_one(s, listener, alive_r, handlers):
+    # close unnecessary stuff and reset signal handlers
     listener.close()
     os.close(alive_r)
-    signal.signal(signal.SIGCHLD, handler)
+    for sig, val in handlers.items():
+        signal.signal(sig, val)
 
     # receive fds from parent process
     fds = reduction.recvfds(s, MAXFDS_TO_SEND + 1)
index 1c9026e77f2e765f0e29f2c534a419e20e266869..f0d5a3ba2073c8683acb1ff44301d809996bb0d1 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -36,6 +36,9 @@ Core and Builtins
 Library
 -------
 
+- bpo-30185: Avoid KeyboardInterrupt tracebacks in forkserver helper process
+  when Ctrl-C is received.
+
 - bpo-28556: Various updates to typing module: add typing.NoReturn type, use
   WrapperDescriptorType, minor bug-fixes.  Original PRs by
   Jim Fasarakis-Hilliard and Ivan Levkivskyi.