Skip to content

Commit

Permalink
bug 413850: patch from patrick mcnerthney. fix race between a server …
Browse files Browse the repository at this point in the history
…responding to an event and closing the channel.
  • Loading branch information
Robey Pointer committed Nov 1, 2009
1 parent e80cec7 commit a60c69c
Showing 1 changed file with 19 additions and 12 deletions.
31 changes: 19 additions & 12 deletions paramiko/channel.py
Expand Up @@ -90,6 +90,7 @@ def __init__(self, chanid):
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
Expand Down Expand Up @@ -152,7 +153,7 @@ def get_pty(self, term='vt100', width=80, height=24):
# 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()

Expand All @@ -179,7 +180,7 @@ def invoke_shell(self):
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()

Expand Down Expand Up @@ -207,7 +208,7 @@ def exec_command(self, command):
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()

Expand All @@ -234,7 +235,7 @@ def invoke_subsystem(self, subsystem):
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()

Expand All @@ -261,7 +262,7 @@ def resize_pty(self, width=80, height=24):
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()

Expand Down Expand Up @@ -374,7 +375,7 @@ def request_x11(self, screen_number=0, auth_protocol=None, auth_cookie=None,
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)
Expand Down Expand Up @@ -917,9 +918,10 @@ def _set_remote_channel(self, chanid, window_size, max_packet_size):
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

Expand Down Expand Up @@ -1067,14 +1069,19 @@ def _handle_close(self, m):
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.
Expand Down

0 comments on commit a60c69c

Please sign in to comment.