classification
Title: Python doesn't exit with proper resultcode on SIGINT
Type: enhancement Stage: patch review
Components: Interpreter Core Versions: Python 3.3
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: foom, gregory.p.smith, haypo, loewis, mwh, petri.lehtinen, pitrou, rnk
Priority: normal Keywords: needs review, patch

Created on 2004-10-25 20:27 by foom, last changed 2011-07-02 20:01 by petri.lehtinen.

Files
File name Uploaded Description Edit
issue1054041-sigint-exit-gps01.diff gregory.p.smith, 2011-01-04 03:21
Messages (9)
msg60590 - (view) Author: James Y Knight (foom) Date: 2004-10-25 20:27
If you kill a python process with SIGINT (e.g. control-c), it catches 
the signal, and raises a KeyboardInterrupt. If the KeyboardInterrupt 
propagates to the top level, python exits. However, it exits with a 
result of 1, not a result of SIGINT. This means that if you run 
python in a shell script, the script will not properly exit on C-c.

When exiting because of a KeyboardInterrupt, python ought to 
reraise the SIGINT, as follows, so that the exit code is correct for 
the caller:
        signal(SIGINT, SIG_DFL);
        kill(getpid(), SIGINT);

See also http://www.cons.org/cracauer/sigint.html for a more 
detailed discussion on the topic.
msg60591 - (view) Author: Michael Hudson (mwh) (Python committer) Date: 2005-04-07 09:26
Logged In: YES 
user_id=6656

Feel like writing a patch?
msg114385 - (view) Author: Mark Lawrence (BreamoreBoy) Date: 2010-08-19 17:59
I'll close this in a couple of weeks unless someone wants it kept open.
msg125287 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2011-01-04 03:21
Here's a patch that implements this behavior.  It is too late in the 3.2 beta/rc cycle to get this into 3.2.  Consider it for 3.3.  I'd like a review.
msg125593 - (view) Author: Reid Kleckner (rnk) (Python committer) Date: 2011-01-06 21:32
Looks good to me.  Do you need the TODO(gps)'s in there after implementing the behavior described?
msg125596 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2011-01-06 22:29
- should KeyboardInterrupt always exit with SIGINT, or only if it was actually raised by a signal handler?
- if _Py_UnhandledKeyboardInterrupt is defined in Modules/main.c but used in Python/pythonrun.c, can't it cause linker errors when embedding Python?
- please use PEP 8 (testKeyboardInterruptSignalExit -> test_some_long_name)
msg125605 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2011-01-06 23:44
I wonder whether there is a precedent of some system mapping SIGINT to
an exception. We could probably learn something from them.

> - should KeyboardInterrupt always exit with SIGINT, or only if it was
> actually raised by a signal handler?

IMO, if we give the illusion that the interpreter was actually killed,
we should equate KeyboardInterrupt with SIGINT; any uncaught
KeyboardInterrupt should consequently always lead to raising SIGINT.
msg125624 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2011-01-07 05:08
> IMO, if we give the illusion that the interpreter was actually killed,
> we should equate KeyboardInterrupt with SIGINT; any uncaught
> KeyboardInterrupt should consequently always lead to raising SIGINT.

Agreed.  Plus that is easier to implement and what I did.

I'll remove the left over TODO(gps) comments (oops) before this is
ever committed. I'm waiting until after 3.2 is released unless the
release manager jumps in and says otherwise.  remaining items:

 1. I need to add a second test case that writes the code to a file
and launches a subprocess executing that file instead of using -c
given that they are different code paths that each need testing.  For
variety I'll probably make that one send an actual SIGINT to the child
process rather than having it raise KeyboardInterrupt.

 2. The tests probably needs a decorator to limit their execution to posix.

 3. Do the signal and kill calls also need to be conditional based on
platform or is the function I put them in already posix-only?  If
necessary I'll protect them with #ifdefs so they don't break a windows
build.
msg136416 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2011-05-21 00:31
+        kill(getpid(), SIGINT);

kill() doesn't exist on Windows: use raise() which is more portable and doesn't require a PID argument.

We may need to do something on Windows for console applications: see SetConsoleCtrlHandler(),
http://msdn.microsoft.com/en-us/library/ms686016(v=vs.85).aspx

+        self.assertEqual(returncode, -signal.SIGINT,
+                         "not a SIGINT exit code. process stderr:\n%s" % stderr)

I don't think that such test can pass on Windows.
History
Date User Action Args
2011-07-02 20:01:21petri.lehtinensetstage: needs patch -> patch review
2011-05-21 00:31:56hayposetnosy: + haypo
messages: + msg136416
2011-05-20 06:34:20petri.lehtinensetnosy: + petri.lehtinen
2011-01-07 05:08:16gregory.p.smithsetnosy: mwh, loewis, gregory.p.smith, foom, pitrou, rnk
messages: + msg125624
2011-01-06 23:44:04loewissetnosy: mwh, loewis, gregory.p.smith, foom, pitrou, rnk
messages: + msg125605
2011-01-06 22:29:15pitrousetnosy: + pitrou, loewis
messages: + msg125596
2011-01-06 21:32:10rnksetnosy: mwh, gregory.p.smith, foom, rnk
messages: + msg125593
2011-01-04 03:21:10gregory.p.smithsetfiles: + issue1054041-sigint-exit-gps01.diff

messages: + msg125287
keywords: + needs review, patch
nosy: mwh, gregory.p.smith, foom, rnk
2011-01-04 01:29:01pitrousetnosy: + rnk
2011-01-04 01:28:56pitrousetnosy: + gregory.p.smith, - BreamoreBoy
stage: test needed -> needs patch
type: behavior -> enhancement
versions: + Python 3.3, - Python 3.1, Python 2.7, Python 3.2
2010-08-19 22:14:59skrahsetstatus: pending -> open
2010-08-19 17:59:03BreamoreBoysetstatus: open -> pending
versions: + Python 3.1, Python 3.2
nosy: + BreamoreBoy

messages: + msg114385

type: enhancement -> behavior
2009-02-14 18:19:07ajaksu2setstage: test needed
type: enhancement
versions: + Python 2.7
2004-10-25 20:27:22foomcreate