Commit 9672da7b authored by Victor Stinner's avatar Victor Stinner

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.
parent 35e5b727
...@@ -376,10 +376,12 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) ...@@ -376,10 +376,12 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
else else
#endif #endif
self->fd = open(name, flags, 0666); self->fd = open(name, flags, 0666);
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
} while (self->fd < 0 && errno == EINTR && } while (self->fd < 0 && errno == EINTR &&
!(async_err = PyErr_CheckSignals())); !(async_err = PyErr_CheckSignals()));
if (async_err)
goto error;
} }
else { else {
PyObject *fdobj; PyObject *fdobj;
...@@ -408,7 +410,6 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) ...@@ -408,7 +410,6 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
fd_is_own = 1; fd_is_own = 1;
if (self->fd < 0) { if (self->fd < 0) {
if (!async_err)
PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj); PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj);
goto error; goto error;
} }
...@@ -576,12 +577,15 @@ fileio_readinto(fileio *self, PyObject *args) ...@@ -576,12 +577,15 @@ fileio_readinto(fileio *self, PyObject *args)
if (_PyVerify_fd(self->fd)) { if (_PyVerify_fd(self->fd)) {
len = pbuf.len; len = pbuf.len;
#ifdef MS_WINDOWS
if (len > INT_MAX)
len = INT_MAX;
#endif
do { do {
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
errno = 0; errno = 0;
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
if (len > INT_MAX)
len = INT_MAX;
n = read(self->fd, pbuf.buf, (int)len); n = read(self->fd, pbuf.buf, (int)len);
#else #else
n = read(self->fd, pbuf.buf, len); n = read(self->fd, pbuf.buf, len);
...@@ -589,6 +593,9 @@ fileio_readinto(fileio *self, PyObject *args) ...@@ -589,6 +593,9 @@ fileio_readinto(fileio *self, PyObject *args)
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
} while (n < 0 && errno == EINTR && } while (n < 0 && errno == EINTR &&
!(async_err = PyErr_CheckSignals())); !(async_err = PyErr_CheckSignals()));
if (async_err)
return NULL;
} else } else
n = -1; n = -1;
err = errno; err = errno;
...@@ -597,7 +604,6 @@ fileio_readinto(fileio *self, PyObject *args) ...@@ -597,7 +604,6 @@ fileio_readinto(fileio *self, PyObject *args)
if (err == EAGAIN) if (err == EAGAIN)
Py_RETURN_NONE; Py_RETURN_NONE;
errno = err; errno = err;
if (!async_err)
PyErr_SetFromErrno(PyExc_IOError); PyErr_SetFromErrno(PyExc_IOError);
return NULL; return NULL;
} }
...@@ -633,7 +639,7 @@ fileio_readall(fileio *self) ...@@ -633,7 +639,7 @@ fileio_readall(fileio *self)
Py_off_t pos, end; Py_off_t pos, end;
PyObject *result; PyObject *result;
Py_ssize_t bytes_read = 0; Py_ssize_t bytes_read = 0;
Py_ssize_t n; Py_ssize_t len, n;
size_t bufsize; size_t bufsize;
int async_err = 0; int async_err = 0;
...@@ -682,20 +688,26 @@ fileio_readall(fileio *self) ...@@ -682,20 +688,26 @@ fileio_readall(fileio *self)
return NULL; return NULL;
} }
} }
len = bufsize - bytes_read;
#ifdef MS_WINDOWS
if (len > INT_MAX)
len = INT_MAX;
#endif
do { do {
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
errno = 0; errno = 0;
n = bufsize - bytes_read;
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
if (n > INT_MAX) n = read(self->fd, PyBytes_AS_STRING(result) + bytes_read, (int)len);
n = INT_MAX;
n = read(self->fd, PyBytes_AS_STRING(result) + bytes_read, (int)n);
#else #else
n = read(self->fd, PyBytes_AS_STRING(result) + bytes_read, n); n = read(self->fd, PyBytes_AS_STRING(result) + bytes_read, len);
#endif #endif
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
} while (n < 0 && errno == EINTR && } while (n < 0 && errno == EINTR &&
!(async_err = PyErr_CheckSignals())); !(async_err = PyErr_CheckSignals()));
if (async_err)
return NULL;
if (n == 0) if (n == 0)
break; break;
if (n < 0) { if (n < 0) {
...@@ -706,7 +718,6 @@ fileio_readall(fileio *self) ...@@ -706,7 +718,6 @@ fileio_readall(fileio *self)
Py_RETURN_NONE; Py_RETURN_NONE;
} }
Py_DECREF(result); Py_DECREF(result);
if (!async_err)
PyErr_SetFromErrno(PyExc_IOError); PyErr_SetFromErrno(PyExc_IOError);
return NULL; return NULL;
} }
...@@ -775,6 +786,9 @@ fileio_read(fileio *self, PyObject *args) ...@@ -775,6 +786,9 @@ fileio_read(fileio *self, PyObject *args)
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
} while (n < 0 && errno == EINTR && } while (n < 0 && errno == EINTR &&
!(async_err = PyErr_CheckSignals())); !(async_err = PyErr_CheckSignals()));
if (async_err)
return NULL;
} else } else
n = -1; n = -1;
...@@ -784,7 +798,6 @@ fileio_read(fileio *self, PyObject *args) ...@@ -784,7 +798,6 @@ fileio_read(fileio *self, PyObject *args)
if (err == EAGAIN) if (err == EAGAIN)
Py_RETURN_NONE; Py_RETURN_NONE;
errno = err; errno = err;
if (!async_err)
PyErr_SetFromErrno(PyExc_IOError); PyErr_SetFromErrno(PyExc_IOError);
return NULL; return NULL;
} }
...@@ -815,9 +828,6 @@ fileio_write(fileio *self, PyObject *args) ...@@ -815,9 +828,6 @@ fileio_write(fileio *self, PyObject *args)
return NULL; return NULL;
if (_PyVerify_fd(self->fd)) { if (_PyVerify_fd(self->fd)) {
do {
Py_BEGIN_ALLOW_THREADS
errno = 0;
len = pbuf.len; len = pbuf.len;
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
if (len > 32767 && isatty(self->fd)) { if (len > 32767 && isatty(self->fd)) {
...@@ -828,6 +838,12 @@ fileio_write(fileio *self, PyObject *args) ...@@ -828,6 +838,12 @@ fileio_write(fileio *self, PyObject *args)
len = 32767; len = 32767;
} else if (len > INT_MAX) } else if (len > INT_MAX)
len = INT_MAX; len = INT_MAX;
#endif
do {
Py_BEGIN_ALLOW_THREADS
errno = 0;
#ifdef MS_WINDOWS
n = write(self->fd, pbuf.buf, (int)len); n = write(self->fd, pbuf.buf, (int)len);
#else #else
n = write(self->fd, pbuf.buf, len); n = write(self->fd, pbuf.buf, len);
...@@ -835,6 +851,9 @@ fileio_write(fileio *self, PyObject *args) ...@@ -835,6 +851,9 @@ fileio_write(fileio *self, PyObject *args)
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
} while (n < 0 && errno == EINTR && } while (n < 0 && errno == EINTR &&
!(async_err = PyErr_CheckSignals())); !(async_err = PyErr_CheckSignals()));
if (async_err)
return NULL;
} else } else
n = -1; n = -1;
err = errno; err = errno;
...@@ -845,7 +864,6 @@ fileio_write(fileio *self, PyObject *args) ...@@ -845,7 +864,6 @@ fileio_write(fileio *self, PyObject *args)
if (err == EAGAIN) if (err == EAGAIN)
Py_RETURN_NONE; Py_RETURN_NONE;
errno = err; errno = err;
if (!async_err)
PyErr_SetFromErrno(PyExc_IOError); PyErr_SetFromErrno(PyExc_IOError);
return NULL; return NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment