diff options
Diffstat (limited to 'channels.c')
-rw-r--r-- | channels.c | 49 |
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" |
42 | RCSID("$OpenBSD: channels.c,v 1.139 2001/10/09 21:59:41 markus Exp $"); | 42 | RCSID("$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 */ | ||
1520 | static void | ||
1521 | channel_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 | |||
1523 | static void | 1541 | static void |
1524 | channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset) | 1542 | channel_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 | ||