summaryrefslogtreecommitdiff
path: root/channels.c
diff options
context:
space:
mode:
Diffstat (limited to 'channels.c')
-rw-r--r--channels.c49
1 files changed, 25 insertions, 24 deletions
diff --git a/channels.c b/channels.c
index 04efd7287..62fd73d74 100644
--- a/channels.c
+++ b/channels.c
@@ -39,7 +39,7 @@
39 */ 39 */
40 40
41#include "includes.h" 41#include "includes.h"
42RCSID("$OpenBSD: channels.c,v 1.139 2001/10/09 21:59:41 markus Exp $"); 42RCSID("$OpenBSD: channels.c,v 1.140 2001/10/10 22:18:47 markus Exp $");
43 43
44#include "ssh.h" 44#include "ssh.h"
45#include "ssh1.h" 45#include "ssh1.h"
@@ -331,10 +331,6 @@ channel_free(Channel *c)
331 debug3("channel_free: status: %s", s); 331 debug3("channel_free: status: %s", s);
332 xfree(s); 332 xfree(s);
333 333
334 if (c->detach_user != NULL) {
335 debug("channel_free: channel %d: detaching channel user", c->self);
336 c->detach_user(c->self, NULL);
337 }
338 if (c->sock != -1) 334 if (c->sock != -1)
339 shutdown(c->sock, SHUT_RDWR); 335 shutdown(c->sock, SHUT_RDWR);
340 channel_close_fds(c); 336 channel_close_fds(c);
@@ -1520,6 +1516,28 @@ channel_handler_init(void)
1520 channel_handler_init_15(); 1516 channel_handler_init_15();
1521} 1517}
1522 1518
1519/* gc dead channels */
1520static void
1521channel_garbage_collect(Channel *c)
1522{
1523 if (c == NULL)
1524 return;
1525 if (c->detach_user != NULL) {
1526 if (!chan_is_dead(c, 0))
1527 return;
1528 debug("channel %d: gc: notify user", c->self);
1529 c->detach_user(c->self, NULL);
1530 /* if we still have a callback */
1531 if (c->detach_user != NULL)
1532 return;
1533 debug("channel %d: gc: user detached", c->self);
1534 }
1535 if (!chan_is_dead(c, 1))
1536 return;
1537 debug("channel %d: garbage collecting", c->self);
1538 channel_free(c);
1539}
1540
1523static void 1541static void
1524channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset) 1542channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset)
1525{ 1543{
@@ -1537,24 +1555,7 @@ channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset)
1537 continue; 1555 continue;
1538 if (ftab[c->type] != NULL) 1556 if (ftab[c->type] != NULL)
1539 (*ftab[c->type])(c, readset, writeset); 1557 (*ftab[c->type])(c, readset, writeset);
1540 if (chan_is_dead(c)) { 1558 channel_garbage_collect(c);
1541 /*
1542 * we have to remove the fd's from the select mask
1543 * before the channels are free'd and the fd's are
1544 * closed
1545 */
1546 if (c->wfd != -1)
1547 FD_CLR(c->wfd, writeset);
1548 if (c->rfd != -1)
1549 FD_CLR(c->rfd, readset);
1550 if (c->efd != -1) {
1551 if (c->extended_usage == CHAN_EXTENDED_READ)
1552 FD_CLR(c->efd, readset);
1553 if (c->extended_usage == CHAN_EXTENDED_WRITE)
1554 FD_CLR(c->efd, writeset);
1555 }
1556 channel_free(c);
1557 }
1558 } 1559 }
1559} 1560}
1560 1561
@@ -1625,7 +1626,7 @@ channel_output_poll()
1625 if (compat20 && 1626 if (compat20 &&
1626 (c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) { 1627 (c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) {
1627 /* XXX is this true? */ 1628 /* XXX is this true? */
1628 debug2("channel %d: no data after CLOSE", c->self); 1629 debug3("channel %d: will not send data after close", c->self);
1629 continue; 1630 continue;
1630 } 1631 }
1631 1632