diff --git a/paramiko/channel.py b/paramiko/channel.py index 052e487..133a2fb 100644 --- a/paramiko/channel.py +++ b/paramiko/channel.py @@ -632,6 +632,27 @@ class Channel (object): return out + def send_ready(self): + """ + Returns true if data can be written to this channel without blocking. + This means the channel is either closed (so any write attempt would + return immediately) or there is at least one byte of space in the + outbound buffer. If there is at least one byte of space in the + outbound buffer, a L{send} call will succeed immediately and return + the number of bytes actually written. + + @return: C{True} if a L{send} call on this channel would immediately + succeed or fail + @rtype: boolean + """ + self.lock.acquire() + try: + if self.closed or self.eof_sent: + return True + return self.out_window_size > 0 + finally: + self.lock.release() + def send(self, s): """ Send data to the channel. Returns the number of bytes sent, or 0 if @@ -640,9 +661,9 @@ class Channel (object): transmitted, the application needs to attempt delivery of the remaining data. - @param s: data to send. + @param s: data to send @type s: str - @return: number of bytes actually sent. + @return: number of bytes actually sent @rtype: int @raise socket.timeout: if no data could be sent before the timeout set diff --git a/tests/test_transport.py b/tests/test_transport.py index 6aaf738..bae960e 100644 --- a/tests/test_transport.py +++ b/tests/test_transport.py @@ -677,3 +677,26 @@ class TransportTest (unittest.TestCase): schan.close() chan.close() + + def test_L_send_ready(self): + """ + verify that send_ready() indicates when a send would not block. + """ + self.setup_test_server() + chan = self.tc.open_session() + chan.invoke_shell() + schan = self.ts.accept(1.0) + + self.assertEquals(chan.send_ready(), True) + total = 0 + K = '*' * 1024 + while total < 1024 * 1024: + chan.send(K) + total += len(K) + if not chan.send_ready(): + break + self.assert_(total < 1024 * 1024) + + schan.close() + chan.close() + self.assertEquals(chan.send_read(), True)