diff options
author | Matt Johnston <matt@ucc.asn.au> | 2008-02-21 14:46:15 +0000 |
---|---|---|
committer | Matt Johnston <matt@ucc.asn.au> | 2008-02-21 14:46:15 +0000 |
commit | 6c9d2abc75e7efc3021c22fc18d65ca99344afcd (patch) | |
tree | ae78fb555ba4a4d7581300b5001dbce2334262f5 | |
parent | e277059339844d7f7dc45743fc45109a86d17218 (diff) |
Don't return until the shell has quit. This will ensure that an exit status
is always returned.
--HG--
extra : convert_revision : 32fc88053016994100eb0ef17f75592881c90d97
-rw-r--r-- | common-channel.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/common-channel.c b/common-channel.c index 97fd4a8..09fe425 100644 --- a/common-channel.c +++ b/common-channel.c @@ -261,6 +261,7 @@ static unsigned int write_pending(struct Channel * channel) { /* EOF/close handling */ 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", channel->writefd, channel->readfd, @@ -274,8 +275,17 @@ static void check_close(struct Channel *channel) { { channel->flushing = 1; } + + // if a type-specific check_close is defined we will only exit + // once that has been triggered. this is only used for a server "session" + // channel, to ensure that the shell has exited (and the exit status + // retrieved) before we close things up. + if (!channel->type->check_close + || channel->type->check_close(channel)) { + close_allowed = 1; + } - if (channel->recv_close && !write_pending(channel)) { + if (channel->recv_close && !write_pending(channel) && close_allowed) { if (!channel->sent_close) { TRACE(("Sending MSG_CHANNEL_CLOSE in response to same.")) send_msg_channel_close(channel); @@ -312,9 +322,10 @@ static void check_close(struct Channel *channel) { } /* And if we can't receive any more data from them either, close up */ - if (!channel->sent_close - && channel->readfd == FD_CLOSED + if (channel->readfd == FD_CLOSED && (ERRFD_IS_WRITE(channel) || channel->errfd == FD_CLOSED) + && !channel->sent_close + && close_allowed && !write_pending(channel)) { TRACE(("sending close, readfd is closed")) send_msg_channel_close(channel); |