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