summaryrefslogtreecommitdiffstats
path: root/Parser
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2020-06-03 12:39:59 (GMT)
committerGitHub <noreply@github.com>2020-06-03 12:39:59 (GMT)
commitfa7ab6aa0f9a4f695e5525db5a113cd21fa93787 (patch)
treedb9c9a9fc6908662ed752d6617a719cc566f155f /Parser
parent18a90248fdd92b27098cc4db773686a2d10a4d24 (diff)
downloadcpython-fa7ab6aa0f9a4f695e5525db5a113cd21fa93787.zip
cpython-fa7ab6aa0f9a4f695e5525db5a113cd21fa93787.tar.gz
cpython-fa7ab6aa0f9a4f695e5525db5a113cd21fa93787.tar.bz2
bpo-40826: Add _PyOS_InterruptOccurred(tstate) function (GH-20599)
my_fgets() now calls _PyOS_InterruptOccurred(tstate) to check for pending signals, rather calling PyOS_InterruptOccurred(). my_fgets() is called with the GIL released, whereas PyOS_InterruptOccurred() must be called with the GIL held. test_repl: use text=True and avoid SuppressCrashReport in test_multiline_string_parsing(). Fix my_fgets() on Windows: fgets(fp) does crash if fileno(fp) is closed.
Diffstat (limited to 'Parser')
-rw-r--r--Parser/myreadline.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/Parser/myreadline.c b/Parser/myreadline.c
index d2787f0..2dd3623 100644
--- a/Parser/myreadline.c
+++ b/Parser/myreadline.c
@@ -24,14 +24,23 @@ static PyThread_type_lock _PyOS_ReadlineLock = NULL;
int (*PyOS_InputHook)(void) = NULL;
/* This function restarts a fgets() after an EINTR error occurred
- except if PyOS_InterruptOccurred() returns true. */
+ except if _PyOS_InterruptOccurred() returns true. */
static int
my_fgets(PyThreadState* tstate, char *buf, int len, FILE *fp)
{
#ifdef MS_WINDOWS
- HANDLE hInterruptEvent;
+ HANDLE handle;
+ _Py_BEGIN_SUPPRESS_IPH
+ handle = (HANDLE)_get_osfhandle(fileno(fp));
+ _Py_END_SUPPRESS_IPH
+
+ /* bpo-40826: fgets(fp) does crash if fileno(fp) is closed */
+ if (handle == INVALID_HANDLE_VALUE) {
+ return -1; /* EOF */
+ }
#endif
+
while (1) {
if (PyOS_InputHook != NULL) {
(void)(PyOS_InputHook)();
@@ -60,7 +69,7 @@ my_fgets(PyThreadState* tstate, char *buf, int len, FILE *fp)
through to check for EOF.
*/
if (GetLastError()==ERROR_OPERATION_ABORTED) {
- hInterruptEvent = _PyOS_SigintEvent();
+ HANDLE hInterruptEvent = _PyOS_SigintEvent();
switch (WaitForSingleObjectEx(hInterruptEvent, 10, FALSE)) {
case WAIT_OBJECT_0:
ResetEvent(hInterruptEvent);
@@ -90,7 +99,7 @@ my_fgets(PyThreadState* tstate, char *buf, int len, FILE *fp)
}
#endif
- if (PyOS_InterruptOccurred()) {
+ if (_PyOS_InterruptOccurred(tstate)) {
return 1; /* Interrupt */
}
return -2; /* Error */