intermittent stderr

Markus Friedl markus.friedl at informatik.uni-erlangen.de
Mon Feb 26 03:28:59 EST 2001


On Thu, Feb 22, 2001 at 02:30:43PM -0800, John Dunlap wrote:
> The command "ssh ls -l /doesnotexist" gives various responses:

please try this patch.

after close of stdin/out remaining stderr data is ignored
in the 'channel' layer of openssh-current.


Index: nchan.c
===================================================================
RCS file: /home/markus/cvs/ssh/nchan.c,v
retrieving revision 1.22
diff -u -r1.22 nchan.c
--- nchan.c	2001/01/21 19:05:52	1.22
+++ nchan.c	2001/02/25 16:19:55
@@ -406,14 +406,40 @@
 {
 	debug3("channel %d: chan_delete_if_full_closed2: istate %d ostate %d",
 	    c->self, c->istate, c->ostate);
+
 	if (c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED) {
-		if (!(c->flags & CHAN_CLOSE_SENT)) {
-			chan_send_close2(c);
-		}
-		if ((c->flags & CHAN_CLOSE_SENT) &&
-		    (c->flags & CHAN_CLOSE_RCVD)) {
-			debug("channel %d: full closed2", c->self);
-			channel_free(c->self);
+		/*
+		 * we have to delay the close message if the efd (for stderr)
+		 * is still active
+		 */
+		if (((c->extended_usage != CHAN_EXTENDED_IGNORE) &&
+		    buffer_len(&c->extended) > 0)
+#if 0
+		    || ((c->extended_usage == CHAN_EXTENDED_READ) &&
+		    c->efd != -1)
+#endif
+		    ) {
+			debug2("channel %d: active efd: %d len %d type %s",
+			    c->self, c->efd, buffer_len(&c->extended),
+			    c->extended_usage==CHAN_EXTENDED_READ ?
+			       "read": "write");
+		} else {
+#if 0
+			if (c->efd != -1) {
+				debug("channel %d: delayed close for efd %d",
+				    c->self, c->efd);
+				close(c->efd);
+				c->efd = -1;
+			}
+#endif
+			if (!(c->flags & CHAN_CLOSE_SENT)) {
+				chan_send_close2(c);
+			}
+			if ((c->flags & CHAN_CLOSE_SENT) &&
+			    (c->flags & CHAN_CLOSE_RCVD)) {
+				debug("channel %d: full closed2", c->self);
+				channel_free(c->self);
+			}
 		}
 	}
 }
Index: channels.c
===================================================================
RCS file: /home/markus/cvs/ssh/channels.c,v
retrieving revision 1.92
diff -u -r1.92 channels.c
--- channels.c	2001/02/16 13:38:18	1.92
+++ channels.c	2001/02/25 16:12:59
@@ -824,7 +824,14 @@
 			    buffer_len(&c->extended));
 			debug2("channel %d: written %d to efd %d",
 			    c->self, len, c->efd);
-			if (len > 0) {
+			if (len < 0 && (errno == EINTR || errno == EAGAIN))
+				return 1;
+			if (len <= 0) {
+				debug2("channel %d: closing write-efd %d",
+				    c->self, c->efd);
+				close(c->efd);
+				c->efd = -1;
+			} else {
 				buffer_consume(&c->extended, len);
 				c->local_consumed += len;
 			}
@@ -833,13 +840,16 @@
 			len = read(c->efd, buf, sizeof(buf));
 			debug2("channel %d: read %d from efd %d",
 			     c->self, len, c->efd);
-			if (len == 0) {
-				debug("channel %d: closing efd %d",
+			if (len < 0 && (errno == EINTR || errno == EAGAIN))
+				return 1;
+			if (len <= 0) {
+				debug2("channel %d: closing read-efd %d",
 				    c->self, c->efd);
 				close(c->efd);
 				c->efd = -1;
-			} else if (len > 0)
+			} else {
 				buffer_append(&c->extended, buf, len);
+			}
 		}
 	}
 	return 1;
@@ -1037,19 +1047,18 @@
 		} else {
 			if (c->type != SSH_CHANNEL_OPEN)
 				continue;
-			if (c->istate != CHAN_INPUT_OPEN &&
-			    c->istate != CHAN_INPUT_WAIT_DRAIN)
-				continue;
 		}
 		if (compat20 &&
 		    (c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) {
+			/* XXX is this true? */
 			debug("channel: %d: no data after CLOSE", c->self);
 			continue;
 		}
 
 		/* Get the amount of buffered data for this channel. */
-		len = buffer_len(&c->input);
-		if (len > 0) {
+		if ((c->istate == CHAN_INPUT_OPEN ||
+		    c->istate == CHAN_INPUT_WAIT_DRAIN) &&
+		    (len = buffer_len(&c->input)) > 0) {
 			/* Send some data for the other side over the secure connection. */
 			if (compat20) {
 				if (len > c->remote_window)
@@ -1089,6 +1098,9 @@
 		    c->remote_window > 0 &&
 		    (len = buffer_len(&c->extended)) > 0 &&
 		    c->extended_usage == CHAN_EXTENDED_READ) {
+			debug2("channel %d: rwin %d elen %d euse %d",
+			    c->self, c->remote_window, buffer_len(&c->extended),
+			    c->extended_usage);
 			if (len > c->remote_window)
 				len = c->remote_window;
 			if (len > c->remote_maxpacket)
@@ -1100,6 +1112,7 @@
 			packet_send();
 			buffer_consume(&c->extended, len);
 			c->remote_window -= len;
+			debug2("channel %d: sent ext data %d", c->self, len);
 		}
 	}
 }





More information about the openssh-unix-dev mailing list