mirror of
https://github.com/python/cpython.git
synced 2025-10-17 12:18:23 +00:00
Issue #11757: subprocess ensures that select() and poll() timeout >= 0
This commit is contained in:
parent
446c8d59c5
commit
7a8d08110c
1 changed files with 19 additions and 14 deletions
|
@ -817,15 +817,10 @@ class Popen(object):
|
||||||
if self._communication_started and input:
|
if self._communication_started and input:
|
||||||
raise ValueError("Cannot send input after starting communication")
|
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
|
# Optimization: If we are not worried about timeouts, we haven't
|
||||||
# started communicating, and we have one or zero pipes, using select()
|
# started communicating, and we have one or zero pipes, using select()
|
||||||
# or threads is unnecessary.
|
# 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):
|
[self.stdin, self.stdout, self.stderr].count(None) >= 2):
|
||||||
stdout = None
|
stdout = None
|
||||||
stderr = None
|
stderr = None
|
||||||
|
@ -840,14 +835,18 @@ class Popen(object):
|
||||||
stderr = self.stderr.read()
|
stderr = self.stderr.read()
|
||||||
self.stderr.close()
|
self.stderr.close()
|
||||||
self.wait()
|
self.wait()
|
||||||
return (stdout, stderr)
|
else:
|
||||||
|
if timeout is not None:
|
||||||
|
endtime = time.time() + timeout
|
||||||
|
else:
|
||||||
|
endtime = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
stdout, stderr = self._communicate(input, endtime, timeout)
|
stdout, stderr = self._communicate(input, endtime, timeout)
|
||||||
finally:
|
finally:
|
||||||
self._communication_started = True
|
self._communication_started = True
|
||||||
|
|
||||||
sts = self.wait(timeout=self._remaining_time(endtime))
|
sts = self.wait(timeout=self._remaining_time(endtime))
|
||||||
|
|
||||||
return (stdout, stderr)
|
return (stdout, stderr)
|
||||||
|
|
||||||
|
@ -1604,8 +1603,11 @@ class Popen(object):
|
||||||
self._input = self._input.encode(self.stdin.encoding)
|
self._input = self._input.encode(self.stdin.encoding)
|
||||||
|
|
||||||
while self._fd2file:
|
while self._fd2file:
|
||||||
|
timeout = self._remaining_time(endtime)
|
||||||
|
if timeout is not None and timeout < 0:
|
||||||
|
raise TimeoutExpired(self.args, orig_timeout)
|
||||||
try:
|
try:
|
||||||
ready = poller.poll(self._remaining_time(endtime))
|
ready = poller.poll(timeout)
|
||||||
except select.error as e:
|
except select.error as e:
|
||||||
if e.args[0] == errno.EINTR:
|
if e.args[0] == errno.EINTR:
|
||||||
continue
|
continue
|
||||||
|
@ -1664,10 +1666,13 @@ class Popen(object):
|
||||||
stderr = self._stderr_buff
|
stderr = self._stderr_buff
|
||||||
|
|
||||||
while self._read_set or self._write_set:
|
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:
|
try:
|
||||||
(rlist, wlist, xlist) = \
|
(rlist, wlist, xlist) = \
|
||||||
select.select(self._read_set, self._write_set, [],
|
select.select(self._read_set, self._write_set, [],
|
||||||
self._remaining_time(endtime))
|
timeout)
|
||||||
except select.error as e:
|
except select.error as e:
|
||||||
if e.args[0] == errno.EINTR:
|
if e.args[0] == errno.EINTR:
|
||||||
continue
|
continue
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue