From 0e7409c7ff6fc760018fce3d5e8b72247bf782b5 Mon Sep 17 00:00:00 2001
From: Matt Johnston <matt@ucc.asn.au>
Date: Mon, 28 Jul 2014 23:23:49 +0800
Subject: [PATCH] Make sure the check_close() handler runs when a server child
 process exits

---
 common-channel.c  | 6 ++++++
 session.h         | 1 +
 svr-chansession.c | 3 +++
 3 files changed, 10 insertions(+)

diff --git a/common-channel.c b/common-channel.c
index 967c937c..63a42fbd 100644
--- a/common-channel.c
+++ b/common-channel.c
@@ -258,6 +258,12 @@ void channelio(fd_set *readfds, fd_set *writefds) {
 			writechannel(channel, channel->errfd, channel->extrabuf);
 			do_check_close = 1;
 		}
+
+		if (ses.channel_signal_pending) {
+			/* SIGCHLD can change channel state for server sessions */
+			do_check_close = 1;
+			ses.channel_signal_pending = 0;
+		}
 	
 		/* handle any channel closing etc */
 		if (do_check_close) {
diff --git a/session.h b/session.h
index 3a0e87aa..b09fa448 100644
--- a/session.h
+++ b/session.h
@@ -187,6 +187,7 @@ struct sshsession {
 	unsigned int chansize; /* the number of Channel*s allocated for channels */
 	unsigned int chancount; /* the number of Channel*s in use */
 	const struct ChanType **chantypes; /* The valid channel types */
+	int channel_signal_pending; /* Flag set by sigchld handler */
 
 	/* TCP priority level for the main "port 22" tcp socket */
 	enum dropbear_prio socket_prio;
diff --git a/svr-chansession.c b/svr-chansession.c
index 4b452948..2a99362e 100644
--- a/svr-chansession.c
+++ b/svr-chansession.c
@@ -89,6 +89,9 @@ static void sesssigchild_handler(int UNUSED(dummy)) {
 
 	const int saved_errno = errno;
 
+	/* Make channel handling code look for closed channels */
+	ses.channel_signal_pending = 1;
+
 	TRACE(("enter sigchld handler"))
 	while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
 		TRACE(("sigchld handler: pid %d", pid))
-- 
GitLab