@@ -36,6 +36,7 @@ static int
3636my_fgets (char * buf , int len , FILE * fp )
3737{
3838 char * p ;
39+ int i ;
3940 int err ;
4041 while (1 ) {
4142 if (PyOS_InputHook != NULL )
@@ -50,32 +51,24 @@ my_fgets(char *buf, int len, FILE *fp)
5051 return 0 ; /* No error */
5152 err = errno ;
5253#ifdef MS_WINDOWS
53- /* In the case of a Ctrl+C or some other external event
54- interrupting the operation:
55- Win2k/NT: ERROR_OPERATION_ABORTED is the most recent Win32
56- error code (and feof() returns TRUE).
57- Win9x: Ctrl+C seems to have no effect on fgets() returning
58- early - the signal handler is called, but the fgets()
59- only returns "normally" (ie, when Enter hit or feof())
54+ /* Ctrl-C anywhere on the line or Ctrl-Z if the only character
55+ on a line will set ERROR_OPERATION_ABORTED. Under normal
56+ circumstances Ctrl-C will also have caused the SIGINT handler
57+ to fire. This signal fires in another thread and is not
58+ guaranteed to have occurred before this point in the code.
59+
60+ Therefore: check in a small loop to see if the trigger has
61+ fired, in which case assume this is a Ctrl-C event. If it
62+ hasn't fired within 10ms assume that this is a Ctrl-Z on its
63+ own or that the signal isn't going to fire for some other
64+ reason and drop through to check for EOF.
6065 */
6166 if (GetLastError ()== ERROR_OPERATION_ABORTED ) {
62- /* Signals come asynchronously, so we sleep a brief
63- moment before checking if the handler has been
64- triggered (we cant just return 1 before the
65- signal handler has been called, as the later
66- signal may be treated as a separate interrupt).
67- */
67+ for (i = 0 ; i < 10 ; i ++ ) {
68+ if (PyOS_InterruptOccurred ())
69+ return 1 ;
6870 Sleep (1 );
69- if (PyOS_InterruptOccurred ()) {
70- return 1 ; /* Interrupt */
7171 }
72- /* Either the sleep wasn't long enough (need a
73- short loop retrying?) or not interrupted at all
74- (in which case we should revisit the whole thing!)
75- Logging some warning would be nice. assert is not
76- viable as under the debugger, the various dialogs
77- mean the condition is not true.
78- */
7972 }
8073#endif /* MS_WINDOWS */
8174 if (feof (fp )) {
0 commit comments