summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJohn Morrissey <jwm@horde.net>2014-12-12 13:23:25 -0500
committerJeff Forcier <jeff@bitprophet.org>2014-12-18 13:49:35 -0800
commitb4e9dc3ab96e699a38a71aa6bb46337a596312d5 (patch)
treef7838a11341d2bc2b986d2c3cfe7f63976fef489
parentfc59b7db5d995d03cc502be906f6fab8e948228c (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.py19
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