mirror of
https://github.com/python/cpython
synced 2026-09-29 12:10:30 +03:00
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.
This commit is contained in:
parent
c4b8979a2f
commit
0bb62b12a3
2 changed files with 31 additions and 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.
|
||||
|
|
|
|||
|
|
@ -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) */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue