]> granicus.if.org Git - python/commitdiff
Fix bug 439992 - [win32] KeyboardInterrupt Not Caught.
authorMark Hammond <mhammond@skippinet.com.au>
Sun, 14 Jul 2002 23:12:29 +0000 (23:12 +0000)
committerMark Hammond <mhammond@skippinet.com.au>
Sun, 14 Jul 2002 23:12:29 +0000 (23:12 +0000)
This gets us closer to consistent Ctrl+C behaviour on NT and Win9x.  NT now reliably generates KeyboardInterrupt exceptions for NT when a file IO operation was aborted.  Bugfix candidate

Parser/myreadline.c

index 10e39e53685b8edf629af75269e67d2406a7c3a8..8fe25ecb8fe3c7ffdf9efb39a1b188ef4d4bd863 100644 (file)
 */
 
 #include "Python.h"
+#ifdef MS_WINDOWS
+#define WIN32_LEAN_AND_MEAN
+#include "windows.h"
+#endif /* MS_WINDOWS */
 
 int (*PyOS_InputHook)(void) = NULL;
 
@@ -31,6 +35,35 @@ my_fgets(char *buf, int len, FILE *fp)
                p = fgets(buf, len, fp);
                if (p != NULL)
                        return 0; /* No error */
+#ifdef MS_WINDOWS
+               /* In the case of a Ctrl+C or some other external event 
+                  interrupting the operation:
+                  Win2k/NT: ERROR_OPERATION_ABORTED is the most recent Win32 
+                  error code (and feof() returns TRUE).
+                  Win9x: Ctrl+C seems to have no effect on fgets() returning
+                  early - the signal handler is called, but the fgets()
+                  only returns "normally" (ie, when Enter hit or feof())
+               */
+               if (GetLastError()==ERROR_OPERATION_ABORTED) {
+                       /* Signals come asynchronously, so we sleep a brief 
+                          moment before checking if the handler has been 
+                          triggered (we cant just return 1 before the 
+                          signal handler has been called, as the later 
+                          signal may be treated as a separate interrupt).
+                       */
+                       Sleep(1);
+                       if (PyOS_InterruptOccurred()) {
+                               return 1; /* Interrupt */
+                       }
+                       /* Either the sleep wasn't long enough (need a
+                          short loop retrying?) or not interrupted at all
+                          (in which case we should revisit the whole thing!)
+                          Logging some warning would be nice.  assert is not
+                          viable as under the debugger, the various dialogs
+                          mean the condition is not true.
+                       */
+               }
+#endif /* MS_WINDOWS */
                if (feof(fp)) {
                        return -1; /* EOF */
                }