mirror of
git://anongit.mindrot.org/openssh.git
synced 2024-12-26 11:52:06 +00:00
- (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@
This commit is contained in:
parent
07877ca680
commit
e42bd24b22
@ -1,3 +1,9 @@
|
||||
20070128
|
||||
- (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@
|
||||
|
||||
20070123
|
||||
- (dtucker) [openbsd-compat/bsd-snprintf.c] Static declarations for public
|
||||
library interfaces aren't very helpful. Fix up the DOPR_OUTCH macro
|
||||
@ -2686,4 +2692,4 @@
|
||||
OpenServer 6 and add osr5bigcrypt support so when someone migrates
|
||||
passwords between UnixWare and OpenServer they will still work. OK dtucker@
|
||||
|
||||
$Id: ChangeLog,v 1.4608 2007/01/23 13:07:29 dtucker Exp $
|
||||
$Id: ChangeLog,v 1.4609 2007/01/28 23:16:28 djm Exp $
|
||||
|
10
channels.c
10
channels.c
@ -1449,10 +1449,11 @@ channel_handle_rfd(Channel *c, fd_set *readset, fd_set *writeset)
|
||||
int len;
|
||||
|
||||
if (c->rfd != -1 &&
|
||||
FD_ISSET(c->rfd, readset)) {
|
||||
(c->detach_close || FD_ISSET(c->rfd, readset))) {
|
||||
errno = 0;
|
||||
len = read(c->rfd, buf, sizeof(buf));
|
||||
if (len < 0 && (errno == EINTR || errno == EAGAIN))
|
||||
if (len < 0 && (errno == EINTR ||
|
||||
(errno == EAGAIN && !(c->isatty && c->detach_close))))
|
||||
return 1;
|
||||
#ifndef PTY_ZEROREAD
|
||||
if (len <= 0) {
|
||||
@ -1604,11 +1605,12 @@ channel_handle_efd(Channel *c, fd_set *readset, fd_set *writeset)
|
||||
c->local_consumed += len;
|
||||
}
|
||||
} else if (c->extended_usage == CHAN_EXTENDED_READ &&
|
||||
FD_ISSET(c->efd, readset)) {
|
||||
(c->detach_close || FD_ISSET(c->efd, readset))) {
|
||||
len = read(c->efd, buf, sizeof(buf));
|
||||
debug2("channel %d: read %d from efd %d",
|
||||
c->self, len, c->efd);
|
||||
if (len < 0 && (errno == EINTR || errno == EAGAIN))
|
||||
if (len < 0 && (errno == EINTR ||
|
||||
(errno == EAGAIN && !c->detach_close)))
|
||||
return 1;
|
||||
if (len <= 0) {
|
||||
debug2("channel %d: closing read-efd %d",
|
||||
|
20
serverloop.c
20
serverloop.c
@ -280,6 +280,7 @@ wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
|
||||
struct timeval tv, *tvp;
|
||||
int ret;
|
||||
int client_alive_scheduled = 0;
|
||||
int program_alive_scheduled = 0;
|
||||
|
||||
/*
|
||||
* if using client_alive, set the max timeout accordingly,
|
||||
@ -317,6 +318,7 @@ wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
|
||||
* the client, try to get some more data from the program.
|
||||
*/
|
||||
if (packet_not_very_much_data_to_write()) {
|
||||
program_alive_scheduled = child_terminated;
|
||||
if (!fdout_eof)
|
||||
FD_SET(fdout, *readsetp);
|
||||
if (!fderr_eof)
|
||||
@ -362,8 +364,16 @@ wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
|
||||
memset(*writesetp, 0, *nallocp);
|
||||
if (errno != EINTR)
|
||||
error("select: %.100s", strerror(errno));
|
||||
} else if (ret == 0 && client_alive_scheduled)
|
||||
client_alive_check();
|
||||
} else {
|
||||
if (ret == 0 && client_alive_scheduled)
|
||||
client_alive_check();
|
||||
if (!compat20 && program_alive_scheduled && fdin_is_tty) {
|
||||
if (!fdout_eof)
|
||||
FD_SET(fdout, *readsetp);
|
||||
if (!fderr_eof)
|
||||
FD_SET(fderr, *readsetp);
|
||||
}
|
||||
}
|
||||
|
||||
notify_done(*readsetp);
|
||||
}
|
||||
@ -407,7 +417,8 @@ process_input(fd_set *readset)
|
||||
if (!fdout_eof && FD_ISSET(fdout, readset)) {
|
||||
errno = 0;
|
||||
len = read(fdout, buf, sizeof(buf));
|
||||
if (len < 0 && (errno == EINTR || errno == EAGAIN)) {
|
||||
if (len < 0 && (errno == EINTR ||
|
||||
(errno == EAGAIN && !child_terminated))) {
|
||||
/* do nothing */
|
||||
#ifndef PTY_ZEROREAD
|
||||
} else if (len <= 0) {
|
||||
@ -425,7 +436,8 @@ process_input(fd_set *readset)
|
||||
if (!fderr_eof && FD_ISSET(fderr, readset)) {
|
||||
errno = 0;
|
||||
len = read(fderr, buf, sizeof(buf));
|
||||
if (len < 0 && (errno == EINTR || errno == EAGAIN)) {
|
||||
if (len < 0 && (errno == EINTR ||
|
||||
(errno == EAGAIN && !child_terminated))) {
|
||||
/* do nothing */
|
||||
#ifndef PTY_ZEROREAD
|
||||
} else if (len <= 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user