summaryrefslogtreecommitdiffstats
path: root/Lib/subprocess.py
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@haypocalc.com>2011-04-05 11:13:08 (GMT)
committerVictor Stinner <victor.stinner@haypocalc.com>2011-04-05 11:13:08 (GMT)
commit7a8d08110c08941a5cf4a0785684c81ce0748dfa (patch)
treeff5a61ccdd32ba844ab69cfe8b3fce6859c49ee0 /Lib/subprocess.py
parent446c8d59c5353db220a263b345c7012ba5435654 (diff)
downloadcpython-7a8d08110c08941a5cf4a0785684c81ce0748dfa.zip
cpython-7a8d08110c08941a5cf4a0785684c81ce0748dfa.tar.gz
cpython-7a8d08110c08941a5cf4a0785684c81ce0748dfa.tar.bz2
Issue #11757: subprocess ensures that select() and poll() timeout >= 0
Diffstat (limited to 'Lib/subprocess.py')
-rw-r--r--Lib/subprocess.py33
1 files changed, 19 insertions, 14 deletions
diff --git a/Lib/subprocess.py b/Lib/subprocess.py
index 40f9636..2bff4b6 100644
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -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