changeset 41:18eccbfb9641

added window-size change handling
author Matt Johnston <matt@ucc.asn.au>
date Sun, 01 Aug 2004 09:41:37 +0000
parents b4874d772210
children 837f9172df09
files chansession.h cli-chansession.c cli-session.c common-session.c session.h
diffstat 5 files changed, 44 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/chansession.h	Sun Aug 01 08:54:01 2004 +0000
+++ b/chansession.h	Sun Aug 01 09:41:37 2004 +0000
@@ -77,6 +77,7 @@
 
 void cli_send_chansess_request();
 void cli_tty_cleanup();
+void cli_chansess_winchange();
 
 void svr_chansessinitialise();
 extern const struct ChanType svrchansess;
--- a/cli-chansession.c	Sun Aug 01 08:54:01 2004 +0000
+++ b/cli-chansession.c	Sun Aug 01 09:41:37 2004 +0000
@@ -203,6 +203,32 @@
 
 }
 
+static void sigwinch_handler(int dummy) {
+
+	cli_ses.winchange = 1;
+
+}
+
+void cli_chansess_winchange() {
+
+	unsigned int i;
+	struct Channel *channel = NULL;
+
+	for (i = 0; i < ses.chansize; i++) {
+		channel = ses.channels[i];
+		if (channel != NULL && channel->type == &clichansess) {
+			CHECKCLEARTOWRITE();
+			buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_REQUEST);
+			buf_putint(ses.writepayload, channel->remotechan);
+			buf_putstring(ses.writepayload, "window-change", 13);
+			buf_putbyte(ses.writepayload, 0); /* FALSE says the spec */
+			put_winsize();
+			encrypt_packet();
+		}
+	}
+	cli_ses.winchange = 0;
+}
+
 static void send_chansess_pty_req(struct Channel *channel) {
 
 	unsigned char* term = NULL;
@@ -228,6 +254,11 @@
 	put_termcodes();
 
 	encrypt_packet();
+
+	/* Set up a window-change handler */
+	if (signal(SIGWINCH, sigwinch_handler) == SIG_ERR) {
+		dropbear_exit("signal error");
+	}
 	TRACE(("leave send_chansess_pty_req"));
 }
 
@@ -275,7 +306,6 @@
 
 }
 
-
 void cli_send_chansess_request() {
 
 	TRACE(("enter cli_send_chansess_request"));
--- a/cli-session.c	Sun Aug 01 08:54:01 2004 +0000
+++ b/cli-session.c	Sun Aug 01 09:41:37 2004 +0000
@@ -80,6 +80,7 @@
 	cli_ses.kex_state = KEX_NOTHING;
 
 	cli_ses.tty_raw_mode = 0;
+	cli_ses.winchange = 0;
 
 	/* For printing "remote host closed" for the user */
 	ses.remoteclosed = cli_remoteclosed;
@@ -170,6 +171,10 @@
 			if (ses.chancount < 1) {
 				cli_finished();
 			}
+
+			if (cli_ses.winchange) {
+				cli_chansess_winchange();
+			}
 			return;
 
 		/* XXX more here needed */
--- a/common-session.c	Sun Aug 01 08:54:01 2004 +0000
+++ b/common-session.c	Sun Aug 01 09:41:37 2004 +0000
@@ -144,6 +144,11 @@
 		
 		if (val < 0) {
 			if (errno == EINTR) {
+				/* This must happen even if we've been interrupted, so that
+				 * changed signal-handler vars can take effect etc */
+				if (loophandler) {
+					loophandler();
+				}
 				continue;
 			} else {
 				dropbear_exit("Error in select");
--- a/session.h	Sun Aug 01 08:54:01 2004 +0000
+++ b/session.h	Sun Aug 01 09:41:37 2004 +0000
@@ -212,6 +212,8 @@
 	int tty_raw_mode; /* Whether we're in raw mode (and have to clean up) */
 	struct termios saved_tio;
 
+	int winchange; /* Set to 1 when a windowchange signal happens */
+
 };
 
 /* Global structs storing the state */