static int my_fgets(char *buf, int len, FILE *fp) { char *p; for (;;) { if (PyOS_InputHook != NULL) (void)(PyOS_InputHook)(); errno = 0; p = fgets(buf, len, fp); if (p != NULL) return 0; /* No error */ if (feof(fp)) { return -1; /* EOF */ } #ifdef EINTR if (errno == EINTR) { if (PyOS_InterruptOccurred()) { return 1; /* Interrupt */ } continue; } #endif if (PyOS_InterruptOccurred()) { return 1; /* Interrupt */ } return -2; /* Error */ } /* NOTREACHED */ }
static int my_fgets(char *buf, int len, FILE *fp) { char *p; for (;;) { 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). */ 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) { if (PyOS_InterruptOccurred()) { return 1; /* Interrupt */ } continue; } #endif if (PyOS_InterruptOccurred()) { return 1; /* Interrupt */ } return -2; /* Error */ } /* NOTREACHED */ }
/* ARGSUSED */ int PyErr_CheckSignals(void) { if (!PyOS_InterruptOccurred()) return 0; PyErr_SetNone(PyExc_KeyboardInterrupt); return -1; }
static int my_fgets(char *buf, int len, FILE *fp) { char *p; #ifdef MS_WINDOWS int i; #endif while (1) { if (PyOS_InputHook != NULL) (void)(PyOS_InputHook)(); errno = 0; clearerr(fp); p = fgets(buf, len, fp); if (p != NULL) return 0; /* No error */ #ifdef MS_WINDOWS /* Ctrl-C anywhere on the line or Ctrl-Z if the only character on a line will set ERROR_OPERATION_ABORTED. Under normal circumstances Ctrl-C will also have caused the SIGINT handler to fire. This signal fires in another thread and is not guaranteed to have occurred before this point in the code. Therefore: check in a small loop to see if the trigger has fired, in which case assume this is a Ctrl-C event. If it hasn't fired within 10ms assume that this is a Ctrl-Z on its own or that the signal isn't going to fire for some other reason and drop through to check for EOF. */ if (GetLastError()==ERROR_OPERATION_ABORTED) { for (i = 0; i < 10; i++) { if (PyOS_InterruptOccurred()) return 1; Sleep(1); } } #endif /* MS_WINDOWS */ if (feof(fp)) { clearerr(fp); return -1; /* EOF */ } #ifdef EINTR if (errno == EINTR) { int s; #ifdef WITH_THREAD // Pyston change: changed to our internal API //PyEval_RestoreThread(_PyOS_ReadlineTState); endAllowThreads(); #endif s = PyErr_CheckSignals(); #ifdef WITH_THREAD // Pyston change: changed to our internal API //PyEval_SaveThread(); beginAllowThreads(); #endif if (s < 0) return 1; /* try again */ continue; } #endif if (PyOS_InterruptOccurred()) { return 1; /* Interrupt */ } return -2; /* Error */ } /* NOTREACHED */ }
static pascal Boolean AEIdleProc(EventRecord *theEvent, long *sleepTime, RgnHandle *mouseRgn) { if ( PyOS_InterruptOccurred() ) return 1; return 0; }
int check_quit_flag (void) { return PyOS_InterruptOccurred (); }
void clear_quit_flag (void) { /* This clears the flag as a side effect. */ PyOS_InterruptOccurred (); }
static int my_fgets(char *buf, int len, FILE *fp) { #ifdef MS_WINDOWS HANDLE hInterruptEvent; #endif char *p; int err; while (1) { if (PyOS_InputHook != NULL) (void)(PyOS_InputHook)(); errno = 0; clearerr(fp); if (_PyVerify_fd(fileno(fp))) p = fgets(buf, len, fp); else p = NULL; if (p != NULL) return 0; /* No error */ err = errno; #ifdef MS_WINDOWS /* Ctrl-C anywhere on the line or Ctrl-Z if the only character on a line will set ERROR_OPERATION_ABORTED. Under normal circumstances Ctrl-C will also have caused the SIGINT handler to fire which will have set the event object returned by _PyOS_SigintEvent. This signal fires in another thread and is not guaranteed to have occurred before this point in the code. Therefore: check whether the event is set with a small timeout. If it is, assume this is a Ctrl-C and reset the event. If it isn't set assume that this is a Ctrl-Z on its own and drop through to check for EOF. */ if (GetLastError()==ERROR_OPERATION_ABORTED) { hInterruptEvent = _PyOS_SigintEvent(); switch (WaitForSingleObject(hInterruptEvent, 10)) { case WAIT_OBJECT_0: ResetEvent(hInterruptEvent); return 1; /* Interrupt */ case WAIT_FAILED: return -2; /* Error */ } } #endif /* MS_WINDOWS */ if (feof(fp)) { clearerr(fp); return -1; /* EOF */ } #ifdef EINTR if (err == 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 */ } return -2; /* Error */ } /* NOTREACHED */ }