Mercurial > dropbear
diff common-channel.c @ 109:2e9d1f29c50f
merge of 50be59810e462f9f44f55e421227d6aa0b31982b
and 69b007796063cb5f042be7cca2d479e90db869c3
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 27 Aug 2004 14:39:01 +0000 |
parents | 10f4d3319780 |
children | 8c2b3506f112 |
line wrap: on
line diff
--- a/common-channel.c Thu Aug 26 13:16:40 2004 +0000 +++ b/common-channel.c Fri Aug 27 14:39:01 2004 +0000 @@ -192,7 +192,8 @@ } /* read from program/pipe stderr */ - if (channel->errfd >= 0 && FD_ISSET(channel->errfd, readfd)) { + if (channel->extrabuf == NULL && + channel->errfd >= 0 && FD_ISSET(channel->errfd, readfd)) { send_msg_channel_data(channel, 1, SSH_EXTENDED_DATA_STDERR); } @@ -245,6 +246,14 @@ /* do all the EOF/close type stuff checking for a channel */ static void checkclose(struct Channel *channel) { + TRACE(("checkclose: infd %d, outfd %d, errfd %d, sentclosed %d, recvclosed %d", + channel->infd, channel->outfd, + channel->errfd, channel->sentclosed, channel->recvclosed)); + TRACE(("writebuf %d extrabuf %s extrabuf %d", + cbuf_getused(channel->writebuf), + channel->writebuf, + channel->writebuf ? 0 : cbuf_getused(channel->extrabuf))); + if (!channel->sentclosed) { /* check for exited - currently only used for server sessions, @@ -257,13 +266,13 @@ if (!channel->senteof && channel->outfd == FD_CLOSED - && channel->errfd == FD_CLOSED) { + && (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) { send_msg_channel_eof(channel); } if (channel->infd == FD_CLOSED - && channel->outfd == FD_CLOSED - && channel->errfd == FD_CLOSED) { + && channel->outfd == FD_CLOSED + && (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) { send_msg_channel_close(channel); } } @@ -383,9 +392,8 @@ if (fd == channel->infd && len == maxlen && channel->recveof) { /* Check if we're closing up */ closeinfd(channel); + TRACE(("leave writechannel: recveof set")); return; - TRACE(("leave writechannel: recveof set")); - } /* Window adjust handling */ @@ -433,7 +441,9 @@ /* For checking FD status (ie closure etc) - we don't actually * read data from infd */ - TRACE(("infd = %d, outfd %d, bufused %d", channel->infd, channel->outfd, + TRACE(("infd = %d, outfd %d, errfd %d, bufused %d", + channel->infd, channel->outfd, + channel->errfd, cbuf_getused(channel->writebuf) )); if (channel->infd >= 0 && channel->infd != channel->outfd) { FD_SET(channel->infd, readfd); @@ -534,9 +544,8 @@ * yet (ie they were shutdown etc */ close(channel->infd); close(channel->outfd); - if (channel->errfd >= 0) { - close(channel->errfd); - } + close(channel->errfd); + channel->typedata = NULL; deletechannel(channel); @@ -619,16 +628,19 @@ } /* read the data */ + TRACE(("maxlen %d", maxlen)); buf = buf_new(maxlen); + TRACE(("buf pos %d data %x", buf->pos, buf->data)); len = read(fd, buf_getwriteptr(buf, maxlen), maxlen); if (len <= 0) { /* on error/eof, send eof */ if (len == 0 || errno != EINTR) { closeoutfd(channel, fd); - TRACE(("leave send_msg_channel_data: read err %d", channel->index)); } buf_free(buf); buf = NULL; + TRACE(("leave send_msg_channel_data: read err or EOF for fd %d", + channel->index)); return; } buf_incrlen(buf, len); @@ -714,7 +726,7 @@ len -= buflen; } - assert(channel->recvwindow > datalen); + assert(channel->recvwindow >= datalen); channel->recvwindow -= datalen; assert(channel->recvwindow <= RECV_MAXWINDOW); @@ -927,10 +939,7 @@ } /* set fd non-blocking */ - if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { - TRACE(("leave send_msg_channel_open_init() - FAILED in fcntl()")); - return DROPBEAR_FAILURE; - } + setnonblocking(fd); chan->infd = chan->outfd = fd; ses.maxfd = MAX(ses.maxfd, fd); @@ -1034,15 +1043,19 @@ closein = closeout = 1; } - if (closeout && fd == channel->errfd) { - channel->errfd = FD_CLOSED; - } if (closeout && fd == channel->outfd) { channel->outfd = FD_CLOSED; } + if (closeout && (channel->extrabuf == NULL) && (fd == channel->errfd)) { + channel->errfd = FD_CLOSED; + } + if (closein && fd == channel->infd) { channel->infd = FD_CLOSED; } + if (closein && (channel->extrabuf != NULL) && (fd == channel->errfd)) { + channel->errfd = FD_CLOSED; + } } #endif /* USING_LISTENERS */