classification
Title: Problems on Linux with Ctrl-D and Ctrl-C during raw_input
Type: behavior Stage: patch review
Components: Library (Lib) Versions: Python 3.3, Python 3.2, Python 3.1, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: Finkregh, Rebecca, ajaksu2, falsetru, georg.brandl, haypo, nvetoshkin, pitrou, python-dev, schmir
Priority: normal Keywords: patch

Created on 2007-09-24 10:48 by Rebecca, last changed 2011-05-30 21:51 by haypo. This issue is now closed.

Files
File name Uploaded Description Edit
clear_eof.patch haypo, 2011-05-10 01:06
Messages (17)
msg56109 - (view) Author: Rebecca Breu (Rebecca) Date: 2007-09-24 10:48
Run the program:

while True:
    try:
        s = raw_input('> ')
    except:
        pass


Press Ctrl-D and then Ctrl-C, and you get

Traceback (most recent call last):
  File "test.py", line 5, in ?
    s = raw_input('> ')
KeyboardInterrupt

Pressing just Ctrl-D or Ctrl-C continues the loop as expected, Ctrl-D
after Ctrl-C works, too. Only Ctrl-C after Ctrl-D sucks, even when you
try to catch "EOFError" and "KeybordInterrupt" explicitly.

The problem occurs with Python 2.4 and 2.5 on Debian testing, friends
confirmed the error under Ubuntu/2.5 and Gentoo/?.

The error does not occur when you import readline first.


Ah, and by the way: http://docs.python.org/lib/reporting-bugs.html
still links to the sourceforce bucktracker.
msg56112 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2007-09-24 14:49
There are a few other issues about raw_input and signals in the tracker,
possibly this is just another incarnation...

The docs tracker link is fixed, but needs a rebuild on the server.
msg59242 - (view) Author: Ralf Schmitt (schmir) Date: 2008-01-04 17:19
The following patch fixes it. The end-of-file indicator is still set,
fgets returns NULL when ctrl-c is pressed, and the code checks for
feof(fp) which is true. PyErr_CheckSignals() isn't called.
This patch calls clearerr on the filepointer and consequently after
ctrl-c feof(fp) is false and PyErr_CheckSignals is called.


What I don't understand is why the backtrace says the KeyboardInterrupt
happens in raw_input. PyErr_CheckSignals must be called on the "pass"
statement otherwise something would be fundamentally broken (But I guess
then python somehow saves the last real bytecode command).



~/Python-2.5.1/ hg diff  
diff --git a/Parser/myreadline.c b/Parser/myreadline.c
--- a/Parser/myreadline.c
+++ b/Parser/myreadline.c
@@ -44,6 +44,7 @@ my_fgets(char *buf, int len, FILE *fp)
                if (PyOS_InputHook != NULL)
                        (void)(PyOS_InputHook)();
                errno = 0;
+               clearerr(fp);
                p = fgets(buf, len, fp);
                if (p != NULL)
                        return 0; /* No error */
msg87647 - (view) Author: Daniel Diniz (ajaksu2) Date: 2009-05-12 17:52
Confirmed in trunk, doesn't seem to affect py3k.
msg116777 - (view) Author: Mark Lawrence (BreamoreBoy) * Date: 2010-09-18 13:46
There's a one line patch in msg59242, could someone please take a look.  Apparantly py3k is not affected by this issue although I haven't tried it myself.
msg120899 - (view) Author: Vetoshkin Nikita (nvetoshkin) Date: 2010-11-09 20:40
Confirming that issue is present in latest svn checkout and Ralf's fix helps.
msg131280 - (view) Author: Vetoshkin Nikita (nvetoshkin) Date: 2011-03-17 19:34
up!
msg131323 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2011-03-18 09:58
Instead of always calling clearerr(), we can only call it on EOF:

diff -r 88fe1ac48460 Parser/myreadline.c
--- a/Parser/myreadline.c       Mon Mar 07 08:31:52 2011 +0100
+++ b/Parser/myreadline.c       Fri Mar 18 10:57:23 2011 +0100
@@ -72,6 +72,7 @@
     }
 #endif /* MS_WINDOWS */
     if (feof(fp)) {
+        clearerr(fp);
         return -1; /* EOF */
     }
 #ifdef EINTR

This patch works around this issue.
msg135659 - (view) Author: Roundup Robot (python-dev) Date: 2011-05-09 22:21
New changeset fa3227c3cf87 by Victor Stinner in branch '3.1':
Issue #1195: Fix input() if it is interrupted by CTRL+d and then CTRL+c,
http://hg.python.org/cpython/rev/fa3227c3cf87

New changeset b5914bfb4d04 by Victor Stinner in branch '3.2':
Issue #1195: Fix input() if it is interrupted by CTRL+d and then CTRL+c, clear
http://hg.python.org/cpython/rev/b5914bfb4d04

New changeset 3ff5d28ab630 by Victor Stinner in branch 'default':
(Merge 3.2) Issue #1195: Fix input() if it is interrupted by CTRL+d and then
http://hg.python.org/cpython/rev/3ff5d28ab630
msg135660 - (view) Author: Roundup Robot (python-dev) Date: 2011-05-09 22:23
New changeset c9f07c69b138 by Victor Stinner in branch '2.7':
(Merge 3.1) Issue #1195: Fix input() if it is interrupted by CTRL+d and then
http://hg.python.org/cpython/rev/c9f07c69b138
msg135661 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2011-05-09 22:24
It should be fixed. Reopen the issue if it doesn't work, I only tested on Linux.
msg135671 - (view) Author: Ralf Schmitt (schmir) Date: 2011-05-10 00:03
The patch still does not handle the case where the eof indicator is already set when calling raw_input. My original patch does.

