From 6c9d2abc75e7efc3021c22fc18d65ca99344afcd Mon Sep 17 00:00:00 2001
From: Matt Johnston <matt@ucc.asn.au>
Date: Thu, 21 Feb 2008 14:46:15 +0000
Subject: [PATCH] Don't return until the shell has quit. This will ensure that
 an exit status is always returned.

--HG--
extra : convert_revision : 32fc88053016994100eb0ef17f75592881c90d97
---
 common-channel.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/common-channel.c b/common-channel.c
index 97fd4a8c..09fe4256 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);
-- 
GitLab