[Python-checkins] cpython (3.2): Issue #10350: Read and save errno before calling a function which might

antoine.pitrou python-checkins at python.org
Fri Dec 16 12:32:38 CET 2011


http://hg.python.org/cpython/rev/6a966179c73a
changeset: 73996:6a966179c73a
branch: 3.2
parent: 73985:5ec7ecf62c1d
user: Antoine Pitrou <solipsis at pitrou.net>
date: Fri Dec 16 12:28:32 2011 +0100
summary:
 Issue #10350: Read and save errno before calling a function which might overwrite it.
Original patch by Hallvard B Furuseth.
files:
 Misc/NEWS | 3 +++
 Modules/_io/fileio.c | 14 +++++++++++---
 Modules/_multiprocessing/semaphore.c | 4 +++-
 Modules/main.c | 3 ++-
 Modules/readline.c | 13 ++++++++-----
 Modules/timemodule.c | 4 +++-
 Parser/myreadline.c | 4 +++-
 7 files changed, 33 insertions(+), 12 deletions(-)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -97,6 +97,9 @@
 Library
 -------
 
+- Issue #10350: Read and save errno before calling a function which might
+ overwrite it. Original patch by Hallvard B Furuseth.
+
 - Issue #13591: A bug in importlib has been fixed that caused import_module
 to load a module twice.
 
diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c
--- a/Modules/_io/fileio.c
+++ b/Modules/_io/fileio.c
@@ -506,6 +506,7 @@
 {
 Py_buffer pbuf;
 Py_ssize_t n, len;
+ int err;
 
 if (self->fd < 0)
 return err_closed();
@@ -529,10 +530,12 @@
 Py_END_ALLOW_THREADS
 } else
 n = -1;
+ err = errno;
 PyBuffer_Release(&pbuf);
 if (n < 0) {
- if (errno == EAGAIN)
+ if (err == EAGAIN)
 Py_RETURN_NONE;
+ errno = err;
 PyErr_SetFromErrno(PyExc_IOError);
 return NULL;
 }
@@ -675,9 +678,11 @@
 n = -1;
 
 if (n < 0) {
+ int err = errno;
 Py_DECREF(bytes);
- if (errno == EAGAIN)
+ if (err == EAGAIN)
 Py_RETURN_NONE;
+ errno = err;
 PyErr_SetFromErrno(PyExc_IOError);
 return NULL;
 }
@@ -697,6 +702,7 @@
 {
 Py_buffer pbuf;
 Py_ssize_t n, len;
+ int err;
 
 if (self->fd < 0)
 return err_closed();
@@ -727,12 +733,14 @@
 Py_END_ALLOW_THREADS
 } else
 n = -1;
+ err = errno;
 
 PyBuffer_Release(&pbuf);
 
 if (n < 0) {
- if (errno == EAGAIN)
+ if (err == EAGAIN)
 Py_RETURN_NONE;
+ errno = err;
 PyErr_SetFromErrno(PyExc_IOError);
 return NULL;
 }
