summaryrefslogtreecommitdiffstats
path: root/channels.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2019-02-08 14:50:36 +1100
committerDamien Miller <djm@mindrot.org>2019-02-08 14:50:36 +1100
commit03e92dd27d491fe6d1a54e7b2f44ef1b0a916e52 (patch)
tree3c1c9e6579ad2ec2067ff26bfaa964fbc54e1436 /channels.c
parent8c53d409baeeaf652c0c125a9b164edc9dbeb6de (diff)
use same close logic for stderr as stdout
Avoids sending SIGPIPE to child processes after their parent exits if they attempt to write to stderr. Analysis and patch from JD Paul; patch reworked by Jakub Jelen and myself. bz#2071; ok dtucker@
Diffstat (limited to 'channels.c')
-rw-r--r--channels.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/channels.c b/channels.c
index 19da16eb..657381b8 100644
--- a/channels.c
+++ b/channels.c
@@ -2100,16 +2100,18 @@ channel_handle_efd_read(struct ssh *ssh, Channel *c,
fd_set *readset, fd_set *writeset)
{
char buf[CHAN_RBUF];
- int r;
ssize_t len;
+ int r, force;
+
+ force = c->isatty && c->detach_close && c->istate != CHAN_INPUT_CLOSED;
- if (!c->detach_close && !FD_ISSET(c->efd, readset))
+ if (c->efd == -1 || (!force && !FD_ISSET(c->efd, readset)))
return 1;
len = read(c->efd, buf, sizeof(buf));
debug2("channel %d: read %zd from efd %d", c->self, len, c->efd);
if (len < 0 && (errno == EINTR || ((errno == EAGAIN ||
- errno == EWOULDBLOCK) && !c->detach_close)))
+ errno == EWOULDBLOCK) && !force)))
return 1;
if (len <= 0) {
debug2("channel %d: closing read-efd %d",