# HG changeset patch # Parent 374f501f4567b7595f2ad7798aa09afa2456bb28 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. diff -r 374f501f4567 Modules/_io/fileio.c --- a/Modules/_io/fileio.c Sat Sep 12 17:36:44 2015 +0100 +++ b/Modules/_io/fileio.c Tue Nov 24 22:09:40 2015 +0000 @@ -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) */