diff options
author | Matt Johnston <matt@ucc.asn.au> | 2006-06-10 16:39:37 +0000 |
---|---|---|
committer | Matt Johnston <matt@ucc.asn.au> | 2006-06-10 16:39:37 +0000 |
commit | 94d86427ff20ed544e299d3a2de5ecc2cc04c191 (patch) | |
tree | dc6bece4692049393b3d3ffd4990629c2c502ff5 /common-channel.c | |
parent | a4bf09e7b929dbd61686783641b98f0b30c907f0 (diff) |
disapproval of revision 'a4c1a9be4db326f8f7adcf30f876fadedf87b203'
--HG--
extra : convert_revision : 332f709a4cb39cde4cedab7c3be89e05f3023067
Diffstat (limited to 'common-channel.c')
-rw-r--r-- | common-channel.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/common-channel.c b/common-channel.c index 7e8d428..54829e5 100644 --- a/common-channel.c +++ b/common-channel.c @@ -203,6 +203,24 @@ void channelio(fd_set *readfds, fd_set *writefds) { send_msg_channel_data(channel, 1, SSH_EXTENDED_DATA_STDERR); } + /* if we can read from the writefd, it might be closed, so we try to + * see if it has errors */ + if (channel->writefd >= 0 && channel->writefd != channel->readfd + && FD_ISSET(channel->writefd, readfds)) { + if (channel->initconn) { + /* Handling for "in progress" connection - this is needed + * to avoid spinning 100% CPU when we connect to a server + * which doesn't send anything (tcpfwding) */ + checkinitdone(channel); + continue; /* Important not to use the channel after + checkinitdone(), as it may be NULL */ + } + ret = write(channel->writefd, NULL, 0); /* Fake write */ + if (ret < 0 && errno != EINTR && errno != EAGAIN) { + closewritefd(channel); + } + } + /* write to program/pipe stdin */ if (channel->writefd >= 0 && FD_ISSET(channel->writefd, writefds)) { if (channel->initconn) { @@ -427,7 +445,17 @@ void setchannelfds(fd_set *readfds, fd_set *writefds) { } } - /* Stuff from the wire */ + /* For checking FD status (ie closure etc) - we don't actually + * read data from writefd */ + TRACE(("writefd = %d, readfd %d, errfd %d, bufused %d", + channel->writefd, channel->readfd, + channel->errfd, + cbuf_getused(channel->writebuf) )) + if (channel->writefd >= 0 && channel->writefd != channel->readfd) { + FD_SET(channel->writefd, readfds); + } + + /* Stuff from the wire, to local program/shell/user etc */ if ((channel->writefd >= 0 && cbuf_getused(channel->writebuf) > 0 ) || channel->initconn) { |