[py-svn] r19114 - py/dist/py/process

dialtone at codespeak.net dialtone at codespeak.net
Fri Oct 28 13:07:11 CEST 2005


Author: dialtone
Date: Fri Oct 28 13:07:09 2005
New Revision: 19114

Modified:
   py/dist/py/process/cmdexec.py
Log:
fixing cmdexec to handle EINTR, EPIPE, EAGAIN and other errors that are in the
select spec.


Modified: py/dist/py/process/cmdexec.py
==============================================================================
--- py/dist/py/process/cmdexec.py	(original)
+++ py/dist/py/process/cmdexec.py	Fri Oct 28 13:07:09 2005
@@ -25,6 +25,7 @@
     """
     __tracebackhide__ = True
     import popen2
+    import errno
 
     #print "execing", cmd
     child = popen2.Popen3(cmd, 1)
@@ -36,8 +37,14 @@
     #     only the next three lines appear to prevent
     #     the read call from blocking infinitely.
     import fcntl
-    fcntl.fcntl(stdout, fcntl.F_SETFL, os.O_NONBLOCK)
-    fcntl.fcntl(stderr, fcntl.F_SETFL, os.O_NONBLOCK)
+    def set_non_block(fd):
+        flags = fcntl.fcntl(fd, fcntl.F_GETFL)
+        flags = flags | os.O_NONBLOCK
+        fcntl.fcntl(fd, fcntl.F_SETFL, flags)
+    set_non_block(stdout.fileno())
+    set_non_block(stderr.fileno())
+    #fcntl.fcntl(stdout, fcntl.F_SETFL, os.O_NONBLOCK)
+    #fcntl.fcntl(stderr, fcntl.F_SETFL, os.O_NONBLOCK)
 
     import select
     out, err = [], []
@@ -45,9 +52,29 @@
         r_list = filter(lambda x: x and not x.closed, [stdout, stderr])
         if not r_list:
             break
-        r_list = select.select(r_list, [], [])[0]
+        try:
+            r_list = select.select(r_list, [], [])[0]
+        except (select.error, IOError), se:
+            if se.args[0] == errno.EINTR:
+                continue
+            else:
+                raise
         for r  in r_list:
-            data = r.read()   # XXX see XXX above
+            try:
+                data = r.read()   # XXX see XXX above
+            except IOError, io:
+                if io.args[0] == errno.EAGAIN:
+                    continue
+                # Connection Lost
+                raise
+            except OSError, ose:
+                if ose.errno == errno.EPIPE:
+                    # Connection Lost
+                    raise
+                if ose.errno == errno.EAGAIN: # MacOS-X does this
+                    continue
+                raise
+
             if not data:
                 r.close()
                 continue



More information about the pytest-commit mailing list