summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_io/fileio.c39
1 files changed, 27 insertions, 12 deletions
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) */