churchyard / rpms / python2

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