summaryrefslogtreecommitdiff
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 19da16eb3..657381b80 100644
--- a/channels.c
+++ b/channels.c
@@ -2100,16 +2100,18 @@ channel_handle_efd_read(struct ssh *ssh, Channel *c,
2100 fd_set *readset, fd_set *writeset) 2100 fd_set *readset, fd_set *writeset)
2101{ 2101{
2102 char buf[CHAN_RBUF]; 2102 char buf[CHAN_RBUF];
2103 int r;
2104 ssize_t len; 2103 ssize_t len;
2104 int r, force;
2105
2106 force = c->isatty && c->detach_close && c->istate != CHAN_INPUT_CLOSED;
2105 2107
2106 if (!c->detach_close && !FD_ISSET(c->efd, readset)) 2108 if (c->efd == -1 || (!force && !FD_ISSET(c->efd, readset)))
2107 return 1; 2109 return 1;
2108 2110
2109 len = read(c->efd, buf, sizeof(buf)); 2111 len = read(c->efd, buf, sizeof(buf));
2110 debug2("channel %d: read %zd from efd %d", c->self, len, c->efd); 2112 debug2("channel %d: read %zd from efd %d", c->self, len, c->efd);
2111 if (len < 0 && (errno == EINTR || ((errno == EAGAIN || 2113 if (len < 0 && (errno == EINTR || ((errno == EAGAIN ||
2112 errno == EWOULDBLOCK) && !c->detach_close))) 2114 errno == EWOULDBLOCK) && !force)))
2113 return 1; 2115 return 1;
2114 if (len <= 0) { 2116 if (len <= 0) {
2115 debug2("channel %d: closing read-efd %d", 2117 debug2("channel %d: closing read-efd %d",