changeset 1828:3f0ac6bc58a1

- Remove "flushing" handling for exited processes, it should be handled by normal file descriptor reads. - Fix sesscheckclose() handling if a channel was closed before a process was ever launched
author Matt Johnston <matt@ucc.asn.au>
date Mon, 11 Oct 2021 15:16:54 +0800
parents 8a78cc13eb30
children a7cc3332d8ab
files channel.h common-channel.c svr-chansession.c
diffstat 3 files changed, 4 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/channel.h	Mon Oct 11 15:14:46 2021 +0800
+++ b/channel.h	Mon Oct 11 15:16:54 2021 +0800
@@ -77,8 +77,6 @@
 					   for this channel (and are awaiting a confirmation
 					   or failure). */
 
-	int flushing;
-
 	/* Used by client chansession to handle ~ escaping, NULL ignored otherwise */
 	void (*read_mangler)(const struct Channel*, const unsigned char* bytes, int *len);
 
--- a/common-channel.c	Mon Oct 11 15:14:46 2021 +0800
+++ b/common-channel.c	Mon Oct 11 15:16:54 2021 +0800
@@ -154,7 +154,6 @@
 	newchan->readfd = FD_UNINIT;
 	newchan->errfd = FD_CLOSED; /* this isn't always set to start with */
 	newchan->await_open = 0;
-	newchan->flushing = 0;
 
 	newchan->writebuf = cbuf_new(opts.recv_window);
 	newchan->recvwindow = opts.recv_window;
@@ -284,14 +283,6 @@
 				channel->writebuf ? cbuf_getused(channel->writebuf) : 0,
 				channel->extrabuf ? cbuf_getused(channel->extrabuf) : 0))
 
-	if (!channel->flushing 
-		&& !channel->sent_close
-		&& channel->type->check_close
-		&& channel->type->check_close(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 
@@ -317,22 +308,6 @@
 		close_chan_fd(channel, channel->writefd, SHUT_WR);
 	}
 
-	/* Special handling for flushing read data after an exit. We
-	   read regardless of whether the select FD was set,
-	   and if there isn't data available, the channel will get closed. */
-	if (channel->flushing) {
-		TRACE(("might send data, flushing"))
-		if (channel->readfd >= 0 && channel->transwindow > 0) {
-			TRACE(("send data readfd"))
-			send_msg_channel_data(channel, 0);
-		}
-		if (ERRFD_IS_READ(channel) && channel->errfd >= 0 
-			&& channel->transwindow > 0) {
-			TRACE(("send data errfd"))
-			send_msg_channel_data(channel, 1);
-		}
-	}
-
 	/* If we're not going to send any more data, send EOF */
 	if (!channel->sent_eof
 			&& channel->readfd == FD_CLOSED 
@@ -779,14 +754,6 @@
 	channel->transwindow -= len;
 
 	encrypt_packet();
-	
-	/* If we receive less data than we requested when flushing, we've
-	   reached the equivalent of EOF */
-	if (channel->flushing && len < (ssize_t)maxlen)
-	{
-		TRACE(("closing from channel, flushing out."))
-		close_chan_fd(channel, fd, SHUT_RD);
-	}
 	TRACE(("leave send_msg_channel_data"))
 }
 
--- a/svr-chansession.c	Mon Oct 11 15:14:46 2021 +0800
+++ b/svr-chansession.c	Mon Oct 11 15:16:54 2021 +0800
@@ -76,10 +76,12 @@
 /* required to clear environment */
 extern char** environ;
 
+/* Returns whether the channel is ready to close. The child process
+   must not be running (has never started, or has exited) */
 static int sesscheckclose(const struct Channel *channel) {
 	struct ChanSess *chansess = (struct ChanSess*)channel->typedata;
-	TRACE(("sesscheckclose, pid is %d", chansess->exit.exitpid))
-	return chansess->exit.exitpid != -1;
+	TRACE(("sesscheckclose, pid %d, exitpid %d", chansess->pid, chansess->exit.exitpid))
+	return chansess->pid == 0 || chansess->exit.exitpid != -1;
 }
 
 /* Handler for childs exiting, store the state for return to the client */