[Python-checkins] cpython (merge 3.5 -> default): Issue #25717: Merge fstat() fix from 3.5

martin.panter python-checkins at python.org
Sat Dec 5 22:51:56 EST 2015


https://hg.python.org/cpython/rev/8c978cbe057c
changeset:   99470:8c978cbe057c
parent:      99464:0c9095566f21
parent:      99469:20ea12222b0e
user:        Martin Panter <vadmium+py at gmail.com>
date:        Sun Dec 06 03:29:54 2015 +0000
summary:
  Issue #25717: Merge fstat() fix from 3.5

files:
  Misc/NEWS            |   4 +++
  Modules/_io/fileio.c |  39 ++++++++++++++++++++++---------
  2 files changed, 31 insertions(+), 12 deletions(-)


diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -109,6 +109,10 @@
 Library
 -------
 
+- Issue #25717: Restore the previous behaviour of tolerating most fstat()
+  errors when opening files.  This was a regression in 3.5a1, and stopped
+  anonymous temporary files from working in special cases.
+
 - Issue #24903: Fix regression in number of arguments compileall accepts when
   '-d' is specified.  The check on the number of arguments has been dropped
   completely as it never worked correctly anyway.
diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c
--- a/Modules/_io/fileio.c
+++ b/Modules/_io/fileio.c
@@ -250,6 +250,7 @@
     int *atomic_flag_works = NULL;
 #endif
     struct _Py_stat_struct fdfstat;
+    int fstat_result;
     int async_err = 0;
 
     assert(PyFileIO_Check(self));
@@ -438,22 +439,36 @@
     }
 
     self->blksize = DEFAULT_BUFFER_SIZE;
-    if (_Py_fstat(self->fd, &fdfstat) < 0)
-        goto error;
+    Py_BEGIN_ALLOW_THREADS
+    fstat_result = _Py_fstat_noraise(self->fd, &fdfstat);
+    Py_END_ALLOW_THREADS
+    if (fstat_result < 0) {
+#ifdef MS_WINDOWS
+        if (GetLastError() == ERROR_INVALID_HANDLE) {
+            PyErr_SetFromWindowsErr(0);
+#else
+        if (errno == EBADF) {
+            PyErr_SetFromErrno(PyExc_OSError);
+#endif
+            goto error;
+        }
+    }
+    else {
 #if defined(S_ISDIR) && defined(EISDIR)
-    /* On Unix, open will succeed for directories.
-       In Python, there should be no file objects referring to
-       directories, so we need a check.  */
-    if (S_ISDIR(fdfstat.st_mode)) {
-        errno = EISDIR;
-        PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, nameobj);
-        goto error;
-    }
+        /* On Unix, open will succeed for directories.
+           In Python, there should be no file objects referring to
+           directories, so we need a check.  */
+        if (S_ISDIR(fdfstat.st_mode)) {
+            errno = EISDIR;
+            PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, nameobj);
+            goto error;
+        }
 #endif /* defined(S_ISDIR) */
 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
-    if (fdfstat.st_blksize > 1)
-        self->blksize = fdfstat.st_blksize;
+        if (fdfstat.st_blksize > 1)
+            self->blksize = fdfstat.st_blksize;
 #endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
+    }
 
 #if defined(MS_WINDOWS) || defined(__CYGWIN__)
     /* don't translate newlines (\r\n <=> \n) */

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list