]> granicus.if.org Git - python/commitdiff
Issue #11757: subprocess ensures that select() and poll() timeout >= 0
authorVictor Stinner <victor.stinner@haypocalc.com>
Tue, 5 Apr 2011 11:13:08 +0000 (13:13 +0200)
committerVictor Stinner <victor.stinner@haypocalc.com>
Tue, 5 Apr 2011 11:13:08 +0000 (13:13 +0200)
Lib/subprocess.py

index 40f9636ff9624c2fd528f0a63e83e171606aa38a..2bff4b6ecf4a917be477c99dc392c941b30e5641 100644 (file)
@@ -817,15 +817,10 @@ class Popen(object):
         if self._communication_started and input:
             raise ValueError("Cannot send input after starting communication")
 
-        if timeout is not None:
-            endtime = time.time() + timeout
-        else:
-            endtime = None
-
         # Optimization: If we are not worried about timeouts, we haven't
         # started communicating, and we have one or zero pipes, using select()
         # or threads is unnecessary.
-        if (endtime is None and not self._communication_started and
+        if (timeout is None and not self._communication_started and
             [self.stdin, self.stdout, self.stderr].count(None) >= 2):
             stdout = None
             stderr = None
@@ -840,14 +835,18 @@ class Popen(object):
                 stderr = self.stderr.read()
                 self.stderr.close()
             self.wait()
-            return (stdout, stderr)
+        else:
+            if timeout is not None:
+                endtime = time.time() + timeout
+            else:
+                endtime = None
 
-        try:
-            stdout, stderr = self._communicate(input, endtime, timeout)
-        finally:
-            self._communication_started = True
+            try:
+                stdout, stderr = self._communicate(input, endtime, timeout)
+            finally:
+                self._communication_started = True
 
-        sts = self.wait(timeout=self._remaining_time(endtime))
+            sts = self.wait(timeout=self._remaining_time(endtime))
 
         return (stdout, stderr)
 
@@ -1604,8 +1603,11 @@ class Popen(object):
                     self._input = self._input.encode(self.stdin.encoding)
 
             while self._fd2file:
+                timeout = self._remaining_time(endtime)
+                if timeout is not None and timeout < 0:
+                    raise TimeoutExpired(self.args, orig_timeout)
                 try:
-                    ready = poller.poll(self._remaining_time(endtime))
+                    ready = poller.poll(timeout)
                 except select.error as e:
                     if e.args[0] == errno.EINTR:
                         continue
@@ -1664,10 +1666,13 @@ class Popen(object):
                 stderr = self._stderr_buff
 
             while self._read_set or self._write_set:
+                timeout = self._remaining_time(endtime)
+                if timeout is not None and timeout < 0:
+                    raise TimeoutExpired(self.args, orig_timeout)
                 try:
                     (rlist, wlist, xlist) = \
                         select.select(self._read_set, self._write_set, [],
-                                      self._remaining_time(endtime))
+                                      timeout)
                 except select.error as e:
                     if e.args[0] == errno.EINTR:
                         continue