Mercurial > dropbear
changeset 364:90cb290836de channel-fix
Passes most test cases now
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 09 Oct 2006 16:31:00 +0000 |
parents | 6ba2894ec8d5 |
children | 49fcc9875045 |
files | common-channel.c svr-chansession.c |
diffstat | 2 files changed, 14 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- a/common-channel.c Sat Oct 07 17:48:55 2006 +0000 +++ b/common-channel.c Mon Oct 09 16:31:00 2006 +0000 @@ -263,10 +263,12 @@ channel->writebuf, channel->writebuf ? 0 : cbuf_getused(channel->extrabuf))) - if (!channel->sent_close - && channel->writefd == FD_CLOSED - && (channel->errfd == FD_CLOSED || channel->extrabuf == NULL)) { - send_msg_channel_close(channel); + /* A bit of a hack for closing up server session channels */ + if (channel->writefd >= 0 + && channel->type->check_close + && channel->type->check_close(channel)) { + TRACE(("channel->type->check_close got hit")) + close_chan_fd(channel, channel->writefd, SHUT_WR); } if (channel->recv_close && !write_pending(channel)) { @@ -278,31 +280,15 @@ return; } -#if 0 - // The only use of check_close is "return channel->writefd == -1;" for a server - // chansession. Should be able to handle that with just the general - // socket close handling...? - if (channel->type->check_close) { - if (channel->type->check_close(channel)) { - close_write_fd(channel); - close_read_fd(channel, channel->readfd); - close_read_fd(channel, channel->errfd); - } + if (channel->recv_eof && !write_pending(channel)) { + close_chan_fd(channel, channel->writefd, SHUT_WR); } -#endif if (!channel->sent_eof && channel->readfd == FD_CLOSED && (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) { send_msg_channel_eof(channel); } - - if (!channel->sent_close - && channel->writefd == FD_CLOSED - && channel->readfd == FD_CLOSED - && (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) { - send_msg_channel_close(channel); - } } @@ -395,13 +381,6 @@ cbuf_incrread(cbuf, len); channel->recvdonelen += len; - /* We're closing out */ - if (channel->recv_eof && cbuf_getused(cbuf) == 0) { - TRACE(("leave writechannel")) - close_chan_fd(channel, fd, SHUT_WR); - return; - } - /* Window adjust handling */ if (channel->recvdonelen >= RECV_WINDOWEXTEND) { /* Set it back to max window */
--- a/svr-chansession.c Sat Oct 07 17:48:55 2006 +0000 +++ b/svr-chansession.c Mon Oct 09 16:31:00 2006 +0000 @@ -65,6 +65,11 @@ /* required to clear environment */ extern char** environ; +static int sesscheckclose(struct Channel *channel) { + struct ChanSess *chansess = (struct ChanSess*)channel->typedata; + return chansess->exit.exitpid != -1; +} + /* Handler for childs exiting, store the state for return to the client */ /* There's a particular race we have to watch out for: if the forked child @@ -962,7 +967,7 @@ 0, /* sepfds */ "session", /* name */ newchansess, /* inithandler */ - NULL, /* checkclosehandler */ + sesscheckclose, /* checkclosehandler */ chansessionrequest, /* reqhandler */ closechansess, /* closehandler */ };