progress towards exiting on writefd closure rather than

on process exit - dbclient hangs with scp, so requires work.

--HG--
extra : convert_revision : 2186a678a5f79ef432f6593a10e3e13df2a313d5
This commit is contained in:
Matt Johnston 2006-06-11 16:19:32 +00:00
parent c9d3c0bc90
commit e8fa3ce478
2 changed files with 29 additions and 26 deletions

View File

@ -181,6 +181,7 @@ void channelio(fd_set *readfds, fd_set *writefds) {
struct Channel *channel; struct Channel *channel;
unsigned int i; unsigned int i;
int ret;
/* iterate through all the possible channels */ /* iterate through all the possible channels */
for (i = 0; i < ses.chansize; i++) { for (i = 0; i < ses.chansize; i++) {
@ -204,7 +205,8 @@ void channelio(fd_set *readfds, fd_set *writefds) {
/* if we can read from the writefd, it might be closed, so we try to /* if we can read from the writefd, it might be closed, so we try to
* see if it has errors */ * see if it has errors */
if (channel->writefd >= 0 && channel->writefd != channel->readfd if (IS_DROPBEAR_SERVER && channel->writefd >= 0
&& channel->writefd != channel->readfd
&& FD_ISSET(channel->writefd, readfds)) { && FD_ISSET(channel->writefd, readfds)) {
if (channel->initconn) { if (channel->initconn) {
/* Handling for "in progress" connection - this is needed /* Handling for "in progress" connection - this is needed
@ -259,28 +261,28 @@ static void checkclose(struct Channel *channel) {
channel->writebuf, channel->writebuf,
channel->writebuf ? 0 : cbuf_getused(channel->extrabuf))) channel->writebuf ? 0 : cbuf_getused(channel->extrabuf)))
if (!channel->sentclosed) { /* server chansession channels are special, since readfd mightn't
* close in the case of "sleep 4 & echo blah" until the sleep is up */
/* check for exited - currently only used for server sessions,
* if the shell has exited etc */
if (channel->type->checkclose) { if (channel->type->checkclose) {
if (channel->type->checkclose(channel)) { if (channel->type->checkclose(channel)) {
closewritefd(channel); closewritefd(channel);
closereadfd(channel, channel->readfd);
closereadfd(channel, channel->errfd);
} }
} }
if (!channel->senteof if (!channel->senteof
&& channel->readfd == FD_CLOSED && channel->readfd == FD_CLOSED
&& (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) { && (channel->extrabuf == NULL || channel->errfd == FD_CLOSED)) {
send_msg_channel_eof(channel); send_msg_channel_eof(channel);
} }
if (channel->writefd == FD_CLOSED if (!channel->sentclosed
&& channel->writefd == FD_CLOSED
&& channel->readfd == FD_CLOSED && channel->readfd == FD_CLOSED
&& (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) { && (channel->extrabuf == NULL || channel->errfd == FD_CLOSED)) {
send_msg_channel_close(channel); send_msg_channel_close(channel);
} }
}
/* When either party wishes to terminate the channel, it sends /* When either party wishes to terminate the channel, it sends
* SSH_MSG_CHANNEL_CLOSE. Upon receiving this message, a party MUST * SSH_MSG_CHANNEL_CLOSE. Upon receiving this message, a party MUST
@ -444,20 +446,22 @@ void setchannelfds(fd_set *readfds, fd_set *writefds) {
} }
} }
/* For checking FD status (ie closure etc) - we don't actually
* read data from writefd */
TRACE(("writefd = %d, readfd %d, errfd %d, bufused %d", TRACE(("writefd = %d, readfd %d, errfd %d, bufused %d",
channel->writefd, channel->readfd, channel->writefd, channel->readfd,
channel->errfd, channel->errfd,
cbuf_getused(channel->writebuf) )) cbuf_getused(channel->writebuf) ))
if (channel->writefd >= 0 && channel->writefd != channel->readfd) {
/* For checking FD status (ie closure etc) - we don't actually
* read data from writefd. We don't want to do this for the client,
* since redirection to /dev/null will make it spin in the select */
if (IS_DROPBEAR_SERVER && channel->writefd >= 0
&& channel->writefd != channel->readfd) {
FD_SET(channel->writefd, readfds); FD_SET(channel->writefd, readfds);
} }
/* Stuff from the wire, to local program/shell/user etc */ /* Stuff from the wire */
if ((channel->writefd >= 0 && cbuf_getused(channel->writebuf) > 0 ) if ((channel->writefd >= 0 && cbuf_getused(channel->writebuf) > 0 )
|| channel->initconn) { || channel->initconn) {
FD_SET(channel->writefd, writefds); FD_SET(channel->writefd, writefds);
} }

View File

@ -67,8 +67,7 @@ static void get_termmodes(struct ChanSess *chansess);
extern char** environ; extern char** environ;
static int sesscheckclose(struct Channel *channel) { static int sesscheckclose(struct Channel *channel) {
struct ChanSess *chansess = (struct ChanSess*)channel->typedata; return channel->writefd == -1;
return chansess->exit.exitpid >= 0;
} }
/* Handler for childs exiting, store the state for return to the client */ /* Handler for childs exiting, store the state for return to the client */