summaryrefslogtreecommitdiffstats
path: root/usr.bin/ssh/channels.c
diff options
context:
space:
mode:
authormarkus <markus@openbsd.org>2001-10-10 22:18:47 +0000
committermarkus <markus@openbsd.org>2001-10-10 22:18:47 +0000
commit76bbdeac8eaecc2bde9c0fbfbf5a422dd38ab601 (patch)
treea41c1119225acb6131dbdf023606ee1230691894 /usr.bin/ssh/channels.c
parentMention the X11 sets, with a note that there is no X server available for (diff)
downloadwireguard-openbsd-76bbdeac8eaecc2bde9c0fbfbf5a422dd38ab601.tar.xz
wireguard-openbsd-76bbdeac8eaecc2bde9c0fbfbf5a422dd38ab601.zip
try to keep channels open until an exit-status message is sent.
don't kill the login shells if the shells stdin/out/err is closed. this should now work: ssh -2n localhost 'exec > /dev/null 2>&1; sleep 10; exit 5'; echo ?
Diffstat (limited to 'usr.bin/ssh/channels.c')
-rw-r--r--usr.bin/ssh/channels.c49
1 files changed, 25 insertions, 24 deletions
diff --git a/usr.bin/ssh/channels.c b/usr.bin/ssh/channels.c
index 4f7f33b685d..3e7ba4c7e28 100644
--- a/usr.bin/ssh/channels.c
+++ b/usr.bin/ssh/channels.c
@@ -39,7 +39,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: channels.c,v 1.139 2001/10/09 21:59:41 markus Exp $");
+RCSID("$OpenBSD: channels.c,v 1.140 2001/10/10 22:18:47 markus Exp $");
#include "ssh.h"
#include "ssh1.h"
@@ -331,10 +331,6 @@ channel_free(Channel *c)
debug3("channel_free: status: %s", s);
xfree(s);
- if (c->detach_user != NULL) {
- debug("channel_free: channel %d: detaching channel user", c->self);
- c->detach_user(c->self, NULL);
- }
if (c->sock != -1)
shutdown(c->sock, SHUT_RDWR);
channel_close_fds(c);
@@ -1520,6 +1516,28 @@ channel_handler_init(void)
channel_handler_init_15();
}
+/* gc dead channels */
+static void
+channel_garbage_collect(Channel *c)
+{
+ if (c == NULL)
+ return;
+ if (c->detach_user != NULL) {
+ if (!chan_is_dead(c, 0))
+ return;
+ debug("channel %d: gc: notify user", c->self);
+ c->detach_user(c->self, NULL);
+ /* if we still have a callback */
+ if (c->detach_user != NULL)
+ return;
+ debug("channel %d: gc: user detached", c->self);
+ }
+ if (!chan_is_dead(c, 1))
+ return;
+ debug("channel %d: garbage collecting", c->self);
+ channel_free(c);
+}
+
static void
channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset)
{
@@ -1537,24 +1555,7 @@ channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset)
continue;
if (ftab[c->type] != NULL)
(*ftab[c->type])(c, readset, writeset);
- if (chan_is_dead(c)) {
- /*
- * we have to remove the fd's from the select mask
- * before the channels are free'd and the fd's are
- * closed
- */
- if (c->wfd != -1)
- FD_CLR(c->wfd, writeset);
- if (c->rfd != -1)
- FD_CLR(c->rfd, readset);
- if (c->efd != -1) {
- if (c->extended_usage == CHAN_EXTENDED_READ)
- FD_CLR(c->efd, readset);
- if (c->extended_usage == CHAN_EXTENDED_WRITE)
- FD_CLR(c->efd, writeset);
- }
- channel_free(c);
- }
+ channel_garbage_collect(c);
}
}
@@ -1625,7 +1626,7 @@ channel_output_poll()
if (compat20 &&
(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) {
/* XXX is this true? */
- debug2("channel %d: no data after CLOSE", c->self);
+ debug3("channel %d: will not send data after close", c->self);
continue;
}