Mercurial > dropbear
diff common-channel.c @ 773:a9f2a6ae4eb5
merge
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sun, 14 Apr 2013 22:49:19 +0800 |
parents | 7577a3afc42d |
children | 35183e8a7851 |
line wrap: on
line diff
--- a/common-channel.c Sun Apr 14 22:49:10 2013 +0800 +++ b/common-channel.c Sun Apr 14 22:49:19 2013 +0800 @@ -273,10 +273,10 @@ static void check_close(struct Channel *channel) { int close_allowed = 0; - TRACE(("check_close: writefd %d, readfd %d, errfd %d, sent_close %d, recv_close %d", + TRACE2(("check_close: writefd %d, readfd %d, errfd %d, sent_close %d, recv_close %d", channel->writefd, channel->readfd, channel->errfd, channel->sent_close, channel->recv_close)) - TRACE(("writebuf size %d extrabuf size %d", + TRACE2(("writebuf size %d extrabuf size %d", channel->writebuf ? cbuf_getused(channel->writebuf) : 0, channel->extrabuf ? cbuf_getused(channel->extrabuf) : 0)) @@ -561,7 +561,11 @@ TRACE(("CLOSE errfd %d", channel->errfd)) close(channel->errfd); - channel->typedata = NULL; + if (!channel->close_handler_done + && channel->type->closehandler) { + channel->type->closehandler(channel); + channel->close_handler_done = 1; + } ses.channels[channel->index] = NULL; m_free(channel); @@ -625,7 +629,7 @@ * exttype if is extended */ maxlen = MIN(maxlen, ses.writepayload->size - 1 - 4 - 4 - (isextended ? 4 : 0)); - TRACE(("maxlen %d", maxlen)) + TRACE(("maxlen %zd", maxlen)) if (maxlen == 0) { TRACE(("leave send_msg_channel_data: no window")) return; @@ -643,6 +647,7 @@ /* read the data */ len = read(fd, buf_getwriteptr(ses.writepayload, maxlen), maxlen); + if (len <= 0) { if (len == 0 || errno != EINTR) { /* This will also get hit in the case of EAGAIN. The only @@ -650,12 +655,22 @@ in which case it can be treated the same as EOF */ close_chan_fd(channel, fd, SHUT_RD); } - ses.writepayload->len = ses.writepayload->pos = 0; + buf_setpos(ses.writepayload, 0); + buf_setlen(ses.writepayload, 0); TRACE(("leave send_msg_channel_data: len %d read err %d or EOF for fd %d", len, errno, fd)) return; } + if (channel->read_mangler) { + channel->read_mangler(channel, buf_getwriteptr(ses.writepayload, len), &len); + if (len == 0) { + buf_setpos(ses.writepayload, 0); + buf_setlen(ses.writepayload, 0); + return; + } + } + TRACE(("send_msg_channel_data: len %d fd %d", len, fd)) buf_incrwritepos(ses.writepayload, len); /* ... real size here */