[Python-bugs-list] [ python-Bugs-439992 ] [win32] KeyboardInterrupt Not Caught

noreply@sourceforge.net noreply@sourceforge.net
Sat, 13 Jul 2002 23:50:18 -0700


Bugs item #439992, was opened at 2001-07-10 19:24
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=439992&group_id=5470

Category: Python Interpreter Core
Group: Platform-specific
Status: Open
Resolution: None
Priority: 5
Submitted By: Nobody/Anonymous (nobody)
>Assigned to: Tim Peters (tim_one)
Summary: [win32] KeyboardInterrupt Not Caught

Initial Comment:
The following program, run under unix (FreeBSD 4.3) and Windows 2000 SP2
with the command line:  python test.py

In both cases, running python 2.1.

The program works as expected under unix and IDLE on Windows 2000, but it
does *not* catch the interrupt in the command line version of Win32 python...
i.e., The traceback message appears rather than my "Leaving Dodge..." message.


while 1:
    try:
        x = raw_input().upper()
        print x
    except KeyboardInterrupt:
        print "Leaving Dodge...\n"
        break

----------------------------------------------------------------------

>Comment By: Mark Hammond (mhammond)
Date: 2002-07-14 16:50

Message:
Logged In: YES 
user_id=14198

Re Ctrl+C - it is indeed Win9x specific and I should have
remembered that.  NT/2k etc sees pretty much instant death.
 My investigations with the debugger show that this "death"
was actually normal termination due to eof() being detected
(rather than the Ctrl+C)

Re sleep - the problem is that we install a signal handler.
 The default signal handler aborts the process
asynchronously, just like Ctrl+Break still does for NT
(which also can be fixed if deemed broken. IIRC, 9x and NT
still have different Ctrl+Break handling.)

Installing a signal handler disables the default.  The
following C program behaves like Python:

#include <signal.h>
#include <windows.h>
static void signal_handler(int sig_num) {}

int main() {
    signal(SIGINT, signal_handler);    
    Sleep(10000); return 0; 
}

but I may even try to fix that <wink>.  If I do, then it
will be quite a different solution than for the patch
proposed here.

Tim - I don't have MSVC on 9x handy here, but would be
interested to see how myreadline.c works on Win9x with a
Ctrl+C.  As the comments imply, on NT we see feof()
returning true, and errno set to something useless (file not
found IIRC)


----------------------------------------------------------------------

Comment By: Tim Peters (tim_one)
Date: 2002-07-14 12:30

Message:
Logged In: YES 
user_id=31435

I don't object to trying to make it better <wink>.  I'm 
confused by a couple of things, though.

1. You said

"""
One side effect is that Ctrl+C in an interactive Python
session no longer terminates the process - just like *nix,
it now prints "KeyboardInterrupt" then returns to the
interactive prompt.
"""

I use Ctrl+C in interactive sessions on Windows a lot, and 
it never terminates the process -- KeyboardInterrupt is 
what I get now.  I don't recall that being specific to Win9x, 
although maybe it is.

2. There's something fishy about Python's time.sleep() on 
Windows too.  If I run this C program on Windows:

#include <windows.h>
int main() { Sleep(10000); return 0; }

then it quits the instant I hit Ctrl+C.  But if I do

time.sleep(10)

from Python and hit Ctrl+C, it waits until 10 seconds are 
up before proceeding and displaying KeyboardInterrupt.

Since time.sleep() just calls Sleep() on Windows, this has 
always baffled me (but not enough to investigate, and 
you're on a roll <wink>).

----------------------------------------------------------------------

Comment By: Mark Hammond (mhammond)
Date: 2002-07-14 11:25

Message:
Logged In: YES 
user_id=14198

This is an interesting one :)

When Python is inside an fgets() and a Ctrl+C is hit, we see
two things:
* fgets() returns immediately with an "eof" condition. 
There is no errno set to indicate the interrupt like there
is on *nix.
* The signal handler is called asynchronously on another thread.

So what the user sees is:
* The EOF flag causes Python to raise an EOFError when
Ctrl+C is pressed.
* When the signal is finally triggered, Python sees
*another* exception, this time a keyboard interrupt.

For example, the following code:
import time, sys
while 1:
    try:
        x = raw_input().upper()
        print x
    except KeyboardInterrupt:
        print "Done"
        break
    except EOFError:
        print "EOF"
        break

will *usually* print "EOF" when Ctrl+C is pressed.

I have determined that when Ctrl+C is pressed, the Win32
function GetLastError() returns ERROR_OPERATION_ABORTED.  By
using this undocumented feature, I have created a patch that
makes Ctrl+C work as it does on *nix.

One side effect is that Ctrl+C in an interactive Python
session no longer terminates the process - just like *nix,
it now prints "KeyboardInterrupt" then returns to the
interactive prompt.

Tim - what say you on this?

----------------------------------------------------------------------

Comment By: Skip Montanaro (montanaro)
Date: 2002-03-10 12:41

Message:
Logged In: YES 
user_id=44345

just a note to remind folks that GvR suggested closing
this as "won't fix" a few months ago.  Seems like it's
still the correct course unless MS has changed Windows
dramtically in the intervening interval. -skip


----------------------------------------------------------------------

Comment By: Tim Peters (tim_one)
Date: 2001-12-12 17:08

Message:
Logged In: YES 
user_id=31435

Umm, I have no idea whether it can be fixed.  Who was this 
assigned to?  Assigning to MarkH in case he has an idea.

----------------------------------------------------------------------

Comment By: Guido van Rossum (gvanrossum)
Date: 2001-12-12 16:34

Message:
Logged In: YES 
user_id=6380

Shall we close this as Won't Fix? Is there a point in
keeping it open while we know we can't fix it?

----------------------------------------------------------------------

Comment By: Tim Peters (tim_one)
Date: 2001-08-08 01:51

Message:
Logged In: YES 
user_id=31435

For posterity, a delightfully confused section of 
MS's "signal" docs:

"""
Note SIGINT is not supported for any Win32 application 
including Windows NT and Windows 95. When a CTRL+C 
interrupt occurs, Win32 operating systems generate a new 
thread to specifically handle that interrupt. This can 
cause a single-thread application such as UNIX, to become 
multithreaded, resulting in unexpected behavior. 
"""

I kid you not.

----------------------------------------------------------------------

Comment By: Guido van Rossum (gvanrossum)
Date: 2001-08-07 23:59

Message:
Logged In: YES 
user_id=6380

Yes, I'm afraid signal handling doesn't always work on
Windows.
I don't know Windows enough to understand how to fix this.

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=439992&group_id=5470