summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Panter <vadmium+py@gmail.com>2015-12-06 03:15:05 (GMT)
committerMartin Panter <vadmium+py@gmail.com>2015-12-06 03:15:05 (GMT)
commit0bb62b12a3a13486c29092b38081391487119223 (patch)
treeb4df3a9178ba57e815488bc8ce9e7a85b2929ec8
parentc4b8979a2f6f78ba0bf835c3b8ba8ec671659204 (diff)
downloadcpython-0bb62b12a3a13486c29092b38081391487119223.zip
cpython-0bb62b12a3a13486c29092b38081391487119223.tar.gz
cpython-0bb62b12a3a13486c29092b38081391487119223.tar.bz2
Issue #25717: Tolerate fstat() failures in the FileIO constructor
This restores 3.4 behaviour, which was removed by revision 3b5279b5bfd1. The fstat() call fails with ENOENT for a Virtual Box shared folder filesystem if the file entry has been unlinked, e.g. for a temporary file.
-rw-r--r--Misc/NEWS4
-rw-r--r--Modules/_io/fileio.c39
2 files changed, 31 insertions, 12 deletions
diff --git a/Misc/NEWS b/Misc/NEWS
index 4399da2..f868037 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -22,6 +22,10 @@ Core and Builtins
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
index 12e37bb..5f88d58 100644
--- a/Modules/_io/fileio.c
+++ b/Modules/_io/fileio.c
@@ -250,6 +250,7 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
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 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
}
self->blksize = DEFAULT_BUFFER_SIZE;
- if (_Py_fstat(self->fd, &fdfstat) < 0)
- goto error;
-#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;
+ 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;
+ }
#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) */