summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/ssh/channels.c9
-rw-r--r--usr.bin/ssh/channels.h7
-rw-r--r--usr.bin/ssh/clientloop.c4
-rw-r--r--usr.bin/ssh/serverloop.c4
-rw-r--r--usr.bin/ssh/session.c37
5 files changed, 37 insertions, 24 deletions
diff --git a/usr.bin/ssh/channels.c b/usr.bin/ssh/channels.c
index fea40009a48..2e40907d9e3 100644
--- a/usr.bin/ssh/channels.c
+++ b/usr.bin/ssh/channels.c
@@ -39,7 +39,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: channels.c,v 1.224 2005/09/07 08:53:53 markus Exp $");
+RCSID("$OpenBSD: channels.c,v 1.225 2005/10/10 10:23:08 djm Exp $");
#include "ssh.h"
#include "ssh1.h"
@@ -268,6 +268,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
c->force_drain = 0;
c->single_connection = 0;
c->detach_user = NULL;
+ c->detach_close = 0;
c->confirm = NULL;
c->confirm_ctx = NULL;
c->input_filter = NULL;
@@ -627,7 +628,7 @@ channel_register_confirm(int id, channel_callback_fn *fn, void *ctx)
c->confirm_ctx = ctx;
}
void
-channel_register_cleanup(int id, channel_callback_fn *fn)
+channel_register_cleanup(int id, channel_callback_fn *fn, int do_close)
{
Channel *c = channel_lookup(id);
@@ -636,6 +637,7 @@ channel_register_cleanup(int id, channel_callback_fn *fn)
return;
}
c->detach_user = fn;
+ c->detach_close = do_close;
}
void
channel_cancel_cleanup(int id)
@@ -647,6 +649,7 @@ channel_cancel_cleanup(int id)
return;
}
c->detach_user = NULL;
+ c->detach_close = 0;
}
void
channel_register_filter(int id, channel_filter_fn *fn)
@@ -1660,7 +1663,7 @@ channel_garbage_collect(Channel *c)
if (c == NULL)
return;
if (c->detach_user != NULL) {
- if (!chan_is_dead(c, 0))
+ if (!chan_is_dead(c, c->detach_close))
return;
debug2("channel %d: gc: notify user", c->self);
c->detach_user(c->self, NULL);
diff --git a/usr.bin/ssh/channels.h b/usr.bin/ssh/channels.h
index 27e760858c7..cd882b46f34 100644
--- a/usr.bin/ssh/channels.h
+++ b/usr.bin/ssh/channels.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.h,v 1.79 2005/07/17 06:49:04 djm Exp $ */
+/* $OpenBSD: channels.h,v 1.80 2005/10/10 10:23:08 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -105,8 +105,9 @@ struct Channel {
/* callback */
channel_callback_fn *confirm;
- channel_callback_fn *detach_user;
void *confirm_ctx;
+ channel_callback_fn *detach_user;
+ int detach_close;
/* filter */
channel_filter_fn *input_filter;
@@ -162,7 +163,7 @@ void channel_stop_listening(void);
void channel_send_open(int);
void channel_request_start(int, char *, int);
-void channel_register_cleanup(int, channel_callback_fn *);
+void channel_register_cleanup(int, channel_callback_fn *, int);
void channel_register_confirm(int, channel_callback_fn *, void *);
void channel_register_filter(int, channel_filter_fn *);
void channel_cancel_cleanup(int);
diff --git a/usr.bin/ssh/clientloop.c b/usr.bin/ssh/clientloop.c
index da5bfd7bd19..fed68495635 100644
--- a/usr.bin/ssh/clientloop.c
+++ b/usr.bin/ssh/clientloop.c
@@ -59,7 +59,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: clientloop.c,v 1.142 2005/09/09 19:18:05 markus Exp $");
+RCSID("$OpenBSD: clientloop.c,v 1.143 2005/10/10 10:23:08 djm Exp $");
#include "ssh.h"
#include "ssh1.h"
@@ -1379,7 +1379,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
simple_escape_filter);
if (session_ident != -1)
channel_register_cleanup(session_ident,
- client_channel_closed);
+ client_channel_closed, 0);
} else {
/* Check if we should immediately send eof on stdin. */
client_check_initial_eof_on_stdin();
diff --git a/usr.bin/ssh/serverloop.c b/usr.bin/ssh/serverloop.c
index 758d73f3b55..138f386fee4 100644
--- a/usr.bin/ssh/serverloop.c
+++ b/usr.bin/ssh/serverloop.c
@@ -35,7 +35,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: serverloop.c,v 1.118 2005/07/17 07:17:55 djm Exp $");
+RCSID("$OpenBSD: serverloop.c,v 1.119 2005/10/10 10:23:08 djm Exp $");
#include "xmalloc.h"
#include "packet.h"
@@ -898,7 +898,7 @@ server_request_session(void)
channel_free(c);
return NULL;
}
- channel_register_cleanup(c->self, session_close_by_channel);
+ channel_register_cleanup(c->self, session_close_by_channel, 0);
return c;
}
diff --git a/usr.bin/ssh/session.c b/usr.bin/ssh/session.c
index 67d22e94267..ac084ab22f5 100644
--- a/usr.bin/ssh/session.c
+++ b/usr.bin/ssh/session.c
@@ -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 @@ static void
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,7 +1817,15 @@ session_exit_message(Session *s, int status)
/* 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.
@@ -1827,15 +1834,6 @@ session_exit_message(Session *s, int status)
*/
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 @@ session_close_by_pid(pid_t pid, int status)
}
if (s->chanid != -1)
session_exit_message(s, status);
- session_close(s);
+ if (s->ttyfd != -1)
+ session_pty_cleanup(s);
}
/*
@@ -1890,6 +1889,7 @@ void
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 @@ session_close_by_channel(int id, void *arg)
}
/* 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 @@ session_setup_x11fwd(Session *s)
}
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. */