Run the following program and hit ctrl-d, then ctrl-c:

import sys
sys.stdin.read()

while True:
    try:
        s = raw_input('> ')
    except:
        pass
msg135672 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2011-05-10 01:06
> The patch still does not handle the case where the eof indicator
> is already set when calling raw_input. My original patch does.

Correct, your example fails, but only in Python 2.7. I don't like the idea of always clearing errors. I prefer to reset stdin only after an error or EOF. Attached patch changes file.read() to clear the EOF flag if the read was stopped because of the EOF.
msg135693 - (view) Author: Ralf Schmitt (schmir) Date: 2011-05-10 09:30
Either you clearerr or you can't rely on feof. fgets might also set the end of file indicator *and* return valid data. I don't see a reason to not call clearerr right before trying to read from the stream.
msg137335 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2011-05-30 21:48
Ooops, I specified the wrong issue number in my commits :-/

New changeset 3b1b06570cf9 by Victor Stinner in branch '2.7':
Issue #12016: my_fgets() now always clears errors before calling fgets(). Fix
http://hg.python.org/cpython/rev/3b1b06570cf9

New changeset de07f90ef45c by Victor Stinner in branch '3.2':
Issue #12016: my_fgets() now always clears errors before calling fgets(). Fix
http://hg.python.org/cpython/rev/de07f90ef45c

New changeset deb6e7859211 by Victor Stinner in branch 'default':
(Merge 3.2) Issue #12016: my_fgets() now always clears errors before calling
http://hg.python.org/cpython/rev/deb6e7859211
msg137336 - (view) Author: Roundup Robot (python-dev) Date: 2011-05-30 21:50
New changeset b40dac6390a9 by Victor Stinner in branch '2.7':
Issue #1195: fix the issue number of the NEWS entry
http://hg.python.org/cpython/rev/b40dac6390a9

New changeset d780ca579e6f by Victor Stinner in branch '3.2':
Issue #1195: fix the issue number of the NEWS entry
http://hg.python.org/cpython/rev/d780ca579e6f

New changeset 29e61c4ba59f by Victor Stinner in branch 'default':
(Merge 3.2) Issue #1195: fix the issue number of the NEWS entry
http://hg.python.org/cpython/rev/29e61c4ba59f
msg137337 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2011-05-30 21:51
> The patch still does not handle the case where the eof indicator
> is already set when calling raw_input. My original patch does.

I commited your original patch but I kept mine because it doesn't hurt to clear the error on EOF at exit. Reopen the issue if it still doesn't work in all cases.
History
Date User Action Args
2011-05-30 21:51:50hayposetstatus: open -> closed
resolution: fixed
messages: + msg137337
2011-05-30 21:50:43python-devsetmessages: + msg137336
2011-05-30 21:48:37hayposetmessages: + msg137335
2011-05-30 08:54:54hayposetstatus: closed -> open
resolution: fixed -> (no value)
2011-05-10 09:30:03schmirsetmessages: + msg135693
2011-05-10 01:06:33hayposetfiles: + clear_eof.patch

messages: + msg135672
2011-05-10 00:03:55schmirsetmessages: + msg135671
2011-05-09 22:24:35hayposetstatus: open -> closed
resolution: fixed
messages: + msg135661
2011-05-09 22:23:28python-devsetmessages: + msg135660
2011-05-09 22:21:50python-devsetnosy: + python-dev
messages: + msg135659
2011-03-18 09:58:15hayposetnosy: georg.brandl, pitrou, falsetru, haypo, ajaksu2, schmir, Rebecca, nvetoshkin, Finkregh
messages: + msg131323
2011-03-17 23:51:21eric.araujosetnosy: + haypo, - BreamoreBoy
versions: + Python 3.1, Python 3.2, Python 3.3
2011-03-17 19:34:02nvetoshkinsetnosy: georg.brandl, pitrou, falsetru, ajaksu2, schmir, Rebecca, nvetoshkin, BreamoreBoy, Finkregh
messages: + msg131280
2010-12-17 09:21:42Finkreghsetnosy: + Finkregh
2010-11-09 20:40:52nvetoshkinsetnosy: + nvetoshkin
messages: + msg120899
2010-11-08 16:16:37eric.araujosetnosy: + pitrou
2010-11-08 06:21:07falsetrusetnosy: + falsetru
2010-09-18 13:46:46BreamoreBoysetversions: + Python 2.7, - Python 2.6
nosy: + BreamoreBoy

messages: + msg116777

stage: test needed -> patch review
2009-05-12 17:52:26ajaksu2setversions: + Python 2.6, - Python 2.5
nosy: + ajaksu2

messages: + msg87647

keywords: + patch
stage: test needed
2008-01-04 17:19:17schmirsetnosy: + schmir
messages: + msg59242
2007-09-24 17:17:07jafosetpriority: normal
type: behavior
components: + Library (Lib), - None
2007-09-24 14:49:49georg.brandlsetnosy: + georg.brandl
messages: + msg56112
2007-09-24 10:48:56Rebeccacreate