diff options
author | John Morrissey <jwm@horde.net> | 2014-12-12 13:23:25 -0500 |
---|---|---|
committer | Jeff Forcier <jeff@bitprophet.org> | 2014-12-18 13:49:35 -0800 |
commit | b4e9dc3ab96e699a38a71aa6bb46337a596312d5 (patch) | |
tree | f7838a11341d2bc2b986d2c3cfe7f63976fef489 | |
parent | fc59b7db5d995d03cc502be906f6fab8e948228c (diff) |
read in >1 byte chunks, and set a useful timeout on select()
this way, we're not rolling this loop over nearly as much, while still
preserving the overall timeout semantics
-rw-r--r-- | paramiko/proxy.py | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/paramiko/proxy.py b/paramiko/proxy.py index 8959b244..25666be5 100644 --- a/paramiko/proxy.py +++ b/paramiko/proxy.py @@ -24,6 +24,7 @@ import signal from subprocess import Popen, PIPE from select import select import socket +import time from paramiko.ssh_exception import ProxyCommandFailure @@ -76,20 +77,24 @@ class ProxyCommand(object): :return: the length of the read content, as an `int` """ try: - start = datetime.now() + start = time.time() while len(self.buffer) < size: + select_timeout = None if self.timeout is not None: - elapsed = (datetime.now() - start).microseconds - timeout = self.timeout * 1000 * 1000 # to microseconds - if elapsed >= timeout: + elapsed = (time.time() - start) + if elapsed >= self.timeout: raise socket.timeout() - r, w, x = select([self.process.stdout], [], [], 0.0) + select_timeout = self.timeout - elapsed + + r, w, x = select( + [self.process.stdout], [], [], select_timeout) if r and r[0] == self.process.stdout: - b = os.read(self.process.stdout.fileno(), 1) + b = os.read( + self.process.stdout.fileno(), size - len(self.buffer)) # Store in class-level buffer for persistence across # timeouts; this makes us act more like a real socket # (where timeouts don't actually drop data.) - self.buffer.append(b) + self.buffer.extend(b) result = ''.join(self.buffer) self.buffer = [] return result |