From edc9eaf4f2993858b10594dbda3d321c45444417 Mon Sep 17 00:00:00 2001 From: Phillip Heller Date: Tue, 20 Nov 2012 16:10:16 -0500 Subject: [PATCH] Added width_pixel and height_pixel parameters to Channel.get_pty() and resize_pty(), and Client.invoke_shell(). Perhaps useless, but more RFC compliant. Updated methods to include these parameters in server messages. Adjusted Channel.resize_pty() to neither request nor wait for a response, as per RFC 4254 6.7 (A response SHOULD NOT be sent to this message.) This is necessary as certain hosts have been observed to not acknowledge this type of channel request (Cisco IOS XR), which causes paramiko to end the session. --- paramiko/channel.py | 24 ++++++++++++++++-------- paramiko/client.py | 9 +++++++-- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/paramiko/channel.py b/paramiko/channel.py index 534f8d7..0c603c6 100644 --- a/paramiko/channel.py +++ b/paramiko/channel.py @@ -122,7 +122,8 @@ class Channel (object): out += '>' return out - def get_pty(self, term='vt100', width=80, height=24): + def get_pty(self, term='vt100', width=80, height=24, width_pixels=0, + height_pixels=0): """ Request a pseudo-terminal from the server. This is usually used right after creating a client channel, to ask the server to provide some @@ -136,6 +137,10 @@ class Channel (object): @type width: int @param height: height (in characters) of the terminal screen @type height: int + @param width_pixels: width (in pixels) of the terminal screen + @type width_pixels: int + @param height_pixels: height (in pixels) of the terminal screen + @type height_pixels: int @raise SSHException: if the request was rejected or the channel was closed @@ -150,8 +155,8 @@ class Channel (object): m.add_string(term) m.add_int(width) m.add_int(height) - # pixel height, width (usually useless) - m.add_int(0).add_int(0) + m.add_int(width_pixels) + m.add_int(height_pixels) m.add_string('') self._event_pending() self.transport._send_user_message(m) @@ -239,7 +244,7 @@ class Channel (object): self.transport._send_user_message(m) self._wait_for_event() - def resize_pty(self, width=80, height=24): + def resize_pty(self, width=80, height=24, width_pixels=0, height_pixels=0): """ Resize the pseudo-terminal. This can be used to change the width and height of the terminal emulation created in a previous L{get_pty} call. @@ -248,6 +253,10 @@ class Channel (object): @type width: int @param height: new height (in characters) of the terminal screen @type height: int + @param width_pixels: new width (in pixels) of the terminal screen + @type width_pixels: int + @param height_pixels: new height (in pixels) of the terminal screen + @type height_pixels: int @raise SSHException: if the request was rejected or the channel was closed @@ -258,13 +267,12 @@ class Channel (object): m.add_byte(chr(MSG_CHANNEL_REQUEST)) m.add_int(self.remote_chanid) m.add_string('window-change') - m.add_boolean(True) + m.add_boolean(False) m.add_int(width) m.add_int(height) - m.add_int(0).add_int(0) - self._event_pending() + m.add_int(width_pixels) + m.add_int(height_pixels) self.transport._send_user_message(m) - self._wait_for_event() def exit_status_ready(self): """ diff --git a/paramiko/client.py b/paramiko/client.py index f863806..5b71958 100644 --- a/paramiko/client.py +++ b/paramiko/client.py @@ -377,7 +377,8 @@ class SSHClient (object): stderr = chan.makefile_stderr('rb', bufsize) return stdin, stdout, stderr - def invoke_shell(self, term='vt100', width=80, height=24): + def invoke_shell(self, term='vt100', width=80, height=24, width_pixels=0, + height_pixels=0): """ Start an interactive shell session on the SSH server. A new L{Channel} is opened and connected to a pseudo-terminal using the requested @@ -389,13 +390,17 @@ class SSHClient (object): @type width: int @param height: the height (in characters) of the terminal window @type height: int + @param width_pixels: the width (in pixels) of the terminal window + @type width_pixels: int + @param height_pixels: the height (in pixels) of the terminal window + @type height_pixels: int @return: a new channel connected to the remote shell @rtype: L{Channel} @raise SSHException: if the server fails to invoke a shell """ chan = self._transport.open_session() - chan.get_pty(term, width, height) + chan.get_pty(term, width, height, width_pixels, height_pixels) chan.invoke_shell() return chan