version 1.1.1.4, 2017/10/07 19:36:12 |
version 1.1.1.5, 2019/04/20 17:13:53 |
|
|
/* $OpenBSD: nchan.c,v 1.67 2017/09/12 06:35:32 djm Exp $ */ |
/* $OpenBSD: nchan.c,v 1.69 2018/10/04 07:47:35 djm Exp $ */ |
/* |
/* |
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. |
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. |
* |
* |
Line 78 static void chan_send_eow2(struct ssh *, |
|
Line 78 static void chan_send_eow2(struct ssh *, |
|
/* helper */ |
/* helper */ |
static void chan_shutdown_write(struct ssh *, Channel *); |
static void chan_shutdown_write(struct ssh *, Channel *); |
static void chan_shutdown_read(struct ssh *, Channel *); |
static void chan_shutdown_read(struct ssh *, Channel *); |
|
static void chan_shutdown_extended_read(struct ssh *, Channel *); |
|
|
static const char *ostates[] = { "open", "drain", "wait_ieof", "closed" }; |
static const char *ostates[] = { "open", "drain", "wait_ieof", "closed" }; |
static const char *istates[] = { "open", "drain", "wait_oclose", "closed" }; |
static const char *istates[] = { "open", "drain", "wait_oclose", "closed" }; |
Line 287 chan_rcvd_oclose(struct ssh *ssh, Channe |
|
Line 288 chan_rcvd_oclose(struct ssh *ssh, Channe |
|
switch (c->istate) { |
switch (c->istate) { |
case CHAN_INPUT_OPEN: |
case CHAN_INPUT_OPEN: |
chan_shutdown_read(ssh, c); |
chan_shutdown_read(ssh, c); |
|
chan_shutdown_extended_read(ssh, c); |
chan_set_istate(c, CHAN_INPUT_CLOSED); |
chan_set_istate(c, CHAN_INPUT_CLOSED); |
break; |
break; |
case CHAN_INPUT_WAIT_DRAIN: |
case CHAN_INPUT_WAIT_DRAIN: |
if (!(c->flags & CHAN_LOCAL)) |
if (!(c->flags & CHAN_LOCAL)) |
chan_send_eof2(ssh, c); |
chan_send_eof2(ssh, c); |
|
chan_shutdown_extended_read(ssh, c); |
chan_set_istate(c, CHAN_INPUT_CLOSED); |
chan_set_istate(c, CHAN_INPUT_CLOSED); |
break; |
break; |
} |
} |
Line 371 chan_shutdown_write(struct ssh *ssh, Cha |
|
Line 374 chan_shutdown_write(struct ssh *ssh, Cha |
|
if (c->type == SSH_CHANNEL_LARVAL) |
if (c->type == SSH_CHANNEL_LARVAL) |
return; |
return; |
/* shutdown failure is allowed if write failed already */ |
/* shutdown failure is allowed if write failed already */ |
debug2("channel %d: close_write", c->self); |
debug2("channel %d: %s (i%d o%d sock %d wfd %d efd %d [%s])", |
|
c->self, __func__, c->istate, c->ostate, c->sock, c->wfd, c->efd, |
|
channel_format_extended_usage(c)); |
if (c->sock != -1) { |
if (c->sock != -1) { |
if (shutdown(c->sock, SHUT_WR) < 0) |
if (shutdown(c->sock, SHUT_WR) < 0) { |
debug2("channel %d: chan_shutdown_write: " |
debug2("channel %d: %s: shutdown() failed for " |
"shutdown() failed for fd %d: %.100s", |
"fd %d [i%d o%d]: %.100s", c->self, __func__, |
c->self, c->sock, strerror(errno)); |
c->sock, c->istate, c->ostate, |
|
strerror(errno)); |
|
} |
} else { |
} else { |
if (channel_close_fd(ssh, &c->wfd) < 0) |
if (channel_close_fd(ssh, &c->wfd) < 0) { |
logit("channel %d: chan_shutdown_write: " |
logit("channel %d: %s: close() failed for " |
"close() failed for fd %d: %.100s", |
"fd %d [i%d o%d]: %.100s", |
c->self, c->wfd, strerror(errno)); |
c->self, __func__, c->wfd, c->istate, c->ostate, |
|
strerror(errno)); |
|
} |
} |
} |
} |
} |
|
|
Line 390 chan_shutdown_read(struct ssh *ssh, Chan |
|
Line 399 chan_shutdown_read(struct ssh *ssh, Chan |
|
{ |
{ |
if (c->type == SSH_CHANNEL_LARVAL) |
if (c->type == SSH_CHANNEL_LARVAL) |
return; |
return; |
debug2("channel %d: close_read", c->self); |
debug2("channel %d: %s (i%d o%d sock %d wfd %d efd %d [%s])", |
|
c->self, __func__, c->istate, c->ostate, c->sock, c->rfd, c->efd, |
|
channel_format_extended_usage(c)); |
if (c->sock != -1) { |
if (c->sock != -1) { |
if (shutdown(c->sock, SHUT_RD) < 0) |
if (shutdown(c->sock, SHUT_RD) < 0) { |
error("channel %d: chan_shutdown_read: " |
error("channel %d: %s: shutdown() failed for " |
"shutdown() failed for fd %d [i%d o%d]: %.100s", |
"fd %d [i%d o%d]: %.100s", |
c->self, c->sock, c->istate, c->ostate, |
c->self, __func__, c->sock, c->istate, c->ostate, |
strerror(errno)); |
strerror(errno)); |
|
} |
} else { |
} else { |
if (channel_close_fd(ssh, &c->rfd) < 0) |
if (channel_close_fd(ssh, &c->rfd) < 0) { |
logit("channel %d: chan_shutdown_read: " |
logit("channel %d: %s: close() failed for " |
"close() failed for fd %d: %.100s", |
"fd %d [i%d o%d]: %.100s", |
c->self, c->rfd, strerror(errno)); |
c->self, __func__, c->rfd, c->istate, c->ostate, |
|
strerror(errno)); |
|
} |
|
} |
|
} |
|
|
|
static void |
|
chan_shutdown_extended_read(struct ssh *ssh, Channel *c) |
|
{ |
|
if (c->type == SSH_CHANNEL_LARVAL || c->efd == -1) |
|
return; |
|
if (c->extended_usage != CHAN_EXTENDED_READ && |
|
c->extended_usage != CHAN_EXTENDED_IGNORE) |
|
return; |
|
debug2("channel %d: %s (i%d o%d sock %d wfd %d efd %d [%s])", |
|
c->self, __func__, c->istate, c->ostate, c->sock, c->rfd, c->efd, |
|
channel_format_extended_usage(c)); |
|
if (channel_close_fd(ssh, &c->efd) < 0) { |
|
logit("channel %d: %s: close() failed for " |
|
"extended fd %d [i%d o%d]: %.100s", |
|
c->self, __func__, c->efd, c->istate, c->ostate, |
|
strerror(errno)); |
} |
} |
} |
} |