Patchwork dispatch: catch KeyboardInterrupt more broadly

login
register
mail settings
Submitter Yuya Nishihara
Date March 12, 2016, 3:35 p.m.
Message ID <f63115ce65dfae3da44c.1457796943@mimosa>
Download mbox | patch
Permalink /patch/13825/
State Accepted
Commit 84cc72c5771ecc26104d1207e775d2f50cbc2d6f
Headers show

Comments

Yuya Nishihara - March 12, 2016, 3:35 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1451191126 -32400
#      Sun Dec 27 13:38:46 2015 +0900
# Node ID f63115ce65dfae3da44c1a008dfb02f72d194e0c
# Parent  ac410dea1b240854b5f0c99dddde66c5b19f6d36
dispatch: catch KeyboardInterrupt more broadly

Because _runcatch() can run long operation in its exception handler, it wasn't
enough to catch KeyboardInterrupt at the same level. For example, "hg unknown"
will load all extension modules, so we could easily make it crashed by Ctrl-C.
Sean Farley - March 12, 2016, 8:30 p.m.
Yuya Nishihara <yuya@tcha.org> writes:

> # HG changeset patch
> # User Yuya Nishihara <yuya@tcha.org>
> # Date 1451191126 -32400
> #      Sun Dec 27 13:38:46 2015 +0900
> # Node ID f63115ce65dfae3da44c1a008dfb02f72d194e0c
> # Parent  ac410dea1b240854b5f0c99dddde66c5b19f6d36
> dispatch: catch KeyboardInterrupt more broadly
>
> Because _runcatch() can run long operation in its exception handler, it wasn't
> enough to catch KeyboardInterrupt at the same level. For example, "hg unknown"
> will load all extension modules, so we could easily make it crashed by Ctrl-C.

Looks good to me.

Patch

diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -120,11 +120,18 @@  def dispatch(req):
     ret = None
     try:
         ret = _runcatch(req)
-        return ret
+    except KeyboardInterrupt:
+        try:
+            req.ui.warn(_("interrupted!\n"))
+        except IOError as inst:
+            if inst.errno != errno.EPIPE:
+                raise
+        ret = -1
     finally:
         duration = time.time() - starttime
         req.ui.log("commandfinish", "%s exited %s after %0.2f seconds\n",
                    msg, ret or 0, duration)
+    return ret
 
 def _runcatch(req):
     def catchterm(*args):
@@ -315,11 +322,7 @@  def _runcatch(req):
         else:
             ui.warn(_("abort: %s\n") % inst.strerror)
     except KeyboardInterrupt:
-        try:
-            ui.warn(_("interrupted!\n"))
-        except IOError as inst:
-            if inst.errno != errno.EPIPE:
-                raise
+        raise
     except MemoryError:
         ui.warn(_("abort: out of memory\n"))
     except SystemExit as inst: