diff options
author | Damien Miller <djm@mindrot.org> | 2001-10-12 11:35:04 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2001-10-12 11:35:04 +1000 |
commit | 3ec2759ad40f054c152c753db046ac55f9670d14 (patch) | |
tree | 3b26532eed14eaf485834a531a4d187cde1b1149 /channels.c | |
parent | 4e088e4de02b6c813b498a1270df85e8136c4499 (diff) |
- (djm) OpenBSD CVS Sync
- markus@cvs.openbsd.org 2001/10/10 22:18:47
[channels.c channels.h clientloop.c nchan.c serverloop.c]
[session.c session.h]
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 'channels.c')
-rw-r--r-- | channels.c | 49 |
1 files changed, 25 insertions, 24 deletions
@@ -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; } |