[Python-checkins] cpython: Issue #23708: Save/restore errno in _Py_read() and _Py_write()

victor.stinner python-checkins at python.org
Fri Mar 20 12:02:38 CET 2015


https://hg.python.org/cpython/rev/07fd54208434
changeset: 95091:07fd54208434
user: Victor Stinner <victor.stinner at gmail.com>
date: Fri Mar 20 11:58:18 2015 +0100
summary:
 Issue #23708: Save/restore errno in _Py_read() and _Py_write()
Save and then restore errno because PyErr_CheckSignals() and
PyErr_SetFromErrno() can modify it.
files:
 Python/fileutils.c | 36 +++++++++++++++++++--------------
 1 files changed, 21 insertions(+), 15 deletions(-)
diff --git a/Python/fileutils.c b/Python/fileutils.c
--- a/Python/fileutils.c
+++ b/Python/fileutils.c
@@ -1137,6 +1137,7 @@
 _Py_read(int fd, void *buf, size_t count)
 {
 Py_ssize_t n;
+ int err;
 int async_err = 0;
 
 /* _Py_read() must not be called with an exception set, otherwise the
@@ -1145,8 +1146,10 @@
 assert(!PyErr_Occurred());
 
 if (!_PyVerify_fd(fd)) {
+ /* save/restore errno because PyErr_SetFromErrno() can modify it */
+ err = errno;
 PyErr_SetFromErrno(PyExc_OSError);
- assert(errno == EBADF);
+ errno = err;
 return -1;
 }
 
@@ -1171,23 +1174,23 @@
 #else
 n = read(fd, buf, count);
 #endif
+ /* save/restore errno because PyErr_CheckSignals()
+ * and PyErr_SetFromErrno() can modify it */
+ err = errno;
 Py_END_ALLOW_THREADS
- } while (n < 0 && errno == EINTR &&
+ } while (n < 0 && err == EINTR &&
 !(async_err = PyErr_CheckSignals()));
 
 if (async_err) {
 /* read() was interrupted by a signal (failed with EINTR)
 * and the Python signal handler raised an exception */
- assert(errno == EINTR);
- assert(PyErr_Occurred());
+ errno = err;
+ assert(errno == EINTR && PyErr_Occurred());
 return -1;
 }
 if (n < 0) {
-#ifndef NDEBUG
- int err = errno;
-#endif
 PyErr_SetFromErrno(PyExc_OSError);
- assert(errno == err);
+ errno = err;
 return -1;
 }
 
@@ -1209,6 +1212,7 @@
 _Py_write(int fd, const void *buf, size_t count)
 {
 Py_ssize_t n;
+ int err;
 int async_err = 0;
 
 /* _Py_write() must not be called with an exception set, otherwise the
@@ -1217,8 +1221,10 @@
 assert(!PyErr_Occurred());
 
 if (!_PyVerify_fd(fd)) {
+ /* save/restore errno because PyErr_SetFromErrno() can modify it */
+ err = errno;
 PyErr_SetFromErrno(PyExc_OSError);
- assert(errno == EBADF);
+ errno = err;
 return -1;
 }
 
@@ -1248,6 +1254,9 @@
 #else
 n = write(fd, buf, count);
 #endif
+ /* save/restore errno because PyErr_CheckSignals()
+ * and PyErr_SetFromErrno() can modify it */
+ err = errno;
 Py_END_ALLOW_THREADS
 } while (n < 0 && errno == EINTR &&
 !(async_err = PyErr_CheckSignals()));
@@ -1255,16 +1264,13 @@
 if (async_err) {
 /* write() was interrupted by a signal (failed with EINTR)
 * and the Python signal handler raised an exception */
- assert(errno == EINTR);
- assert(PyErr_Occurred());
+ errno = err;
+ assert(errno == EINTR && PyErr_Occurred());
 return -1;
 }
 if (n < 0) {
-#ifndef NDEBUG
- int err = errno;
-#endif
 PyErr_SetFromErrno(PyExc_OSError);
- assert(errno == err);
+ errno = err;
 return -1;
 }
 
-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /