summaryrefslogtreecommitdiff
path: root/paramiko
diff options
context:
space:
mode:
authorRobey Pointer <robey@twitter.com>2009-10-31 17:55:52 -0700
committerRobey Pointer <robey@twitter.com>2009-10-31 17:55:52 -0700
commita60c69c81caefa51f75c2b68356e59e1e77bc63a (patch)
treec75caf19fe1f22ed1d1f725bb89c7bf934138d16 /paramiko
parente80cec73b63ba5a333acd3b1d4e35a69bf609b0f (diff)
downloadparamiko-a60c69c81caefa51f75c2b68356e59e1e77bc63a.tar.gz
bug 413850: patch from patrick mcnerthney. fix race between a server responding to an event and closing the channel.
Diffstat (limited to 'paramiko')
-rw-r--r--paramiko/channel.py31
1 files changed, 19 insertions, 12 deletions
diff --git a/paramiko/channel.py b/paramiko/channel.py
index 0798d73b..4694eef3 100644
--- a/paramiko/channel.py
+++ b/paramiko/channel.py
@@ -90,6 +90,7 @@ class Channel (object):
self.logger = util.get_logger('paramiko.transport')
self._pipe = None
self.event = threading.Event()
+ self.event_ready = False
self.combine_stderr = False
self.exit_status = -1
self.origin_addr = None
@@ -152,7 +153,7 @@ class Channel (object):
# pixel height, width (usually useless)
m.add_int(0).add_int(0)
m.add_string('')
- self.event.clear()
+ self._event_pending()
self.transport._send_user_message(m)
self._wait_for_event()
@@ -179,7 +180,7 @@ class Channel (object):
m.add_int(self.remote_chanid)
m.add_string('shell')
m.add_boolean(1)
- self.event.clear()
+ self._event_pending()
self.transport._send_user_message(m)
self._wait_for_event()
@@ -207,7 +208,7 @@ class Channel (object):
m.add_string('exec')
m.add_boolean(True)
m.add_string(command)
- self.event.clear()
+ self._event_pending()
self.transport._send_user_message(m)
self._wait_for_event()
@@ -234,7 +235,7 @@ class Channel (object):
m.add_string('subsystem')
m.add_boolean(True)
m.add_string(subsystem)
- self.event.clear()
+ self._event_pending()
self.transport._send_user_message(m)
self._wait_for_event()
@@ -261,7 +262,7 @@ class Channel (object):
m.add_int(width)
m.add_int(height)
m.add_int(0).add_int(0)
- self.event.clear()
+ self._event_pending()
self.transport._send_user_message(m)
self._wait_for_event()
@@ -374,7 +375,7 @@ class Channel (object):
m.add_string(auth_protocol)
m.add_string(auth_cookie)
m.add_int(screen_number)
- self.event.clear()
+ self._event_pending()
self.transport._send_user_message(m)
self._wait_for_event()
self.transport._set_x11_handler(handler)
@@ -917,9 +918,10 @@ class Channel (object):
self.out_max_packet_size = max(max_packet_size, MIN_PACKET_SIZE)
self.active = 1
self._log(DEBUG, 'Max packet out: %d bytes' % max_packet_size)
-
+
def _request_success(self, m):
self._log(DEBUG, 'Sesch channel %d request ok' % self.chanid)
+ self.event_ready = True
self.event.set()
return
@@ -1067,14 +1069,19 @@ class Channel (object):
def _log(self, level, msg, *args):
self.logger.log(level, "[chan " + self._name + "] " + msg, *args)
+ def _event_pending(self):
+ self.event.clear()
+ self.event_ready = False
+
def _wait_for_event(self):
self.event.wait()
assert self.event.isSet()
- if self.closed:
- e = self.transport.get_exception()
- if e is None:
- e = SSHException('Channel closed.')
- raise e
+ if self.event_ready:
+ return
+ e = self.transport.get_exception()
+ if e is None:
+ e = SSHException('Channel closed.')
+ raise e
def _set_closed(self):
# you are holding the lock.