Commit 0bb62b12 authored by Martin Panter's avatar Martin Panter

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.
parent c4b8979a
...@@ -22,6 +22,10 @@ Core and Builtins ...@@ -22,6 +22,10 @@ Core and Builtins
Library 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 - Issue #24903: Fix regression in number of arguments compileall accepts when
'-d' is specified. The check on the number of arguments has been dropped '-d' is specified. The check on the number of arguments has been dropped
completely as it never worked correctly anyway. completely as it never worked correctly anyway.
......
...@@ -250,6 +250,7 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, ...@@ -250,6 +250,7 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
int *atomic_flag_works = NULL; int *atomic_flag_works = NULL;
#endif #endif
struct _Py_stat_struct fdfstat; struct _Py_stat_struct fdfstat;
int fstat_result;
int async_err = 0; int async_err = 0;
assert(PyFileIO_Check(self)); assert(PyFileIO_Check(self));
...@@ -438,22 +439,36 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, ...@@ -438,22 +439,36 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
} }
self->blksize = DEFAULT_BUFFER_SIZE; self->blksize = DEFAULT_BUFFER_SIZE;
if (_Py_fstat(self->fd, &fdfstat) < 0) Py_BEGIN_ALLOW_THREADS
goto error; fstat_result = _Py_fstat_noraise(self->fd, &fdfstat);
#if defined(S_ISDIR) && defined(EISDIR) Py_END_ALLOW_THREADS
/* On Unix, open will succeed for directories. if (fstat_result < 0) {
In Python, there should be no file objects referring to #ifdef MS_WINDOWS
directories, so we need a check. */ if (GetLastError() == ERROR_INVALID_HANDLE) {
if (S_ISDIR(fdfstat.st_mode)) { PyErr_SetFromWindowsErr(0);
errno = EISDIR; #else
PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, nameobj); if (errno == EBADF) {
goto error; 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) */ #endif /* defined(S_ISDIR) */
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
if (fdfstat.st_blksize > 1) if (fdfstat.st_blksize > 1)
self->blksize = fdfstat.st_blksize; self->blksize = fdfstat.st_blksize;
#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */ #endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
}
#if defined(MS_WINDOWS) || defined(__CYGWIN__) #if defined(MS_WINDOWS) || defined(__CYGWIN__)
/* don't translate newlines (\r\n <=> \n) */ /* don't translate newlines (\r\n <=> \n) */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment