changeset: 99470:8c978cbe057c parent: 99464:0c9095566f21 parent: 99469:20ea12222b0e user: Martin Panter date: Sun Dec 06 03:29:54 2015 +0000 files: Misc/NEWS description: Issue #25717: Merge fstat() fix from 3.5 diff -r 0c9095566f21 -r 8c978cbe057c Misc/NEWS --- a/Misc/NEWS Sat Dec 05 10:18:25 2015 +0000 +++ b/Misc/NEWS Sun Dec 06 03:29:54 2015 +0000 @@ -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 -r 0c9095566f21 -r 8c978cbe057c Modules/_io/fileio.c --- a/Modules/_io/fileio.c Sat Dec 05 10:18:25 2015 +0000 +++ b/Modules/_io/fileio.c Sun Dec 06 03:29:54 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) */