summaryrefslogtreecommitdiff
path: root/channels.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2007-01-29 10:16:28 +1100
committerDamien Miller <djm@mindrot.org>2007-01-29 10:16:28 +1100
commite42bd24b22bdce7e58b517d0b797d1d66bbec52b (patch)
treeeade7b9ec5316bd757b75711e9aeaa37b50474ba /channels.c
parent07877ca68066593473fbe29dd309dcdc61b6d629 (diff)
- (djm) [channels.c serverloop.c] Fix so-called "hang on exit" (bz #52)
when closing a tty session when a background process still holds tty fds open. Great detective work and patch by Marc Aurele La France, slightly tweaked by me; ok dtucker@
Diffstat (limited to 'channels.c')
-rw-r--r--channels.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/channels.c b/channels.c
index 9d522a6c3..c68ad6419 100644
--- a/channels.c
+++ b/channels.c
@@ -1449,10 +1449,11 @@ channel_handle_rfd(Channel *c, fd_set *readset, fd_set *writeset)
1449 int len; 1449 int len;
1450 1450
1451 if (c->rfd != -1 && 1451 if (c->rfd != -1 &&
1452 FD_ISSET(c->rfd, readset)) { 1452 (c->detach_close || FD_ISSET(c->rfd, readset))) {
1453 errno = 0; 1453 errno = 0;
1454 len = read(c->rfd, buf, sizeof(buf)); 1454 len = read(c->rfd, buf, sizeof(buf));
1455 if (len < 0 && (errno == EINTR || errno == EAGAIN)) 1455 if (len < 0 && (errno == EINTR ||
1456 (errno == EAGAIN && !(c->isatty && c->detach_close))))
1456 return 1; 1457 return 1;
1457#ifndef PTY_ZEROREAD 1458#ifndef PTY_ZEROREAD
1458 if (len <= 0) { 1459 if (len <= 0) {
@@ -1604,11 +1605,12 @@ channel_handle_efd(Channel *c, fd_set *readset, fd_set *writeset)
1604 c->local_consumed += len; 1605 c->local_consumed += len;
1605 } 1606 }
1606 } else if (c->extended_usage == CHAN_EXTENDED_READ && 1607 } else if (c->extended_usage == CHAN_EXTENDED_READ &&
1607 FD_ISSET(c->efd, readset)) { 1608 (c->detach_close || FD_ISSET(c->efd, readset))) {
1608 len = read(c->efd, buf, sizeof(buf)); 1609 len = read(c->efd, buf, sizeof(buf));
1609 debug2("channel %d: read %d from efd %d", 1610 debug2("channel %d: read %d from efd %d",
1610 c->self, len, c->efd); 1611 c->self, len, c->efd);
1611 if (len < 0 && (errno == EINTR || errno == EAGAIN)) 1612 if (len < 0 && (errno == EINTR ||
1613 (errno == EAGAIN && !c->detach_close)))
1612 return 1; 1614 return 1;
1613 if (len <= 0) { 1615 if (len <= 0) {
1614 debug2("channel %d: closing read-efd %d", 1616 debug2("channel %d: closing read-efd %d",