diff options
author | Matt Johnston <matt@ucc.asn.au> | 2004-08-01 09:41:37 +0000 |
---|---|---|
committer | Matt Johnston <matt@ucc.asn.au> | 2004-08-01 09:41:37 +0000 |
commit | 55c9b4564937d6f3348896d010bde2bb3711a1fd (patch) | |
tree | 0b0c8d4e47918a3bae2318ed82ca5ac673fafe63 | |
parent | 051b7454f80a52d2b0bea2e34562949a3bc70fe4 (diff) |
added window-size change handling
--HG--
extra : convert_revision : 93a39c7b76f478035046b9c6f88af54612cce36f
-rw-r--r-- | chansession.h | 1 | ||||
-rw-r--r-- | cli-chansession.c | 32 | ||||
-rw-r--r-- | cli-session.c | 5 | ||||
-rw-r--r-- | common-session.c | 5 | ||||
-rw-r--r-- | session.h | 2 |
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"); @@ -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 */ |