summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobey Pointer <robey@lag.net>2005-02-28 07:14:11 +0000
committerRobey Pointer <robey@lag.net>2005-02-28 07:14:11 +0000
commit4b8a9d3b7af4f80d3c4fc0d541c5425a063471a6 (patch)
treedd3ec572777d3ae5baa0792fc2f26b5270cc01aa
parent8ee26cd41246ee90418c148a8a5cf9bf78f09e45 (diff)
[project @ Arch-1:robey@lag.net--2003-public%secsh--dev--1.0--patch-150]
when combining stderr with stdout on a channel, merge the buffers too when turning on combine-stderr mode on a channel, grab the channel lock and feed any existing stderr buffer into the normal buffer. this should help applications (and my unit tests) avoid races between data coming in over stderr and setting combine-stderr. _send_eof is now slightly safer too, although i don't think that really fixed anything. it just makes me feel better.
-rw-r--r--paramiko/channel.py28
1 files changed, 22 insertions, 6 deletions
diff --git a/paramiko/channel.py b/paramiko/channel.py
index 0072a490..41df4d9c 100644
--- a/paramiko/channel.py
+++ b/paramiko/channel.py
@@ -371,8 +371,19 @@ class Channel (object):
@since: 1.1
"""
- old = self.combine_stderr
- self.combine_stderr = combine
+ data = ''
+ self.lock.acquire()
+ try:
+ old = self.combine_stderr
+ self.combine_stderr = combine
+ if combine and not old:
+ # copy old stderr buffer into primary buffer
+ data = self.in_stderr_buffer
+ self.in_stderr_buffer = ''
+ finally:
+ self.lock.release()
+ if len(data) > 0:
+ self._feed(data)
return old
@@ -762,8 +773,8 @@ class Channel (object):
used to simulate an open FD, but I haven't figured out how to make
pipes enter non-blocking mode on Windows yet.
"""
+ self.lock.acquire()
try:
- self.lock.acquire()
if self.pipe_rfd != None:
return self.pipe_rfd
# create the pipe and feed in any existing data
@@ -793,7 +804,11 @@ class Channel (object):
# feign "read" shutdown
self.eof_received = 1
if (how == 1) or (how == 2):
- self._send_eof()
+ self.lock.acquire()
+ try:
+ self._send_eof()
+ finally:
+ self.lock.release()
def shutdown_read(self):
"""
@@ -963,7 +978,7 @@ class Channel (object):
self.lock.acquire()
try:
if not self.eof_received:
- self.eof_received = 1
+ self.eof_received = True
self.in_buffer_cv.notifyAll()
self.in_stderr_buffer_cv.notifyAll()
if self.pipe_wfd != None:
@@ -999,13 +1014,14 @@ class Channel (object):
self.out_buffer_cv.notifyAll()
def _send_eof(self):
+ # you are holding the lock.
if self.eof_sent:
return
m = Message()
m.add_byte(chr(MSG_CHANNEL_EOF))
m.add_int(self.remote_chanid)
self.transport._send_user_message(m)
- self.eof_sent = 1
+ self.eof_sent = True
self._log(DEBUG, 'EOF sent')
return