diff --git a/paramiko/channel.py b/paramiko/channel.py index c1a2652..b331fbf 100644 --- a/paramiko/channel.py +++ b/paramiko/channel.py @@ -265,6 +265,19 @@ class Channel (object): self.transport._send_user_message(m) self._wait_for_event() + def exit_status_ready(self): + """ + Return true if the remote process has exited and returned an exit + status. You may use this to poll the process status if you don't + want to block in L{recv_exit_status}. Note that the server may not + return an exit status in some cases (like bad servers). + + @return: True if L{recv_exit_status} will return immediately + @rtype: bool + @since: 1.7.3 + """ + return self.closed or self.status_event.isSet() + def recv_exit_status(self): """ Return the exit status from the process on the server. This is diff --git a/tests/test_transport.py b/tests/test_transport.py index 894c69d..f46fda7 100644 --- a/tests/test_transport.py +++ b/tests/test_transport.py @@ -283,6 +283,7 @@ class TransportTest (unittest.TestCase): schan = self.ts.accept(1.0) chan.exec_command('yes') schan.send('Hello there.\n') + self.assert_(not chan.exit_status_ready()) # trigger an EOF schan.shutdown_read() schan.shutdown_write() @@ -292,6 +293,12 @@ class TransportTest (unittest.TestCase): f = chan.makefile() self.assertEquals('Hello there.\n', f.readline()) self.assertEquals('', f.readline()) + count = 0 + while not chan.exit_status_ready(): + time.sleep(0.1) + count += 1 + if count > 50: + raise Exception("timeout") self.assertEquals(23, chan.recv_exit_status()) chan.close()