=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/session.c,v retrieving revision 1.186 retrieving revision 1.187 diff -u -r1.186 -r1.187 --- src/usr.bin/ssh/session.c 2005/07/25 11:59:40 1.186 +++ src/usr.bin/ssh/session.c 2005/10/10 10:23:08 1.187 @@ -33,7 +33,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: session.c,v 1.186 2005/07/25 11:59:40 markus Exp $"); +RCSID("$OpenBSD: session.c,v 1.187 2005/10/10 10:23:08 djm Exp $"); #include "ssh.h" #include "ssh1.h" @@ -1792,7 +1792,6 @@ session_exit_message(Session *s, int status) { Channel *c; - u_int i; if ((c = channel_lookup(s->chanid)) == NULL) fatal("session_exit_message: session %d: no channel %d", @@ -1818,8 +1817,16 @@ /* disconnect channel */ debug("session_exit_message: release channel %d", s->chanid); - channel_cancel_cleanup(s->chanid); + s->pid = 0; + /* + * Adjust cleanup callback attachment to send close messages when + * the channel gets EOF. The session will be then be closed + * by session_close_by_channel when the childs close their fds. + */ + channel_register_cleanup(c->self, session_close_by_channel, 1); + + /* * emulate a write failure with 'chan_write_failed', nobody will be * interested in data we write. * Note that we must not call 'chan_read_failed', since there could @@ -1827,15 +1834,6 @@ */ if (c->ostate != CHAN_OUTPUT_CLOSED) chan_write_failed(c); - s->chanid = -1; - - /* Close any X11 listeners associated with this session */ - if (s->x11_chanids != NULL) { - for (i = 0; s->x11_chanids[i] != -1; i++) { - session_close_x11(s->x11_chanids[i]); - s->x11_chanids[i] = -1; - } - } } void @@ -1879,7 +1877,8 @@ } if (s->chanid != -1) session_exit_message(s, status); - session_close(s); + if (s->ttyfd != -1) + session_pty_cleanup(s); } /* @@ -1890,6 +1889,7 @@ session_close_by_channel(int id, void *arg) { Session *s = session_by_channel(id); + u_int i; if (s == NULL) { debug("session_close_by_channel: no session for id %d", id); @@ -1909,6 +1909,15 @@ } /* detach by removing callback */ channel_cancel_cleanup(s->chanid); + + /* Close any X11 listeners associated with this session */ + if (s->x11_chanids != NULL) { + for (i = 0; s->x11_chanids[i] != -1; i++) { + session_close_x11(s->x11_chanids[i]); + s->x11_chanids[i] = -1; + } + } + s->chanid = -1; session_close(s); } @@ -1994,7 +2003,7 @@ } for (i = 0; s->x11_chanids[i] != -1; i++) { channel_register_cleanup(s->x11_chanids[i], - session_close_single_x11); + session_close_single_x11, 0); } /* Set up a suitable value for the DISPLAY variable. */