return (stdout, stderr)
- def _communicate_with_poll(self, input):
++ def _save_input(self, input):
++ # This method is called from the _communicate_with_*() methods
++ # so that if we time out while communicating, we can continue
++ # sending input if we retry.
++ if self.stdin and self._input is None:
++ self._input_offset = 0
++ self._input = input
++ if self.universal_newlines and input is not None:
++ self._input = self._input.encode(self.stdin.encoding)
++
++
+ def _communicate_with_poll(self, input, endtime, orig_timeout):
stdout = None # Return
stderr = None # Return
- fd2file = {}
- fd2output = {}
+
+ if not self._communication_started:
+ self._fd2file = {}
poller = select.poll()
def register_and_append(file_obj, eventmask):
select_POLLIN_POLLPRI = select.POLLIN | select.POLLPRI
if self.stdout:
register_and_append(self.stdout, select_POLLIN_POLLPRI)
- fd2output[self.stdout.fileno()] = stdout = []
+ stdout = self._fd2output[self.stdout.fileno()]
if self.stderr:
register_and_append(self.stderr, select_POLLIN_POLLPRI)
- fd2output[self.stderr.fileno()] = stderr = []
+ stderr = self._fd2output[self.stderr.fileno()]
- # Save the input here so that if we time out while communicating,
- # we can continue sending input if we retry.
- if self.stdin and self._input is None:
- self._input_offset = 0
- self._input = input
- if self.universal_newlines:
- self._input = self._input.encode(self.stdin.encoding)
- input_offset = 0
- while fd2file:
++ self._save_input(input)
+
+ 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()
+ ready = poller.poll(timeout)
except select.error as e:
if e.args[0] == errno.EINTR:
continue
return (stdout, stderr)
- def _communicate_with_select(self, input):
- read_set = []
- write_set = []
+ def _communicate_with_select(self, input, endtime, orig_timeout):
+ if not self._communication_started:
+ self._read_set = []
+ self._write_set = []
+ if self.stdin and input:
+ self._write_set.append(self.stdin)
+ if self.stdout:
+ self._read_set.append(self.stdout)
+ if self.stderr:
+ self._read_set.append(self.stderr)
+
- if self.stdin and self._input is None:
- self._input_offset = 0
- self._input = input
- if self.universal_newlines:
- self._input = self._input.encode(self.stdin.encoding)
++ self._save_input(input)
+
stdout = None # Return
stderr = None # Return