summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMatt Johnston <matt@ucc.asn.au>2004-08-01 09:41:37 +0000
committerMatt Johnston <matt@ucc.asn.au>2004-08-01 09:41:37 +0000
commit55c9b4564937d6f3348896d010bde2bb3711a1fd (patch)
tree0b0c8d4e47918a3bae2318ed82ca5ac673fafe63
parent051b7454f80a52d2b0bea2e34562949a3bc70fe4 (diff)
added window-size change handling
--HG-- extra : convert_revision : 93a39c7b76f478035046b9c6f88af54612cce36f
-rw-r--r--chansession.h1
-rw-r--r--cli-chansession.c32
-rw-r--r--cli-session.c5
-rw-r--r--common-session.c5
-rw-r--r--session.h2
5 files changed, 44 insertions, 1 deletions
diff --git a/chansession.h b/chansession.h
index 0930d9d..3fb1901 100644
--- a/chansession.h
+++ b/chansession.h
@@ -77,6 +77,7 @@ void addnewvar(const char* param, const char* var);
void cli_send_chansess_request();
void cli_tty_cleanup();
+void cli_chansess_winchange();
void svr_chansessinitialise();
extern const struct ChanType svrchansess;
diff --git a/cli-chansession.c b/cli-chansession.c
index be6fc14..e34c6fd 100644
--- a/cli-chansession.c
+++ b/cli-chansession.c
@@ -203,6 +203,32 @@ static void put_winsize() {
}
+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 @@ static void send_chansess_pty_req(struct Channel *channel) {
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 @@ static int cli_initchansess(struct Channel *channel) {
}
-
void cli_send_chansess_request() {
TRACE(("enter cli_send_chansess_request"));
diff --git a/cli-session.c b/cli-session.c
index 42770f5..6882d2e 100644
--- a/cli-session.c
+++ b/cli-session.c
@@ -80,6 +80,7 @@ static void cli_session_init() {
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 @@ static void cli_sessionloop() {
if (ses.chancount < 1) {
cli_finished();
}
+
+ if (cli_ses.winchange) {
+ cli_chansess_winchange();
+ }
return;
/* XXX more here needed */
diff --git a/common-session.c b/common-session.c
index 79166f4..601136f 100644
--- a/common-session.c
+++ b/common-session.c
@@ -144,6 +144,11 @@ void session_loop(void(*loophandler)()) {
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");
diff --git a/session.h b/session.h
index 1ce944a..2009054 100644
--- a/session.h
+++ b/session.h
@@ -212,6 +212,8 @@ struct clientsession {
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 */