You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
3.9 KiB
135 lines
3.9 KiB
diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c |
|
index 4a71a57ec0d..2b40ada195a 100644 |
|
--- a/Modules/_io/fileio.c |
|
+++ b/Modules/_io/fileio.c |
|
@@ -146,9 +146,15 @@ dircheck(fileio* self, PyObject *nameobj) |
|
{ |
|
#if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR) |
|
struct stat buf; |
|
+ int res; |
|
if (self->fd < 0) |
|
return 0; |
|
- if (fstat(self->fd, &buf) == 0 && S_ISDIR(buf.st_mode)) { |
|
+ |
|
+ Py_BEGIN_ALLOW_THREADS |
|
+ res = fstat(self->fd, &buf); |
|
+ Py_END_ALLOW_THREADS |
|
+ |
|
+ if (res == 0 && S_ISDIR(buf.st_mode)) { |
|
errno = EISDIR; |
|
PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, nameobj); |
|
return -1; |
|
@@ -162,17 +168,34 @@ check_fd(int fd) |
|
{ |
|
#if defined(HAVE_FSTAT) |
|
struct stat buf; |
|
- if (!_PyVerify_fd(fd) || (fstat(fd, &buf) < 0 && errno == EBADF)) { |
|
- PyObject *exc; |
|
- char *msg = strerror(EBADF); |
|
- exc = PyObject_CallFunction(PyExc_OSError, "(is)", |
|
- EBADF, msg); |
|
- PyErr_SetObject(PyExc_OSError, exc); |
|
- Py_XDECREF(exc); |
|
- return -1; |
|
+ int res; |
|
+ PyObject *exc; |
|
+ char *msg; |
|
+ |
|
+ if (!_PyVerify_fd(fd)) { |
|
+ goto badfd; |
|
} |
|
-#endif |
|
+ |
|
+ Py_BEGIN_ALLOW_THREADS |
|
+ res = fstat(fd, &buf); |
|
+ Py_END_ALLOW_THREADS |
|
+ |
|
+ if (res < 0 && errno == EBADF) { |
|
+ goto badfd; |
|
+ } |
|
+ |
|
return 0; |
|
+ |
|
+badfd: |
|
+ msg = strerror(EBADF); |
|
+ exc = PyObject_CallFunction(PyExc_OSError, "(is)", |
|
+ EBADF, msg); |
|
+ PyErr_SetObject(PyExc_OSError, exc); |
|
+ Py_XDECREF(exc); |
|
+ return -1; |
|
+#else |
|
+ return 0; |
|
+#endif |
|
} |
|
|
|
|
|
@@ -519,9 +542,19 @@ new_buffersize(fileio *self, size_t currentsize) |
|
#ifdef HAVE_FSTAT |
|
off_t pos, end; |
|
struct stat st; |
|
- if (fstat(self->fd, &st) == 0) { |
|
+ int res; |
|
+ |
|
+ Py_BEGIN_ALLOW_THREADS |
|
+ res = fstat(self->fd, &st); |
|
+ Py_END_ALLOW_THREADS |
|
+ |
|
+ if (res == 0) { |
|
end = st.st_size; |
|
+ |
|
+ Py_BEGIN_ALLOW_THREADS |
|
pos = lseek(self->fd, 0L, SEEK_CUR); |
|
+ Py_END_ALLOW_THREADS |
|
+ |
|
/* Files claiming a size smaller than SMALLCHUNK may |
|
actually be streaming pseudo-files. In this case, we |
|
apply the more aggressive algorithm below. |
|
diff --git a/Objects/fileobject.c b/Objects/fileobject.c |
|
index 2f63c374d1e..8d1c5812f0d 100644 |
|
--- a/Objects/fileobject.c |
|
+++ b/Objects/fileobject.c |
|
@@ -121,10 +121,15 @@ dircheck(PyFileObject* f) |
|
{ |
|
#if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR) |
|
struct stat buf; |
|
+ int res; |
|
if (f->f_fp == NULL) |
|
return f; |
|
- if (fstat(fileno(f->f_fp), &buf) == 0 && |
|
- S_ISDIR(buf.st_mode)) { |
|
+ |
|
+ Py_BEGIN_ALLOW_THREADS |
|
+ res = fstat(fileno(f->f_fp), &buf); |
|
+ Py_END_ALLOW_THREADS |
|
+ |
|
+ if (res == 0 && S_ISDIR(buf.st_mode)) { |
|
char *msg = strerror(EISDIR); |
|
PyObject *exc = PyObject_CallFunction(PyExc_IOError, "(isO)", |
|
EISDIR, msg, f->f_name); |
|
@@ -1010,7 +1015,13 @@ new_buffersize(PyFileObject *f, size_t currentsize) |
|
#ifdef HAVE_FSTAT |
|
off_t pos, end; |
|
struct stat st; |
|
- if (fstat(fileno(f->f_fp), &st) == 0) { |
|
+ int res; |
|
+ |
|
+ Py_BEGIN_ALLOW_THREADS |
|
+ res = fstat(fileno(f->f_fp), &st); |
|
+ Py_END_ALLOW_THREADS |
|
+ |
|
+ if (res == 0) { |
|
end = st.st_size; |
|
/* The following is not a bug: we really need to call lseek() |
|
*and* ftell(). The reason is that some stdio libraries |
|
@@ -1021,7 +1032,11 @@ new_buffersize(PyFileObject *f, size_t currentsize) |
|
works. We can't use the lseek() value either, because we |
|
need to take the amount of buffered data into account. |
|
(Yet another reason why stdio stinks. :-) */ |
|
+ |
|
+ Py_BEGIN_ALLOW_THREADS |
|
pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR); |
|
+ Py_END_ALLOW_THREADS |
|
+ |
|
if (pos >= 0) { |
|
pos = ftell(f->f_fp); |
|
}
|
|
|