- (djm) OpenBSD CVS Sync
- markus@cvs.openbsd.org 2001/10/10 22:18:47 [channels.c channels.h clientloop.c nchan.c serverloop.c] [session.c session.h] try to keep channels open until an exit-status message is sent. don't kill the login shells if the shells stdin/out/err is closed. this should now work: ssh -2n localhost 'exec > /dev/null 2>&1; sleep 10; exit 5'; echo ?
This commit is contained in:
parent
4e088e4de0
commit
3ec2759ad4
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
20011012
|
||||
- (djm) OpenBSD CVS Sync
|
||||
- markus@cvs.openbsd.org 2001/10/10 22:18:47
|
||||
[channels.c channels.h clientloop.c nchan.c serverloop.c]
|
||||
[session.c session.h]
|
||||
try to keep channels open until an exit-status message is sent.
|
||||
don't kill the login shells if the shells stdin/out/err is closed.
|
||||
this should now work:
|
||||
ssh -2n localhost 'exec > /dev/null 2>&1; sleep 10; exit 5'; echo ?
|
||||
|
||||
20011010
|
||||
- (djm) OpenBSD CVS Sync
|
||||
- markus@cvs.openbsd.org 2001/10/04 14:34:16
|
||||
|
@ -6695,4 +6705,4 @@
|
|||
- Wrote replacements for strlcpy and mkdtemp
|
||||
- Released 1.0pre1
|
||||
|
||||
$Id: ChangeLog,v 1.1600 2001/10/10 20:45:43 mouring Exp $
|
||||
$Id: ChangeLog,v 1.1601 2001/10/12 01:35:04 djm Exp $
|
||||
|
|
49
channels.c
49
channels.c
|
@ -39,7 +39,7 @@
|
|||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: channels.c,v 1.139 2001/10/09 21:59:41 markus Exp $");
|
||||
RCSID("$OpenBSD: channels.c,v 1.140 2001/10/10 22:18:47 markus Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "ssh1.h"
|
||||
|
@ -331,10 +331,6 @@ channel_free(Channel *c)
|
|||
debug3("channel_free: status: %s", s);
|
||||
xfree(s);
|
||||
|
||||
if (c->detach_user != NULL) {
|
||||
debug("channel_free: channel %d: detaching channel user", c->self);
|
||||
c->detach_user(c->self, NULL);
|
||||
}
|
||||
if (c->sock != -1)
|
||||
shutdown(c->sock, SHUT_RDWR);
|
||||
channel_close_fds(c);
|
||||
|
@ -1520,6 +1516,28 @@ channel_handler_init(void)
|
|||
channel_handler_init_15();
|
||||
}
|
||||
|
||||
/* gc dead channels */
|
||||
static void
|
||||
channel_garbage_collect(Channel *c)
|
||||
{
|
||||
if (c == NULL)
|
||||
return;
|
||||
if (c->detach_user != NULL) {
|
||||
if (!chan_is_dead(c, 0))
|
||||
return;
|
||||
debug("channel %d: gc: notify user", c->self);
|
||||
c->detach_user(c->self, NULL);
|
||||
/* if we still have a callback */
|
||||
if (c->detach_user != NULL)
|
||||
return;
|
||||
debug("channel %d: gc: user detached", c->self);
|
||||
}
|
||||
if (!chan_is_dead(c, 1))
|
||||
return;
|
||||
debug("channel %d: garbage collecting", c->self);
|
||||
channel_free(c);
|
||||
}
|
||||
|
||||
static void
|
||||
channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset)
|
||||
{
|
||||
|
@ -1537,24 +1555,7 @@ channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset)
|
|||
continue;
|
||||
if (ftab[c->type] != NULL)
|
||||
(*ftab[c->type])(c, readset, writeset);
|
||||
if (chan_is_dead(c)) {
|
||||
/*
|
||||
* we have to remove the fd's from the select mask
|
||||
* before the channels are free'd and the fd's are
|
||||
* closed
|
||||
*/
|
||||
if (c->wfd != -1)
|
||||
FD_CLR(c->wfd, writeset);
|
||||
if (c->rfd != -1)
|
||||
FD_CLR(c->rfd, readset);
|
||||
if (c->efd != -1) {
|
||||
if (c->extended_usage == CHAN_EXTENDED_READ)
|
||||
FD_CLR(c->efd, readset);
|
||||
if (c->extended_usage == CHAN_EXTENDED_WRITE)
|
||||
FD_CLR(c->efd, writeset);
|
||||
}
|
||||
channel_free(c);
|
||||
}
|
||||
channel_garbage_collect(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1625,7 +1626,7 @@ channel_output_poll()
|
|||
if (compat20 &&
|
||||
(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) {
|
||||
/* XXX is this true? */
|
||||
debug2("channel %d: no data after CLOSE", c->self);
|
||||
debug3("channel %d: will not send data after close", c->self);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/* RCSID("$OpenBSD: channels.h,v 1.49 2001/10/09 21:59:41 markus Exp $"); */
|
||||
/* RCSID("$OpenBSD: channels.h,v 1.50 2001/10/10 22:18:47 markus Exp $"); */
|
||||
|
||||
#ifndef CHANNEL_H
|
||||
#define CHANNEL_H
|
||||
|
@ -214,7 +214,7 @@ void auth_input_open_request(int, int, void *);
|
|||
|
||||
/* channel close */
|
||||
|
||||
int chan_is_dead(Channel *);
|
||||
int chan_is_dead(Channel *, int);
|
||||
void chan_mark_dead(Channel *);
|
||||
void chan_init_iostates(Channel *);
|
||||
void chan_init(void);
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: clientloop.c,v 1.82 2001/09/17 20:52:47 markus Exp $");
|
||||
RCSID("$OpenBSD: clientloop.c,v 1.83 2001/10/10 22:18:47 markus Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "ssh1.h"
|
||||
|
@ -753,6 +753,7 @@ client_channel_closed(int id, void *arg)
|
|||
if (id != session_ident)
|
||||
error("client_channel_closed: id %d != session_ident %d",
|
||||
id, session_ident);
|
||||
channel_cancel_cleanup(id);
|
||||
session_closed = 1;
|
||||
if (in_raw_mode())
|
||||
leave_raw_mode();
|
||||
|
|
15
nchan.c
15
nchan.c
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: nchan.c,v 1.31 2001/07/17 21:04:57 markus Exp $");
|
||||
RCSID("$OpenBSD: nchan.c,v 1.32 2001/10/10 22:18:47 markus Exp $");
|
||||
|
||||
#include "ssh1.h"
|
||||
#include "ssh2.h"
|
||||
|
@ -432,7 +432,7 @@ chan_mark_dead(Channel *c)
|
|||
}
|
||||
|
||||
int
|
||||
chan_is_dead(Channel *c)
|
||||
chan_is_dead(Channel *c, int send)
|
||||
{
|
||||
if (c->type == SSH_CHANNEL_ZOMBIE) {
|
||||
debug("channel %d: zombie", c->self);
|
||||
|
@ -461,7 +461,16 @@ chan_is_dead(Channel *c)
|
|||
"read": "write");
|
||||
} else {
|
||||
if (!(c->flags & CHAN_CLOSE_SENT)) {
|
||||
chan_send_close2(c);
|
||||
if (send) {
|
||||
chan_send_close2(c);
|
||||
} else {
|
||||
/* channel would be dead if we sent a close */
|
||||
if (c->flags & CHAN_CLOSE_RCVD) {
|
||||
debug("channel %d: almost dead",
|
||||
c->self);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((c->flags & CHAN_CLOSE_SENT) &&
|
||||
(c->flags & CHAN_CLOSE_RCVD)) {
|
||||
|
|
57
serverloop.c
57
serverloop.c
|
@ -35,7 +35,7 @@
|
|||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: serverloop.c,v 1.81 2001/10/09 21:59:41 markus Exp $");
|
||||
RCSID("$OpenBSD: serverloop.c,v 1.82 2001/10/10 22:18:47 markus Exp $");
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "packet.h"
|
||||
|
@ -208,9 +208,6 @@ wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
|
|||
max_time_milliseconds = options.client_alive_interval * 1000;
|
||||
}
|
||||
|
||||
/* When select fails we restart from here. */
|
||||
retry_select:
|
||||
|
||||
/* Allocate and update select() masks for channel descriptors. */
|
||||
channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, 0);
|
||||
|
||||
|
@ -275,12 +272,11 @@ retry_select:
|
|||
ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp);
|
||||
|
||||
if (ret == -1) {
|
||||
memset(*readsetp, 0, *maxfdp);
|
||||
memset(*writesetp, 0, *maxfdp);
|
||||
if (errno != EINTR)
|
||||
error("select: %.100s", strerror(errno));
|
||||
else
|
||||
goto retry_select;
|
||||
}
|
||||
if (ret == 0 && client_alive_scheduled)
|
||||
} else if (ret == 0 && client_alive_scheduled)
|
||||
client_alive_check();
|
||||
}
|
||||
|
||||
|
@ -668,13 +664,30 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
|
|||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static void
|
||||
collect_children(void)
|
||||
{
|
||||
pid_t pid;
|
||||
sigset_t oset, nset;
|
||||
int status;
|
||||
|
||||
/* block SIGCHLD while we check for dead children */
|
||||
sigemptyset(&nset);
|
||||
sigaddset(&nset, SIGCHLD);
|
||||
sigprocmask(SIG_BLOCK, &nset, &oset);
|
||||
if (child_terminated) {
|
||||
while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
|
||||
session_close_by_pid(pid, status);
|
||||
child_terminated = 0;
|
||||
}
|
||||
sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
server_loop2(Authctxt *authctxt)
|
||||
{
|
||||
fd_set *readset = NULL, *writeset = NULL;
|
||||
int rekeying = 0, max_fd, status, nalloc = 0;
|
||||
pid_t pid;
|
||||
sigset_t oset, nset;
|
||||
int rekeying = 0, max_fd, nalloc = 0;
|
||||
|
||||
debug("Entering interactive session for SSH2.");
|
||||
|
||||
|
@ -698,16 +711,7 @@ server_loop2(Authctxt *authctxt)
|
|||
wait_until_can_do_something(&readset, &writeset, &max_fd,
|
||||
&nalloc, 0);
|
||||
|
||||
/* block SIGCHLD while we check for dead children */
|
||||
sigemptyset(&nset);
|
||||
sigaddset(&nset, SIGCHLD);
|
||||
sigprocmask(SIG_BLOCK, &nset, &oset);
|
||||
if (child_terminated) {
|
||||
while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
|
||||
session_close_by_pid(pid, status);
|
||||
child_terminated = 0;
|
||||
}
|
||||
sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
collect_children();
|
||||
if (!rekeying)
|
||||
channel_after_select(readset, writeset);
|
||||
process_input(readset);
|
||||
|
@ -715,6 +719,8 @@ server_loop2(Authctxt *authctxt)
|
|||
break;
|
||||
process_output(writeset);
|
||||
}
|
||||
collect_children();
|
||||
|
||||
if (readset)
|
||||
xfree(readset);
|
||||
if (writeset)
|
||||
|
@ -723,13 +729,8 @@ server_loop2(Authctxt *authctxt)
|
|||
/* free all channels, no more reads and writes */
|
||||
channel_free_all();
|
||||
|
||||
/* collect remaining dead children, XXX not necessary? */
|
||||
mysignal(SIGCHLD, SIG_DFL);
|
||||
while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
|
||||
session_close_by_pid(pid, status);
|
||||
|
||||
/* close remaining sessions, e.g remove wtmp entries */
|
||||
session_close_all();
|
||||
/* free remaining sessions, e.g. remove wtmp entries */
|
||||
session_destroy_all();
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
29
session.c
29
session.c
|
@ -33,7 +33,7 @@
|
|||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: session.c,v 1.106 2001/10/09 21:59:41 markus Exp $");
|
||||
RCSID("$OpenBSD: session.c,v 1.107 2001/10/10 22:18:47 markus Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "ssh1.h"
|
||||
|
@ -1958,36 +1958,29 @@ session_close_by_channel(int id, void *arg)
|
|||
{
|
||||
Session *s = session_by_channel(id);
|
||||
if (s == NULL) {
|
||||
debug("session_close_by_channel: no session for channel %d", id);
|
||||
debug("session_close_by_channel: no session for id %d", id);
|
||||
return;
|
||||
}
|
||||
/* disconnect channel */
|
||||
debug("session_close_by_channel: channel %d child %d", id, s->pid);
|
||||
if (s->pid != 0) {
|
||||
/* delay detach */
|
||||
debug("session_close_by_channel: channel %d: has child", id);
|
||||
return;
|
||||
}
|
||||
/* detach by removing callback */
|
||||
channel_cancel_cleanup(s->chanid);
|
||||
s->chanid = -1;
|
||||
|
||||
debug("session_close_by_channel: channel %d kill %d", id, s->pid);
|
||||
if (s->pid != 0) {
|
||||
/* notify child */
|
||||
if (kill(s->pid, SIGHUP) < 0)
|
||||
error("session_close_by_channel: kill %d: %s",
|
||||
s->pid, strerror(errno));
|
||||
}
|
||||
session_close(s);
|
||||
}
|
||||
|
||||
void
|
||||
session_close_all(void)
|
||||
session_destroy_all(void)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < MAX_SESSIONS; i++) {
|
||||
Session *s = &sessions[i];
|
||||
if (s->used) {
|
||||
if (s->chanid != -1) {
|
||||
channel_cancel_cleanup(s->chanid);
|
||||
s->chanid = -1;
|
||||
}
|
||||
if (s->used)
|
||||
session_close(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: session.h,v 1.12 2001/10/09 21:59:41 markus Exp $ */
|
||||
/* $OpenBSD: session.h,v 1.13 2001/10/10 22:18:47 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
|
@ -32,6 +32,6 @@ int session_open(Authctxt*, int);
|
|||
void session_input_channel_req(int, void *);
|
||||
void session_close_by_pid(pid_t, int);
|
||||
void session_close_by_channel(int, void *);
|
||||
void session_close_all(void);
|
||||
void session_destroy_all(void);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue