diff options
author | Martin Panter <vadmium+py@gmail.com> | 2015-12-06 03:15:05 (GMT) |
---|---|---|
committer | Martin Panter <vadmium+py@gmail.com> | 2015-12-06 03:15:05 (GMT) |
commit | 0bb62b12a3a13486c29092b38081391487119223 (patch) | |
tree | b4df3a9178ba57e815488bc8ce9e7a85b2929ec8 | |
parent | c4b8979a2f6f78ba0bf835c3b8ba8ec671659204 (diff) | |
download | cpython-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/NEWS | 4 | ||||
-rw-r--r-- | Modules/_io/fileio.c | 39 |
2 files changed, 31 insertions, 12 deletions
@@ -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) */ |