diff --git a/Modules/_multiprocessing/semaphore.c b/Modules/_multiprocessing/semaphore.c
--- a/Modules/_multiprocessing/semaphore.c
+++ b/Modules/_multiprocessing/semaphore.c
@@ -267,7 +267,7 @@
 static PyObject *
 semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds)
 {
- int blocking = 1, res;
+ int blocking = 1, res, err = 0;
 double timeout;
 PyObject *timeout_obj = Py_None;
 struct timespec deadline = {0};
@@ -313,11 +313,13 @@
 else
 res = sem_timedwait(self->handle, &deadline);
 Py_END_ALLOW_THREADS
+ err = errno;
 if (res == MP_EXCEPTION_HAS_BEEN_SET)
 break;
 } while (res < 0 && errno == EINTR && !PyErr_CheckSignals());
 
 if (res < 0) {
+ errno = err;
 if (errno == EAGAIN || errno == ETIMEDOUT)
 Py_RETURN_FALSE;
 else if (errno == EINTR)
diff --git a/Modules/main.c b/Modules/main.c
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -654,13 +654,14 @@
 if (fp == NULL) {
 char *cfilename_buffer;
 const char *cfilename;
+ int err = errno;
 cfilename_buffer = _Py_wchar2char(filename, NULL);
 if (cfilename_buffer != NULL)
 cfilename = cfilename_buffer;
 else
 cfilename = "<unprintable file name>";
 fprintf(stderr, "%ls: can't open file '%s': [Errno %d] %s\n",
- argv[0], cfilename, errno, strerror(errno));
+ argv[0], cfilename, err, strerror(err));
 if (cfilename_buffer)
 PyMem_Free(cfilename_buffer);
 return 2;
diff --git a/Modules/readline.c b/Modules/readline.c
--- a/Modules/readline.c
+++ b/Modules/readline.c
@@ -154,6 +154,7 @@
 {
 PyObject *filename_obj = Py_None, *filename_bytes;
 char *filename;
+ int err;
 if (!PyArg_ParseTuple(args, "|O:write_history_file", &filename_obj))
 return NULL;
 if (filename_obj != Py_None) {
@@ -164,10 +165,11 @@
 filename_bytes = NULL;
 filename = NULL;
 }
- errno = write_history(filename);
- if (!errno && _history_length >= 0)
+ errno = err = write_history(filename);
+ if (!err && _history_length >= 0)
 history_truncate_file(filename, _history_length);
 Py_XDECREF(filename_bytes);
+ errno = err;
 if (errno)
 return PyErr_SetFromErrno(PyExc_IOError);
 Py_RETURN_NONE;
@@ -970,7 +972,7 @@
 completed_input_string = not_done_reading;
 
 while (completed_input_string == not_done_reading) {
- int has_input = 0;
+ int has_input = 0, err = 0;
 
 while (!has_input)
 { struct timeval timeout = {0, 100000}; /* 0.1 seconds */
@@ -984,13 +986,14 @@
 /* select resets selectset if no input was available */
 has_input = select(fileno(rl_instream) + 1, &selectset,
 NULL, NULL, timeoutp);
+ err = errno;
 if(PyOS_InputHook) PyOS_InputHook();
 }
 
- if(has_input > 0) {
+ if (has_input > 0) {
 rl_callback_read_char();
 }
- else if (errno == EINTR) {
+ else if (err == EINTR) {
 int s;
 #ifdef WITH_THREAD
 PyEval_RestoreThread(_PyOS_ReadlineTState);
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -527,12 +527,14 @@
 * will be ahead of time...
 */
 for (i = 1024; ; i += i) {
+ int err;
 outbuf = (time_char *)PyMem_Malloc(i*sizeof(time_char));
 if (outbuf == NULL) {
 PyErr_NoMemory();
 break;
 }
 buflen = format_time(outbuf, i, fmt, &buf);
+ err = errno;
 if (buflen > 0 || i >= 256 * fmtlen) {
 /* If the buffer is 256 times as long as the format,
 it's probably not failing for lack of room!
@@ -550,7 +552,7 @@
 PyMem_Free(outbuf);
 #if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
 /* VisualStudio .NET 2005 does this properly */
- if (buflen == 0 && errno == EINVAL) {
+ if (buflen == 0 && err == EINVAL) {
 PyErr_SetString(PyExc_ValueError, "Invalid format string");
 break;
 }
diff --git a/Parser/myreadline.c b/Parser/myreadline.c
--- a/Parser/myreadline.c
+++ b/Parser/myreadline.c
@@ -36,6 +36,7 @@
 my_fgets(char *buf, int len, FILE *fp)
 {
 char *p;
+ int err;
 while (1) {
 if (PyOS_InputHook != NULL)
 (void)(PyOS_InputHook)();
@@ -44,6 +45,7 @@
 p = fgets(buf, len, fp);
 if (p != NULL)
 return 0; /* No error */
+ err = errno;
 #ifdef MS_WINDOWS
 /* In the case of a Ctrl+C or some other external event
 interrupting the operation:
@@ -78,7 +80,7 @@
 return -1; /* EOF */
 }
 #ifdef EINTR
- if (errno == EINTR) {
+ if (err == EINTR) {
 int s;
 #ifdef WITH_THREAD
 PyEval_RestoreThread(_PyOS_ReadlineTState);
-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list

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