churchyard / rpms / python2

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