summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobey Pointer <robey@lag.net>2004-11-01 03:54:01 +0000
committerRobey Pointer <robey@lag.net>2004-11-01 03:54:01 +0000
commit6eb59a2b533fa61566ff01865a784b6c720db51b (patch)
tree3ab688fd35c7d74dc74ad9232b0e4ffb626872a4
parentd7caa20213130445f5631e7b0aebfc5fb1507ec6 (diff)
[project @ Arch-1:robey@lag.net--2003-public%secsh--dev--1.0--patch-98]
don't unlink a Channel until the server closes it too when close()'ing a Channel, don't immediately unlink it from the Transport. instead, wait for the server to send a close message. this should fix a bug where doing close() on an EOF'd channel would cause the entire transport to be killed, because the server would send an 'exit-status' and 'close' message for a channel that we no longer had a record of.
-rw-r--r--paramiko/channel.py31
1 files changed, 16 insertions, 15 deletions
diff --git a/paramiko/channel.py b/paramiko/channel.py
index cb22a6b2..9b7384e3 100644
--- a/paramiko/channel.py
+++ b/paramiko/channel.py
@@ -359,19 +359,21 @@ class Channel (object):
is flushed). Channels are automatically closed when they are garbage-
collected, or when their L{Transport} is closed.
"""
+ self.lock.acquire()
try:
- self.lock.acquire()
- if self.active and not self.closed:
- try:
- self._send_eof()
- m = Message()
- m.add_byte(chr(MSG_CHANNEL_CLOSE))
- m.add_int(self.remote_chanid)
- self.transport._send_user_message(m)
- except EOFError:
- pass
- self._set_closed()
- self.transport._unlink_channel(self.chanid)
+ if not self.active or self.closed:
+ return
+ try:
+ self._send_eof()
+ m = Message()
+ m.add_byte(chr(MSG_CHANNEL_CLOSE))
+ m.add_int(self.remote_chanid)
+ self.transport._send_user_message(m)
+ except EOFError:
+ pass
+ self._set_closed()
+ # can't unlink from the Transport yet -- the remote side may still
+ # try to send meta-data (exit-status, etc)
finally:
self.lock.release()
@@ -722,10 +724,9 @@ class Channel (object):
def _handle_close(self, m):
self.close()
+ self.lock.acquire()
try:
- self.lock.acquire()
- self.in_buffer_cv.notifyAll()
- self.out_buffer_cv.notifyAll()
+ self.transport._unlink_channel(self.chanid)
if self.pipe_wfd != None:
os.close(self.pipe_wfd)
self.pipe_wfd = None