[Python-checkins] cpython (merge 3.2 -> default): (Merge 3.2) Issue #11650: PyOS_StdioReadline() retries fgets() if it was

victor.stinner python-checkins at python.org
Sat Apr 9 16:02:06 CEST 2011


http://hg.python.org/cpython/rev/64de1ded0744
changeset:   69212:64de1ded0744
parent:      69209:78a66c98288d
parent:      69211:fc2f251e660a
user:        Victor Stinner <victor.stinner at haypocalc.com>
date:        Sat Apr 09 16:01:55 2011 +0200
summary:
  (Merge 3.2) Issue #11650: PyOS_StdioReadline() retries fgets() if it was
interrupted (EINTR), for example if the program is stopped with CTRL+z on Mac
OS X. Patch written by Charles-Francois Natali.

files:
  Misc/NEWS           |    4 +
  Parser/myreadline.c |  106 ++++++++++++++++---------------
  2 files changed, 59 insertions(+), 51 deletions(-)


diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,10 @@
 Core and Builtins
 -----------------
 
+- Issue #11650: PyOS_StdioReadline() retries fgets() if it was interrupted
+  (EINTR), for example if the program is stopped with CTRL+z on Mac OS X. Patch
+  written by Charles-Francois Natali.
+
 - Issue #9319: Include the filename in "Non-UTF8 code ..." syntax error.
 
 - Issue #10785: Store the filename as Unicode in the Python parser.
diff --git a/Parser/myreadline.c b/Parser/myreadline.c
--- a/Parser/myreadline.c
+++ b/Parser/myreadline.c
@@ -36,63 +36,67 @@
 my_fgets(char *buf, int len, FILE *fp)
 {
     char *p;
-    if (PyOS_InputHook != NULL)
-        (void)(PyOS_InputHook)();
-    errno = 0;
-    p = fgets(buf, len, fp);
-    if (p != NULL)
-        return 0; /* No error */
+    while (1) {
+        if (PyOS_InputHook != NULL)
+            (void)(PyOS_InputHook)();
+        errno = 0;
+        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).
+        /* 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())
         */
-        Sleep(1);
+        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 */
+        }
+#ifdef EINTR
+        if (errno == EINTR) {
+            int s;
+#ifdef WITH_THREAD
+            PyEval_RestoreThread(_PyOS_ReadlineTState);
+#endif
+            s = PyErr_CheckSignals();
+#ifdef WITH_THREAD
+            PyEval_SaveThread();
+#endif
+            if (s < 0)
+                    return 1;
+	    /* try again */
+            continue;
+        }
+#endif
         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.
-        */
+        return -2; /* Error */
     }
-#endif /* MS_WINDOWS */
-    if (feof(fp)) {
-        return -1; /* EOF */
-    }
-#ifdef EINTR
-    if (errno == EINTR) {
-        int s;
-#ifdef WITH_THREAD
-        PyEval_RestoreThread(_PyOS_ReadlineTState);
-#endif
-        s = PyErr_CheckSignals();
-#ifdef WITH_THREAD
-        PyEval_SaveThread();
-#endif
-        if (s < 0) {
-            return 1;
-        }
-    }
-#endif
-    if (PyOS_InterruptOccurred()) {
-        return 1; /* Interrupt */
-    }
-    return -2; /* Error */
+    /* NOTREACHED */
 }
 
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list