summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nchan.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/nchan.c b/nchan.c
index da7a9d6d6..8294d7fca 100644
--- a/nchan.c
+++ b/nchan.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: nchan.c,v 1.68 2018/10/04 00:10:11 djm Exp $ */ 1/* $OpenBSD: nchan.c,v 1.69 2018/10/04 07:47:35 djm Exp $ */
2/* 2/*
3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. 3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
4 * 4 *
@@ -80,6 +80,7 @@ static void chan_send_eow2(struct ssh *, Channel *);
80/* helper */ 80/* helper */
81static void chan_shutdown_write(struct ssh *, Channel *); 81static void chan_shutdown_write(struct ssh *, Channel *);
82static void chan_shutdown_read(struct ssh *, Channel *); 82static void chan_shutdown_read(struct ssh *, Channel *);
83static void chan_shutdown_extended_read(struct ssh *, Channel *);
83 84
84static const char *ostates[] = { "open", "drain", "wait_ieof", "closed" }; 85static const char *ostates[] = { "open", "drain", "wait_ieof", "closed" };
85static const char *istates[] = { "open", "drain", "wait_oclose", "closed" }; 86static const char *istates[] = { "open", "drain", "wait_oclose", "closed" };
@@ -289,11 +290,13 @@ chan_rcvd_oclose(struct ssh *ssh, Channel *c)
289 switch (c->istate) { 290 switch (c->istate) {
290 case CHAN_INPUT_OPEN: 291 case CHAN_INPUT_OPEN:
291 chan_shutdown_read(ssh, c); 292 chan_shutdown_read(ssh, c);
293 chan_shutdown_extended_read(ssh, c);
292 chan_set_istate(c, CHAN_INPUT_CLOSED); 294 chan_set_istate(c, CHAN_INPUT_CLOSED);
293 break; 295 break;
294 case CHAN_INPUT_WAIT_DRAIN: 296 case CHAN_INPUT_WAIT_DRAIN:
295 if (!(c->flags & CHAN_LOCAL)) 297 if (!(c->flags & CHAN_LOCAL))
296 chan_send_eof2(ssh, c); 298 chan_send_eof2(ssh, c);
299 chan_shutdown_extended_read(ssh, c);
297 chan_set_istate(c, CHAN_INPUT_CLOSED); 300 chan_set_istate(c, CHAN_INPUT_CLOSED);
298 break; 301 break;
299 } 302 }
@@ -422,3 +425,22 @@ chan_shutdown_read(struct ssh *ssh, Channel *c)
422 } 425 }
423 } 426 }
424} 427}
428
429static void
430chan_shutdown_extended_read(struct ssh *ssh, Channel *c)
431{
432 if (c->type == SSH_CHANNEL_LARVAL || c->efd == -1)
433 return;
434 if (c->extended_usage != CHAN_EXTENDED_READ &&
435 c->extended_usage != CHAN_EXTENDED_IGNORE)
436 return;
437 debug2("channel %d: %s (i%d o%d sock %d wfd %d efd %d [%s])",
438 c->self, __func__, c->istate, c->ostate, c->sock, c->rfd, c->efd,
439 channel_format_extended_usage(c));
440 if (channel_close_fd(ssh, &c->efd) < 0) {
441 logit("channel %d: %s: close() failed for "
442 "extended fd %d [i%d o%d]: %.100s",
443 c->self, __func__, c->efd, c->istate, c->ostate,
444 strerror(errno));
445 }
446}