[Python-checkins] cpython: Issue #23285: Fix handling of EINTR in fileio.c
victor.stinner
python-checkins at python.org
Wed Mar 4 18:47:31 CET 2015
https://hg.python.org/cpython/rev/cad6eac598ec
changeset: 94846:cad6eac598ec
user: Victor Stinner <victor.stinner at gmail.com>
date: Wed Mar 04 18:40:10 2015 +0100
summary:
Issue #23285: Fix handling of EINTR in fileio.c
Fix handling of EINTR: don't return None if PyErr_CheckSignals() raised an
exception.
Initialize also the length outside the loop to only initialize it once.
files:
Modules/_io/fileio.c | 74 +++++++++++++++++++------------
1 files changed, 46 insertions(+), 28 deletions(-)
diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c
--- a/Modules/_io/fileio.c
+++ b/Modules/_io/fileio.c
@@ -376,10 +376,12 @@
else
#endif
self->fd = open(name, flags, 0666);
-
Py_END_ALLOW_THREADS
} while (self->fd < 0 && errno == EINTR &&
!(async_err = PyErr_CheckSignals()));
+
+ if (async_err)
+ goto error;
}
else {
PyObject *fdobj;
@@ -408,8 +410,7 @@
fd_is_own = 1;
if (self->fd < 0) {
- if (!async_err)
- PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj);
+ PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj);
goto error;
}
@@ -576,12 +577,15 @@
if (_PyVerify_fd(self->fd)) {
len = pbuf.len;
+#ifdef MS_WINDOWS
+ if (len > INT_MAX)
+ len = INT_MAX;
+#endif
+
do {
Py_BEGIN_ALLOW_THREADS
errno = 0;
#ifdef MS_WINDOWS
- if (len > INT_MAX)
- len = INT_MAX;
n = read(self->fd, pbuf.buf, (int)len);
#else
n = read(self->fd, pbuf.buf, len);
@@ -589,6 +593,9 @@
Py_END_ALLOW_THREADS
} while (n < 0 && errno == EINTR &&
!(async_err = PyErr_CheckSignals()));
+
+ if (async_err)
+ return NULL;
} else
n = -1;
err = errno;
@@ -597,8 +604,7 @@
if (err == EAGAIN)
Py_RETURN_NONE;
errno = err;
- if (!async_err)
- PyErr_SetFromErrno(PyExc_IOError);
+ PyErr_SetFromErrno(PyExc_IOError);
return NULL;
}
@@ -633,7 +639,7 @@
Py_off_t pos, end;
PyObject *result;
Py_ssize_t bytes_read = 0;
- Py_ssize_t n;
+ Py_ssize_t len, n;
size_t bufsize;
int async_err = 0;
@@ -682,20 +688,26 @@
return NULL;
}
}
+
+ len = bufsize - bytes_read;
+#ifdef MS_WINDOWS
+ if (len > INT_MAX)
+ len = INT_MAX;
+#endif
do {
Py_BEGIN_ALLOW_THREADS
errno = 0;
- n = bufsize - bytes_read;
#ifdef MS_WINDOWS
- if (n > INT_MAX)
- n = INT_MAX;
- n = read(self->fd, PyBytes_AS_STRING(result) + bytes_read, (int)n);
+ n = read(self->fd, PyBytes_AS_STRING(result) + bytes_read, (int)len);
#else
- n = read(self->fd, PyBytes_AS_STRING(result) + bytes_read, n);
+ n = read(self->fd, PyBytes_AS_STRING(result) + bytes_read, len);
#endif
Py_END_ALLOW_THREADS
} while (n < 0 && errno == EINTR &&
!(async_err = PyErr_CheckSignals()));
+
+ if (async_err)
+ return NULL;
if (n == 0)
break;
if (n < 0) {
@@ -706,8 +718,7 @@
Py_RETURN_NONE;
}
Py_DECREF(result);
- if (!async_err)
- PyErr_SetFromErrno(PyExc_IOError);
+ PyErr_SetFromErrno(PyExc_IOError);
return NULL;
}
bytes_read += n;
@@ -775,6 +786,9 @@
Py_END_ALLOW_THREADS
} while (n < 0 && errno == EINTR &&
!(async_err = PyErr_CheckSignals()));
+
+ if (async_err)
+ return NULL;
} else
n = -1;
@@ -784,8 +798,7 @@
if (err == EAGAIN)
Py_RETURN_NONE;
errno = err;
- if (!async_err)
- PyErr_SetFromErrno(PyExc_IOError);
+ PyErr_SetFromErrno(PyExc_IOError);
return NULL;
}
@@ -815,19 +828,22 @@
return NULL;
if (_PyVerify_fd(self->fd)) {
+ len = pbuf.len;
+#ifdef MS_WINDOWS
+ if (len > 32767 && isatty(self->fd)) {
+ /* Issue #11395: the Windows console returns an error (12: not
+ enough space error) on writing into stdout if stdout mode is
+ binary and the length is greater than 66,000 bytes (or less,
+ depending on heap usage). */
+ len = 32767;
+ } else if (len > INT_MAX)
+ len = INT_MAX;
+#endif
+
do {
Py_BEGIN_ALLOW_THREADS
errno = 0;
- len = pbuf.len;
#ifdef MS_WINDOWS
- if (len > 32767 && isatty(self->fd)) {
- /* Issue #11395: the Windows console returns an error (12: not
- enough space error) on writing into stdout if stdout mode is
- binary and the length is greater than 66,000 bytes (or less,
- depending on heap usage). */
- len = 32767;
- } else if (len > INT_MAX)
- len = INT_MAX;
n = write(self->fd, pbuf.buf, (int)len);
#else
n = write(self->fd, pbuf.buf, len);
@@ -835,6 +851,9 @@
Py_END_ALLOW_THREADS
} while (n < 0 && errno == EINTR &&
!(async_err = PyErr_CheckSignals()));
+
+ if (async_err)
+ return NULL;
} else
n = -1;
err = errno;
@@ -845,8 +864,7 @@
if (err == EAGAIN)
Py_RETURN_NONE;
errno = err;
- if (!async_err)
- PyErr_SetFromErrno(PyExc_IOError);
+ PyErr_SetFromErrno(PyExc_IOError);
return NULL;
}
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list